00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00012
00013 #include "taskqueue.h"
00014 #include "mythlogging.h"
00015
00016 #include <QDateTime>
00017
00018 #include <iostream>
00019
00021
00023
00024 static QMutex g_pTaskQueueCreationLock;
00025 TaskQueue* TaskQueue::g_pTaskQueue = NULL;
00026
00029
00030
00031
00034
00035 long Task::m_nTaskCount = 0;
00036
00038
00040
00041 Task::Task()
00042 {
00043 m_nTaskId = m_nTaskCount++;
00044 }
00045
00047
00049
00050 Task::~Task()
00051 {
00052 }
00053
00056
00057
00058
00061
00063
00065
00066 TaskQueue* TaskQueue::Instance()
00067 {
00068 QMutexLocker locker(&g_pTaskQueueCreationLock);
00069 return g_pTaskQueue ? g_pTaskQueue : (g_pTaskQueue = new TaskQueue());
00070 }
00071
00073
00075
00076 void TaskQueue::Shutdown()
00077 {
00078 QMutexLocker locker(&g_pTaskQueueCreationLock);
00079 delete g_pTaskQueue;
00080 g_pTaskQueue = NULL;
00081 }
00082
00084
00086
00087 TaskQueue::TaskQueue() : MThread("TaskQueue"), m_bTermRequested( false )
00088 {
00089 LOG(VB_UPNP, LOG_INFO, "Starting TaskQueue Thread...");
00090
00091 start();
00092
00093 LOG(VB_UPNP, LOG_INFO, "TaskQueue Thread Started.");
00094 }
00095
00097
00099
00100 TaskQueue::~TaskQueue()
00101 {
00102 m_bTermRequested = true;
00103
00104 wait();
00105
00106 Clear();
00107 }
00108
00109 void TaskQueue::RequestTerminate()
00110 {
00111 m_bTermRequested = true;
00112 }
00113
00115
00117
00118 void TaskQueue::run( )
00119 {
00120 RunProlog();
00121
00122 Task *pTask;
00123
00124 LOG(VB_UPNP, LOG_INFO, "TaskQueue Thread Running.");
00125
00126 while ( !m_bTermRequested )
00127 {
00128
00129
00130
00131
00132 TaskTime ttNow;
00133 gettimeofday( (&ttNow), NULL );
00134
00135 if ((pTask = GetNextExpiredTask( ttNow )) != NULL)
00136 {
00137 try
00138 {
00139 pTask->Execute( this );
00140 pTask->Release();
00141 }
00142 catch( ... )
00143 {
00144 LOG(VB_GENERAL, LOG_ERR, "Call to Execute threw an exception.");
00145 }
00146
00147 }
00148
00149
00150 msleep( 100 );
00151 }
00152
00153 RunEpilog();
00154 }
00155
00157
00159
00160 void TaskQueue::Clear( )
00161 {
00162 m_mutex.lock();
00163
00164 for ( TaskMap::iterator it = m_mapTasks.begin();
00165 it != m_mapTasks.end();
00166 ++it )
00167 {
00168 if ((*it).second != NULL)
00169 (*it).second->Release();
00170 }
00171
00172 m_mapTasks.clear();
00173
00174 m_mutex.unlock();
00175 }
00176
00178
00180
00181 void TaskQueue::AddTask( long msec, Task *pTask )
00182 {
00183 TaskTime tt;
00184 gettimeofday( (&tt), NULL );
00185
00186 AddMicroSecToTaskTime( tt, (msec * 1000) );
00187
00188 AddTask( tt, pTask );
00189 }
00190
00192
00194
00195 void TaskQueue::AddTask( TaskTime ttKey, Task *pTask )
00196 {
00197
00198 if (pTask != NULL)
00199 {
00200 m_mutex.lock();
00201 pTask->AddRef();
00202 m_mapTasks.insert( TaskMap::value_type( ttKey, pTask ));
00203 m_mutex.unlock();
00204 }
00205 }
00206
00208
00210
00211 void TaskQueue::AddTask( Task *pTask )
00212 {
00213
00214 if (pTask != NULL)
00215 {
00216 TaskTime tt;
00217 gettimeofday( (&tt), NULL );
00218
00219 AddTask( tt, pTask );
00220 }
00221 }
00222
00224
00226
00227 Task *TaskQueue::GetNextExpiredTask( TaskTime tt, long nWithinMilliSecs )
00228 {
00229 Task *pTask = NULL;
00230
00231 AddMicroSecToTaskTime( tt, nWithinMilliSecs * 1000 );
00232
00233 m_mutex.lock();
00234
00235 TaskMap::iterator it = m_mapTasks.begin();
00236
00237 if (it != m_mapTasks.end())
00238 {
00239 TaskTime ttTask = (*it).first;
00240
00241 if (ttTask < tt)
00242 {
00243
00244
00245 pTask = (*it).second;
00246
00247 m_mapTasks.erase( it );
00248 }
00249 }
00250 m_mutex.unlock();
00251
00252 return pTask;
00253 }