#ifndef JMUTEX_H
#define JMUTEX_H
#if (defined(WIN32) || defined(_WIN32_WCE))
#ifndef _WIN32_WCE
#include <process.h>
#endif // _WIN32_WCE
#include <winsock2.h>
#include <windows.h>
#define JMUTEX_CRITICALSECTION
#else // using pthread
#include <pthread.h>
#endif // WIN32
#define ERR_JMUTEX_ALREADYINIT -1
#define ERR_JMUTEX_NOTINIT -2
#define ERR_JMUTEX_CANTCREATEMUTEX -3
class JMutex
{
public:
JMutex();
~JMutex();
int Init();
int Lock();
int Unlock();
bool IsInitialized() { return initialized; }
private:
#if (defined(WIN32) || defined(_WIN32_WCE))
#ifdef JMUTEX_CRITICALSECTION
CRITICAL_SECTION mutex;
#else // Use standard mutex
HANDLE mutex;
#endif // JMUTEX_CRITICALSECTION
#else // pthread mutex
pthread_mutex_t mutex;
#endif // WIN32
bool initialized;
};
#endif // JMUTEX_H #ifndef JTHREAD_H
#define JTHREAD_H
#include "jmutex.h"
#define ERR_JTHREAD_CANTINITMUTEX -1
#define ERR_JTHREAD_CANTSTARTTHREAD -2
#define ERR_JTHREAD_THREADFUNCNOTSET -3
#define ERR_JTHREAD_NOTRUNNING -4
#define ERR_JTHREAD_ALREADYRUNNING -5
class JThread
{
public:
JThread();
virtual ~JThread();
int Start();
int Kill();
virtual void *Thread() = 0;
bool IsRunning();
void *GetReturnValue();
protected:
void ThreadStarted();
private:
#if (defined(WIN32) || defined(_WIN32_WCE))
#ifdef _WIN32_WCE
DWORD threadid;
static DWORD WINAPI TheThread(void *param);
#else
static UINT __stdcall TheThread(void *param);
UINT threadid;
#endif // _WIN32_WCE
HANDLE threadhandle;
#else // pthread type threads
static void *TheThread(void *param);
pthread_t threadid;
#endif // WIN32
void *retval;
bool running;
JMutex runningmutex;
JMutex continuemutex,continuemutex2;
bool mutexinit;
};
#endif // JTHREAD_H #include "jmutex.h"
JMutex::JMutex()
{
initialized = false;
Init();
}
JMutex::~JMutex()
{
if (initialized)
#ifdef JMUTEX_CRITICALSECTION
DeleteCriticalSection(&mutex);
#else
CloseHandle(mutex);
#endif // JMUTEX_CRITICALSECTION
}
int JMutex::Init()
{
if (initialized)
return ERR_JMUTEX_ALREADYINIT;
#ifdef JMUTEX_CRITICALSECTION
InitializeCriticalSection(&mutex);
#else
mutex = CreateMutex(NULL,FALSE,NULL);
if (mutex == NULL)
return ERR_JMUTEX_CANTCREATEMUTEX;
#endif // JMUTEX_CRITICALSECTION
initialized = true;
return 0;
}
int JMutex::Lock()
{
if (!initialized)
return ERR_JMUTEX_NOTINIT;
#ifdef JMUTEX_CRITICALSECTION
EnterCriticalSection(&mutex);
#else
WaitForSingleObject(mutex,INFINITE);
#endif // JMUTEX_CRITICALSECTION
return 0;
}
int JMutex::Unlock()
{
if (!initialized)
return ERR_JMUTEX_NOTINIT;
#ifdef JMUTEX_CRITICALSECTION
LeaveCriticalSection(&mutex);
#else
ReleaseMutex(mutex);
#endif // JMUTEX_CRITICALSECTION
return 0;
} #include "jthread.h"
#ifndef _WIN32_WCE
#include <process.h>
#endif // _WIN32_WCE
JThread::JThread()
{
retval = NULL;
mutexinit = false;
running = false;
}
JThread::~JThread()
{
Kill();
}
int JThread::Start()
{
if (!mutexinit)
{
if (!runningmutex.IsInitialized())
{
if (runningmutex.Init() < 0)
return ERR_JTHREAD_CANTINITMUTEX;
}
if (!continuemutex.IsInitialized())
{
if (continuemutex.Init() < 0)
return ERR_JTHREAD_CANTINITMUTEX;
}
if (!continuemutex2.IsInitialized())
{
if (continuemutex2.Init() < 0)
return ERR_JTHREAD_CANTINITMUTEX;
} mutexinit = true;
}
runningmutex.Lock();
if (running)
{
runningmutex.Unlock();
return ERR_JTHREAD_ALREADYRUNNING;
}
runningmutex.Unlock();
continuemutex.Lock();
#ifndef _WIN32_WCE
threadhandle = (HANDLE)_beginthreadex(NULL,0,TheThread,this,0,&threadid);
#else
threadhandle = CreateThread(NULL,0,TheThread,this,0,&threadid);
#endif // _WIN32_WCE
if (threadhandle == NULL)
{
continuemutex.Unlock();
return ERR_JTHREAD_CANTSTARTTHREAD;
}
/* Wait until 'running' is set */
runningmutex.Lock();
while (!running)
{
runningmutex.Unlock();
Sleep(1);
runningmutex.Lock();
}
runningmutex.Unlock();
continuemutex.Unlock();
continuemutex2.Lock();
continuemutex2.Unlock();
return 0;
}
int JThread::Kill()
{
runningmutex.Lock();
if (!running)
{
runningmutex.Unlock();
return ERR_JTHREAD_NOTRUNNING;
}
TerminateThread(threadhandle,0);
CloseHandle(threadhandle);
running = false;
runningmutex.Unlock();
return 0;
}
bool JThread::IsRunning()
{
bool r;
runningmutex.Lock();
r = running;
runningmutex.Unlock();
return r;
}
void *JThread::GetReturnValue()
{
void *val;
runningmutex.Lock();
if (running)
val = NULL;
else
val = retval;
runningmutex.Unlock();
return val;
}
#ifndef _WIN32_WCE
UINT __stdcall JThread::TheThread(void *param)
#else
DWORD WINAPI JThread::TheThread(void *param)
#endif // _WIN32_WCE
{
JThread *jthread;
void *ret;
jthread = (JThread *)param;
jthread->continuemutex2.Lock();
jthread->runningmutex.Lock();
jthread->running = true;
jthread->runningmutex.Unlock();
jthread->continuemutex.Lock();
jthread->continuemutex.Unlock();
ret = jthread->Thread();
jthread->runningmutex.Lock();
jthread->running = false;
jthread->retval = ret;
CloseHandle(jthread->threadhandle);
jthread->runningmutex.Unlock();
return 0;
}
void JThread::ThreadStarted()
{
continuemutex2.Unlock();
}
#define JMUTEX_H
#if (defined(WIN32) || defined(_WIN32_WCE))
#ifndef _WIN32_WCE
#include <process.h>
#endif // _WIN32_WCE
#include <winsock2.h>
#include <windows.h>
#define JMUTEX_CRITICALSECTION
#else // using pthread
#include <pthread.h>
#endif // WIN32
#define ERR_JMUTEX_ALREADYINIT -1
#define ERR_JMUTEX_NOTINIT -2
#define ERR_JMUTEX_CANTCREATEMUTEX -3
class JMutex
{
public:
JMutex();
~JMutex();
int Init();
int Lock();
int Unlock();
bool IsInitialized() { return initialized; }
private:
#if (defined(WIN32) || defined(_WIN32_WCE))
#ifdef JMUTEX_CRITICALSECTION
CRITICAL_SECTION mutex;
#else // Use standard mutex
HANDLE mutex;
#endif // JMUTEX_CRITICALSECTION
#else // pthread mutex
pthread_mutex_t mutex;
#endif // WIN32
bool initialized;
};
#endif // JMUTEX_H #ifndef JTHREAD_H
#define JTHREAD_H
#include "jmutex.h"
#define ERR_JTHREAD_CANTINITMUTEX -1
#define ERR_JTHREAD_CANTSTARTTHREAD -2
#define ERR_JTHREAD_THREADFUNCNOTSET -3
#define ERR_JTHREAD_NOTRUNNING -4
#define ERR_JTHREAD_ALREADYRUNNING -5
class JThread
{
public:
JThread();
virtual ~JThread();
int Start();
int Kill();
virtual void *Thread() = 0;
bool IsRunning();
void *GetReturnValue();
protected:
void ThreadStarted();
private:
#if (defined(WIN32) || defined(_WIN32_WCE))
#ifdef _WIN32_WCE
DWORD threadid;
static DWORD WINAPI TheThread(void *param);
#else
static UINT __stdcall TheThread(void *param);
UINT threadid;
#endif // _WIN32_WCE
HANDLE threadhandle;
#else // pthread type threads
static void *TheThread(void *param);
pthread_t threadid;
#endif // WIN32
void *retval;
bool running;
JMutex runningmutex;
JMutex continuemutex,continuemutex2;
bool mutexinit;
};
#endif // JTHREAD_H #include "jmutex.h"
JMutex::JMutex()
{
initialized = false;
Init();
}
JMutex::~JMutex()
{
if (initialized)
#ifdef JMUTEX_CRITICALSECTION
DeleteCriticalSection(&mutex);
#else
CloseHandle(mutex);
#endif // JMUTEX_CRITICALSECTION
}
int JMutex::Init()
{
if (initialized)
return ERR_JMUTEX_ALREADYINIT;
#ifdef JMUTEX_CRITICALSECTION
InitializeCriticalSection(&mutex);
#else
mutex = CreateMutex(NULL,FALSE,NULL);
if (mutex == NULL)
return ERR_JMUTEX_CANTCREATEMUTEX;
#endif // JMUTEX_CRITICALSECTION
initialized = true;
return 0;
}
int JMutex::Lock()
{
if (!initialized)
return ERR_JMUTEX_NOTINIT;
#ifdef JMUTEX_CRITICALSECTION
EnterCriticalSection(&mutex);
#else
WaitForSingleObject(mutex,INFINITE);
#endif // JMUTEX_CRITICALSECTION
return 0;
}
int JMutex::Unlock()
{
if (!initialized)
return ERR_JMUTEX_NOTINIT;
#ifdef JMUTEX_CRITICALSECTION
LeaveCriticalSection(&mutex);
#else
ReleaseMutex(mutex);
#endif // JMUTEX_CRITICALSECTION
return 0;
} #include "jthread.h"
#ifndef _WIN32_WCE
#include <process.h>
#endif // _WIN32_WCE
JThread::JThread()
{
retval = NULL;
mutexinit = false;
running = false;
}
JThread::~JThread()
{
Kill();
}
int JThread::Start()
{
if (!mutexinit)
{
if (!runningmutex.IsInitialized())
{
if (runningmutex.Init() < 0)
return ERR_JTHREAD_CANTINITMUTEX;
}
if (!continuemutex.IsInitialized())
{
if (continuemutex.Init() < 0)
return ERR_JTHREAD_CANTINITMUTEX;
}
if (!continuemutex2.IsInitialized())
{
if (continuemutex2.Init() < 0)
return ERR_JTHREAD_CANTINITMUTEX;
} mutexinit = true;
}
runningmutex.Lock();
if (running)
{
runningmutex.Unlock();
return ERR_JTHREAD_ALREADYRUNNING;
}
runningmutex.Unlock();
continuemutex.Lock();
#ifndef _WIN32_WCE
threadhandle = (HANDLE)_beginthreadex(NULL,0,TheThread,this,0,&threadid);
#else
threadhandle = CreateThread(NULL,0,TheThread,this,0,&threadid);
#endif // _WIN32_WCE
if (threadhandle == NULL)
{
continuemutex.Unlock();
return ERR_JTHREAD_CANTSTARTTHREAD;
}
/* Wait until 'running' is set */
runningmutex.Lock();
while (!running)
{
runningmutex.Unlock();
Sleep(1);
runningmutex.Lock();
}
runningmutex.Unlock();
continuemutex.Unlock();
continuemutex2.Lock();
continuemutex2.Unlock();
return 0;
}
int JThread::Kill()
{
runningmutex.Lock();
if (!running)
{
runningmutex.Unlock();
return ERR_JTHREAD_NOTRUNNING;
}
TerminateThread(threadhandle,0);
CloseHandle(threadhandle);
running = false;
runningmutex.Unlock();
return 0;
}
bool JThread::IsRunning()
{
bool r;
runningmutex.Lock();
r = running;
runningmutex.Unlock();
return r;
}
void *JThread::GetReturnValue()
{
void *val;
runningmutex.Lock();
if (running)
val = NULL;
else
val = retval;
runningmutex.Unlock();
return val;
}
#ifndef _WIN32_WCE
UINT __stdcall JThread::TheThread(void *param)
#else
DWORD WINAPI JThread::TheThread(void *param)
#endif // _WIN32_WCE
{
JThread *jthread;
void *ret;
jthread = (JThread *)param;
jthread->continuemutex2.Lock();
jthread->runningmutex.Lock();
jthread->running = true;
jthread->runningmutex.Unlock();
jthread->continuemutex.Lock();
jthread->continuemutex.Unlock();
ret = jthread->Thread();
jthread->runningmutex.Lock();
jthread->running = false;
jthread->retval = ret;
CloseHandle(jthread->threadhandle);
jthread->runningmutex.Unlock();
return 0;
}
void JThread::ThreadStarted()
{
continuemutex2.Unlock();
}
使用这个宏的话,应该就表示使用临界区来实现JMutex
不打开这个宏的话,就表示使用 Mutex来实现咯。