[email protected] | b4481b22 | 2012-03-16 17:13:11 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 76d7f72 | 2011-10-10 17:22:41 | [diff] [blame] | 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 NET_DNS_SERIAL_WORKER_H_ |
| 6 | #define NET_DNS_SERIAL_WORKER_H_ |
[email protected] | 76d7f72 | 2011-10-10 17:22:41 | [diff] [blame] | 7 | |
| 8 | #include <string> |
| 9 | |
| 10 | #include "base/compiler_specific.h" |
Avi Drissman | 13fc893 | 2015-12-20 04:40:46 | [diff] [blame] | 11 | #include "base/macros.h" |
[email protected] | 76d7f72 | 2011-10-10 17:22:41 | [diff] [blame] | 12 | #include "base/memory/ref_counted.h" |
| 13 | #include "net/base/net_export.h" |
| 14 | |
| 15 | // Forward declaration |
| 16 | namespace base { |
anujk.sharma | 7c907f0 | 2015-05-29 02:55:44 | [diff] [blame] | 17 | class SingleThreadTaskRunner; |
[email protected] | 76d7f72 | 2011-10-10 17:22:41 | [diff] [blame] | 18 | } |
| 19 | |
| 20 | namespace net { |
| 21 | |
| 22 | // SerialWorker executes a job on WorkerPool serially -- **once at a time**. |
| 23 | // On |WorkNow|, a call to |DoWork| is scheduled on the WorkerPool. Once it |
| 24 | // completes, |OnWorkFinished| is called on the origin thread. |
| 25 | // If |WorkNow| is called (1 or more times) while |DoWork| is already under way, |
| 26 | // |DoWork| will be called once: after current |DoWork| completes, before a |
| 27 | // call to |OnWorkFinished|. |
| 28 | // |
| 29 | // This behavior is designed for updating a result after some trigger, for |
| 30 | // example reading a file once FilePathWatcher indicates it changed. |
| 31 | // |
| 32 | // Derived classes should store results of work done in |DoWork| in dedicated |
| 33 | // fields and read them in |OnWorkFinished| which is executed on the origin |
| 34 | // thread. This avoids the need to template this class. |
| 35 | // |
| 36 | // This implementation avoids locking by using the |state_| member to ensure |
| 37 | // that |DoWork| and |OnWorkFinished| cannot execute in parallel. |
| 38 | // |
| 39 | // TODO(szym): update to WorkerPool::PostTaskAndReply once available. |
| 40 | class NET_EXPORT_PRIVATE SerialWorker |
| 41 | : NON_EXPORTED_BASE(public base::RefCountedThreadSafe<SerialWorker>) { |
| 42 | public: |
| 43 | SerialWorker(); |
| 44 | |
| 45 | // Unless already scheduled, post |DoWork| to WorkerPool. |
| 46 | // Made virtual to allow mocking. |
| 47 | virtual void WorkNow(); |
| 48 | |
[email protected] | b4481b22 | 2012-03-16 17:13:11 | [diff] [blame] | 49 | // Stop scheduling jobs. |
[email protected] | 76d7f72 | 2011-10-10 17:22:41 | [diff] [blame] | 50 | void Cancel(); |
| 51 | |
| 52 | bool IsCancelled() const { return state_ == CANCELLED; } |
| 53 | |
[email protected] | 76d7f72 | 2011-10-10 17:22:41 | [diff] [blame] | 54 | protected: |
| 55 | friend class base::RefCountedThreadSafe<SerialWorker>; |
| 56 | // protected to allow sub-classing, but prevent deleting |
| 57 | virtual ~SerialWorker(); |
| 58 | |
| 59 | // Executed on WorkerPool, at most once at a time. |
| 60 | virtual void DoWork() = 0; |
| 61 | |
| 62 | // Executed on origin thread after |DoRead| completes. |
| 63 | virtual void OnWorkFinished() = 0; |
| 64 | |
anujk.sharma | 7c907f0 | 2015-05-29 02:55:44 | [diff] [blame] | 65 | base::SingleThreadTaskRunner* loop() { return task_runner_.get(); } |
[email protected] | 76d7f72 | 2011-10-10 17:22:41 | [diff] [blame] | 66 | |
| 67 | private: |
| 68 | enum State { |
| 69 | CANCELLED = -1, |
| 70 | IDLE = 0, |
| 71 | WORKING, // |DoWorkJob| posted on WorkerPool, until |OnWorkJobFinished| |
| 72 | PENDING, // |WorkNow| while WORKING, must re-do work |
| 73 | WAITING, // WorkerPool is busy, |RetryWork| is posted |
| 74 | }; |
| 75 | |
| 76 | // Called on the worker thread, executes |DoWork| and notifies the origin |
| 77 | // thread. |
| 78 | void DoWorkJob(); |
| 79 | |
| 80 | // Called on the the origin thread after |DoWork| completes. |
| 81 | void OnWorkJobFinished(); |
| 82 | |
| 83 | // Posted to message loop in case WorkerPool is busy. (state == WAITING) |
| 84 | void RetryWork(); |
| 85 | |
anujk.sharma | 7c907f0 | 2015-05-29 02:55:44 | [diff] [blame] | 86 | // Task runner for the thread of origin. |
| 87 | scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
[email protected] | 76d7f72 | 2011-10-10 17:22:41 | [diff] [blame] | 88 | |
| 89 | State state_; |
| 90 | |
| 91 | DISALLOW_COPY_AND_ASSIGN(SerialWorker); |
| 92 | }; |
| 93 | |
| 94 | } // namespace net |
| 95 | |
| 96 | #endif // NET_DNS_SERIAL_WORKER_H_ |
| 97 | |