version 1.11.2.1, 2008/08/20 23:05:50
|
version 1.14, 2008/09/16 18:37:03
|
|
|
#include "Time.h" | #include "Time.h" |
#include "PegasusAssert.h" | #include "PegasusAssert.h" |
#include "Once.h" | #include "Once.h" |
|
#include "Exception.h" |
|
#include "System.h" |
|
|
|
#define MUTEX_LOCK_FAILED_KEY "Common.InternalException.MUTEX_LOCK_FAILED" |
|
#define MUTEX_LOCK_FAILED_MSG "Failed to acquire mutex lock: $0" |
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
| |
|
|
{ | { |
PEGASUS_DEBUG_ASSERT(_magic); | PEGASUS_DEBUG_ASSERT(_magic); |
| |
switch (pthread_mutex_lock(&_rep.mutex)) |
int r = pthread_mutex_lock(&_rep.mutex); |
|
|
|
if (r == 0) |
{ | { |
case 0: |
|
#if defined(PEGASUS_DEBUG) | #if defined(PEGASUS_DEBUG) |
_rep.count++; | _rep.count++; |
#endif | #endif |
break; |
} |
|
else |
|
{ |
|
if (r != -1) |
|
{ |
|
// Special behavior for Single UNIX Specification, Version 3 |
|
errno = r; |
|
} |
| |
default: |
throw Exception(MessageLoaderParms( |
throw WaitFailed(Threads::self()); |
MUTEX_LOCK_FAILED_KEY, |
|
MUTEX_LOCK_FAILED_MSG, |
|
PEGASUS_SYSTEM_ERRORMSG_NLS)); |
} | } |
} | } |
| |
|
|
PEGASUS_DEBUG_ASSERT(_magic); | PEGASUS_DEBUG_ASSERT(_magic); |
| |
int r = pthread_mutex_trylock(&_rep.mutex); | int r = pthread_mutex_trylock(&_rep.mutex); |
if (r == -1) |
|
r=errno; |
|
| |
if (r == 0) | if (r == 0) |
{ | { |
|
|
return true; | return true; |
} | } |
| |
if (r == EBUSY) |
if (r != -1) |
|
{ |
|
// Special behavior for Single UNIX Specification, Version 3 |
|
errno = r; |
|
} |
|
|
|
if (errno == EBUSY) |
{ | { |
return false; | return false; |
} | } |
| |
throw WaitFailed(Threads::self()); |
throw Exception(MessageLoaderParms( |
|
MUTEX_LOCK_FAILED_KEY, |
|
MUTEX_LOCK_FAILED_MSG, |
|
PEGASUS_SYSTEM_ERRORMSG_NLS)); |
} | } |
| |
Boolean Mutex::timed_lock(Uint32 milliseconds) | Boolean Mutex::timed_lock(Uint32 milliseconds) |
{ | { |
PEGASUS_DEBUG_ASSERT(_magic); |
|
|
|
struct timeval now; | struct timeval now; |
struct timeval finish; | struct timeval finish; |
struct timeval remaining; | struct timeval remaining; |
|
|
finish.tv_usec = usec % 1000000; | finish.tv_usec = usec % 1000000; |
} | } |
| |
for (;;) |
while (!try_lock()) |
{ |
|
int r=pthread_mutex_trylock(&_rep.mutex); |
|
if (r == -1) |
|
r = errno; |
|
|
|
if (r == 0) |
|
{ |
|
break; |
|
} |
|
else if (r == EBUSY) |
|
{ | { |
gettimeofday(&now, NULL); | gettimeofday(&now, NULL); |
| |
|
|
| |
Threads::yield(); | Threads::yield(); |
} | } |
else |
|
{ |
|
throw WaitFailed(Threads::self()); |
|
} |
|
} |
|
| |
#if defined(PEGASUS_DEBUG) |
|
_rep.count++; |
|
#endif |
|
return true; | return true; |
} | } |
| |
|
|
_rep.count--; | _rep.count--; |
#endif | #endif |
| |
if (pthread_mutex_unlock(&_rep.mutex) != 0) |
int rc = pthread_mutex_unlock(&_rep.mutex); |
throw Permission(Threads::self()); |
// All documented error codes represent coding errors. |
|
PEGASUS_ASSERT(rc == 0); |
} | } |
| |
#if defined(PEGASUS_OS_LINUX) || \ | #if defined(PEGASUS_OS_LINUX) || \ |
|
|
DWORD rc = WaitForSingleObject(_rep.handle, INFINITE); | DWORD rc = WaitForSingleObject(_rep.handle, INFINITE); |
| |
if (rc == WAIT_FAILED) | if (rc == WAIT_FAILED) |
throw WaitFailed(Threads::self()); |
{ |
|
throw Exception(MessageLoaderParms( |
|
MUTEX_LOCK_FAILED_KEY, |
|
MUTEX_LOCK_FAILED_MSG, |
|
PEGASUS_SYSTEM_ERRORMSG_NLS)); |
|
} |
| |
_rep.count++; | _rep.count++; |
} | } |
|
|
| |
if (rc == WAIT_FAILED) | if (rc == WAIT_FAILED) |
{ | { |
throw WaitFailed(Threads::self()); |
throw Exception(MessageLoaderParms( |
|
MUTEX_LOCK_FAILED_KEY, |
|
MUTEX_LOCK_FAILED_MSG, |
|
PEGASUS_SYSTEM_ERRORMSG_NLS)); |
} | } |
| |
_rep.count++; | _rep.count++; |
|
|
return false; | return false; |
| |
if (rc == WAIT_FAILED) | if (rc == WAIT_FAILED) |
throw WaitFailed(Threads::self()); |
{ |
|
throw Exception(MessageLoaderParms( |
|
MUTEX_LOCK_FAILED_KEY, |
|
MUTEX_LOCK_FAILED_MSG, |
|
PEGASUS_SYSTEM_ERRORMSG_NLS)); |
|
} |
| |
_rep.count++; | _rep.count++; |
return true; | return true; |