EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Mutex.cpp
Go to the documentation of this file.
1 /*
2  ------------------------------------------------------------------------------------
3  LICENSE:
4  ------------------------------------------------------------------------------------
5  This file is part of EVEmu: EVE Online Server Emulator
6  Copyright 2006 - 2021 The EVEmu Team
7  For the latest information visit https://evemu.dev
8  ------------------------------------------------------------------------------------
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13 
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public License along with
19  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20  Place - Suite 330, Boston, MA 02111-1307, USA, or go to
21  http://www.gnu.org/copyleft/lesser.txt.
22  ------------------------------------------------------------------------------------
23  Author: Zhur
24 */
25 
26 #include "eve-core.h"
27 
28 #include "threading/Mutex.h"
29 
30 /*************************************************************************/
31 /* Mutex */
32 /*************************************************************************/
34 {
35 #ifdef HAVE_WINDOWS_H
36  InitializeCriticalSection( &mCriticalSection );
37 #else /* !HAVE_WINDOWS_H */
38  pthread_mutexattr_t attr;
39  pthread_mutexattr_init( &attr );
40 
41  pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );
42 
43  pthread_mutex_init( &mMutex, &attr );
44  pthread_mutexattr_destroy( &attr );
45 #endif /* !HAVE_WINDOWS_H */
46 }
47 
49 {
50 #ifdef HAVE_WINDOWS_H
51  DeleteCriticalSection( &mCriticalSection );
52 #else /* !HAVE_WINDOWS_H */
53  pthread_mutex_destroy( &mMutex );
54 #endif /* !HAVE_WINDOWS_H */
55 }
56 
58 {
59 #ifdef HAVE_WINDOWS_H
60  EnterCriticalSection( &mCriticalSection );
61 #else /* !HAVE_WINDOWS_H */
62  pthread_mutex_lock( &mMutex );
63 #endif /* !HAVE_WINDOWS_H */
64 }
65 
67 {
68 #ifdef HAVE_WINDOWS_H
69  return TRUE == TryEnterCriticalSection( &mCriticalSection );
70 #else /* !HAVE_WINDOWS_H */
71  return 0 == pthread_mutex_trylock( &mMutex );
72 #endif /* !HAVE_WINDOWS_H */
73 }
74 
76 {
77 #ifdef HAVE_WINDOWS_H
78  LeaveCriticalSection( &mCriticalSection );
79 #else /* !HAVE_WINDOWS_H */
80  pthread_mutex_unlock( &mMutex );
81 #endif /* !HAVE_WINDOWS_H */
82 }
83 
84 /*************************************************************************/
85 /* MRMutex */
86 /*************************************************************************/
88  rl = 0;
89  wr = 0;
90  wl = 0;
91 }
92 
94 #ifdef _EQDEBUG
95  if (wl || rl) {
96  cout << "MRMutex::~MRMutex: poor cleanup detected: rl=" << rl << ", wl=" << wl << endl;
97  }
98 #endif
99 }
100 
102  while (!TryReadLock()) {
103  Sleep(1);
104  }
105 }
106 
108  MCounters.Lock();
109  if (!wr && !wl) {
110  ++rl;
111  MCounters.Unlock();
112  return true;
113  }
114  else {
115  MCounters.Unlock();
116  return false;
117  }
118 }
119 
121  MCounters.Lock();
122  --rl;
123 #ifdef _EQDEBUG
124  if (rl < 0) {
125  ThrowError("rl < 0 in MRMutex::UnReadLock()");
126  }
127 #endif
128  MCounters.Unlock();
129 }
130 
132  MCounters.Lock();
133  if (!rl && !wl) {
134  ++wl;
135  MCounters.Unlock();
136  return;
137  }
138  else {
139  ++wr;
140  MCounters.Unlock();
141  while (1) {
142  Sleep(1);
143  MCounters.Lock();
144  if (!rl && !wl) {
145  --wr;
146  MCounters.Unlock();
147  return;
148  }
149  MCounters.Lock();
150  }
151  }
152 }
153 
155  MCounters.Lock();
156  if (!rl && !wl) {
157  ++wl;
158  MCounters.Unlock();
159  return true;
160  }
161  else {
162  MCounters.Unlock();
163  return false;
164  }
165 }
166 
168  MCounters.Lock();
169  --wl;
170 #ifdef _EQDEBUG
171  if (wl < 0) {
172  ThrowError("wl < 0 in MRMutex::UnWriteLock()");
173  }
174 #endif
175  MCounters.Unlock();
176 }
177 
179  MCounters.Lock();
180  int32 ret = rl;
181  MCounters.Unlock();
182  return ret;
183 }
184 
186  MCounters.Lock();
187  int32 ret = wl;
188  MCounters.Unlock();
189  return ret;
190 }
Mutex()
Primary contructor.
Definition: Mutex.cpp:33
bool TryLock()
Attempts to lock the mutex.
Definition: Mutex.cpp:66
bool TryReadLock()
Definition: Mutex.cpp:107
int32 ReadLockCount()
Definition: Mutex.cpp:178
void Lock()
Locks the mutex.
Definition: Mutex.cpp:57
void WriteLock()
Definition: Mutex.cpp:131
bool TryWriteLock()
Definition: Mutex.cpp:154
signed __int32 int32
Definition: eve-compat.h:49
~Mutex()
Destructor, releases allocated resources.
Definition: Mutex.cpp:48
int32 WriteLockCount()
Definition: Mutex.cpp:185
pthread_mutex_t mMutex
A pthread mutex used for mutex implementation using pthread library.
Definition: Mutex.h:72
int32 wl
Definition: Mutex.h:100
void UnReadLock()
Definition: Mutex.cpp:120
MRMutex()
Definition: Mutex.cpp:87
Mutex MCounters
Definition: Mutex.h:101
void Unlock()
Unlocks the mutex.
Definition: Mutex.cpp:75
~MRMutex()
Definition: Mutex.cpp:93
void ReadLock()
Definition: Mutex.cpp:101
void Sleep(uint32 x)
Definition: eve-compat.cpp:32
void UnWriteLock()
Definition: Mutex.cpp:167
int32 wr
Definition: Mutex.h:99
int32 rl
Definition: Mutex.h:98