version 1.1.2.1, 2006/07/27 23:11:52
|
version 1.1.2.2, 2006/07/28 17:41:27
|
|
|
#include "PegasusAssert.h" | #include "PegasusAssert.h" |
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
|
|
//============================================================================== | //============================================================================== |
// | // |
// PEGASUS_USE_POSIX_RWLOCK | // PEGASUS_USE_POSIX_RWLOCK |
// | // |
//============================================================================== | //============================================================================== |
|
|
#ifdef PEGASUS_USE_POSIX_RWLOCK | #ifdef PEGASUS_USE_POSIX_RWLOCK |
|
|
ReadWriteSem::ReadWriteSem() : _readers(0), _writers(0) | ReadWriteSem::ReadWriteSem() : _readers(0), _writers(0) |
{ | { |
pthread_rwlock_init(&_rwlock.rwlock, NULL); | pthread_rwlock_init(&_rwlock.rwlock, NULL); |
|
|
| |
// timedrdlock and timedwrlock are not supported on HPUX | // timedrdlock and timedwrlock are not supported on HPUX |
// mdday Sun Aug 5 14:21:00 2001 | // mdday Sun Aug 5 14:21:00 2001 |
void ReadWriteSem::timed_wait( |
void ReadWriteSem::timed_wait(Uint32 mode, |
Uint32 mode, |
ThreadType caller, int milliseconds) |
ThreadType caller, |
|
int milliseconds) |
|
{ | { |
int errorcode = 0, timeout; | int errorcode = 0, timeout; |
struct timeval now, finish, remaining; | struct timeval now, finish, remaining; |
|
|
gettimeofday(&now, NULL); | gettimeofday(&now, NULL); |
} | } |
while (errorcode == EBUSY && | while (errorcode == EBUSY && |
(0 == |
(0 == (timeout = Time::subtract(&remaining, &finish, &now)))); |
(timeout = Time::subtract(&remaining, &finish, &now)))); |
|
if (0 == errorcode) | if (0 == errorcode) |
{ | { |
_readers++; | _readers++; |
|
|
gettimeofday(&now, NULL); | gettimeofday(&now, NULL); |
} | } |
while (errorcode == EBUSY && | while (errorcode == EBUSY && |
(0 == |
(0 == (timeout = Time::subtract(&remaining, &finish, &now)))); |
(timeout = Time::subtract(&remaining, &finish, &now)))); |
|
| |
if (0 == errorcode) | if (0 == errorcode) |
{ | { |
|
|
_writers--; | _writers--; |
} | } |
| |
int ReadWriteSem::read_count() const |
int ReadWriteSem::read_count() const const |
{ | { |
#if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) | #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) |
PEGASUS_ASSERT(_readers.get() == _rwlock.rwlock.__rw_readers); | PEGASUS_ASSERT(_readers.get() == _rwlock.rwlock.__rw_readers); |
|
|
return (_readers.get()); | return (_readers.get()); |
} | } |
| |
int ReadWriteSem::write_count() const |
int ReadWriteSem::write_count() const const |
{ | { |
#if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) | #if defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) |
if (_rwlock.rwlock.__rw_writer != NULL) | if (_rwlock.rwlock.__rw_writer != NULL) |
|
|
ReadWriteSem *rws = (ReadWriteSem *)parm; | ReadWriteSem *rws = (ReadWriteSem *)parm; |
ThreadType myself = Threads::self(); | ThreadType myself = Threads::self(); |
| |
if(rws->_rwlock._wlock.get_owner() == myself) |
if (Threads::equal(rws->_rwlock._wlock.get_owner(), myself)) |
rws->_rwlock._wlock.unlock(); | rws->_rwlock._wlock.unlock(); |
else |
else if (rws->_readers.get() > 0) |
if(rws->_readers.get() > 0) |
|
rws->_rwlock._rlock.signal(); | rws->_rwlock._rlock.signal(); |
if (rws->_rwlock._internal_lock.get_owner() == myself) |
|
|
if (Threads::equal(rws->_rwlock._internal_lock.get_owner(), myself)) |
rws->_rwlock._internal_lock.unlock(); | rws->_rwlock._internal_lock.unlock(); |
} | } |
| |
|
|
} | } |
catch(Deadlock& d) | catch(Deadlock& d) |
{ | { |
d = d; // no problem - we own the lock, which is what we want |
d = d; // no problem - we own the lock, which is |
|
// what we want |
} | } |
catch(IPCException& ) | catch(IPCException& ) |
{ | { |
|
|
// if milliseconds == -1, wait indefinately | // if milliseconds == -1, wait indefinately |
// if milliseconds == 0, fast wait | // if milliseconds == 0, fast wait |
//----------------------------------------------------------------- | //----------------------------------------------------------------- |
void ReadWriteSem::timed_wait(Uint32 mode, ThreadType caller, int milliseconds) |
void ReadWriteSem::timed_wait(Uint32 mode, ThreadType caller, |
|
int milliseconds) |
{ | { |
| |
//----------------------------------------------------------------- | //----------------------------------------------------------------- |
|
|
//TooManyReaders caughtTooManyReaders((ThreadType)0); | //TooManyReaders caughtTooManyReaders((ThreadType)0); |
| |
ThreadType zero; | ThreadType zero; |
zero = 0; |
|
IPCException caught(zero); | IPCException caught(zero); |
WaitFailed caughtWaitFailed(zero); | WaitFailed caughtWaitFailed(zero); |
TimeOut caughtTimeOut(zero); | TimeOut caughtTimeOut(zero); |
|
|
else if(milliseconds == -1) | else if(milliseconds == -1) |
_rwlock._internal_lock.lock(Threads::self()); | _rwlock._internal_lock.lock(Threads::self()); |
else | else |
_rwlock._internal_lock.timed_lock(milliseconds, Threads::self()); |
_rwlock._internal_lock.timed_lock(milliseconds, |
|
Threads::self()); |
} | } |
catch(const IPCException& e) | catch(const IPCException& e) |
{ | { |
|
|
while(_readers.get() > 0) | while(_readers.get() > 0) |
{ | { |
gettimeofday(&now, NULL); | gettimeofday(&now, NULL); |
if((now.tv_usec > start.tv_usec) || now.tv_sec > start.tv_sec ) |
if ((now.tv_usec > start.tv_usec) || |
|
now.tv_sec > start.tv_sec) |
{ | { |
_rwlock._internal_lock.unlock(); | _rwlock._internal_lock.unlock(); |
//caught.reset(new TimeOut(Threads::self())); | //caught.reset(new TimeOut(Threads::self())); |
|
|
while(_writers.get() > 0) | while(_writers.get() > 0) |
{ | { |
Time::gettimeofday(&now); | Time::gettimeofday(&now); |
if((now.tv_usec > start.tv_usec) || (now.tv_sec > start.tv_sec)) |
if ((now.tv_usec > start.tv_usec) || |
|
(now.tv_sec > start.tv_sec)) |
{ | { |
_rwlock._internal_lock.unlock(); | _rwlock._internal_lock.unlock(); |
//caught.reset(new TimeOut(Threads::self())); | //caught.reset(new TimeOut(Threads::self())); |
|
|
} | } |
catch(const IPCException&) | catch(const IPCException&) |
{ | { |
// the wait failed, there must be too many readers already. |
// the wait failed, there must be too many readers |
|
// already. |
// unlock the object | // unlock the object |
caughtTooManyReaders = TooManyReaders(Threads::self()); | caughtTooManyReaders = TooManyReaders(Threads::self()); |
_rwlock._internal_lock.unlock(); | _rwlock._internal_lock.unlock(); |
|
|
Threads::cleanup_pop(0); | Threads::cleanup_pop(0); |
} // cleanup stack frame | } // cleanup stack frame |
| |
if (caught.get_owner() != 0) |
if (caught.get_owner().id() != 0) |
throw caught; | throw caught; |
if (caughtWaitFailed.get_owner() != 0) |
if (caughtWaitFailed.get_owner().id() != 0) |
throw caughtWaitFailed; | throw caughtWaitFailed; |
if (caughtTimeOut.get_owner() != 0) |
if (caughtTimeOut.get_owner().id() != 0) |
throw caughtTimeOut; | throw caughtTimeOut; |
if (caughtTooManyReaders.get_owner() != 0) |
if (caughtTooManyReaders.get_owner().id() != 0) |
throw caughtTooManyReaders; | throw caughtTooManyReaders; |
return; | return; |
} | } |
|
|
} | } |
| |
int ReadWriteSem::read_count() const | int ReadWriteSem::read_count() const |
|
|
{ | { |
return( _readers.get() ); | return( _readers.get() ); |
} | } |