Listing 1: Defines thread and mutex classes
///////////////////////////////////////////////////////////////////
// Copyright (c) Panos Kougiouris, Marco Framba 1997
///////////////////////////////////////////////////////////////////
#ifndef __KFTHREAD_HH_
#define __KFTHREAD_HH_
#include <kfBase.h>
#include <kfReferenceCount.h>
class CKFMTRunnableImplementation;
class CKFMTThreadImplementation;
class CKFMTMutexImplementation;
class CKFMTRWMutexImplementation;
class CKFMTConditionImplementation;
class ostream;
class CKFEXPORT CKFMT {
public:
enum {Infinity = 0};
enum RetValue {Timeout, Ok, Error, AlreadyLocked};
// This is the main object. Users should subclass it.
// It can be used with both threads and the scheduler
class CKFEXPORT CRunnable : public CKFReferenceCount {
public:
CRunnable(const char* a_name = "Unnamed");
virtual void run() = 0;
const char* get_name();
RetValue wait_for_completion(unsigned msecs = Infinity);
protected:
friend class CKFMTThreadImplementation;
CKFMTRunnableImplementation *m_impl;
// Reference counted objects are not deleted their
// reference count is decremented
virtual ~CRunnable();
};
//-------------------------------------------------------------
// A thread class. Threads are created to run runnable objects.
// Threads should always be created on the heap because when
// they exit the runtime deletes the object
class CKFEXPORT CThread {
public:
// A stack size of 0 gives a defualt stack size depending
// on the architecture. The thread is constructed in a
// suspended state. The make_runnable() method should be
// called to get the thread into a runnable state. The
// Runnable will be decremenented when the thread is done.
// The thread will delete itself when it is done.
CThread(CRunnable*, int stack_size = 0);
CThread(const CThread&);
CThread& operator= (const CThread&);
~CThread();
void make_runnable();
unsigned long get_thread_id();
// Abnormally terminates a different thread.
// Should be avoided
void exit(int code);
// Related to the current thread
static unsigned long current_id();
static void current_exit(int code); // Recommended exit
protected:
CKFMTThreadImplementation *m_impl;
friend class CKFMTThreadImplementation;
};
//--------------------------------------------------------
class CKFEXPORT CMutex {
public:
CMutex(const char* name = "");
~CMutex();
CMutex(const CMutex&);
CMutex& operator= (const CMutex&);
RetValue lock();
RetValue try_lock();
RetValue unlock();
CKFBool am_owner();
//private:
CKFMTMutexImplementation *m_impl;
friend class CCondition;
private:
};
// Used to help acquire and hold a mutex lock ONLY while inside
// the C++ scope
//
enum GrabAction
{DoGrab, DoNotGrab, GrabOnlyIfCurrentThreadNotOwner};
class CKFEXPORT CMutexGrabber {
public:
CMutexGrabber(CMutex& a_mut, GrabAction act = DoGrab);
~CMutexGrabber() {if (m_do_ungrab) m_mut->unlock();};
private:
CMutex* m_mut;
CKFBool m_do_ungrab;
};
//--------------------------------------------------------
// Read/Write lock
//
class CKFEXPORT CRWMutex {
public:
CRWMutex(const char* name = "");
CRWMutex(const CRWMutex&);
CRWMutex& operator= (const CRWMutex&);
~CRWMutex();
void rdlock();
RetValue try_rdlock();
void wrlock();
RetValue try_wrlock();
void unlock();
private:
CKFMTRWMutexImplementation *m_impl;
};
//
// Used to help acquire and hold a RWmutex lock ONLY while
// inside the C++ scope
//
class CKFEXPORT CRWMutexGrabber {
public:
CRWMutexGrabber
(CRWMutex& a_mut,
CKFBool a_iswrtr = CKFFalse,
GrabAction act = DoGrab
) : m_mut(&a_mut)
{ if (act == DoGrab) {
a_iswrtr ? m_mut->wrlock() : m_mut->rdlock() ;
}
};
~CRWMutexGrabber() {m_mut->unlock();};
private:
CRWMutex *m_mut;
};
//-------------------------------------------------------------
class CKFEXPORT CCondition {
public:
CCondition(const char* name = "");
CCondition(const CCondition&);
CCondition& operator= (const CCondition&);
~CCondition();
RetValue wait(CMutex, unsigned msecs = Infinity);
RetValue signal();
RetValue broadcast();
private:
CKFMTConditionImplementation *m_impl;
};
};
inline ostream& operator<<(ostream& a_str, CKFMT::CRunnable* a_run)
{
return a_str << a_run->get_name();
}
#endif
//End of File