new library

This commit is contained in:
mpc
2004-06-29 02:55:53 +00:00
committed by zzz
parent 021b933ad3
commit e9cdb0f78d
4 changed files with 256 additions and 34 deletions

View File

@@ -0,0 +1,103 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* 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 "mutex.hpp"
/*
* Creates a mutex
*/
Mutex::Mutex(void)
{
#ifdef WINTHREADS
mutex = CreateMutex(NULL, FALSE, NULL);
if (mutex == NULL) {
TCHAR str[80];
throw Mutex_error(win_strerror(str, sizeof str));
}
#else
int rc = pthread_mutex_init(&mutex, NULL);
if (!rc)
throw Mutex_error(strerror(rc));
#endif
}
/*
* Destroys a mutex
*/
Mutex::~Mutex(void)
{
#ifdef WINTHREADS
if (!CloseHandle(mutex)) {
TCHAR str[80];
throw Mutex_error(win_strerror(str, sizeof str));
}
#else
int rc = pthread_mutex_destroy(&mutex);
if (!rc)
throw Mutex_error(strerror(rc));
#endif
}
/*
* Locks the mutex
*/
void Mutex::lock(void)
{
#ifdef WINTHREADS
if (WaitForSingleObject(mutex, INFINITE) == WAIT_FAILED) {
TCHAR str[80];
throw Mutex_error(win_strerror(str, sizeof str));
}
#else
int rc = pthread_mutex_lock(&mutex);
if (!rc)
throw Mutex_error(strerror(rc));
#endif
}
/*
* Unlocks the mutex
*/
void Mutex::unlock(void)
{
#ifdef WINTHREADS
if (!ReleaseMutex(mutex)) {
TCHAR str[80];
throw Mutex_error(win_strerror(str, sizeof str));
}
#else
int rc = pthread_mutex_unlock(&mutex);
if (!rc)
throw Mutex_error(strerror(rc));
#endif
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* 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 MUTEX_HPP
#define MUTEX_HPP
namespace Libsockthread {
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
HANDLE mutex;
#else
pthread_mutex_t mutex;
#endif
};
class Mutex_error : public runtime_error {
Mutex_error(const string& s) : runtime_error(s) { }
};
}
#endif // MUTEX_HPP

View File

@@ -0,0 +1,143 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* 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<Thread*>(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;
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 2004, Matthew P. Cashdollar <mpc@innographx.com>
* 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