1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef NET_DNS_SERIAL_WORKER_H_ 6*6777b538SAndroid Build Coastguard Worker #define NET_DNS_SERIAL_WORKER_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <memory> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include "base/compiler_specific.h" 11*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h" 12*6777b538SAndroid Build Coastguard Worker #include "base/memory/weak_ptr.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/sequence_checker.h" 14*6777b538SAndroid Build Coastguard Worker #include "base/task/task_traits.h" 15*6777b538SAndroid Build Coastguard Worker #include "base/timer/timer.h" 16*6777b538SAndroid Build Coastguard Worker #include "net/base/backoff_entry.h" 17*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h" 18*6777b538SAndroid Build Coastguard Worker 19*6777b538SAndroid Build Coastguard Worker namespace net { 20*6777b538SAndroid Build Coastguard Worker 21*6777b538SAndroid Build Coastguard Worker // `SerialWorker` executes a job on `ThreadPool` serially -- **one at a time**. 22*6777b538SAndroid Build Coastguard Worker // On `WorkNow()`, a `WorkItem` is created using `CreateWorkItem()` and sent to 23*6777b538SAndroid Build Coastguard Worker // the `ThreadPool`. There, a call to `DoWork()` is made. On completion of work, 24*6777b538SAndroid Build Coastguard Worker // `OnWorkFinished()` is called on the origin thread (if the `SerialWorker` is 25*6777b538SAndroid Build Coastguard Worker // still alive), passing back the `WorkItem` to allow retrieving any results or 26*6777b538SAndroid Build Coastguard Worker // passed objects. If `WorkNow()` is called (1 or more times) while a `WorkItem` 27*6777b538SAndroid Build Coastguard Worker // is already under way, after completion of the work and before any call is 28*6777b538SAndroid Build Coastguard Worker // made to `OnWorkFinished()` the same `WorkItem` will be passed back to the 29*6777b538SAndroid Build Coastguard Worker // `ThreadPool`, and `DoWork()` will be called once more. 30*6777b538SAndroid Build Coastguard Worker // 31*6777b538SAndroid Build Coastguard Worker // If |OnWorkFinished| returns a failure and |max_number_of_retries| 32*6777b538SAndroid Build Coastguard Worker // is non-zero, retries will be scheduled according to the |backoff_policy|. 33*6777b538SAndroid Build Coastguard Worker // A default backoff policy is used if one is not provided. 34*6777b538SAndroid Build Coastguard Worker // 35*6777b538SAndroid Build Coastguard Worker // This behavior is designed for updating a result after some trigger, for 36*6777b538SAndroid Build Coastguard Worker // example reading a file once FilePathWatcher indicates it changed. 37*6777b538SAndroid Build Coastguard Worker // 38*6777b538SAndroid Build Coastguard Worker // Derived classes should store results of work in the `WorkItem` and retrieve 39*6777b538SAndroid Build Coastguard Worker // results from it when passed back to `OnWorkFinished()`. The `SerialWorker` is 40*6777b538SAndroid Build Coastguard Worker // guaranteed to only run one `WorkItem` at a time, always passing it back to 41*6777b538SAndroid Build Coastguard Worker // `OnWorkFinished()` before calling `CreateWorkItem()` again. Therefore, a 42*6777b538SAndroid Build Coastguard Worker // derived class may safely pass objects between `WorkItem`s, or even reuse the 43*6777b538SAndroid Build Coastguard Worker // same `WorkItem`, to allow storing helper objects directly in the `WorkItem`. 44*6777b538SAndroid Build Coastguard Worker // However, it is not guaranteed that the `SerialWorker` will remain alive while 45*6777b538SAndroid Build Coastguard Worker // the `WorkItem` runs. Therefore, the `WorkItem` should never access any memory 46*6777b538SAndroid Build Coastguard Worker // owned by the `SerialWorker` or derived class. 47*6777b538SAndroid Build Coastguard Worker class NET_EXPORT_PRIVATE SerialWorker { 48*6777b538SAndroid Build Coastguard Worker public: 49*6777b538SAndroid Build Coastguard Worker // A work item that will be passed to and run on the `ThreadPool` (potentially 50*6777b538SAndroid Build Coastguard Worker // multiple times if the `SerialWorker` needs to run again immediately) and 51*6777b538SAndroid Build Coastguard Worker // then passed back to the origin thread on completion. Expected usage is to 52*6777b538SAndroid Build Coastguard Worker // store any parameters, results, and helper objects in the `WorkItem` and 53*6777b538SAndroid Build Coastguard Worker // read results from it when passed back to the origin thread. 54*6777b538SAndroid Build Coastguard Worker // 55*6777b538SAndroid Build Coastguard Worker // `SerialWorker` calls `FollowupWork()` *on the origin thread* after calling 56*6777b538SAndroid Build Coastguard Worker // `DoWork()` on the `ThreadPool` to asynchronously handle any work that must 57*6777b538SAndroid Build Coastguard Worker // be part of the serialization but that cannot run on a worker thread. 58*6777b538SAndroid Build Coastguard Worker class NET_EXPORT_PRIVATE WorkItem { 59*6777b538SAndroid Build Coastguard Worker public: 60*6777b538SAndroid Build Coastguard Worker virtual ~WorkItem() = default; 61*6777b538SAndroid Build Coastguard Worker virtual void DoWork() = 0; 62*6777b538SAndroid Build Coastguard Worker virtual void FollowupWork(base::OnceClosure closure); 63*6777b538SAndroid Build Coastguard Worker }; 64*6777b538SAndroid Build Coastguard Worker 65*6777b538SAndroid Build Coastguard Worker explicit SerialWorker( 66*6777b538SAndroid Build Coastguard Worker int max_number_of_retries = 0, 67*6777b538SAndroid Build Coastguard Worker const net::BackoffEntry::Policy* backoff_policy = nullptr); 68*6777b538SAndroid Build Coastguard Worker 69*6777b538SAndroid Build Coastguard Worker SerialWorker(const SerialWorker&) = delete; 70*6777b538SAndroid Build Coastguard Worker SerialWorker& operator=(const SerialWorker&) = delete; 71*6777b538SAndroid Build Coastguard Worker 72*6777b538SAndroid Build Coastguard Worker // Unless already scheduled, post |DoWork| to ThreadPool. 73*6777b538SAndroid Build Coastguard Worker // Made virtual to allow mocking. 74*6777b538SAndroid Build Coastguard Worker virtual void WorkNow(); 75*6777b538SAndroid Build Coastguard Worker 76*6777b538SAndroid Build Coastguard Worker // Stop scheduling jobs. 77*6777b538SAndroid Build Coastguard Worker void Cancel(); 78*6777b538SAndroid Build Coastguard Worker IsCancelled()79*6777b538SAndroid Build Coastguard Worker bool IsCancelled() const { return state_ == State::kCancelled; } 80*6777b538SAndroid Build Coastguard Worker 81*6777b538SAndroid Build Coastguard Worker // Allows tests to inspect the current backoff/retry state. 82*6777b538SAndroid Build Coastguard Worker const BackoffEntry& GetBackoffEntryForTesting() const; 83*6777b538SAndroid Build Coastguard Worker const base::OneShotTimer& GetRetryTimerForTesting() const; 84*6777b538SAndroid Build Coastguard Worker 85*6777b538SAndroid Build Coastguard Worker protected: 86*6777b538SAndroid Build Coastguard Worker // protected to allow sub-classing, but prevent deleting 87*6777b538SAndroid Build Coastguard Worker virtual ~SerialWorker(); 88*6777b538SAndroid Build Coastguard Worker 89*6777b538SAndroid Build Coastguard Worker // Create a new WorkItem to be passed to and run on the ThreadPool. 90*6777b538SAndroid Build Coastguard Worker virtual std::unique_ptr<WorkItem> CreateWorkItem() = 0; 91*6777b538SAndroid Build Coastguard Worker 92*6777b538SAndroid Build Coastguard Worker // Executed on origin thread after `WorkItem` completes. 93*6777b538SAndroid Build Coastguard Worker // Must return true on success. 94*6777b538SAndroid Build Coastguard Worker virtual bool OnWorkFinished(std::unique_ptr<WorkItem> work_item) = 0; 95*6777b538SAndroid Build Coastguard Worker 96*6777b538SAndroid Build Coastguard Worker // Returns the failure count for this job. 97*6777b538SAndroid Build Coastguard Worker int GetFailureCount() const; 98*6777b538SAndroid Build Coastguard Worker 99*6777b538SAndroid Build Coastguard Worker base::WeakPtr<SerialWorker> AsWeakPtr(); 100*6777b538SAndroid Build Coastguard Worker 101*6777b538SAndroid Build Coastguard Worker // Used to verify that the constructor, WorkNow(), Cancel() and 102*6777b538SAndroid Build Coastguard Worker // OnWorkJobFinished() are called on the same sequence. 103*6777b538SAndroid Build Coastguard Worker SEQUENCE_CHECKER(sequence_checker_); 104*6777b538SAndroid Build Coastguard Worker 105*6777b538SAndroid Build Coastguard Worker private: 106*6777b538SAndroid Build Coastguard Worker enum class State { 107*6777b538SAndroid Build Coastguard Worker kCancelled = -1, 108*6777b538SAndroid Build Coastguard Worker kIdle = 0, 109*6777b538SAndroid Build Coastguard Worker kWorking, // |DoWorkJob| posted to ThreadPool, until |OnWorkJobFinished| 110*6777b538SAndroid Build Coastguard Worker kPending, // |WorkNow| while WORKING, must re-do work 111*6777b538SAndroid Build Coastguard Worker }; 112*6777b538SAndroid Build Coastguard Worker 113*6777b538SAndroid Build Coastguard Worker void WorkNowInternal(); 114*6777b538SAndroid Build Coastguard Worker 115*6777b538SAndroid Build Coastguard Worker // Called on the origin thread after `WorkItem::DoWork()` completes. 116*6777b538SAndroid Build Coastguard Worker void OnDoWorkFinished(std::unique_ptr<WorkItem> work_item); 117*6777b538SAndroid Build Coastguard Worker 118*6777b538SAndroid Build Coastguard Worker // Called on the origin thread after `WorkItem::FollowupWork()` completes. 119*6777b538SAndroid Build Coastguard Worker void OnFollowupWorkFinished(std::unique_ptr<WorkItem> work_item); 120*6777b538SAndroid Build Coastguard Worker 121*6777b538SAndroid Build Coastguard Worker void RerunWork(std::unique_ptr<WorkItem> work_item); 122*6777b538SAndroid Build Coastguard Worker 123*6777b538SAndroid Build Coastguard Worker State state_ = State::kIdle; 124*6777b538SAndroid Build Coastguard Worker 125*6777b538SAndroid Build Coastguard Worker // Max retries and backoff entry to control timing. 126*6777b538SAndroid Build Coastguard Worker const int max_number_of_retries_; 127*6777b538SAndroid Build Coastguard Worker BackoffEntry backoff_entry_; 128*6777b538SAndroid Build Coastguard Worker base::OneShotTimer retry_timer_; 129*6777b538SAndroid Build Coastguard Worker 130*6777b538SAndroid Build Coastguard Worker base::WeakPtrFactory<SerialWorker> weak_factory_{this}; 131*6777b538SAndroid Build Coastguard Worker }; 132*6777b538SAndroid Build Coastguard Worker 133*6777b538SAndroid Build Coastguard Worker } // namespace net 134*6777b538SAndroid Build Coastguard Worker 135*6777b538SAndroid Build Coastguard Worker #endif // NET_DNS_SERIAL_WORKER_H_ 136