1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file. 4*635a8641SAndroid Build Coastguard Worker 5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_SEQUENCED_TASK_RUNNER_H_ 6*635a8641SAndroid Build Coastguard Worker #define BASE_SEQUENCED_TASK_RUNNER_H_ 7*635a8641SAndroid Build Coastguard Worker 8*635a8641SAndroid Build Coastguard Worker #include <memory> 9*635a8641SAndroid Build Coastguard Worker 10*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h" 11*635a8641SAndroid Build Coastguard Worker #include "base/callback.h" 12*635a8641SAndroid Build Coastguard Worker #include "base/sequenced_task_runner_helpers.h" 13*635a8641SAndroid Build Coastguard Worker #include "base/task_runner.h" 14*635a8641SAndroid Build Coastguard Worker 15*635a8641SAndroid Build Coastguard Worker namespace base { 16*635a8641SAndroid Build Coastguard Worker 17*635a8641SAndroid Build Coastguard Worker // A SequencedTaskRunner is a subclass of TaskRunner that provides 18*635a8641SAndroid Build Coastguard Worker // additional guarantees on the order that tasks are started, as well 19*635a8641SAndroid Build Coastguard Worker // as guarantees on when tasks are in sequence, i.e. one task finishes 20*635a8641SAndroid Build Coastguard Worker // before the other one starts. 21*635a8641SAndroid Build Coastguard Worker // 22*635a8641SAndroid Build Coastguard Worker // Summary 23*635a8641SAndroid Build Coastguard Worker // ------- 24*635a8641SAndroid Build Coastguard Worker // Non-nested tasks with the same delay will run one by one in FIFO 25*635a8641SAndroid Build Coastguard Worker // order. 26*635a8641SAndroid Build Coastguard Worker // 27*635a8641SAndroid Build Coastguard Worker // Detailed guarantees 28*635a8641SAndroid Build Coastguard Worker // ------------------- 29*635a8641SAndroid Build Coastguard Worker // 30*635a8641SAndroid Build Coastguard Worker // SequencedTaskRunner also adds additional methods for posting 31*635a8641SAndroid Build Coastguard Worker // non-nestable tasks. In general, an implementation of TaskRunner 32*635a8641SAndroid Build Coastguard Worker // may expose task-running methods which are themselves callable from 33*635a8641SAndroid Build Coastguard Worker // within tasks. A non-nestable task is one that is guaranteed to not 34*635a8641SAndroid Build Coastguard Worker // be run from within an already-running task. Conversely, a nestable 35*635a8641SAndroid Build Coastguard Worker // task (the default) is a task that can be run from within an 36*635a8641SAndroid Build Coastguard Worker // already-running task. 37*635a8641SAndroid Build Coastguard Worker // 38*635a8641SAndroid Build Coastguard Worker // The guarantees of SequencedTaskRunner are as follows: 39*635a8641SAndroid Build Coastguard Worker // 40*635a8641SAndroid Build Coastguard Worker // - Given two tasks T2 and T1, T2 will start after T1 starts if: 41*635a8641SAndroid Build Coastguard Worker // 42*635a8641SAndroid Build Coastguard Worker // * T2 is posted after T1; and 43*635a8641SAndroid Build Coastguard Worker // * T2 has equal or higher delay than T1; and 44*635a8641SAndroid Build Coastguard Worker // * T2 is non-nestable or T1 is nestable. 45*635a8641SAndroid Build Coastguard Worker // 46*635a8641SAndroid Build Coastguard Worker // - If T2 will start after T1 starts by the above guarantee, then 47*635a8641SAndroid Build Coastguard Worker // T2 will start after T1 finishes and is destroyed if: 48*635a8641SAndroid Build Coastguard Worker // 49*635a8641SAndroid Build Coastguard Worker // * T2 is non-nestable, or 50*635a8641SAndroid Build Coastguard Worker // * T1 doesn't call any task-running methods. 51*635a8641SAndroid Build Coastguard Worker // 52*635a8641SAndroid Build Coastguard Worker // - If T2 will start after T1 finishes by the above guarantee, then 53*635a8641SAndroid Build Coastguard Worker // all memory changes in T1 and T1's destruction will be visible 54*635a8641SAndroid Build Coastguard Worker // to T2. 55*635a8641SAndroid Build Coastguard Worker // 56*635a8641SAndroid Build Coastguard Worker // - If T2 runs nested within T1 via a call to the task-running 57*635a8641SAndroid Build Coastguard Worker // method M, then all memory changes in T1 up to the call to M 58*635a8641SAndroid Build Coastguard Worker // will be visible to T2, and all memory changes in T2 will be 59*635a8641SAndroid Build Coastguard Worker // visible to T1 from the return from M. 60*635a8641SAndroid Build Coastguard Worker // 61*635a8641SAndroid Build Coastguard Worker // Note that SequencedTaskRunner does not guarantee that tasks are run 62*635a8641SAndroid Build Coastguard Worker // on a single dedicated thread, although the above guarantees provide 63*635a8641SAndroid Build Coastguard Worker // most (but not all) of the same guarantees. If you do need to 64*635a8641SAndroid Build Coastguard Worker // guarantee that tasks are run on a single dedicated thread, see 65*635a8641SAndroid Build Coastguard Worker // SingleThreadTaskRunner (in single_thread_task_runner.h). 66*635a8641SAndroid Build Coastguard Worker // 67*635a8641SAndroid Build Coastguard Worker // Some corollaries to the above guarantees, assuming the tasks in 68*635a8641SAndroid Build Coastguard Worker // question don't call any task-running methods: 69*635a8641SAndroid Build Coastguard Worker // 70*635a8641SAndroid Build Coastguard Worker // - Tasks posted via PostTask are run in FIFO order. 71*635a8641SAndroid Build Coastguard Worker // 72*635a8641SAndroid Build Coastguard Worker // - Tasks posted via PostNonNestableTask are run in FIFO order. 73*635a8641SAndroid Build Coastguard Worker // 74*635a8641SAndroid Build Coastguard Worker // - Tasks posted with the same delay and the same nestable state 75*635a8641SAndroid Build Coastguard Worker // are run in FIFO order. 76*635a8641SAndroid Build Coastguard Worker // 77*635a8641SAndroid Build Coastguard Worker // - A list of tasks with the same nestable state posted in order of 78*635a8641SAndroid Build Coastguard Worker // non-decreasing delay is run in FIFO order. 79*635a8641SAndroid Build Coastguard Worker // 80*635a8641SAndroid Build Coastguard Worker // - A list of tasks posted in order of non-decreasing delay with at 81*635a8641SAndroid Build Coastguard Worker // most a single change in nestable state from nestable to 82*635a8641SAndroid Build Coastguard Worker // non-nestable is run in FIFO order. (This is equivalent to the 83*635a8641SAndroid Build Coastguard Worker // statement of the first guarantee above.) 84*635a8641SAndroid Build Coastguard Worker // 85*635a8641SAndroid Build Coastguard Worker // Some theoretical implementations of SequencedTaskRunner: 86*635a8641SAndroid Build Coastguard Worker // 87*635a8641SAndroid Build Coastguard Worker // - A SequencedTaskRunner that wraps a regular TaskRunner but makes 88*635a8641SAndroid Build Coastguard Worker // sure that only one task at a time is posted to the TaskRunner, 89*635a8641SAndroid Build Coastguard Worker // with appropriate memory barriers in between tasks. 90*635a8641SAndroid Build Coastguard Worker // 91*635a8641SAndroid Build Coastguard Worker // - A SequencedTaskRunner that, for each task, spawns a joinable 92*635a8641SAndroid Build Coastguard Worker // thread to run that task and immediately quit, and then 93*635a8641SAndroid Build Coastguard Worker // immediately joins that thread. 94*635a8641SAndroid Build Coastguard Worker // 95*635a8641SAndroid Build Coastguard Worker // - A SequencedTaskRunner that stores the list of posted tasks and 96*635a8641SAndroid Build Coastguard Worker // has a method Run() that runs each runnable task in FIFO order 97*635a8641SAndroid Build Coastguard Worker // that can be called from any thread, but only if another 98*635a8641SAndroid Build Coastguard Worker // (non-nested) Run() call isn't already happening. 99*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT SequencedTaskRunner : public TaskRunner { 100*635a8641SAndroid Build Coastguard Worker public: 101*635a8641SAndroid Build Coastguard Worker // The two PostNonNestable*Task methods below are like their 102*635a8641SAndroid Build Coastguard Worker // nestable equivalents in TaskRunner, but they guarantee that the 103*635a8641SAndroid Build Coastguard Worker // posted task will not run nested within an already-running task. 104*635a8641SAndroid Build Coastguard Worker // 105*635a8641SAndroid Build Coastguard Worker // A simple corollary is that posting a task as non-nestable can 106*635a8641SAndroid Build Coastguard Worker // only delay when the task gets run. That is, posting a task as 107*635a8641SAndroid Build Coastguard Worker // non-nestable may not affect when the task gets run, or it could 108*635a8641SAndroid Build Coastguard Worker // make it run later than it normally would, but it won't make it 109*635a8641SAndroid Build Coastguard Worker // run earlier than it normally would. 110*635a8641SAndroid Build Coastguard Worker 111*635a8641SAndroid Build Coastguard Worker // TODO(akalin): Get rid of the boolean return value for the methods 112*635a8641SAndroid Build Coastguard Worker // below. 113*635a8641SAndroid Build Coastguard Worker 114*635a8641SAndroid Build Coastguard Worker bool PostNonNestableTask(const Location& from_here, OnceClosure task); 115*635a8641SAndroid Build Coastguard Worker 116*635a8641SAndroid Build Coastguard Worker virtual bool PostNonNestableDelayedTask(const Location& from_here, 117*635a8641SAndroid Build Coastguard Worker OnceClosure task, 118*635a8641SAndroid Build Coastguard Worker base::TimeDelta delay) = 0; 119*635a8641SAndroid Build Coastguard Worker 120*635a8641SAndroid Build Coastguard Worker // Submits a non-nestable task to delete the given object. Returns 121*635a8641SAndroid Build Coastguard Worker // true if the object may be deleted at some point in the future, 122*635a8641SAndroid Build Coastguard Worker // and false if the object definitely will not be deleted. 123*635a8641SAndroid Build Coastguard Worker template <class T> DeleteSoon(const Location & from_here,const T * object)124*635a8641SAndroid Build Coastguard Worker bool DeleteSoon(const Location& from_here, const T* object) { 125*635a8641SAndroid Build Coastguard Worker return DeleteOrReleaseSoonInternal(from_here, &DeleteHelper<T>::DoDelete, 126*635a8641SAndroid Build Coastguard Worker object); 127*635a8641SAndroid Build Coastguard Worker } 128*635a8641SAndroid Build Coastguard Worker 129*635a8641SAndroid Build Coastguard Worker template <class T> DeleteSoon(const Location & from_here,std::unique_ptr<T> object)130*635a8641SAndroid Build Coastguard Worker bool DeleteSoon(const Location& from_here, std::unique_ptr<T> object) { 131*635a8641SAndroid Build Coastguard Worker return DeleteSoon(from_here, object.release()); 132*635a8641SAndroid Build Coastguard Worker } 133*635a8641SAndroid Build Coastguard Worker 134*635a8641SAndroid Build Coastguard Worker // Submits a non-nestable task to release the given object. Returns 135*635a8641SAndroid Build Coastguard Worker // true if the object may be released at some point in the future, 136*635a8641SAndroid Build Coastguard Worker // and false if the object definitely will not be released. 137*635a8641SAndroid Build Coastguard Worker template <class T> ReleaseSoon(const Location & from_here,const T * object)138*635a8641SAndroid Build Coastguard Worker bool ReleaseSoon(const Location& from_here, const T* object) { 139*635a8641SAndroid Build Coastguard Worker return DeleteOrReleaseSoonInternal(from_here, &ReleaseHelper<T>::DoRelease, 140*635a8641SAndroid Build Coastguard Worker object); 141*635a8641SAndroid Build Coastguard Worker } 142*635a8641SAndroid Build Coastguard Worker 143*635a8641SAndroid Build Coastguard Worker protected: 144*635a8641SAndroid Build Coastguard Worker ~SequencedTaskRunner() override = default; 145*635a8641SAndroid Build Coastguard Worker 146*635a8641SAndroid Build Coastguard Worker private: 147*635a8641SAndroid Build Coastguard Worker bool DeleteOrReleaseSoonInternal(const Location& from_here, 148*635a8641SAndroid Build Coastguard Worker void (*deleter)(const void*), 149*635a8641SAndroid Build Coastguard Worker const void* object); 150*635a8641SAndroid Build Coastguard Worker }; 151*635a8641SAndroid Build Coastguard Worker 152*635a8641SAndroid Build Coastguard Worker // Sample usage with std::unique_ptr : 153*635a8641SAndroid Build Coastguard Worker // std::unique_ptr<Foo, base::OnTaskRunnerDeleter> ptr( 154*635a8641SAndroid Build Coastguard Worker // new Foo, base::OnTaskRunnerDeleter(my_task_runner)); 155*635a8641SAndroid Build Coastguard Worker // 156*635a8641SAndroid Build Coastguard Worker // For RefCounted see base::RefCountedDeleteOnSequence. 157*635a8641SAndroid Build Coastguard Worker struct BASE_EXPORT OnTaskRunnerDeleter { 158*635a8641SAndroid Build Coastguard Worker explicit OnTaskRunnerDeleter(scoped_refptr<SequencedTaskRunner> task_runner); 159*635a8641SAndroid Build Coastguard Worker ~OnTaskRunnerDeleter(); 160*635a8641SAndroid Build Coastguard Worker 161*635a8641SAndroid Build Coastguard Worker OnTaskRunnerDeleter(OnTaskRunnerDeleter&&); 162*635a8641SAndroid Build Coastguard Worker OnTaskRunnerDeleter& operator=(OnTaskRunnerDeleter&&); 163*635a8641SAndroid Build Coastguard Worker 164*635a8641SAndroid Build Coastguard Worker // For compatibility with std:: deleters. 165*635a8641SAndroid Build Coastguard Worker template <typename T> operatorOnTaskRunnerDeleter166*635a8641SAndroid Build Coastguard Worker void operator()(const T* ptr) { 167*635a8641SAndroid Build Coastguard Worker if (ptr) 168*635a8641SAndroid Build Coastguard Worker task_runner_->DeleteSoon(FROM_HERE, ptr); 169*635a8641SAndroid Build Coastguard Worker } 170*635a8641SAndroid Build Coastguard Worker 171*635a8641SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> task_runner_; 172*635a8641SAndroid Build Coastguard Worker }; 173*635a8641SAndroid Build Coastguard Worker 174*635a8641SAndroid Build Coastguard Worker } // namespace base 175*635a8641SAndroid Build Coastguard Worker 176*635a8641SAndroid Build Coastguard Worker #endif // BASE_SEQUENCED_TASK_RUNNER_H_ 177