blob: c48a61b1e26313e1e7b516d67cc6660e54f6bba9 [file] [log] [blame]
[email protected]b4481b222012-03-16 17:13:111// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]76d7f722011-10-10 17:22:412// 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]76d7f722011-10-10 17:22:417
8#include <string>
9
10#include "base/compiler_specific.h"
Avi Drissman13fc8932015-12-20 04:40:4611#include "base/macros.h"
[email protected]76d7f722011-10-10 17:22:4112#include "base/memory/ref_counted.h"
13#include "net/base/net_export.h"
14
15// Forward declaration
16namespace base {
anujk.sharma7c907f02015-05-29 02:55:4417class SingleThreadTaskRunner;
[email protected]76d7f722011-10-10 17:22:4118}
19
20namespace 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.
40class 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]b4481b222012-03-16 17:13:1149 // Stop scheduling jobs.
[email protected]76d7f722011-10-10 17:22:4150 void Cancel();
51
52 bool IsCancelled() const { return state_ == CANCELLED; }
53
[email protected]76d7f722011-10-10 17:22:4154 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.sharma7c907f02015-05-29 02:55:4465 base::SingleThreadTaskRunner* loop() { return task_runner_.get(); }
[email protected]76d7f722011-10-10 17:22:4166
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.sharma7c907f02015-05-29 02:55:4486 // Task runner for the thread of origin.
87 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
[email protected]76d7f722011-10-10 17:22:4188
89 State state_;
90
91 DISALLOW_COPY_AND_ASSIGN(SerialWorker);
92};
93
94} // namespace net
95
96#endif // NET_DNS_SERIAL_WORKER_H_
97