1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
|
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "CThread.h"
#include "XMT.h"
#include "XThread.h"
#include "CLog.h"
#include "IJob.h"
#include "CArch.h"
//
// CThread
//
CThread::CThread(IJob* job)
{
m_thread = ARCH->newThread(&CThread::threadFunc, job);
if (m_thread == NULL) {
// couldn't create thread
delete job;
throw XMTThreadUnavailable();
}
}
CThread::CThread(const CThread& thread)
{
m_thread = ARCH->copyThread(thread.m_thread);
}
CThread::CThread(CArchThread adoptedThread)
{
m_thread = adoptedThread;
}
CThread::~CThread()
{
ARCH->closeThread(m_thread);
}
CThread&
CThread::operator=(const CThread& thread)
{
// copy given thread and release ours
CArchThread copy = ARCH->copyThread(thread.m_thread);
ARCH->closeThread(m_thread);
// cut over
m_thread = copy;
return *this;
}
void
CThread::exit(void* result)
{
throw XThreadExit(result);
}
void
CThread::cancel()
{
ARCH->cancelThread(m_thread);
}
void
CThread::setPriority(int n)
{
ARCH->setPriorityOfThread(m_thread, n);
}
void
CThread::unblockPollSocket()
{
ARCH->unblockPollSocket(m_thread);
}
CThread
CThread::getCurrentThread()
{
return CThread(ARCH->newCurrentThread());
}
void
CThread::testCancel()
{
ARCH->testCancelThread();
}
bool
CThread::wait(double timeout) const
{
return ARCH->wait(m_thread, timeout);
}
void*
CThread::getResult() const
{
if (wait())
return ARCH->getResultOfThread(m_thread);
else
return NULL;
}
IArchMultithread::ThreadID
CThread::getID() const
{
return ARCH->getIDOfThread(m_thread);
}
bool
CThread::operator==(const CThread& thread) const
{
return ARCH->isSameThread(m_thread, thread.m_thread);
}
bool
CThread::operator!=(const CThread& thread) const
{
return !ARCH->isSameThread(m_thread, thread.m_thread);
}
void*
CThread::threadFunc(void* vjob)
{
// get this thread's id for logging
IArchMultithread::ThreadID id;
{
CArchThread thread = ARCH->newCurrentThread();
id = ARCH->getIDOfThread(thread);
ARCH->closeThread(thread);
}
// get job
IJob* job = reinterpret_cast<IJob*>(vjob);
// run job
void* result = NULL;
try {
// go
LOG((CLOG_DEBUG1 "thread 0x%08x entry", id));
job->run();
LOG((CLOG_DEBUG1 "thread 0x%08x exit", id));
}
catch (XThreadCancel&) {
// client called cancel()
LOG((CLOG_DEBUG1 "caught cancel on thread 0x%08x", id));
delete job;
throw;
}
catch (XThreadExit& e) {
// client called exit()
result = e.m_result;
LOG((CLOG_DEBUG1 "caught exit on thread 0x%08x, result %p", id, result));
}
catch (XBase& e) {
LOG((CLOG_ERR "exception on thread 0x%08x: %s", id, e.what()));
delete job;
throw;
}
catch (...) {
LOG((CLOG_ERR "exception on thread 0x%08x: <unknown>", id));
delete job;
throw;
}
// done with job
delete job;
// return exit result
return result;
}
|