1 // Copyright 2013 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_ONE_SHOT_EVENT_H_ 6 #define BASE_ONE_SHOT_EVENT_H_ 7 8 #include <vector> 9 10 #include "base/base_export.h" 11 #include "base/check.h" 12 #include "base/functional/callback_forward.h" 13 #include "base/memory/weak_ptr.h" 14 #include "base/sequence_checker.h" 15 #include "base/task/sequenced_task_runner.h" 16 #include "base/task/single_thread_task_runner.h" 17 18 namespace base { 19 20 class Location; 21 class TimeDelta; 22 23 // This class represents an event that's expected to happen once. It allows 24 // clients to guarantee that code is run after the `OneShotEvent` is signaled. 25 // If the `OneShotEvent` is destroyed before it's signaled, the closures are 26 // destroyed without being run. 27 // 28 // This class is similar to a `WaitableEvent` combined with several 29 // `WaitableEventWatcher`s, but using it is simpler. 30 // 31 // This class' methods must be used from a single sequence (although not 32 // necessarily the one in which it has been constructed). 33 // However, there are no restrictions on the `TaskRunner`s used - and hence, the 34 // sequence/thread on which the posted tasks will run. By default they will 35 // be posted to the current sequence's default task runner. 36 class BASE_EXPORT OneShotEvent { 37 public: 38 OneShotEvent(); 39 // Use the following constructor to create an already signaled event. This is 40 // useful if you construct the event on a different thread from where it is 41 // used, in which case it is not possible to call `Signal` just after 42 // construction. 43 explicit OneShotEvent(bool signaled); 44 ~OneShotEvent(); 45 46 // True if `Signal` has been called. This function is mostly for migrating old 47 // code; usually calling `Post` unconditionally will result in more readable 48 // code. is_signaled()49 bool is_signaled() const { 50 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 51 return signaled_; 52 } 53 54 // Causes `is_signaled` to return true and all tasks to be posted to their 55 // corresponding task runners in the FIFO order. Note that tasks posted to 56 // different `TaskRunner`s may still execute in arbitrary order. This 57 // method must only be called once. 58 void Signal(); 59 60 // Schedules `task` to be called on `runner` after `is_signaled` becomes 61 // `true`. If called with `delay`, then the task will happen (roughly) `delay` 62 // after `is_signaled`, *not* `delay` after the post. Inside `task`, if this 63 // `OneShotEvent` is still alive, `CHECK(is_signaled())` will never fail 64 // (which implies that `OneShotEvent::Reset` doesn't exist). 65 // 66 // If `*this` is destroyed before being released, none of these tasks will be 67 // executed. 68 // 69 // Tasks are posted in FIFO order, however, tasks may still execute in an 70 // arbitrary order (specified by the combination and type of `TaskRunner`s 71 // used). Tasks will never be called on the current sequence before this 72 // function returns. 73 // Beware that there's no simple way to wait for all tasks on a `OneShotEvent` 74 // to complete, so it's almost never safe to use `base::Unretained` when 75 // creating one. 76 void Post(const Location& from_here, 77 OnceClosure task, 78 scoped_refptr<TaskRunner> runner = 79 SequencedTaskRunner::GetCurrentDefault()) const; 80 void PostDelayed(const Location& from_here, 81 OnceClosure task, 82 const TimeDelta& delay, 83 scoped_refptr<TaskRunner> runner = 84 SequencedTaskRunner::GetCurrentDefault()) const; 85 86 private: 87 struct TaskInfo; 88 SEQUENCE_CHECKER(sequence_checker_); 89 90 bool signaled_ = false; 91 92 // The task list is mutable because it's not part of the logical state of the 93 // object. This lets us return const references to the `OneShotEvent` to 94 // clients that just want to run tasks through it without worrying that 95 // they'll signal the event. 96 // 97 // Optimization note: We could reduce the size of this class to a single 98 // pointer by storing `signaled_` in the low bit of a pointer, and storing the 99 // size and capacity of the array (if any) on the far end of the pointer. 100 mutable std::vector<TaskInfo> tasks_; 101 }; 102 103 } // namespace base 104 105 #endif // BASE_ONE_SHOT_EVENT_H_ 106