1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
// Geometric Tools, LLC
// Copyright (c) 1998-2014
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
// http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
//
// File Version: 5.0.2 (2010/09/07)
#include "Wm5CorePCH.h"
#include "Wm5Mutex.h"
#include "Wm5Assert.h"
using namespace Wm5;
#if defined(WIN32)
// The system mutex is very slow and are not needed for the single-process
// applications of Wild Magic. Critical sections are faster. In case you
// relied on the system mutex, you can comment out this define to get the
// old behavior
#define WM5_USE_CRITICAL_SECTIONS
//----------------------------------------------------------------------------
#ifdef WM5_USING_VC80
// See the comments at
// http://msdn.microsoft.com/en-us/library/ms683476(VS.85).aspx
// about why these #defines expose InitializeCriticalSectionAndSpinCount.
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0500
#endif
#include <windows.h>
//----------------------------------------------------------------------------
Mutex::Mutex ()
{
#ifdef WM5_USE_CRITICAL_SECTIONS
// The MSVS2010 documentation mentioned that the heap manager spin lock
// was set to approximately 4000. Let's see how 4096 does.
mMutex = new CRITICAL_SECTION;
BOOL success = InitializeCriticalSectionAndSpinCount(
(CRITICAL_SECTION*)mMutex, 4096);
assertion(success == TRUE, "Failed to initialize critical section.\n");
WM5_UNUSED(success);
#else
mMutex = CreateMutex(NULL, FALSE, NULL);
assertion(mMutex != 0, "Failed to create mutex\n");
#endif
}
//----------------------------------------------------------------------------
Mutex::~Mutex ()
{
#ifdef WM5_USE_CRITICAL_SECTIONS
DeleteCriticalSection((CRITICAL_SECTION*)mMutex);
delete mMutex;
#else
BOOL closed = CloseHandle((HANDLE)mMutex);
assertion(closed == TRUE, "Failed to destroy mutex\n");
WM5_UNUSED(closed);
#endif
}
//----------------------------------------------------------------------------
void Mutex::Enter ()
{
#ifdef WM5_USE_CRITICAL_SECTIONS
EnterCriticalSection((CRITICAL_SECTION*)mMutex);
#else
DWORD result = WaitForSingleObject((HANDLE)mMutex, INFINITE);
WM5_UNUSED(result);
// result:
// WAIT_ABANDONED (0x00000080)
// WAIT_OBJECT_0 (0x00000000), signaled
// WAIT_TIMEOUT (0x00000102), [not possible with INFINITE]
// WAIT_FAILED (0xFFFFFFFF), not signaled
#endif
}
//----------------------------------------------------------------------------
void Mutex::Leave ()
{
#ifdef WM5_USE_CRITICAL_SECTIONS
LeaveCriticalSection((CRITICAL_SECTION*)mMutex);
#else
BOOL released = ReleaseMutex((HANDLE)mMutex);
WM5_UNUSED(released);
#endif
}
//----------------------------------------------------------------------------
#elif defined(__LINUX__) || defined(__APPLE__)
//----------------------------------------------------------------------------
Mutex::Mutex ()
{
int result;
WM5_UNUSED(result);
result = pthread_mutexattr_init(&mMutex.Attribute);
// successful = 0
// errors = ENOMEM
result = pthread_mutexattr_settype(&mMutex.Attribute,
PTHREAD_MUTEX_RECURSIVE);
// successful = 0
result = pthread_mutex_init(&mMutex.Mutex, &mMutex.Attribute);
// successful = 0
// errors = EAGAIN, ENOMEM, EPERM, EBUSY, EINVAL
}
//----------------------------------------------------------------------------
Mutex::~Mutex ()
{
int result;
WM5_UNUSED(result);
result = pthread_mutex_destroy(&mMutex.Mutex);
// successful = 0
// errors = EINVAL
result = pthread_mutexattr_destroy(&mMutex.Attribute);
// successful = 0
// errors = EBUSY, EINVAL
}
//----------------------------------------------------------------------------
void Mutex::Enter ()
{
int result = pthread_mutex_lock(&mMutex.Mutex);
WM5_UNUSED(result);
// successful = 0
// errors = EINVAL, EDEADLK
}
//----------------------------------------------------------------------------
void Mutex::Leave ()
{
int result = pthread_mutex_unlock(&mMutex.Mutex);
WM5_UNUSED(result);
// successful = 0
// errors = EINVAL, EPERM
}
//----------------------------------------------------------------------------
#else
#error Other platforms not yet implemented.
#endif
//----------------------------------------------------------------------------
|