root/trunk/src/shared/Mthread.cpp @ 248

Revision 44, 4.7 kB (checked in by yumileroy, 17 years ago)

[svn] * Merge Temp dev SVN with Assembla.
* Changes include:

  • Implementation of w12x's Outdoor PvP and Game Event Systems.
  • Temporary removal of IRC Chat Bot (until infinite loop when disabled is fixed).
  • All mangos -> trinity (to convert your mangos_string table, please run mangos_string_to_trinity_string.sql).
  • Improved Config cleanup.
  • And many more changes.

Original author: Seline
Date: 2008-10-14 11:57:03-05:00

Line 
1/*
2    Cross-platform thread handling
3    Copyright (C) 2005 Andrew Zabolotny
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Library General Public
7    License as published by the Free Software Foundation; either
8    version 2 of the License, or (at your option) any later version.
9
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Library General Public License for more details.
14
15    You should have received a copy of the GNU Library General Public
16    License along with this library; if not, write to the Free
17    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20#include "Mthread.h"
21
22#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE_CC__)
23#  define TRINITY_PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE
24#else
25#  define TRINITY_PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
26#endif
27
28#if PLATFORM != PLATFORM_WINDOWS
29
30MThread::MThread ()
31{
32    tid = 0;
33}
34
35MThread::~MThread ()
36{
37    /* Kill thread if this is not the current thread */
38    if (tid && (pthread_self () != tid))
39    {
40        pthread_cancel (tid);
41        pthread_join (tid, NULL);
42    }
43}
44
45static void *thread_start_routine (void *arg)
46{
47    MThread *newthr = (MThread *)arg;
48    pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
49    newthr->routine (newthr->arg);
50    return NULL;
51}
52
53MThread *MThread::Start (void (*routine) (void *arg), void *arg)
54{
55    MThread *newthr = new MThread ();
56    newthr->routine = routine;
57    newthr->arg = arg;
58    int rc = pthread_create (&newthr->tid, NULL, thread_start_routine, newthr);
59    if (rc)
60    {
61        newthr->DecRef ();
62        return NULL;
63    }
64
65    return newthr;
66}
67
68pthread_mutexattr_t MMutex::attr;
69int MMutex::attr_refcount = 0;
70
71MMutex::MMutex ()
72{
73    if (!attr_refcount++)
74    {
75        pthread_mutexattr_init (&attr);
76        pthread_mutexattr_settype (&attr, TRINITY_PTHREAD_MUTEX_RECURSIVE);
77    }
78
79    pthread_mutex_init (&mutex, &attr);
80}
81
82MMutex::~MMutex ()
83{
84    pthread_mutex_destroy (&mutex);
85    if (!--attr_refcount)
86        pthread_mutexattr_destroy (&attr);
87}
88
89bool MMutex::Lock ()
90{
91    return (pthread_mutex_lock (&mutex) == 0);
92}
93
94bool MMutex::TryLock ()
95{
96    return (pthread_mutex_trylock (&mutex) == 0);
97}
98
99void MMutex::Unlock ()
100{
101    pthread_mutex_unlock (&mutex);
102}
103
104MMutex *MMutex::Create ()
105{
106    return new MMutex ();
107}
108
109#else                                                       //windows
110
111MThread::MThread()
112{
113    th = NULL;
114}
115
116MThread::~MThread ()
117{
118    /* Kill thread if this is not current thread */
119    if (th && (GetCurrentThreadId () != id))
120    {
121        TerminateThread (th, 0);
122        WaitForSingleObject (th, INFINITE);
123        CloseHandle (th);
124    }
125}
126
127bool MThread::SetPriority (ThreadPriority prio)
128{
129    int p;
130    switch (prio)
131    {
132        case IDLE:      p = THREAD_PRIORITY_IDLE; break;
133        case LOWER:     p = THREAD_PRIORITY_LOWEST; break;
134        case LOW:       p = THREAD_PRIORITY_BELOW_NORMAL; break;
135        case NORMAL:    p = THREAD_PRIORITY_NORMAL; break;
136        case HIGH:      p = THREAD_PRIORITY_ABOVE_NORMAL; break;
137        case HIGHER:    p = THREAD_PRIORITY_HIGHEST; break;
138        case REALTIME:  p = THREAD_PRIORITY_TIME_CRITICAL; break;
139        default:        p = THREAD_PRIORITY_NORMAL; break;
140    }
141    return SetThreadPriority (th, p);
142}
143
144static DWORD WINAPI thread_start_routine (void *arg)
145//static void thread_start_routine (void *arg)
146{
147    MThread *newthr = (MThread *)arg;
148    newthr->id = GetCurrentThreadId ();
149    newthr->routine (newthr->arg);
150    return 0;
151}
152
153MThread *MThread::Start (void (*routine) (void *arg), void *arg)
154{
155    DWORD dwtid;
156    MThread *newthr = new MThread ();
157    newthr->routine = routine;
158    newthr->arg = arg;
159    newthr->th = CreateThread (NULL, WIN32_THREAD_STACK_SIZE, thread_start_routine, newthr, 0, &dwtid);
160    //newthr->th = (HANDLE)_beginthread(thread_start_routine, 0, newthr);
161    if (!newthr->th)
162    {
163        newthr->DecRef ();
164        return NULL;
165    }
166    return newthr;
167}
168
169MMutex::MMutex ()
170{
171    sem = CreateMutex (NULL, FALSE, NULL);
172}
173
174MMutex::~MMutex ()
175{
176    CloseHandle (sem);
177}
178
179bool MMutex::Lock ()
180{
181    return (WaitForSingleObject (sem, INFINITE) != WAIT_FAILED);
182}
183
184bool MMutex::TryLock ()
185{
186    DWORD state = WaitForSingleObject (sem, 0);
187    return (state == WAIT_OBJECT_0) && (state != WAIT_ABANDONED);
188}
189
190void MMutex::Unlock ()
191{
192    ReleaseMutex (sem);
193}
194
195MMutex *MMutex::Create ()
196{
197    MMutex *mutex = new MMutex ();
198    if (!mutex->sem)
199    {
200        mutex->DecRef ();
201        return NULL;
202    }
203    return mutex;
204}
205#endif
Note: See TracBrowser for help on using the browser.