From e9cdb0f78d266a741929d225c362324a9deba655 Mon Sep 17 00:00:00 2001 From: mpc Date: Tue, 29 Jun 2004 02:55:53 +0000 Subject: [PATCH] new library --- .../enclave/{ => libsockthread}/src/mutex.cpp | 45 +++--- .../enclave/{ => libsockthread}/src/mutex.hpp | 30 ++-- apps/enclave/libsockthread/src/thread.cpp | 143 ++++++++++++++++++ apps/enclave/libsockthread/src/thread.hpp | 72 +++++++++ 4 files changed, 256 insertions(+), 34 deletions(-) rename apps/enclave/{ => libsockthread}/src/mutex.cpp (77%) rename apps/enclave/{ => libsockthread}/src/mutex.hpp (81%) create mode 100644 apps/enclave/libsockthread/src/thread.cpp create mode 100644 apps/enclave/libsockthread/src/thread.hpp diff --git a/apps/enclave/src/mutex.cpp b/apps/enclave/libsockthread/src/mutex.cpp similarity index 77% rename from apps/enclave/src/mutex.cpp rename to apps/enclave/libsockthread/src/mutex.cpp index f4a123e92..7e2aca5c1 100644 --- a/apps/enclave/src/mutex.cpp +++ b/apps/enclave/libsockthread/src/mutex.cpp @@ -28,40 +28,43 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +// Modelled after JThread by Jori Liesenborgs + #include "platform.hpp" #include "mutex.hpp" +/* + * Creates a mutex + */ Mutex::Mutex(void) { #ifdef WINTHREADS mutex = CreateMutex(NULL, FALSE, NULL); if (mutex == NULL) { - LERROR << strerror(rc) << '\n'; - throw runtime_error(strerror(rc)); + TCHAR str[80]; + throw Mutex_error(win_strerror(str, sizeof str)); } #else int rc = pthread_mutex_init(&mutex, NULL); - if (rc != 0) { - LERROR << strerror(rc) << '\n'; - throw runtime_error(strerror(rc)); - } + if (!rc) + throw Mutex_error(strerror(rc)); #endif } +/* + * Destroys a mutex + */ Mutex::~Mutex(void) { #ifdef WINTHREADS if (!CloseHandle(mutex)) { TCHAR str[80]; - LERROR << win_strerror(str, sizeof str) << '\n'; - throw runtime_error(str); + throw Mutex_error(win_strerror(str, sizeof str)); } #else int rc = pthread_mutex_destroy(&mutex); - if (rc != 0) { - LERROR << strerror(rc) << '\n'; - throw runtime_error(strerror(rc)); - } + if (!rc) + throw Mutex_error(strerror(rc)); #endif } @@ -73,15 +76,12 @@ void Mutex::lock(void) #ifdef WINTHREADS if (WaitForSingleObject(mutex, INFINITE) == WAIT_FAILED) { TCHAR str[80]; - LERROR << win_strerror(str, sizeof str) << '\n'; - throw runtime_error(str); + throw Mutex_error(win_strerror(str, sizeof str)); } #else int rc = pthread_mutex_lock(&mutex); - if (rc != 0) { - LERROR << strerror(rc) << '\n'; - throw runtime_error(strerror(rc)); - } + if (!rc) + throw Mutex_error(strerror(rc)); #endif } @@ -93,14 +93,11 @@ void Mutex::unlock(void) #ifdef WINTHREADS if (!ReleaseMutex(mutex)) { TCHAR str[80]; - LERROR << win_strerror(str, sizeof str) << '\n'; - throw runtime_error(str); + throw Mutex_error(win_strerror(str, sizeof str)); } #else int rc = pthread_mutex_unlock(&mutex); - if (rc != 0) { - LERROR << strerror(rc) << '\n'; - throw runtime_error(strerror(rc)); - } + if (!rc) + throw Mutex_error(strerror(rc)); #endif } diff --git a/apps/enclave/src/mutex.hpp b/apps/enclave/libsockthread/src/mutex.hpp similarity index 81% rename from apps/enclave/src/mutex.hpp rename to apps/enclave/libsockthread/src/mutex.hpp index 8085139b0..2237652f0 100644 --- a/apps/enclave/src/mutex.hpp +++ b/apps/enclave/libsockthread/src/mutex.hpp @@ -28,22 +28,32 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +// Modelled after JThread by Jori Liesenborgs + #ifndef MUTEX_HPP #define MUTEX_HPP -class Mutex { - public: - Mutex(void); - ~Mutex(void); +namespace Libsockthread { - void lock(void); - void unlock(void); + class Mutex { + public: + Mutex(void); // throws Mutex_error + ~Mutex(void); // throws Mutex_error + + void lock(void); // throws Mutex_error + void unlock(void); // throws Mutex_error private: -#ifdef WINTHREADS + #ifdef WINTHREADS HANDLE mutex; -#else + #else pthread_mutex_t mutex; -#endif -}; + #endif + }; + + class Mutex_error : public runtime_error { + Mutex_error(const string& s) : runtime_error(s) { } + }; + +} #endif // MUTEX_HPP diff --git a/apps/enclave/libsockthread/src/thread.cpp b/apps/enclave/libsockthread/src/thread.cpp new file mode 100644 index 000000000..c87e5e84d --- /dev/null +++ b/apps/enclave/libsockthread/src/thread.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// Modelled after JThread by Jori Liesenborgs + +#include "platform.hpp" +#include "thread.hpp" + +/* + * Gets the return value of a finished thread + */ +void* Thread::get_retval(void) +{ + void* val; + running_m.lock(); + if (running) + val = 0; + else + val = retval; + running_m.unlock(); + return val; +} + +/* + * Checks whether the thread is running + */ +bool Thread::is_running(void) +{ + running_m.lock(); + bool r = running; + running_m.unlock(); + return r; +} + +/* + * Stops the thread + * Generally NOT a good idea + * + * Returns: true if the thread was killed, or false if it was already dead + */ +bool Thread::kill(void) +{ + running_m.lock(); + if (!running) { + running_m.unlock(); + return false; + } +#ifdef WINTHREADS + if (!TerminateThread(handle, 0)) { + TCHAR str[80]; + throw Thread_error(win_strerror(str, sizeof str)); + } +#else + int rc = pthread_cancel(id); + if (!rc) + throw Thread_error(strerror(rc)); +#endif + running = false; + running_m.unlock(); + return true; +} + +/* + * Starts the thread + */ +void Thread::start(void) +{ + #ifndef NDEBUG + // check whether the thread is already running + running_m.lock(); + assert(!running); + running_m.unlock(); + #endif + continue_m.lock(); +#ifdef WINTHREADS + handle = CreateThread(NULL, 0, &the_thread, this, 0, &id); + if (handle == NULL) { + TCHAR str[80]; + throw Thread_error(win_strerror(str, sizeof str)); + } +#else + int rc = pthread_create(&id, NULL, &the_thread, this); + if (!rc) { + continue_m.unlock(); + throw Thread_error(strerror(rc)); + } +#endif + // Wait until `running' is set + running_m.lock(); + while (!running) { + running_m.unlock(); + running_m.lock(); + } + running_m.unlock(); + continue_m.unlock(); +} + +/* + * Wrapper for the thread + */ +void* Thread::the_thread(void *param) +{ + Thread* t = dynamic_cast(param); + t->running_m.lock(); + t->running = true; + t->running_m.unlock(); + // wait until we can continue + t->continue_m.lock(); + t->continue_m.unlock(); + void* ret = t->execute(); + t->running_m.lock(); + t->running = false; + t->retval = ret; + t->running_m.unlock(); + return 0; +} diff --git a/apps/enclave/libsockthread/src/thread.hpp b/apps/enclave/libsockthread/src/thread.hpp new file mode 100644 index 000000000..52913559d --- /dev/null +++ b/apps/enclave/libsockthread/src/thread.hpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2004, Matthew P. Cashdollar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// Modelled after JThread by Jori Liesenborgs + +#ifndef THREAD_HPP +#define THREAD_HPP + +namespace Libsockthread { + + class Thread { + public: + Thread(void) // throws Mutex_error + : retval(0), running(false) { } + virtual ~Thread(void) // throws Thread_error + { kill(); } + + virtual void *execute(void) = 0; + void* get_retval(void); + bool is_running(void); + bool kill(void); // throws Thread_error + void start(void); // throws Thread_error + + private: +#ifdef WINTHREADS + static DWORD WINAPI the_thread(void* param); + HANDLE handle; + DWORD id; +#else + static void* the_thread(void* param); + pthread_t id; +#endif + void *retval; + bool running; + Mutex running_m; + Mutex continue_m; + }; + + class Thread_error : public runtime_error { + Thread_error(const string& s) : runtime_error(s) { } + }; + +} + +#endif // THREAD_HPP