| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef BASE_THREADING_SEQUENCED_WORKER_POOL_H_ | 5 #ifndef BASE_THREADING_SEQUENCED_WORKER_POOL_H_ |
| 6 #define BASE_THREADING_SEQUENCED_WORKER_POOL_H_ | 6 #define BASE_THREADING_SEQUENCED_WORKER_POOL_H_ |
| 7 | 7 |
| 8 #include <cstddef> | 8 #include <cstddef> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 // | 38 // |
| 39 // - No two tasks with the same token will run at the same time. | 39 // - No two tasks with the same token will run at the same time. |
| 40 // | 40 // |
| 41 // - Given two tasks T1 and T2 with the same token such that T2 will | 41 // - Given two tasks T1 and T2 with the same token such that T2 will |
| 42 // run after T1, then T2 will start after T1 is destroyed. | 42 // run after T1, then T2 will start after T1 is destroyed. |
| 43 // | 43 // |
| 44 // - If T2 will run after T1, then all memory changes in T1 and T1's | 44 // - If T2 will run after T1, then all memory changes in T1 and T1's |
| 45 // destruction will be visible to T2. | 45 // destruction will be visible to T2. |
| 46 // | 46 // |
| 47 // Example: | 47 // Example: |
| 48 // SequencedWorkerPool::SequenceToken token = pool.GetSequenceToken(); | 48 // SequencedWorkerPool::SequenceToken token = |
| 49 // SequencedWorkerPool::GetSequenceToken(); |
| 49 // pool.PostSequencedWorkerTask(token, SequencedWorkerPool::SKIP_ON_SHUTDOWN, | 50 // pool.PostSequencedWorkerTask(token, SequencedWorkerPool::SKIP_ON_SHUTDOWN, |
| 50 // FROM_HERE, base::Bind(...)); | 51 // FROM_HERE, base::Bind(...)); |
| 51 // pool.PostSequencedWorkerTask(token, SequencedWorkerPool::SKIP_ON_SHUTDOWN, | 52 // pool.PostSequencedWorkerTask(token, SequencedWorkerPool::SKIP_ON_SHUTDOWN, |
| 52 // FROM_HERE, base::Bind(...)); | 53 // FROM_HERE, base::Bind(...)); |
| 53 // | 54 // |
| 54 // You can make named sequence tokens to make it easier to share a token | 55 // You can make named sequence tokens to make it easier to share a token |
| 55 // across different components. | 56 // across different components. |
| 56 // | 57 // |
| 57 // You can also post tasks to the pool without ordering using PostWorkerTask. | 58 // You can also post tasks to the pool without ordering using PostWorkerTask. |
| 58 // These will be executed in an unspecified order. The order of execution | 59 // These will be executed in an unspecified order. The order of execution |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 virtual void OnHasWork() = 0; | 155 virtual void OnHasWork() = 0; |
| 155 virtual void WillWaitForShutdown() = 0; | 156 virtual void WillWaitForShutdown() = 0; |
| 156 virtual void OnDestruct() = 0; | 157 virtual void OnDestruct() = 0; |
| 157 }; | 158 }; |
| 158 | 159 |
| 159 // Gets the SequencedToken of the current thread. | 160 // Gets the SequencedToken of the current thread. |
| 160 // If current thread is not a SequencedWorkerPool worker thread or is running | 161 // If current thread is not a SequencedWorkerPool worker thread or is running |
| 161 // an unsequenced task, returns an invalid SequenceToken. | 162 // an unsequenced task, returns an invalid SequenceToken. |
| 162 static SequenceToken GetSequenceTokenForCurrentThread(); | 163 static SequenceToken GetSequenceTokenForCurrentThread(); |
| 163 | 164 |
| 164 // Returns the SequencedWorkerPool that owns this thread, or null if the | 165 // Gets a SequencedTaskRunner for the current thread. If the current thread is |
| 165 // current thread is not a SequencedWorkerPool worker thread. | 166 // running an unsequenced task, a new SequenceToken will be generated and set, |
| 166 static scoped_refptr<SequencedWorkerPool> GetWorkerPoolForCurrentThread(); | 167 // so that the returned SequencedTaskRunner is guaranteed to run tasks after |
| 168 // the current task has finished running. |
| 169 static scoped_refptr<SequencedTaskRunner> |
| 170 GetSequencedTaskRunnerForCurrentThread(); |
| 171 |
| 172 // Returns a unique token that can be used to sequence tasks posted to |
| 173 // PostSequencedWorkerTask(). Valid tokens are always nonzero. |
| 174 // TODO(bauerb): Rename this to better differentiate from |
| 175 // GetSequenceTokenForCurrentThread(). |
| 176 static SequenceToken GetSequenceToken(); |
| 167 | 177 |
| 168 // When constructing a SequencedWorkerPool, there must be a | 178 // When constructing a SequencedWorkerPool, there must be a |
| 169 // ThreadTaskRunnerHandle on the current thread unless you plan to | 179 // ThreadTaskRunnerHandle on the current thread unless you plan to |
| 170 // deliberately leak it. | 180 // deliberately leak it. |
| 171 | 181 |
| 172 // Pass the maximum number of threads (they will be lazily created as needed) | 182 // Pass the maximum number of threads (they will be lazily created as needed) |
| 173 // and a prefix for the thread name to aid in debugging. | 183 // and a prefix for the thread name to aid in debugging. |
| 174 SequencedWorkerPool(size_t max_threads, | 184 SequencedWorkerPool(size_t max_threads, |
| 175 const std::string& thread_name_prefix); | 185 const std::string& thread_name_prefix); |
| 176 | 186 |
| 177 // Like above, but with |observer| for testing. Does not take ownership of | 187 // Like above, but with |observer| for testing. Does not take ownership of |
| 178 // |observer|. | 188 // |observer|. |
| 179 SequencedWorkerPool(size_t max_threads, | 189 SequencedWorkerPool(size_t max_threads, |
| 180 const std::string& thread_name_prefix, | 190 const std::string& thread_name_prefix, |
| 181 TestingObserver* observer); | 191 TestingObserver* observer); |
| 182 | 192 |
| 183 // Returns a unique token that can be used to sequence tasks posted to | |
| 184 // PostSequencedWorkerTask(). Valid tokens are always nonzero. | |
| 185 SequenceToken GetSequenceToken(); | |
| 186 | |
| 187 // Returns the sequence token associated with the given name. Calling this | 193 // Returns the sequence token associated with the given name. Calling this |
| 188 // function multiple times with the same string will always produce the | 194 // function multiple times with the same string will always produce the |
| 189 // same sequence token. If the name has not been used before, a new token | 195 // same sequence token. If the name has not been used before, a new token |
| 190 // will be created. | 196 // will be created. |
| 191 SequenceToken GetNamedSequenceToken(const std::string& name); | 197 SequenceToken GetNamedSequenceToken(const std::string& name); |
| 192 | 198 |
| 193 // Returns a SequencedTaskRunner wrapper which posts to this | 199 // Returns a SequencedTaskRunner wrapper which posts to this |
| 194 // SequencedWorkerPool using the given sequence token. Tasks with nonzero | 200 // SequencedWorkerPool using the given sequence token. Tasks with nonzero |
| 195 // delay are posted with SKIP_ON_SHUTDOWN behavior and tasks with zero delay | 201 // delay are posted with SKIP_ON_SHUTDOWN behavior and tasks with zero delay |
| 196 // are posted with BLOCK_SHUTDOWN behavior. | 202 // are posted with BLOCK_SHUTDOWN behavior. |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 // TaskRunner implementation. Forwards to PostDelayedWorkerTask(). | 307 // TaskRunner implementation. Forwards to PostDelayedWorkerTask(). |
| 302 bool PostDelayedTask(const tracked_objects::Location& from_here, | 308 bool PostDelayedTask(const tracked_objects::Location& from_here, |
| 303 const Closure& task, | 309 const Closure& task, |
| 304 TimeDelta delay) override; | 310 TimeDelta delay) override; |
| 305 bool RunsTasksOnCurrentThread() const override; | 311 bool RunsTasksOnCurrentThread() const override; |
| 306 | 312 |
| 307 // Returns true if the current thread is processing a task with the given | 313 // Returns true if the current thread is processing a task with the given |
| 308 // sequence_token. | 314 // sequence_token. |
| 309 bool IsRunningSequenceOnCurrentThread(SequenceToken sequence_token) const; | 315 bool IsRunningSequenceOnCurrentThread(SequenceToken sequence_token) const; |
| 310 | 316 |
| 317 // Returns true if any thread is currently processing a task with the given |
| 318 // sequence token. Should only be called with a valid sequence token. |
| 319 bool IsRunningSequence(SequenceToken sequence_token) const; |
| 320 |
| 311 // Blocks until all pending tasks are complete. This should only be called in | 321 // Blocks until all pending tasks are complete. This should only be called in |
| 312 // unit tests when you want to validate something that should have happened. | 322 // unit tests when you want to validate something that should have happened. |
| 313 // This will not flush delayed tasks; delayed tasks get deleted. | 323 // This will not flush delayed tasks; delayed tasks get deleted. |
| 314 // | 324 // |
| 315 // Note that calling this will not prevent other threads from posting work to | 325 // Note that calling this will not prevent other threads from posting work to |
| 316 // the queue while the calling thread is waiting on Flush(). In this case, | 326 // the queue while the calling thread is waiting on Flush(). In this case, |
| 317 // Flush will return only when there's no more work in the queue. Normally, | 327 // Flush will return only when there's no more work in the queue. Normally, |
| 318 // this doesn't come up since in a test, all the work is being posted from | 328 // this doesn't come up since in a test, all the work is being posted from |
| 319 // the main thread. | 329 // the main thread. |
| 320 void FlushForTesting(); | 330 void FlushForTesting(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 // Avoid pulling in too many headers by putting (almost) everything | 369 // Avoid pulling in too many headers by putting (almost) everything |
| 360 // into |inner_|. | 370 // into |inner_|. |
| 361 const scoped_ptr<Inner> inner_; | 371 const scoped_ptr<Inner> inner_; |
| 362 | 372 |
| 363 DISALLOW_COPY_AND_ASSIGN(SequencedWorkerPool); | 373 DISALLOW_COPY_AND_ASSIGN(SequencedWorkerPool); |
| 364 }; | 374 }; |
| 365 | 375 |
| 366 } // namespace base | 376 } // namespace base |
| 367 | 377 |
| 368 #endif // BASE_THREADING_SEQUENCED_WORKER_POOL_H_ | 378 #endif // BASE_THREADING_SEQUENCED_WORKER_POOL_H_ |
| OLD | NEW |