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