00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef VRS_MT_TASKMANAGER_H
00019 #define VRS_MT_TASKMANAGER_H
00020
00021 #include <vrs/callback.h>
00022
00023 #include <stdexcept>
00024
00025 namespace VRS {
00026 namespace MT {
00027
00028 class TaskManager;
00029
00031 class VRS_CORE_API TaskBase :
00032 public VRS::SharedObj
00033 {
00034 public:
00035 VRS_TYPEINFO(TaskBase, VRS::SharedObj);
00036
00038 enum State {
00039 State_Queued,
00040 State_Running,
00041 State_Canceling,
00042 State_Finished,
00043 State_Canceled,
00044 State_Exception
00045 };
00046
00048 virtual State state() const;
00049
00052 virtual bool ended() const;
00053
00055 virtual double priority() const;
00056
00060 virtual void changePriority(double newPriority);
00061
00065 virtual void wait() const;
00066
00072 virtual bool wait(double seconds) const;
00073
00082 virtual void cancel();
00083
00084 public:
00087 static void Sleep(double seconds);
00088
00090 static void Yield();
00091
00096 static bool ShouldBeCanceled();
00097
00099 static void DoCancelation();
00100
00101 protected:
00103 TaskBase(
00104 double priority,
00105 double cancelIfNotStartedWithinSecond,
00106 bool finished
00107 );
00108
00109 public:
00111 virtual ~TaskBase();
00112
00113 protected:
00115 virtual void work() = 0;
00116
00118 void workImpl();
00119
00120 protected:
00121 friend class TaskManager;
00122
00123 public:
00124 struct Impl;
00125 Impl* const m_impl;
00126 };
00127
00129 template<class RESULT_TYPE>
00130 class Task :
00131 public TaskBase
00132 {
00133 public:
00138 const RESULT_TYPE& result() const {
00139 wait();
00140 switch(state()) {
00141 case State_Finished: return m_result;
00142 case State_Canceled: throw std::exception("task has been canceled");
00143 case State_Exception: throw std::exception("exception during task execution");
00144 case State_Queued:
00145 case State_Running:
00146 case State_Canceling:
00147 default: throw std::exception("unreachable code reached");
00148 }
00149 return m_result;
00150 }
00151
00152 protected:
00153 friend class TaskManager;
00154
00156 Task(
00157 SO<CallbackR<RESULT_TYPE> > taskCallback,
00158 double priority,
00159 double cancelIfNotStartedWithinSeconds
00160 ) :
00161 TaskBase(priority, cancelIfNotStartedWithinSeconds, false),
00162 m_taskCallback(taskCallback),
00163 m_result()
00164 {
00165 VRS_CheckArg(taskCallback, "no task callback");
00166 }
00167
00169 Task(
00170 const RESULT_TYPE& result
00171 ) :
00172 TaskBase(0.0, 0.0, true),
00173 m_taskCallback(NULL),
00174 m_result(result)
00175 { }
00176
00178 virtual void work() {
00179 if(!m_taskCallback) { return; }
00180 m_result = m_taskCallback->callback();
00181 m_taskCallback = NULL;
00182 }
00183
00184 private:
00185 SO<CallbackR<RESULT_TYPE> > m_taskCallback;
00186 RESULT_TYPE m_result;
00187 };
00188
00191 class VRS_CORE_API TaskManager {
00192 public:
00201 template<class RESULT_TYPE>
00202 static SO<Task<RESULT_TYPE> > AddTask(
00203 SO<CallbackR<RESULT_TYPE> > taskCallback,
00204 double priority = 0.5,
00205 double cancelIfNotStartedWithinSeconds = 0.0
00206 ) {
00207 SO<Task<RESULT_TYPE> > task = new Task<RESULT_TYPE>(taskCallback, priority, cancelIfNotStartedWithinSeconds);
00208 ScheduleTask(task);
00209 return task;
00210 }
00211
00215 template<class RESULT_TYPE>
00216 static SO<Task<RESULT_TYPE> > AddResult(
00217 const RESULT_TYPE& result
00218 ) {
00219 SO<Task<RESULT_TYPE> > task = new Task<RESULT_TYPE>(result);
00220 return task;
00221 }
00222
00224 static size_t QueuedTasks();
00225
00229 static void CancelAllTasks();
00230
00231 protected:
00233 static void ScheduleTask(
00234 SO<TaskBase> task
00235 );
00236
00238 static void DispatchTasks();
00239
00241 static void Initialize();
00242 };
00243
00244 }
00245 }
00246
00247 #endif // VRS_MT_TASKMANAGER_H