From 9b1b081cfdb1c0fb6457278775e0823f8bc10f62 Mon Sep 17 00:00:00 2001 From: Unit 193 Date: Wed, 25 Apr 2018 18:07:30 -0400 Subject: Import Upstream version 2.0.0+dfsg --- src/lib/mt/Thread.cpp | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 src/lib/mt/Thread.cpp (limited to 'src/lib/mt/Thread.cpp') diff --git a/src/lib/mt/Thread.cpp b/src/lib/mt/Thread.cpp new file mode 100644 index 0000000..7474c16 --- /dev/null +++ b/src/lib/mt/Thread.cpp @@ -0,0 +1,187 @@ +/* + * barrier -- mouse and keyboard sharing utility + * Copyright (C) 2012-2016 Symless Ltd. + * 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 LICENSE 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "mt/Thread.h" + +#include "mt/XMT.h" +#include "mt/XThread.h" +#include "arch/Arch.h" +#include "base/Log.h" +#include "base/IJob.h" + +// +// Thread +// + +Thread::Thread(IJob* job) +{ + m_thread = ARCH->newThread(&Thread::threadFunc, job); + if (m_thread == NULL) { + // couldn't create thread + delete job; + throw XMTThreadUnavailable(); + } +} + +Thread::Thread(const Thread& thread) +{ + m_thread = ARCH->copyThread(thread.m_thread); +} + +Thread::Thread(ArchThread adoptedThread) +{ + m_thread = adoptedThread; +} + +Thread::~Thread() +{ + ARCH->closeThread(m_thread); +} + +Thread& +Thread::operator=(const Thread& thread) +{ + // copy given thread and release ours + ArchThread copy = ARCH->copyThread(thread.m_thread); + ARCH->closeThread(m_thread); + + // cut over + m_thread = copy; + + return *this; +} + +void +Thread::exit(void* result) +{ + throw XThreadExit(result); +} + +void +Thread::cancel() +{ + ARCH->cancelThread(m_thread); +} + +void +Thread::setPriority(int n) +{ + ARCH->setPriorityOfThread(m_thread, n); +} + +void +Thread::unblockPollSocket() +{ + ARCH->unblockPollSocket(m_thread); +} + +Thread +Thread::getCurrentThread() +{ + return Thread(ARCH->newCurrentThread()); +} + +void +Thread::testCancel() +{ + ARCH->testCancelThread(); +} + +bool +Thread::wait(double timeout) const +{ + return ARCH->wait(m_thread, timeout); +} + +void* +Thread::getResult() const +{ + if (wait()) + return ARCH->getResultOfThread(m_thread); + else + return NULL; +} + +IArchMultithread::ThreadID +Thread::getID() const +{ + return ARCH->getIDOfThread(m_thread); +} + +bool +Thread::operator==(const Thread& thread) const +{ + return ARCH->isSameThread(m_thread, thread.m_thread); +} + +bool +Thread::operator!=(const Thread& thread) const +{ + return !ARCH->isSameThread(m_thread, thread.m_thread); +} + +void* +Thread::threadFunc(void* vjob) +{ + // get this thread's id for logging + IArchMultithread::ThreadID id; + { + ArchThread thread = ARCH->newCurrentThread(); + id = ARCH->getIDOfThread(thread); + ARCH->closeThread(thread); + } + + // get job + IJob* job = static_cast(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: ", id)); + delete job; + throw; + } + + // done with job + delete job; + + // return exit result + return result; +} -- cgit v1.2.3