version 1.9.16.1, 2007/09/11 16:32:43
|
version 1.9.16.2, 2007/09/11 18:18:09
|
|
|
| |
Mutex::Mutex(RecursiveTag) | Mutex::Mutex(RecursiveTag) |
{ | { |
|
_rep.recursive = 1; |
pthread_mutex_init(&_rep.mutex, NULL); | pthread_mutex_init(&_rep.mutex, NULL); |
pthread_cond_init(&_rep.cond, NULL); | pthread_cond_init(&_rep.cond, NULL); |
_rep.owner = 0; | _rep.owner = 0; |
|
|
| |
Mutex::Mutex(NonRecursiveTag) | Mutex::Mutex(NonRecursiveTag) |
{ | { |
|
_rep.recursive = 0; |
pthread_mutex_init(&_rep.mutex, NULL); | pthread_mutex_init(&_rep.mutex, NULL); |
pthread_cond_init(&_rep.cond, NULL); |
|
_rep.owner = 0; |
|
_rep.count = 0; |
|
} | } |
| |
Mutex::~Mutex() | Mutex::~Mutex() |
{ | { |
PEGASUS_DEBUG_ASSERT(_magic); | PEGASUS_DEBUG_ASSERT(_magic); |
pthread_mutex_destroy(&_rep.mutex); | pthread_mutex_destroy(&_rep.mutex); |
|
|
|
if (_rep.recursive) |
pthread_cond_destroy(&_rep.cond); | pthread_cond_destroy(&_rep.cond); |
} | } |
| |
void Mutex::lock() | void Mutex::lock() |
{ | { |
PEGASUS_DEBUG_ASSERT(_magic); | PEGASUS_DEBUG_ASSERT(_magic); |
|
|
|
if (_rep.recursive) |
|
{ |
pthread_t self = pthread_self(); | pthread_t self = pthread_self(); |
| |
pthread_mutex_lock(&_rep.mutex); | pthread_mutex_lock(&_rep.mutex); |
|
|
} | } |
pthread_mutex_unlock(&_rep.mutex); | pthread_mutex_unlock(&_rep.mutex); |
} | } |
|
else |
|
{ |
|
if (pthread_mutex_lock(&_rep.mutex) != 0) |
|
{ |
|
throw WaitFailed(Threads::self()); |
|
} |
|
} |
|
} |
| |
void Mutex::try_lock() | void Mutex::try_lock() |
{ | { |
PEGASUS_DEBUG_ASSERT(_magic); | PEGASUS_DEBUG_ASSERT(_magic); |
|
|
|
if (_rep.recursive) |
|
{ |
pthread_t self = pthread_self(); | pthread_t self = pthread_self(); |
| |
pthread_mutex_lock(&_rep.mutex); | pthread_mutex_lock(&_rep.mutex); |
|
|
} | } |
pthread_mutex_unlock(&_rep.mutex); | pthread_mutex_unlock(&_rep.mutex); |
} | } |
|
else |
|
{ |
|
int r = pthread_mutex_trylock(&_rep.mutex); |
|
|
|
if (r == -1) |
|
r = errno; |
|
|
|
switch (r) |
|
{ |
|
case 0: |
|
break; |
|
|
|
case EBUSY: |
|
throw AlreadyLocked(Threads::self()); |
|
|
|
default: |
|
throw WaitFailed(Threads::self()); |
|
} |
|
} |
|
} |
| |
void Mutex::timed_lock(Uint32 milliseconds) | void Mutex::timed_lock(Uint32 milliseconds) |
{ | { |
PEGASUS_DEBUG_ASSERT(_magic); | PEGASUS_DEBUG_ASSERT(_magic); |
|
|
|
if (_rep.recursive) |
|
{ |
pthread_t self = pthread_self(); | pthread_t self = pthread_self(); |
| |
pthread_mutex_lock(&_rep.mutex); | pthread_mutex_lock(&_rep.mutex); |
|
|
| |
while (_rep.count > 0) | while (_rep.count > 0) |
{ | { |
if (pthread_cond_timedwait(&_rep.cond, &_rep.mutex, &ts) != 0) |
if (pthread_cond_timedwait( |
|
&_rep.cond, &_rep.mutex, &ts) != 0) |
{ | { |
pthread_mutex_unlock(&_rep.mutex); | pthread_mutex_unlock(&_rep.mutex); |
throw TimeOut(Threads::self()); | throw TimeOut(Threads::self()); |
|
|
} | } |
pthread_mutex_unlock(&_rep.mutex); | pthread_mutex_unlock(&_rep.mutex); |
} | } |
|
else |
|
{ |
|
struct timeval now; |
|
struct timeval finish; |
|
struct timeval remaining; |
|
{ |
|
Uint32 usec; |
|
gettimeofday(&finish, NULL); |
|
finish.tv_sec += (milliseconds / 1000 ); |
|
milliseconds %= 1000; |
|
usec = finish.tv_usec + ( milliseconds * 1000 ); |
|
finish.tv_sec += (usec / 1000000); |
|
finish.tv_usec = usec % 1000000; |
|
} |
|
|
|
for (;;) |
|
{ |
|
int r = pthread_mutex_trylock(&_rep.mutex); |
|
|
|
if (r == -1) |
|
r = errno; |
|
|
|
switch (r) |
|
{ |
|
case 0: |
|
return; |
|
|
|
case EBUSY: |
|
{ |
|
gettimeofday(&now, NULL); |
|
|
|
if (Time::subtract(&remaining, &finish, &now)) |
|
throw TimeOut(Threads::self()); |
|
|
|
Threads::yield(); |
|
break; |
|
} |
|
|
|
default: |
|
throw WaitFailed(Threads::self()); |
|
} |
|
} |
|
} |
|
} |
| |
void Mutex::unlock() | void Mutex::unlock() |
{ | { |
PEGASUS_DEBUG_ASSERT(_magic); | PEGASUS_DEBUG_ASSERT(_magic); |
|
|
|
if (_rep.recursive) |
|
{ |
pthread_t self = pthread_self(); | pthread_t self = pthread_self(); |
| |
pthread_mutex_lock(&_rep.mutex); | pthread_mutex_lock(&_rep.mutex); |
|
|
} | } |
pthread_mutex_unlock(&_rep.mutex); | pthread_mutex_unlock(&_rep.mutex); |
} | } |
|
else |
|
{ |
|
if (pthread_mutex_unlock(&_rep.mutex) != 0) |
|
throw Permission(Threads::self()); |
|
} |
|
} |
| |
#endif /* PEGASUS_HAVE_PTHREADS && !PEGASUS_HAVE_RECURSIVE_MUTEXES */ | #endif /* PEGASUS_HAVE_PTHREADS && !PEGASUS_HAVE_RECURSIVE_MUTEXES */ |
| |