thread.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "thread.h"
00028
00029 namespace common
00030 {
00031
00032 Task::Task()
00033 {
00034 aborted = false;
00035 }
00036
00037 Task::~Task()
00038 {
00039 }
00040
00041 void Task::send_abort_request()
00042 {
00043 aborted = true;
00044 }
00045
00046 Thread::Thread()
00047 : thread(NULL),
00048 thread_cmd(CMD_NONE),
00049 running_task(0)
00050 {
00051 queue_mutex = g_mutex_new();
00052 queue_cond = g_cond_new();
00053 }
00054
00055 Thread::~Thread()
00056 {
00057 g_mutex_free(queue_mutex);
00058 g_cond_free(queue_cond);
00059 }
00060
00061 gpointer Thread::thread_func(gpointer args)
00062 {
00063 Thread* thiz = reinterpret_cast<Thread *>(args);
00064 return thiz->non_static_thread_func();
00065 }
00066
00067
00068 gpointer Thread::non_static_thread_func()
00069 {
00070 while (true)
00071 {
00072 g_mutex_lock(queue_mutex);
00073 while (task_queue.empty())
00074 {
00075 if (thread_cmd != CMD_NONE)
00076 {
00077 g_mutex_unlock(queue_mutex);
00078 goto CleanUp;
00079 }
00080
00081 g_cond_wait(queue_cond, queue_mutex);
00082 }
00083
00084 if (thread_cmd == CMD_TERMINATE)
00085 {
00086 g_mutex_unlock(queue_mutex);
00087 goto CleanUp;
00088 }
00089
00090
00091 Task *task = task_queue.front();
00092 task_queue.pop_front();
00093
00094 g_mutex_unlock(queue_mutex);
00095
00096
00097 running_task = task;
00098 task->execute();
00099
00100 running_task = 0;
00101
00102
00103 delete task;
00104 }
00105
00106 CleanUp:
00107 clear_all();
00108 return 0;
00109 }
00110
00111 void Thread::clear_all()
00112 {
00113 g_mutex_lock(queue_mutex);
00114
00115 std::list<Task*>::iterator it = task_queue.begin();
00116 while (it != task_queue.end())
00117 {
00118 delete *it;
00119 it = task_queue.erase(it);
00120 }
00121
00122 g_mutex_unlock(queue_mutex);
00123 }
00124
00125 bool Thread::start()
00126 {
00127 if (thread != NULL)
00128 {
00129
00130 return false;
00131 }
00132
00133 thread = g_thread_create(thread_func, this, TRUE, NULL);
00134 return thread != NULL;
00135 }
00136
00137 void Thread::stop(bool cancel_all_tasks)
00138 {
00139 if (thread == NULL)
00140 {
00141 return;
00142 }
00143
00144 thread_cmd = cancel_all_tasks ? CMD_TERMINATE : CMD_STOP;
00145
00146 if (running_task != 0)
00147 {
00148 if (cancel_all_tasks)
00149 {
00150 running_task->send_abort_request();
00151 }
00152 }
00153 else
00154 {
00155
00156 g_cond_signal(queue_cond);
00157 }
00158
00159
00160 g_thread_join(thread);
00161
00162
00163 thread = NULL;
00164 }
00165
00166 bool Thread::append_task(Task* new_task)
00167 {
00168 if (thread_cmd == CMD_NONE)
00169 {
00170
00171 g_mutex_lock(queue_mutex);
00172 task_queue.push_back(new_task);
00173 g_mutex_unlock(queue_mutex);
00174
00175
00176 g_cond_signal(queue_cond);
00177 return true;
00178 }
00179 else
00180 {
00181 delete new_task;
00182 return false;
00183 }
00184 }
00185
00186 bool Thread::prepend_task(Task* new_task, bool abort_current)
00187 {
00188 if (thread_cmd == CMD_NONE)
00189 {
00190
00191 g_mutex_lock(queue_mutex);
00192 task_queue.push_front(new_task);
00193
00194 if (abort_current)
00195 {
00196 abort_current_task();
00197 }
00198
00199 g_mutex_unlock(queue_mutex);
00200
00201
00202 g_cond_signal(queue_cond);
00203
00204 return true;
00205 }
00206 else
00207 {
00208 delete new_task;
00209 return false;
00210 }
00211 }
00212
00213 bool Thread::abort_current_task()
00214 {
00215 if (running_task != 0)
00216 {
00217
00218 running_task->send_abort_request();
00219 return true;
00220 }
00221 else
00222 {
00223
00224 return false;
00225 }
00226 }
00227
00228 }