From 83fc39219825532fbbbaa6a6af2942e82f350845 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Wed, 1 Feb 2012 12:25:26 +0000 Subject: new cIsThread object for thread encapsulation git-svn-id: http://mc-server.googlecode.com/svn/trunk@214 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/cIsThread.cpp | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 source/cIsThread.cpp (limited to 'source/cIsThread.cpp') diff --git a/source/cIsThread.cpp b/source/cIsThread.cpp new file mode 100644 index 000000000..cee4d4477 --- /dev/null +++ b/source/cIsThread.cpp @@ -0,0 +1,148 @@ + +// cIsThread.cpp + +// Implements the cIsThread class representing an OS-independent wrapper for a class that implements a thread. +// This class will eventually suupersede the old cThread class + +#include "Globals.h" + +#include "cIsThread.h" + + + + + +// When in MSVC, the debugger provides "thread naming" by catching special exceptions. Interface here: +#ifdef _MSC_VER +// +// Usage: SetThreadName (-1, "MainThread"); +// + +static void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName) +{ + struct + { + DWORD dwType; // must be 0x1000 + LPCSTR szName; // pointer to name (in user addr space) + DWORD dwThreadID; // thread ID (-1=caller thread) + DWORD dwFlags; // reserved for future use, must be zero + } info; + + info.dwType = 0x1000; + info.szName = szThreadName; + info.dwThreadID = dwThreadID; + info.dwFlags = 0; + + __try + { + RaiseException(0x406D1388, 0, sizeof(info) / sizeof(DWORD), (DWORD *)&info); + } + __except(EXCEPTION_CONTINUE_EXECUTION) + { + } +} +#endif // _MSC_VER + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cIsThread: + +cIsThread::cIsThread(const AString & iThreadName) : + mThreadName(iThreadName), + mShouldTerminate(false), + #ifdef _WIN32 + mHandle(NULL) + #else // _WIN32 + mHasStarted(false) + #endif // else _WIN32 +{ +} + + + + + +cIsThread::~cIsThread() +{ + Wait(); +} + + + + + +bool cIsThread::Start(void) +{ + #ifdef _WIN32 + assert(mHandle == NULL); // Has already started one thread? + + // Create the thread suspended, so that the mHandle variable is valid in the thread procedure + DWORD ThreadID = 0; + HANDLE mHandle = CreateThread(NULL, 0, thrExecute, this, CREATE_SUSPENDED, &ThreadID); + if (mHandle == NULL) + { + LOGERROR("ERROR: Could not create thread \"%s\", GLE = %d!", mThreadName.c_str(), GetLastError()); + return false; + } + ResumeThread(mHandle); + + #if defined(_DEBUG) && defined(_MSC_VER) + // Thread naming is available only in MSVC + if (!mThreadName.empty()) + { + SetThreadName(ThreadID, mThreadName.c_str()); + } + #endif // _DEBUG and _MSC_VER + + #else // _WIN32 + assert(!mHasStarted); + + if (pthread_create(&mHandle, NULL, thrExecute, this)) + { + LOGERROR("ERROR: Could not create thread \"%s\", !", mThreadName.c_str()); + return false; + } + #endif // else _WIN32 + + return true; +} + + + + + +bool cIsThread::Wait(void) +{ + #ifdef _WIN32 + + if (mHandle == NULL) + { + return true; + } + LOG("Waiting for thread \"%s\" to terminate.", mThreadName.c_str()); + int res = WaitForSingleObject(mHandle, INFINITE); + mHandle = NULL; + LOG("Thread \"%s\" %s terminated, GLE = %d", mThreadName.c_str(), (res == WAIT_OBJECT_0) ? "" : "not", GetLastError()); + return (res == WAIT_OBJECT_0); + + #else // _WIN32 + + if (!mHasStarted) + { + return true; + } + LOG("Waiting for thread \"%s\" to terminate.", mThreadName.c_str()); + int res = pthread_join(mHandle, NULL); + mHasStarted = false; + LOG("Thread \"%s\" %s terminated, errno = %d", mThreadName.c_str(), (res == 0) ? "" : "not", errno); + return (res == 0); + + #endif // else _WIN32 +} + + + + -- cgit v1.2.3