00001 // Copyright 2011 Google Inc. 00016 00017 #ifndef NET_INSTAWEB_UTIL_PUBLIC_SCHEDULER_H_ 00018 #define NET_INSTAWEB_UTIL_PUBLIC_SCHEDULER_H_ 00019 00020 #include <set> 00021 00022 #include "base/scoped_ptr.h" 00023 #include "net/instaweb/util/public/atomic_bool.h" 00024 #include "net/instaweb/util/public/basictypes.h" 00025 #include "net/instaweb/util/public/function.h" 00026 #include "net/instaweb/util/public/queued_worker_pool.h" 00027 #include "net/instaweb/util/public/thread_system.h" 00028 00029 namespace net_instaweb { 00030 00031 class Timer; 00032 00042 class Scheduler { 00043 public: 00047 class Alarm; 00048 00051 struct CompareAlarms { 00052 bool operator()(const Alarm* a, const Alarm* b) const; 00053 }; 00054 00055 Scheduler(ThreadSystem* thread_system, Timer* timer); 00056 virtual ~Scheduler(); 00057 00058 ThreadSystem::CondvarCapableMutex* mutex(); 00059 00061 void DCheckLocked(); 00062 00066 00069 void BlockingTimedWait(int64 timeout_ms); 00070 00076 void TimedWait(int64 timeout_ms, Function* callback); 00077 00084 void Signal(); 00085 00088 00095 Alarm* AddAlarm(int64 wakeup_time_us, Function* callback); 00096 00109 bool CancelAlarm(Alarm* alarm); 00110 00117 void ProcessAlarms(int64 timeout_us); 00118 00121 Timer* timer() { return timer_; } 00122 00124 ThreadSystem* thread_system() { return thread_system_; } 00125 00129 void Wakeup(); 00130 00134 virtual void RegisterWorker(QueuedWorkerPool::Sequence* w); 00135 virtual void UnregisterWorker(QueuedWorkerPool::Sequence* w); 00136 00137 protected: 00143 virtual void AwaitWakeupUntilUs(int64 wakeup_time_us); 00144 00145 bool running_waiting_alarms() const { return running_waiting_alarms_; } 00146 00147 private: 00148 class CondVarTimeout; 00149 class CondVarCallbackTimeout; 00150 friend class SchedulerTest; 00151 00152 typedef std::set<Alarm*, CompareAlarms> AlarmSet; 00153 00154 int64 RunAlarms(bool* ran_alarms); 00155 void AddAlarmMutexHeld(int64 wakeup_time_us, Alarm* alarm); 00156 void CancelWaiting(Alarm* alarm); 00157 bool NoPendingAlarms(); 00158 00159 ThreadSystem* thread_system_; 00160 Timer* timer_; 00161 scoped_ptr<ThreadSystem::CondvarCapableMutex> mutex_; 00164 scoped_ptr<ThreadSystem::Condvar> condvar_; 00165 uint32 index_; 00166 AlarmSet outstanding_alarms_; 00167 00168 00169 int64 signal_count_; 00170 AlarmSet waiting_alarms_; 00171 bool running_waiting_alarms_; 00172 00173 DISALLOW_COPY_AND_ASSIGN(Scheduler); 00174 }; 00175 00182 class SchedulerBlockingFunction : public Function { 00183 public: 00184 explicit SchedulerBlockingFunction(Scheduler* scheduler); 00185 virtual ~SchedulerBlockingFunction(); 00186 virtual void Run(); 00187 virtual void Cancel(); 00189 bool Block(); 00190 private: 00191 Scheduler* scheduler_; 00192 bool success_; 00193 AtomicBool done_; 00194 DISALLOW_COPY_AND_ASSIGN(SchedulerBlockingFunction); 00195 }; 00196 00197 } 00198 00199 #endif ///< NET_INSTAWEB_UTIL_PUBLIC_SCHEDULER_H_