aboutsummaryrefslogtreecommitdiff
path: root/externals/g3dlite/G3D.lib/source/GThread.cpp
diff options
context:
space:
mode:
authorRat <none@none>2010-06-07 00:09:54 +0200
committerRat <none@none>2010-06-07 00:09:54 +0200
commitb86a4f58f1eafd88144b0773c89bc4d1b5e74507 (patch)
tree8cade56509296fd5fb62b784e5065078f8476600 /externals/g3dlite/G3D.lib/source/GThread.cpp
parent910980d3c65273e1dba78ec3928d5b4e78d713bd (diff)
added newest G3D(lite) + VS project files
stripped, but can be stripped more later --HG-- branch : trunk
Diffstat (limited to 'externals/g3dlite/G3D.lib/source/GThread.cpp')
-rw-r--r--externals/g3dlite/G3D.lib/source/GThread.cpp203
1 files changed, 203 insertions, 0 deletions
diff --git a/externals/g3dlite/G3D.lib/source/GThread.cpp b/externals/g3dlite/G3D.lib/source/GThread.cpp
new file mode 100644
index 00000000000..090370436c4
--- /dev/null
+++ b/externals/g3dlite/G3D.lib/source/GThread.cpp
@@ -0,0 +1,203 @@
+/**
+ @file GThread.cpp
+
+ GThread class.
+
+ @created 2005-09-24
+ @edited 2005-10-22
+ */
+
+#include "G3D/GThread.h"
+#include "G3D/System.h"
+#include "G3D/debugAssert.h"
+
+
+namespace G3D {
+
+namespace _internal {
+
+class BasicThread: public GThread {
+public:
+ BasicThread(const std::string& name, void (*proc)(void*), void* param):
+ GThread(name), m_wrapperProc(proc), m_param(param) { }
+protected:
+ virtual void threadMain() {
+ m_wrapperProc(m_param);
+ }
+
+private:
+ void (*m_wrapperProc)(void*);
+
+ void* m_param;
+};
+
+} // namespace _internal
+
+
+GThread::GThread(const std::string& name):
+ m_status(STATUS_CREATED),
+ m_name(name) {
+
+#ifdef G3D_WIN32
+ m_event = NULL;
+#endif
+
+ // system-independent clear of handle
+ System::memset(&m_handle, 0, sizeof(m_handle));
+}
+
+GThread::~GThread() {
+#ifdef _MSC_VER
+# pragma warning( push )
+# pragma warning( disable : 4127 )
+#endif
+ alwaysAssertM(m_status != STATUS_RUNNING, "Deleting thread while running.");
+#ifdef _MSC_VER
+# pragma warning( pop )
+#endif
+
+#ifdef G3D_WIN32
+ if (m_event) {
+ ::CloseHandle(m_event);
+ }
+#endif
+}
+
+GThreadRef GThread::create(const std::string& name, void (*proc)(void*), void* param) {
+ return new _internal::BasicThread(name, proc, param);
+}
+
+
+bool GThread::started() const {
+ return m_status != STATUS_CREATED;
+}
+
+bool GThread::start() {
+
+ debugAssertM(! started(), "Thread has already executed.");
+ if (started()) {
+ return false;
+ }
+
+ m_status = STATUS_STARTED;
+
+# ifdef G3D_WIN32
+ DWORD threadId;
+
+ m_event = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+ debugAssert(m_event);
+
+ m_handle = ::CreateThread(NULL, 0, &internalThreadProc, this, 0, &threadId);
+
+ if (m_handle == NULL) {
+ ::CloseHandle(m_event);
+ m_event = NULL;
+ }
+
+ return (m_handle != NULL);
+# else
+ if (!pthread_create(&m_handle, NULL, &internalThreadProc, this)) {
+ return true;
+ } else {
+ // system-independent clear of handle
+ System::memset(&m_handle, 0, sizeof(m_handle));
+
+ return false;
+ }
+# endif
+}
+
+void GThread::terminate() {
+ if (m_handle) {
+# ifdef G3D_WIN32
+ ::TerminateThread(m_handle, 0);
+# else
+ pthread_kill(m_handle, SIGSTOP);
+# endif
+ // system-independent clear of handle
+ System::memset(&m_handle, 0, sizeof(m_handle));
+ }
+}
+
+bool GThread::running() const{
+ return (m_status == STATUS_RUNNING);
+}
+
+bool GThread::completed() const {
+ return (m_status == STATUS_COMPLETED);
+}
+
+void GThread::waitForCompletion() {
+# ifdef G3D_WIN32
+ debugAssert(m_event);
+ ::WaitForSingleObject(m_event, INFINITE);
+# else
+ debugAssert(m_handle);
+ pthread_join(m_handle, NULL);
+# endif
+}
+
+#ifdef G3D_WIN32
+DWORD WINAPI GThread::internalThreadProc(LPVOID param) {
+ GThread* current = reinterpret_cast<GThread*>(param);
+ debugAssert(current->m_event);
+ current->m_status = STATUS_RUNNING;
+ current->threadMain();
+ current->m_status = STATUS_COMPLETED;
+ ::SetEvent(current->m_event);
+ return 0;
+}
+#else
+void* GThread::internalThreadProc(void* param) {
+ GThread* current = reinterpret_cast<GThread*>(param);
+ current->m_status = STATUS_RUNNING;
+ current->threadMain();
+ current->m_status = STATUS_COMPLETED;
+ return (void*)NULL;
+}
+#endif
+
+
+
+GMutex::GMutex() {
+# ifdef G3D_WIN32
+ ::InitializeCriticalSection(&m_handle);
+# else
+ pthread_mutex_init(&m_handle, NULL);
+# endif
+}
+
+GMutex::~GMutex() {
+ //TODO: Debug check for locked
+# ifdef G3D_WIN32
+ ::DeleteCriticalSection(&m_handle);
+# else
+ pthread_mutex_destroy(&m_handle);
+# endif
+}
+
+//bool GMutex::tryLock() {
+//# ifdef G3D_WIN32
+// return ::TryEnterCriticalSection(&m_handle);
+//# else
+// return pthread_mutex_trylock(&m_handle);
+//# endif
+//}
+
+void GMutex::lock() {
+# ifdef G3D_WIN32
+ ::EnterCriticalSection(&m_handle);
+# else
+ pthread_mutex_lock(&m_handle);
+# endif
+}
+
+void GMutex::unlock() {
+# ifdef G3D_WIN32
+ ::LeaveCriticalSection(&m_handle);
+# else
+ pthread_mutex_unlock(&m_handle);
+# endif
+}
+
+} // namespace G3D