aboutsummaryrefslogtreecommitdiff
path: root/src/shared/Mthread.cpp
diff options
context:
space:
mode:
authorNeo2003 <none@none>2008-10-02 16:23:55 -0500
committerNeo2003 <none@none>2008-10-02 16:23:55 -0500
commit9b1c0e006f20091f28f3f468cfcab1feb51286bd (patch)
treeb5d1ba94a656e6679f8737f9ea6bed1239b73b14 /src/shared/Mthread.cpp
[svn] * Proper SVN structureinit
--HG-- branch : trunk
Diffstat (limited to 'src/shared/Mthread.cpp')
-rw-r--r--src/shared/Mthread.cpp205
1 files changed, 205 insertions, 0 deletions
diff --git a/src/shared/Mthread.cpp b/src/shared/Mthread.cpp
new file mode 100644
index 00000000000..0dfaac4fcf7
--- /dev/null
+++ b/src/shared/Mthread.cpp
@@ -0,0 +1,205 @@
+/*
+ Cross-platform thread handling
+ Copyright (C) 2005 Andrew Zabolotny
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "Mthread.h"
+
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE_CC__)
+# define MANGOS_PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE
+#else
+# define MANGOS_PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
+#endif
+
+#if PLATFORM != PLATFORM_WINDOWS
+
+MThread::MThread ()
+{
+ tid = 0;
+}
+
+MThread::~MThread ()
+{
+ /* Kill thread if this is not the current thread */
+ if (tid && (pthread_self () != tid))
+ {
+ pthread_cancel (tid);
+ pthread_join (tid, NULL);
+ }
+}
+
+static void *thread_start_routine (void *arg)
+{
+ MThread *newthr = (MThread *)arg;
+ pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+ newthr->routine (newthr->arg);
+ return NULL;
+}
+
+MThread *MThread::Start (void (*routine) (void *arg), void *arg)
+{
+ MThread *newthr = new MThread ();
+ newthr->routine = routine;
+ newthr->arg = arg;
+ int rc = pthread_create (&newthr->tid, NULL, thread_start_routine, newthr);
+ if (rc)
+ {
+ newthr->DecRef ();
+ return NULL;
+ }
+
+ return newthr;
+}
+
+pthread_mutexattr_t MMutex::attr;
+int MMutex::attr_refcount = 0;
+
+MMutex::MMutex ()
+{
+ if (!attr_refcount++)
+ {
+ pthread_mutexattr_init (&attr);
+ pthread_mutexattr_settype (&attr, MANGOS_PTHREAD_MUTEX_RECURSIVE);
+ }
+
+ pthread_mutex_init (&mutex, &attr);
+}
+
+MMutex::~MMutex ()
+{
+ pthread_mutex_destroy (&mutex);
+ if (!--attr_refcount)
+ pthread_mutexattr_destroy (&attr);
+}
+
+bool MMutex::Lock ()
+{
+ return (pthread_mutex_lock (&mutex) == 0);
+}
+
+bool MMutex::TryLock ()
+{
+ return (pthread_mutex_trylock (&mutex) == 0);
+}
+
+void MMutex::Unlock ()
+{
+ pthread_mutex_unlock (&mutex);
+}
+
+MMutex *MMutex::Create ()
+{
+ return new MMutex ();
+}
+
+#else //windows
+
+MThread::MThread()
+{
+ th = NULL;
+}
+
+MThread::~MThread ()
+{
+ /* Kill thread if this is not current thread */
+ if (th && (GetCurrentThreadId () != id))
+ {
+ TerminateThread (th, 0);
+ WaitForSingleObject (th, INFINITE);
+ CloseHandle (th);
+ }
+}
+
+bool MThread::SetPriority (ThreadPriority prio)
+{
+ int p;
+ switch (prio)
+ {
+ case IDLE: p = THREAD_PRIORITY_IDLE; break;
+ case LOWER: p = THREAD_PRIORITY_LOWEST; break;
+ case LOW: p = THREAD_PRIORITY_BELOW_NORMAL; break;
+ case NORMAL: p = THREAD_PRIORITY_NORMAL; break;
+ case HIGH: p = THREAD_PRIORITY_ABOVE_NORMAL; break;
+ case HIGHER: p = THREAD_PRIORITY_HIGHEST; break;
+ case REALTIME: p = THREAD_PRIORITY_TIME_CRITICAL; break;
+ default: p = THREAD_PRIORITY_NORMAL; break;
+ }
+ return SetThreadPriority (th, p);
+}
+
+static DWORD WINAPI thread_start_routine (void *arg)
+//static void thread_start_routine (void *arg)
+{
+ MThread *newthr = (MThread *)arg;
+ newthr->id = GetCurrentThreadId ();
+ newthr->routine (newthr->arg);
+ return 0;
+}
+
+MThread *MThread::Start (void (*routine) (void *arg), void *arg)
+{
+ DWORD dwtid;
+ MThread *newthr = new MThread ();
+ newthr->routine = routine;
+ newthr->arg = arg;
+ newthr->th = CreateThread (NULL, WIN32_THREAD_STACK_SIZE, thread_start_routine, newthr, 0, &dwtid);
+ //newthr->th = (HANDLE)_beginthread(thread_start_routine, 0, newthr);
+ if (!newthr->th)
+ {
+ newthr->DecRef ();
+ return NULL;
+ }
+ return newthr;
+}
+
+MMutex::MMutex ()
+{
+ sem = CreateMutex (NULL, FALSE, NULL);
+}
+
+MMutex::~MMutex ()
+{
+ CloseHandle (sem);
+}
+
+bool MMutex::Lock ()
+{
+ return (WaitForSingleObject (sem, INFINITE) != WAIT_FAILED);
+}
+
+bool MMutex::TryLock ()
+{
+ DWORD state = WaitForSingleObject (sem, 0);
+ return (state == WAIT_OBJECT_0) && (state != WAIT_ABANDONED);
+}
+
+void MMutex::Unlock ()
+{
+ ReleaseMutex (sem);
+}
+
+MMutex *MMutex::Create ()
+{
+ MMutex *mutex = new MMutex ();
+ if (!mutex->sem)
+ {
+ mutex->DecRef ();
+ return NULL;
+ }
+ return mutex;
+}
+#endif