notepad_commandqueue.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 "notepad_commandqueue.h"
00028 #include "log.h"
00029
00030
00031 namespace notepad
00032 {
00033
00034
00035 CmdQueue::CmdQueue()
00036 : thread(0)
00037 , current_command(0)
00038 , stop_flag(false)
00039 , flush_flag(false)
00040 {
00041 }
00042
00043 CmdQueue::~CmdQueue()
00044 {
00045 empty_queue();
00046 }
00047
00048 gpointer CmdQueue::thread_func(gpointer args)
00049 {
00050 g_assert(args);
00051 CmdQueue* thiz = reinterpret_cast<CmdQueue *>(args);
00052 return thiz->non_static_thread_func();
00053 }
00054
00055
00056 gpointer CmdQueue::non_static_thread_func()
00057 {
00058 LOGPRINTF("entry");
00059
00060 while (true)
00061 {
00062 LOGPRINTF("waiting for semaphore");
00063 sem.p();
00064
00065 if (stop_flag)
00066 {
00067 MutexLocker ml(&queue_mutex);
00068 LOGPRINTF("break here");
00069 empty_queue();
00070 sem.set(0);
00071 stop_flag = false;
00072 break;
00073 }
00074 if (flush_flag)
00075 {
00076 MutexLocker ml(&queue_mutex);
00077 LOGPRINTF("flushing queue");
00078 empty_queue();
00079 sem.set(0);
00080 flush_flag = false;
00081 continue;
00082 }
00083
00084 current_command = the_queue.front();
00085 current_command->execute();
00086 {
00087 MutexLocker ml(&queue_mutex);
00088 the_queue.pop_front();
00089 }
00090 current_command = 0;
00091 g_thread_yield();
00092 }
00093
00094 LOGPRINTF("exit");
00095 return 0;
00096 }
00097
00098 void CmdQueue::empty_queue()
00099 {
00100 LOGPRINTF("entry");
00101
00102 CommandQueueIter idx = the_queue.begin();
00103
00104 if (current_command != 0) idx++;
00105 while (idx != the_queue.end())
00106 {
00107 delete *idx;
00108 idx = the_queue.erase(idx);
00109 idx++;
00110 }
00111 the_queue.clear();
00112 g_assert(the_queue.empty());
00113 LOGPRINTF("exit");
00114 }
00115
00116 void CmdQueue::flush()
00117 {
00118 LOGPRINTF("entry");
00119 if (thread == 0)
00120 {
00121 return;
00122 }
00123 flush_flag = true;
00124 sem.v();
00125
00126 LOGPRINTF("exit");
00127 }
00128
00129 bool CmdQueue::start()
00130 {
00131 LOGPRINTF("entry");
00132 if (thread != 0)
00133 {
00134
00135 return false;
00136 }
00137
00138 thread = g_thread_create(thread_func, this, TRUE, 0);
00139 LOGPRINTF("exit");
00140 return thread != 0;
00141 }
00142
00143 void CmdQueue::stop()
00144 {
00145 LOGPRINTF("entry");
00146 if (thread == 0)
00147 {
00148 return;
00149 }
00150 stop_flag = true;
00151 sem.v();
00152
00153
00154 g_thread_join(thread);
00155 LOGPRINTF("thread is stopped");
00156
00157
00158 thread = 0;
00159 LOGPRINTF("exit");
00160 }
00161
00162 void CmdQueue::add(Command* new_command)
00163 {
00164 LOGPRINTF("entry");
00165 g_assert(thread);
00166
00167
00168 while (flush_flag)
00169 {
00170 g_thread_yield();
00171 }
00172
00173
00174 {
00175 MutexLocker ml(&queue_mutex);
00176 the_queue.push_back(new_command);
00177 sem.v();
00178 }
00179 LOGPRINTF("exit");
00180 }
00181
00182
00183 }
00184