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