00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00024
00025 #ifndef NET_INSTAWEB_UTIL_PUBLIC_QUEUED_WORKER_POOL_H_
00026 #define NET_INSTAWEB_UTIL_PUBLIC_QUEUED_WORKER_POOL_H_
00027
00028 #include <cstddef>
00029 #include <deque>
00030 #include <set>
00031 #include <vector>
00032
00033 #include "base/scoped_ptr.h"
00034 #include "net/instaweb/util/public/basictypes.h"
00035 #include "net/instaweb/util/public/function.h"
00036 #include "net/instaweb/util/public/thread_system.h"
00037
00038 namespace net_instaweb {
00039
00040 class AbstractMutex;
00041 class QueuedWorker;
00042 class Waveform;
00043
00046 class QueuedWorkerPool {
00047 public:
00048 static const int kNoLoadShedding = -1;
00049
00050 QueuedWorkerPool(int max_workers, ThreadSystem* thread_system);
00051 ~QueuedWorkerPool();
00052
00057 class Sequence {
00058 public:
00063 class AddFunction : public Function {
00064 public:
00065 AddFunction(Sequence* sequence, Function* callback)
00066 : sequence_(sequence), callback_(callback) { }
00067 virtual ~AddFunction();
00068
00069 protected:
00070 virtual void Run() {
00071 sequence_->Add(callback_);
00072 }
00073 virtual void Cancel() {
00074 sequence_->Add(MakeFunction(callback_, &Function::CallCancel));
00075 }
00076
00077 private:
00078 Sequence* sequence_;
00079 Function* callback_;
00080 DISALLOW_COPY_AND_ASSIGN(AddFunction);
00081 };
00082
00092 void Add(Function* function);
00093
00094 void set_queue_size_stat(Waveform* x) { queue_size_ = x; }
00095
00096 private:
00098 Sequence(ThreadSystem* thread_system, QueuedWorkerPool* pool);
00099
00101 ~Sequence();
00102
00104 void Reset();
00105
00112 void WaitForShutDown();
00113
00117 bool InitiateShutDown();
00118
00121 Function* NextFunction();
00122
00124 bool IsBusy();
00125
00127 int CancelTasksOnWorkQueue();
00128
00131 void Cancel();
00132
00133 friend class QueuedWorkerPool;
00134 std::deque<Function*> work_queue_;
00135 scoped_ptr<ThreadSystem::CondvarCapableMutex> sequence_mutex_;
00136 QueuedWorkerPool* pool_;
00137 bool shutdown_;
00138 bool active_;
00139 scoped_ptr<ThreadSystem::Condvar> termination_condvar_;
00140 Waveform* queue_size_;
00141
00142 DISALLOW_COPY_AND_ASSIGN(Sequence);
00143 };
00144
00145 typedef std::set<Sequence*> SequenceSet;
00146
00151 Sequence* NewSequence();
00152
00155 void FreeSequence(Sequence* sequence);
00156
00159 void ShutDown();
00160
00175 static bool AreBusy(const SequenceSet& sequences);
00176
00186 void SetLoadSheddingThreshold(int x);
00187
00191 void set_queue_size_stat(Waveform* x) { queue_size_ = x; }
00192
00193 private:
00194 friend class Sequence;
00195 void Run(Sequence* sequence, QueuedWorker* worker);
00196 void QueueSequence(Sequence* sequence);
00197 Sequence* AssignWorkerToNextSequence(QueuedWorker* worker);
00198 void SequenceNoLongerActive(Sequence* sequence);
00199
00200 ThreadSystem* thread_system_;
00201 scoped_ptr<AbstractMutex> mutex_;
00202
00204 std::set<QueuedWorker*> active_workers_;
00205 std::vector<QueuedWorker*> available_workers_;
00206
00209 std::vector<Sequence*> all_sequences_;
00210 std::deque<Sequence*> queued_sequences_;
00211 std::vector<Sequence*> free_sequences_;
00212
00213 size_t max_workers_;
00214 bool shutdown_;
00215
00216 Waveform* queue_size_;
00217 int load_shedding_threshold_;
00218
00219 DISALLOW_COPY_AND_ASSIGN(QueuedWorkerPool);
00220 };
00221
00222 }
00223
00224 #endif ///< NET_INSTAWEB_UTIL_PUBLIC_QUEUED_WORKER_POOL_H_