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 #include "ArExport.h"
00027
00028
00029
00030 #include "ariaOSDef.h"
00031 #include <list>
00032 #include "ArThread.h"
00033 #include "ArLog.h"
00034 #include "ArSignalHandler.h"
00035
00036
00037 static DWORD WINAPI run(void *arg)
00038 {
00039 ArThread *t=(ArThread*)arg;
00040 void *ret=NULL;
00041
00042 if (t->getBlockAllSignals())
00043 ArSignalHandler::blockCommonThisThread();
00044
00045 if (dynamic_cast<ArRetFunctor<void*>*>(t->getFunc()))
00046 ret=((ArRetFunctor<void*>*)t->getFunc())->invokeR();
00047 else
00048 t->getFunc()->invoke();
00049
00050 return((DWORD)ret);
00051 }
00052
00053 void ArThread::init()
00054 {
00055 ArThread *main;
00056 ThreadType pt;
00057 MapType::iterator iter;
00058
00059 pt=GetCurrentThread();
00060
00061 ourThreadsMutex.lock();
00062 if (ourThreads.size())
00063 {
00064 ourThreadsMutex.unlock();
00065 return;
00066 }
00067 main=new ArThread;
00068 main->myJoinable=true;
00069 main->myRunning=true;
00070 main->myThread=pt;
00071 ourThreads.insert(MapType::value_type(pt, main));
00072 ourThreadsMutex.unlock();
00073 }
00074
00075
00076 AREXPORT ArThread * ArThread::self()
00077 {
00078 ThreadType pt;
00079 MapType::iterator iter;
00080
00081 ourThreadsMutex.lock();
00082 pt=GetCurrentThread();
00083 iter=ourThreads.find(pt);
00084 ourThreadsMutex.unlock();
00085
00086 if (iter != ourThreads.end())
00087 return((*iter).second);
00088 else
00089 return(NULL);
00090 }
00091
00092 AREXPORT void ArThread::cancelAll()
00093 {
00094 DWORD ret=0;
00095 MapType::iterator iter;
00096
00097 ourThreadsMutex.lock();
00098 for (iter=ourThreads.begin(); iter != ourThreads.end(); ++iter)
00099 TerminateThread((*iter).first, ret);
00100 ourThreads.clear();
00101 ourThreadsMutex.unlock();
00102 }
00103
00104 AREXPORT int ArThread::create(ArFunctor *func, bool joinable,
00105 bool lowerPriority)
00106 {
00107 DWORD ret=0, err;
00108
00109 myJoinable=joinable;
00110 myFunc=func;
00111 myRunning=true;
00112
00113 myThread=CreateThread(0, 0, &run, this, 0, &ret);
00114 err=GetLastError();
00115 if (myThread == 0)
00116 {
00117 ArLog::log(ArLog::Terse, "ArThread::create: Failed to create thread.");
00118 return(STATUS_FAILED);
00119 }
00120 else
00121 {
00122 if (myName.size() == 0)
00123 ArLog::log(ourLogLevel, "Created anonymous thread with ID %d",
00124 myThread);
00125 else
00126 ArLog::log(ourLogLevel, "Created %s thread with ID %d", myName.c_str(),
00127 myThread);
00128 ourThreadsMutex.lock();
00129 ourThreads.insert(MapType::value_type(myThread, this));
00130 ourThreadsMutex.unlock();
00131 if (lowerPriority)
00132 SetThreadPriority(myThread, THREAD_PRIORITY_IDLE);
00133 return(0);
00134 }
00135 }
00136
00137 AREXPORT int ArThread::doJoin(void **iret)
00138 {
00139 DWORD ret;
00140
00141 ret=WaitForSingleObject(myThread, INFINITE);
00142 if (ret == WAIT_FAILED)
00143 {
00144 ArLog::log(ArLog::Terse, "ArThread::doJoin: Failed to join on thread.");
00145 return(STATUS_FAILED);
00146 }
00147
00148 return(0);
00149 }
00150
00151 AREXPORT int ArThread::detach()
00152 {
00153 return(0);
00154 }
00155
00156 AREXPORT void ArThread::cancel()
00157 {
00158 DWORD ret=0;
00159
00160 ourThreadsMutex.lock();
00161 ourThreads.erase(myThread);
00162 ourThreadsMutex.unlock();
00163 TerminateThread(myThread, ret);
00164 }
00165
00166 AREXPORT void ArThread::yieldProcessor()
00167 {
00168 Sleep(0);
00169 }
00170
00171
00172 AREXPORT void ArThread::threadStarted(void)
00173 {
00174 if (myName.size() == 0)
00175 ArLog::log(ourLogLevel, "Anonymous thread (%d) is running",
00176 myThread);
00177 else
00178 ArLog::log(ourLogLevel, "Thread %s (%d) is running",
00179 myName.c_str(), myThread);
00180 }
00181
00182 AREXPORT void ArThread::logThreadInfo(void)
00183 {
00184 if (myName.size() == 0)
00185 ArLog::log(ourLogLevel, "Anonymous thread (%d) is running",
00186 myThread);
00187 else
00188 ArLog::log(ourLogLevel, "Thread %s (%d) is running",
00189 myName.c_str(), myThread);
00190 }