123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- // Copyright 2013 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef BASE_ONE_SHOT_EVENT_H_
- #define BASE_ONE_SHOT_EVENT_H_
- #include <vector>
- #include "base/callback_forward.h"
- #include "base/check.h"
- #include "base/memory/ref_counted.h"
- #include "base/memory/weak_ptr.h"
- #include "base/threading/thread_checker.h"
- #include "base/threading/thread_task_runner_handle.h"
- namespace base {
- class Location;
- class SingleThreadTaskRunner;
- class TimeDelta;
- // This class represents an event that's expected to happen once. It
- // allows clients to guarantee that code is run after the OneShotEvent
- // is signaled. If the OneShotEvent is destroyed before it's
- // signaled, the closures are destroyed without being run.
- //
- // This class is similar to a WaitableEvent combined with several
- // WaitableEventWatchers, but using it is simpler.
- //
- // This class is not thread-safe, and must be used from a single thread.
- class BASE_EXPORT OneShotEvent {
- public:
- OneShotEvent();
- // Use the following constructor to create an already signaled event. This is
- // useful if you construct the event on a different thread from where it is
- // used, in which case it is not possible to call Signal() just after
- // construction.
- explicit OneShotEvent(bool signaled);
- ~OneShotEvent();
- // True if Signal has been called. This function is mostly for
- // migrating old code; usually calling Post() unconditionally will
- // result in more readable code.
- bool is_signaled() const {
- DCHECK(thread_checker_.CalledOnValidThread());
- return signaled_;
- }
- // Causes is_signaled() to return true and all tasks to be posted to their
- // corresponding task runners in the FIFO order. Note that tasks posted to
- // different SingleThreadTaskRunners may still execute in arbitrary order.
- // This method must only be called once.
- void Signal();
- // Scheduled |task| to be called on |runner| after is_signaled()
- // becomes true. If called with |delay|, then the task will happen
- // (roughly) |delay| after is_signaled(), *not* |delay| after the
- // post. Inside |task|, if this OneShotEvent is still alive,
- // CHECK(is_signaled()) will never fail (which implies that
- // OneShotEvent::Reset() doesn't exist).
- //
- // If |*this| is destroyed before being released, none of these
- // tasks will be executed.
- //
- // Tasks are posted in FIFO order, however, tasks posted to different
- // SingleThreadTaskRunners may still execute in an arbitrary order. Tasks will
- // never be called on the current thread before this function returns. Beware
- // that there's no simple way to wait for all tasks on a OneShotEvent to
- // complete, so it's almost never safe to use base::Unretained() when creating
- // one.
- void Post(const Location& from_here,
- OnceClosure task,
- scoped_refptr<SingleThreadTaskRunner> runner =
- ThreadTaskRunnerHandle::Get()) const;
- void PostDelayed(const Location& from_here,
- OnceClosure task,
- const TimeDelta& delay) const;
- private:
- struct TaskInfo;
- void PostImpl(const Location& from_here,
- OnceClosure task,
- scoped_refptr<SingleThreadTaskRunner> runner,
- const TimeDelta& delay) const;
- ThreadChecker thread_checker_;
- bool signaled_;
- // The task list is mutable because it's not part of the logical
- // state of the object. This lets us return const references to the
- // OneShotEvent to clients that just want to run tasks through it
- // without worrying that they'll signal the event.
- //
- // Optimization note: We could reduce the size of this class to a
- // single pointer by storing |signaled_| in the low bit of a
- // pointer, and storing the size and capacity of the array (if any)
- // on the far end of the pointer.
- mutable std::vector<TaskInfo> tasks_;
- };
- } // namespace base
- #endif // BASE_ONE_SHOT_EVENT_H_
|