1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 REMOTING_BASE_PLUGIN_THREAD_TASK_RUNNER_H_ 6 #define REMOTING_BASE_PLUGIN_THREAD_TASK_RUNNER_H_ 7 8 #include <set> 9 10 #include "base/callback_forward.h" 11 #include "base/compiler_specific.h" 12 #include "base/pending_task.h" 13 #include "base/single_thread_task_runner.h" 14 #include "base/synchronization/lock.h" 15 #include "base/synchronization/waitable_event.h" 16 #include "base/threading/platform_thread.h" 17 #include "base/time/time.h" 18 19 namespace remoting { 20 21 // SingleThreadTaskRunner for plugin main threads. 22 class PluginThreadTaskRunner : public base::SingleThreadTaskRunner { 23 public: 24 class Delegate { 25 public: 26 virtual ~Delegate(); 27 28 virtual bool RunOnPluginThread( 29 base::TimeDelta delay, void(function)(void*), void* data) = 0; 30 }; 31 32 // Caller keeps ownership of delegate. 33 PluginThreadTaskRunner(Delegate* delegate); 34 35 // Detaches the PluginThreadTaskRunner from the underlying Delegate and 36 // processes posted tasks until Quit() is called. This is used during plugin 37 // shutdown, when the plugin environment has stopped accepting new tasks to 38 // run, to process cleanup tasks posted to the plugin thread. 39 // This method must be called on the plugin thread. 40 void DetachAndRunShutdownLoop(); 41 42 // Makes DetachAndRunShutdownLoop() stop processing tasks and return control 43 // to the caller. Calling Quit() before DetachAndRunShutdownLoop() causes 44 // the latter to exit immediately when called, without processing any delayed 45 // shutdown tasks. This method can be called from any thread. 46 void Quit(); 47 48 // base::SingleThreadTaskRunner interface. 49 virtual bool PostDelayedTask( 50 const tracked_objects::Location& from_here, 51 const base::Closure& task, 52 base::TimeDelta delay) OVERRIDE; 53 virtual bool PostNonNestableDelayedTask( 54 const tracked_objects::Location& from_here, 55 const base::Closure& task, 56 base::TimeDelta delay) OVERRIDE; 57 virtual bool RunsTasksOnCurrentThread() const OVERRIDE; 58 59 protected: 60 virtual ~PluginThreadTaskRunner(); 61 62 private: 63 // Methods that can be called from any thread. 64 65 // Schedules RunTasks to be called on the plugin thread. 66 void PostRunTasks(); 67 68 // Methods that are always called on the plugin thread. 69 70 // Schedules RunDelayedTasks() to be called on the plugin thread. |when| 71 // specifies the time when RunDelayedTasks() should be called. 72 void PostDelayedRunTasks(base::TimeTicks when); 73 74 // Processes the incoming task queue: runs all non delayed tasks and posts all 75 // delayed tasks to |delayed_queue_|. 76 void ProcessIncomingTasks(); 77 78 // Called in response to PostDelayedRunTasks(). 79 void RunDelayedTasks(base::TimeTicks when); 80 81 // Runs all tasks that are due. 82 void RunDueTasks(base::TimeTicks now); 83 84 // Called in response to PostRunTasks(). 85 void RunTasks(); 86 87 static void TaskSpringboard(void* data); 88 89 const base::PlatformThreadId plugin_thread_id_; 90 91 // Used by the shutdown loop to block the thread until there is a task ready 92 // to run. 93 base::WaitableEvent event_; 94 95 base::Lock lock_; 96 97 // The members below are protected by |lock_|. 98 99 // Pointer to the delegate that implements scheduling tasks via the plugin 100 // API. 101 Delegate* delegate_; 102 103 // Contains all posted tasks that haven't been sorted yet. 104 base::TaskQueue incoming_queue_; 105 106 // The next sequence number to use for delayed tasks. 107 int next_sequence_num_; 108 109 // True if Quit() has been called. 110 bool quit_received_; 111 112 // The members below are accessed only on the plugin thread. 113 114 // Contains delayed tasks, sorted by their 'delayed_run_time' property. 115 base::DelayedTaskQueue delayed_queue_; 116 117 // The list of timestamps when scheduled timers are expected to fire. 118 std::set<base::TimeTicks> scheduled_timers_; 119 120 // True if the shutdown task loop was been stopped. 121 bool stopped_; 122 123 DISALLOW_COPY_AND_ASSIGN(PluginThreadTaskRunner); 124 }; 125 126 } // namespace remoting 127 128 #endif // REMOTING_BASE_PLUGIN_THREAD_TASK_RUNNER_H_ 129