// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_MESSAGE_LOOP_MESSAGE_LOOP_TASK_RUNNER_H_ #define BASE_MESSAGE_LOOP_MESSAGE_LOOP_TASK_RUNNER_H_ #include "base/base_export.h" #include "base/callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/message_loop/sequenced_task_source.h" #include "base/pending_task.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/lock.h" #include "base/threading/platform_thread.h" #include "base/time/time.h" namespace base { namespace internal { // A SingleThreadTaskRunner which receives and queues tasks destined to its // owning MessageLoop. It does not manage delays (i.e. tasks returned by // TakeTask() might have a non-zero delay). class BASE_EXPORT MessageLoopTaskRunner : public SingleThreadTaskRunner, public SequencedTaskSource { public: // Constructs a MessageLoopTaskRunner which will notify |task_source_observer| // about tasks it receives. |task_source_observer| will be bound to this // MessageLoopTaskRunner's lifetime. Ownership is required as opposed to a raw // pointer since MessageLoopTaskRunner impls tend to receive tasks beyond the // destination's lifetime. For the same reasons, |task_source_observer| needs // to support being invoked racily during shutdown. MessageLoopTaskRunner( std::unique_ptr task_source_observer); // Initialize this MessageLoopTaskRunner on the current thread. void BindToCurrentThread(); // Instructs this task runner to stop accepting tasks, this cannot be undone. // Note that the registered SequencedTaskSource::Observer may still racily // receive a few DidQueueTask() calls while the Shutdown() signal propagates // to other threads and it needs to support that. void Shutdown(); // SingleThreadTaskRunner: bool PostDelayedTask(const Location& from_here, OnceClosure task, TimeDelta delay) override; bool PostNonNestableDelayedTask(const Location& from_here, OnceClosure task, TimeDelta delay) override; bool RunsTasksInCurrentSequence() const override; // SequencedTaskSource: PendingTask TakeTask() override; bool HasTasks() override; void InjectTask(OnceClosure task) override; // When this functionality is enabled, AddToIncomingQueue() will also add the // queue time to the task. void SetAddQueueTimeToTasks(bool enable); private: friend class RefCountedThreadSafe; ~MessageLoopTaskRunner() override; // Appends a task to the incoming queue. Thread-safe. // Returns true if the task was successfully added to the queue. bool AddToIncomingQueue(const Location& from_here, OnceClosure task, TimeDelta delay, Nestable nestable); // ID of the thread |this| was created on. Could be accessed on multiple // threads, protected by |valid_thread_id_lock_|. PlatformThreadId valid_thread_id_ = kInvalidThreadId; mutable Lock valid_thread_id_lock_; std::unique_ptr task_source_observer_; // Tasks to be returned to TakeTask(). Reloaded from |incoming_queue_| when // it becomes empty. TaskQueue outgoing_queue_; // Synchronizes access to all members below this line. base::Lock incoming_queue_lock_; // An incoming queue of tasks that are acquired under a mutex for processing // on this instance's thread. These tasks have not yet been been pushed to // |outgoing_queue_|. TaskQueue incoming_queue_; // True if the |outgoing_queue_| is empty. Toggled under // |incoming_queue_lock_| when reloading the work queue so that // PostPendingTaskLockRequired() can tell, without accessing the thread unsafe // |outgoing_queue_|, if this SequencedTaskSource has been made non-empty by a // PostTask() (and needs to inform its Observer). bool outgoing_queue_empty_ = true; // True if new tasks should be accepted. bool accept_new_tasks_ = true; // The next sequence number to use for delayed tasks. int next_sequence_num_ = 0; // Whether to add the queue time to tasks. bool add_queue_time_to_tasks_ = false; DISALLOW_COPY_AND_ASSIGN(MessageLoopTaskRunner); }; } // namespace internal } // namespace base #endif // BASE_MESSAGE_LOOP_MESSAGE_LOOP_TASK_RUNNER_H_