| Index: base/task_scheduler/scheduler_worker.h
|
| diff --git a/base/task_scheduler/scheduler_worker.h b/base/task_scheduler/scheduler_worker.h
|
| index fdaf4d32c80cbae2429cf7e3b24c9db775c9bec9..71d4cbcc91667b27be3537c8519aafc802bd4221 100644
|
| --- a/base/task_scheduler/scheduler_worker.h
|
| +++ b/base/task_scheduler/scheduler_worker.h
|
| @@ -21,7 +21,8 @@ namespace internal {
|
|
|
| class TaskTracker;
|
|
|
| -// A thread that runs Tasks from Sequences returned by a delegate.
|
| +// A worker that manages a single thread to run Tasks from Sequences returned
|
| +// by a delegate.
|
| //
|
| // A SchedulerWorker starts out sleeping. It is woken up by a call to WakeUp().
|
| // After a wake-up, a SchedulerWorker runs Tasks from Sequences returned by the
|
| @@ -29,8 +30,11 @@ class TaskTracker;
|
| // also periodically checks with its TaskTracker whether shutdown has completed
|
| // and exits when it has.
|
| //
|
| +// The worker is free to release and reallocate the platform thread with
|
| +// guidance from the delegate.
|
| +//
|
| // This class is thread-safe.
|
| -class BASE_EXPORT SchedulerWorker : public PlatformThread::Delegate {
|
| +class BASE_EXPORT SchedulerWorker {
|
| public:
|
| // Delegate interface for SchedulerWorker. The methods are always called from
|
| // a thread managed by the SchedulerWorker instance.
|
| @@ -39,6 +43,7 @@ class BASE_EXPORT SchedulerWorker : public PlatformThread::Delegate {
|
| virtual ~Delegate() = default;
|
|
|
| // Called by a thread managed by |worker| when it enters its main function.
|
| + // If a thread is recreated after detachment, this call will occur again.
|
| virtual void OnMainEntry(SchedulerWorker* worker) = 0;
|
|
|
| // Called by a thread managed by |worker| to get a Sequence from which to
|
| @@ -53,25 +58,46 @@ class BASE_EXPORT SchedulerWorker : public PlatformThread::Delegate {
|
| // GetWork(). GetWork() may be called before this timeout expires if the
|
| // worker's WakeUp() method is called.
|
| virtual TimeDelta GetSleepTimeout() = 0;
|
| +
|
| + // Called by a thread if it is allowed to detach if the last call to
|
| + // GetWork() returned nullptr.
|
| + //
|
| + // It is the responsibility of the delegate to determine if detachment is
|
| + // safe. If the delegate is responsible for thread-affine work, detachment
|
| + // is generally not safe.
|
| + //
|
| + // When true is returned:
|
| + // - The next WakeUp() could be more costly due to new thread creation.
|
| + // - The worker will take this as a signal that it can detach, but it is not
|
| + // obligated to do so.
|
| + // This MUST return false if SchedulerWorker::JoinForTesting() is in
|
| + // progress.
|
| + virtual bool CanDetach(SchedulerWorker* worker) = 0;
|
| };
|
|
|
| + enum class InitialState { ALIVE, DETACHED };
|
| +
|
| // Creates a SchedulerWorker with priority |thread_priority| that runs Tasks
|
| // from Sequences returned by |delegate|. |task_tracker| is used to handle
|
| - // shutdown behavior of Tasks. Returns nullptr if creating the underlying
|
| - // platform thread fails.
|
| + // shutdown behavior of Tasks. If |worker_state| is DETACHED, the thread will
|
| + // be created upon a WakeUp(). Returns nullptr if creating the underlying
|
| + // platform thread fails during Create().
|
| static std::unique_ptr<SchedulerWorker> Create(
|
| ThreadPriority thread_priority,
|
| std::unique_ptr<Delegate> delegate,
|
| - TaskTracker* task_tracker);
|
| + TaskTracker* task_tracker,
|
| + InitialState initial_state);
|
|
|
| // Destroying a SchedulerWorker in production is not allowed; it is always
|
| // leaked. In tests, it can only be destroyed after JoinForTesting() has
|
| // returned.
|
| - ~SchedulerWorker() override;
|
| + ~SchedulerWorker();
|
|
|
| // Wakes up this SchedulerWorker if it wasn't already awake. After this
|
| // is called, this SchedulerWorker will run Tasks from Sequences
|
| // returned by the GetWork() method of its delegate until it returns nullptr.
|
| + // WakeUp() may fail if the worker is detached and it fails to allocate a new
|
| + // worker. If this happens, there will be no call to GetWork().
|
| void WakeUp();
|
|
|
| SchedulerWorker::Delegate* delegate() { return delegate_.get(); }
|
| @@ -80,22 +106,34 @@ class BASE_EXPORT SchedulerWorker : public PlatformThread::Delegate {
|
| // allowed to complete its execution. This can only be called once.
|
| void JoinForTesting();
|
|
|
| + // Returns true if the worker is alive.
|
| + bool ThreadAliveForTesting() const;
|
| +
|
| private:
|
| + class Thread;
|
| +
|
| SchedulerWorker(ThreadPriority thread_priority,
|
| std::unique_ptr<Delegate> delegate,
|
| TaskTracker* task_tracker);
|
|
|
| - // PlatformThread::Delegate:
|
| - void ThreadMain() override;
|
| + // Returns the thread instance if the detach was successful so that it can be
|
| + // freed upon termination of the thread.
|
| + // If the detach is not possible, returns nullptr.
|
| + std::unique_ptr<SchedulerWorker::Thread> Detach();
|
| +
|
| + void CreateThread();
|
| +
|
| + void CreateThreadAssertSynchronized();
|
|
|
| bool ShouldExitForTesting() const;
|
|
|
| - // Platform thread managed by this SchedulerWorker.
|
| - PlatformThreadHandle thread_handle_;
|
| + // Synchronizes access to |thread_|
|
| + mutable SchedulerLock thread_lock_;
|
|
|
| - // Event signaled to wake up this SchedulerWorker.
|
| - WaitableEvent wake_up_event_;
|
| + // The underlying thread for this SchedulerWorker.
|
| + std::unique_ptr<Thread> thread_;
|
|
|
| + const ThreadPriority thread_priority_;
|
| const std::unique_ptr<Delegate> delegate_;
|
| TaskTracker* const task_tracker_;
|
|
|
|
|