00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "CThread.h"
00020 #include "XMT.h"
00021 #include "XThread.h"
00022 #include "CLog.h"
00023 #include "IJob.h"
00024 #include "CArch.h"
00025
00026
00027
00028
00029
00030 CThread::CThread(IJob* job)
00031 {
00032 m_thread = ARCH->newThread(&CThread::threadFunc, job);
00033 if (m_thread == NULL) {
00034
00035 delete job;
00036 throw XMTThreadUnavailable();
00037 }
00038 }
00039
00040 CThread::CThread(const CThread& thread)
00041 {
00042 m_thread = ARCH->copyThread(thread.m_thread);
00043 }
00044
00045 CThread::CThread(CArchThread adoptedThread)
00046 {
00047 m_thread = adoptedThread;
00048 }
00049
00050 CThread::~CThread()
00051 {
00052 ARCH->closeThread(m_thread);
00053 }
00054
00055 CThread&
00056 CThread::operator=(const CThread& thread)
00057 {
00058
00059 CArchThread copy = ARCH->copyThread(thread.m_thread);
00060 ARCH->closeThread(m_thread);
00061
00062
00063 m_thread = copy;
00064
00065 return *this;
00066 }
00067
00068 void
00069 CThread::exit(void* result)
00070 {
00071 throw XThreadExit(result);
00072 }
00073
00074 void
00075 CThread::cancel()
00076 {
00077 ARCH->cancelThread(m_thread);
00078 }
00079
00080 void
00081 CThread::setPriority(int n)
00082 {
00083 ARCH->setPriorityOfThread(m_thread, n);
00084 }
00085
00086 void
00087 CThread::unblockPollSocket()
00088 {
00089 ARCH->unblockPollSocket(m_thread);
00090 }
00091
00092 CThread
00093 CThread::getCurrentThread()
00094 {
00095 return CThread(ARCH->newCurrentThread());
00096 }
00097
00098 void
00099 CThread::testCancel()
00100 {
00101 ARCH->testCancelThread();
00102 }
00103
00104 bool
00105 CThread::wait(double timeout) const
00106 {
00107 return ARCH->wait(m_thread, timeout);
00108 }
00109
00110 void*
00111 CThread::getResult() const
00112 {
00113 if (wait())
00114 return ARCH->getResultOfThread(m_thread);
00115 else
00116 return NULL;
00117 }
00118
00119 IArchMultithread::ThreadID
00120 CThread::getID() const
00121 {
00122 return ARCH->getIDOfThread(m_thread);
00123 }
00124
00125 bool
00126 CThread::operator==(const CThread& thread) const
00127 {
00128 return ARCH->isSameThread(m_thread, thread.m_thread);
00129 }
00130
00131 bool
00132 CThread::operator!=(const CThread& thread) const
00133 {
00134 return !ARCH->isSameThread(m_thread, thread.m_thread);
00135 }
00136
00137 void*
00138 CThread::threadFunc(void* vjob)
00139 {
00140
00141 IArchMultithread::ThreadID id;
00142 {
00143 CArchThread thread = ARCH->newCurrentThread();
00144 id = ARCH->getIDOfThread(thread);
00145 ARCH->closeThread(thread);
00146 }
00147
00148
00149 IJob* job = reinterpret_cast<IJob*>(vjob);
00150
00151
00152 void* result = NULL;
00153 try {
00154
00155 LOG((CLOG_DEBUG1 "thread 0x%08x entry", id));
00156 job->run();
00157 LOG((CLOG_DEBUG1 "thread 0x%08x exit", id));
00158 }
00159
00160 catch (XThreadCancel&) {
00161
00162 LOG((CLOG_DEBUG1 "caught cancel on thread 0x%08x", id));
00163 delete job;
00164 throw;
00165 }
00166 catch (XThreadExit& e) {
00167
00168 result = e.m_result;
00169 LOG((CLOG_DEBUG1 "caught exit on thread 0x%08x, result %p", id, result));
00170 }
00171 catch (XBase& e) {
00172 LOG((CLOG_ERR "exception on thread 0x%08x: %s", id, e.what()));
00173 delete job;
00174 throw;
00175 }
00176 catch (...) {
00177 LOG((CLOG_ERR "exception on thread 0x%08x: <unknown>", id));
00178 delete job;
00179 throw;
00180 }
00181
00182
00183 delete job;
00184
00185
00186 return result;
00187 }