Update of /cvsroot/sharedaemon/sharedaemon-ui-web/src/thread
In directory sc8-pr-cvs1:/tmp/cvs-serv659/src/thread
Modified Files:
Mutex.cpp Condition.cpp Condition.h
Added Files:
Thread.cpp Semaphore.cpp Thread.h Semaphore.h
Log Message:
24/12/2003 Barbeaux
* Added simple test programs for Exceptions and Threads.
* Implemented Semaphore and Thread.
--- NEW FILE: Thread.cpp ---
/*
* This file is part of webInterface.
* Copyright (C) 2003 Mikael Barbeaux <mik...@us...>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Thread.h"
/**
* Creates a thread object.
* Initializes parameters only.
*/
Thread::Thread() : Condition(), thread(0), cancel_th(false),
running(false) {}
/**
* Thread destructor
* Waits for the thread to terminate before deleting it.
*/
Thread::~Thread() throw (ThreadException) {
lock();
if(thread) {
// try to cancel thread execution if still running
cancel_th = true;
if(running)
waitForSignal();
// wait for thread to terminate
#ifdef _WIN32_
::WaitForSingleObject(*thread, INFINITE);
#else
::pthread_join(*thread, 0);
#endif
// delete thread
delete thread;
}
unlock();
}
/**
* Launch the thread
*/
void *Thread::launch(void* th) throw (ThreadException) {
// Retrieve the thread to launch
Thread *thread = (Thread*) th;
// signal waiting threads that it is going to be run
thread->lock();
thread->running = true;
thread->sendSignal();
thread->unlock();
// run
thread->run();
// signal waiting threads that it is terminated
thread->lock();
thread->running = false;
thread->sendBroadcastSignal();
thread->unlock();
return 0;
}
/**
* Sets a cancellation point.
*/
void Thread::setCancelPoint() throw (ThreadException) {
lock();
// exit thread if cancellation has been requested
if(cancel_th) {
running = false;
sendBroadcastSignal();
unlock();
#ifdef _WIN32_
::ExitThread(0);
#else
::pthread_exit(0);
#endif
}
unlock();
}
/**
* Cancels the thread execution.
*/
void Thread::cancel() {
cancel_th = true;
}
/**
* Tests if the thread is currently running.
*/
bool Thread::isRunning() {
return running;
}
/**
* Make the current thread stop execution
* for the given time.
*/
void Thread::sleep(float time) throw (ThreadException) {
if(time < 0)
throw ThreadException(ThreadExcp, "Invalid sleep time.", "Thread::sleep");
// sleep
#ifdef _WIN32_
::Sleep((unsigned int) (1000*time));
#else
if(::usleep((unsigned int) (1000000*time)) != 0)
throw ThreadException(ThreadExcp, "Cannot sleep", "Thread::sleep");
#endif
}
/**
* Starts the thread execution.
*/
void Thread::start() throw (ThreadException) {
lock();
// Allocates pthread
thread = new pthread_t;
if(thread == 0)
throw ThreadException(ThreadExcp, "Cannot allocate the thread.",
"Thread::start");
#ifdef _WIN32_
if((*thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) launch,
this, 0 ,0)) == 0)
throw ThreadException(ThreadExcp, "Cannot create the thread.",
"Thread::start");
#else
if(::pthread_create(thread, 0, launch, this) != 0)
throw ThreadException(ThreadExcp, "Cannot create the thread.",
"Thread::start");
#endif
// wait for thread to start
if(! running)
waitForSignal();
unlock();
}
/**
* Wait for the condition, with locks
* if given parameter is true.
*/
void Thread::wait(bool toLock) throw (ThreadException) {
if(toLock)
lock();
if(running)
waitForSignal();
if(toLock)
unlock();
}
--- NEW FILE: Semaphore.cpp ---
/*
* This file is part of webInterface.
* Copyright (C) 2003 Mikael Barbeaux <mik...@us...>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Semaphore.h"
/**
* Posts a signal.
*/
void Semaphore::post() throw (ThreadException) {
lock();
++number;
if(number <= 0)
sendSignal();
unlock();
}
/**
* Tries to enter the semaphore without any wait.
*/
bool Semaphore::tryWait() throw (ThreadException) {
lock();
if(number <= 0) {
unlock();
return false;
}
--number;
if(number < 0)
waitForSignal();
unlock();
return true;
}
/**
* Wait for the semaphore to let the thread enter.
*/
void Semaphore::wait() throw (ThreadException) {
lock();
--number;
if(number < 0)
waitForSignal();
unlock();
}
--- NEW FILE: Thread.h ---
/*
* This file is part of webInterface.
* Copyright (C) 2003 Mikael Barbeaux <mik...@us...>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _THREAD_H_
#define _THREAD_H_
#include "Condition.h"
#ifdef _WIN32_
#include <windows.h>
/**
* As pthread doesn't exist for Windows,
* create the object type.
*/
typedef HANDLE pthread_t;
#else
#include <pthread.h>
#include <unistd.h>
#include <sys/errno.h>
#endif
/**
* Defines a Thread object.
* A thread is used to run a part of code into a
* system condition-thread. Implements the run()
* method to define what your thread must do.
*/
class Thread : public Condition {
private:
/**
* Launch the thread
*/
static void *launch(void* th) throw (ThreadException);
protected:
// the thread
pthread_t *thread;
// cancel ?
bool cancel_th;
// running ?
bool running;
/**
* Defines what the thread will do.
*/
virtual void run() = 0;
/**
* Sets a cancellation point.
*/
void setCancelPoint() throw (ThreadException);
public:
/**
* Creates a thread object.
*/
Thread();
/**
* Thread destructor.
*/
virtual ~Thread() throw (ThreadException);
/**
* Cancels the thread execution.
*/
void cancel();
/**
* Tests if the thread is currently running.
*
* @return bool
*/
bool isRunning();
/**
* Make the current thread stop execution
* for the given time.
*
* @param time
*/
static void sleep(float time) throw (ThreadException);
/**
* Starts the thread execution.
*/
void start() throw (ThreadException);
/**
* Wait for the condition, with locks
* if given parameter is true.
*
* @param bool
*/
void wait(bool toLock = true) throw (ThreadException);
};
#endif
--- NEW FILE: Semaphore.h ---
/*
* This file is part of webInterface.
* Copyright (C) 2003 Mikael Barbeaux <mik...@us...>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _SEMAPHORE_H_
#define _SEMAPHORE_H_
#include "Condition.h"
#include "../exceptions/ThreadException.h"
/**
* Defines a Semaphore object.
* A semaphore is a condition with a maximum
* number of executing thread. If this number
* is reached, every threads that will try
* to enter the semaphore will be waiting for
* another thread to leave the semaphore.
*/
class Semaphore : public Condition {
protected:
// Max number of executing threads.
int number;
public:
/**
* Creates a semaphore with the given maximum
* number of executings threads.
*
* @param nb
*/
Semaphore(unsigned int nb) throw (ThreadException) :
number(nb) {}
/**
* Semaphore destructor
*/
~Semaphore() {}
/**
* Returns the max number of executings threads.
*
* @return unsigned int
*/
unsigned int getNumber() { return number; }
/**
* Posts a signal.
*/
void post() throw (ThreadException);
/**
* Sets the maximum number of executing threads.
*/
void setNumber(unsigned int nb) { number = nb; }
/**
* Tries to enter the semaphore without any wait.
*
* @return bool
*/
bool tryWait() throw (ThreadException);
/**
* Wait for the semaphore to let the thread enter.
*/
void wait() throw (ThreadException);
};
#endif
Index: Mutex.cpp
===================================================================
RCS file: /cvsroot/sharedaemon/sharedaemon-ui-web/src/thread/Mutex.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- Mutex.cpp 24 Dec 2003 11:52:49 -0000 1.1
+++ Mutex.cpp 24 Dec 2003 13:03:54 -0000 1.2
@@ -28,16 +28,16 @@
// Allocate mutex
mutex = new pthread_mutex_t;
if(mutex == 0)
- throw ThreadException(MutexError, "Cannot allocate the mutex.",
+ throw ThreadException(MutexExcp, "Cannot allocate the mutex.",
"Mutex::Mutex");
// Initialize the mutex
#ifdef _WIN32_
if((*mutex = ::CreateMutex(0,0,0)) == 0)
- throw ThreadException(MutexError, "Cannot create the mutex",
+ throw ThreadException(MutexExcp, "Cannot create the mutex",
"Mutex::Mutex");
#else
if(::pthread_mutex_init(mutex, 0))
- throw ThreadException(MutexError, "Cannot create the mutex",
+ throw ThreadException(MutexExcp, "Cannot create the mutex",
"Mutex::Mutex");
#endif
}
@@ -73,11 +73,11 @@
#ifdef _WIN32_
// waits indefinitively for the mutex...
if(::WaitForSingleObject(*mutex, INFINITE) != WAIT_OBJECT_0)
- throw ThreadException(MutexError, "Cannot lock the mutex.",
+ throw ThreadException(MutexExcp, "Cannot lock the mutex.",
"Mutex::lock");
#else
if(::pthread_mutex_lock(mutex) != 0)
- throw ThreadException(MutexError, "Cannot lock the mutex.",
+ throw ThreadException(MutexExcp, "Cannot lock the mutex.",
"Mutex::lock");
#endif
}
@@ -98,7 +98,7 @@
if(ret == WAIT_TIMEOUT)
return false;
else if(ret != WAIT_OBJECT_0)
- throw ThreadException(MutexError, "Cannot tryLock the mutex.",
+ throw ThreadException(MutexExcp, "Cannot tryLock the mutex.",
"Mutex::tryLock");
return true;
#else
@@ -106,7 +106,7 @@
if(ret == EBUSY)
return false;
else if(ret != 0)
- throw ThreadException(MutexError, "Cannot tryLock the mutex",
+ throw ThreadException(MutexExcp, "Cannot tryLock the mutex",
"Mutex::tryLock");
return true;
#endif
@@ -119,11 +119,11 @@
// Unlocking the mutex...
#ifdef _WIN32_
if(::ReleaseMutex(*mutex) == 0)
- throw ThreadException(MutexError, "Cannot unlock the mutex.",
+ throw ThreadException(MutexExcp, "Cannot unlock the mutex.",
"Mutex::unlock");
#else
if(::pthread_mutex_unlock(mutex) != 0)
- throw ThreadException(MutexError, "Cannot unlock the mutex.",
+ throw ThreadException(MutexExcp, "Cannot unlock the mutex.",
"Mutex::unlock");
#endif
}
Index: Condition.cpp
===================================================================
RCS file: /cvsroot/sharedaemon/sharedaemon-ui-web/src/thread/Condition.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- Condition.cpp 24 Dec 2003 11:52:49 -0000 1.1
+++ Condition.cpp 24 Dec 2003 13:03:54 -0000 1.2
@@ -26,7 +26,7 @@
Condition::Condition() throw (ThreadException){
condition = new pthread_cond_t;
if(condition == 0)
- throw ThreadException(ConditionError, "Cannot allocate the condition.",
+ throw ThreadException(ConditionExcp, "Cannot allocate the condition.",
"Condition::Condition");
#ifdef _WIN32_
// Init struct parameters
@@ -40,12 +40,12 @@
can't create condition. */
if((condition->semaphore == 0) ||
(condition->waiters_done == 0))
- throw ThreadException(ConditionError, "Cannot create the condition.",
+ throw ThreadException(ConditionExcp, "Cannot create the condition.",
"Condition::Condition");
#else
// init pthread condition
if(::pthread_cond_init(condition, 0) != 0)
- throw ThreadException(ConditionError, "Cannot create the condition.",
+ throw ThreadException(ConditionExcp, "Cannot create the condition.",
"Condition::Condition");
#endif
}
@@ -92,7 +92,7 @@
INFINITE, false) != WAIT_OBJECT_0) {
// semaphore is invalid
unlock();
- throw ThreadException(ConditionError, "Invalid semaphore.",
+ throw ThreadException(ConditionExcp, "Invalid semaphore.",
"Condition::waitforSignal");
}
// Waiting time is finished, we leave the waiting area
@@ -108,7 +108,7 @@
INFINITE, false) != WAIT_OBJECT_0) {
// the mutex is invalid
unlock();
- throw ThreadException(ConditionError, "Invalid mutex.",
+ throw ThreadException(ConditionExcp, "Invalid mutex.",
"Condition::waitForSignal");
}
}
@@ -117,13 +117,13 @@
else if(::WaitForSingleObject(*mutex_t, INFINITE)
!= WAIT_OBJECT_0) {
unlock();
- throw ThreadException(ConditionError, "Invalid mutex.",
+ throw ThreadException(ConditionExcp, "Invalid mutex.",
"Condition::waitForSignal");
}
#else
if(::pthread_cond_wait(condition, mutex) != 0) {
unlock();
- throw ThreadException(ConditionError, "Invalid condition.",
+ throw ThreadException(ConditionExcp, "Invalid condition.",
"Condition::waitForSignal");
}
#endif
@@ -144,13 +144,13 @@
(::ReleaseSemaphore(condition->semaphore,1,0) == 0)) {
// if the condition is invalid
unlock();
- throw ThreadException(ConditionError, "Invalid condition.",
+ throw ThreadException(ConditionExcp, "Invalid condition.",
"Condition::sendSignal");
}
#else
if(::pthread_cond_signal(condition) != 0) {
unlock();
- throw ThreadException(ConditionError, "Invalid condition",
+ throw ThreadException(ConditionExcp, "Invalid condition",
"Condition::sendSignal");
}
#endif
@@ -171,7 +171,7 @@
condition->nb_waiting, 0)) {
// Can't release the semaphore
unlock();
- throw ThreadException(ConditionError, "Cannot release the semaphore.",
+ throw ThreadException(ConditionExcp, "Cannot release the semaphore.",
"Condition::sendBroadcastSignal");
}
LeaveCriticalSection(&(condition->waiting_lock));
@@ -179,7 +179,7 @@
if(::WaitForSingleObject(condition->waiters_done,
INFINITE) != WAIT_OBJECT_0) {
unlock();
- throw ThreadException(ConditionError, "Invalid event.",
+ throw ThreadException(ConditionExcp, "Invalid event.",
"Condition::sendBroadcastSignal");
}
condition->broadcast = false;
@@ -188,7 +188,7 @@
#else
if(::pthread_cond_broadcast(condition) != 0) {
unlock();
- throw ThreadException(ConditionError, "Invalid condition.",
+ throw ThreadException(ConditionExcp, "Invalid condition.",
"Condition::sendBroadcastSignal");
}
#endif
Index: Condition.h
===================================================================
RCS file: /cvsroot/sharedaemon/sharedaemon-ui-web/src/thread/Condition.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- Condition.h 24 Dec 2003 11:52:49 -0000 1.1
+++ Condition.h 24 Dec 2003 13:03:54 -0000 1.2
@@ -17,8 +17,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef _CONDITION_H
-#define _CONDITION_H
+#ifndef _CONDITION_H_
+#define _CONDITION_H_
#include "Mutex.h"
#include "../exceptions/ThreadException.h"
|