SenderX wrote:
Yeah I guess I forgot to release the lock on destructor and public the
constructor on that last one.. is this new code below good
wrapper/impl of lock?
no.
This is:
http://appcore.home.comcast.net/pthreads/mutex.h
Go to the mutex.h link.
This was just an illustration. It doesn't properly report resource-not-
available errors. Mutex constructor can throw std::bad_alloc, to begin
with (std::try_again and std::no_way aside for a moment ;-) ). As for
the lock acquisition... since lock initialization can be done in "a
lazy fashion", the same applies for the initial calls done by threads;
"in general", so to speak. Here is an illustration to clarify it.
#define SWAP_BASED_MUTEX_FOR_WINDOWS_INITIALIZER { 0, 0 }
class swap_based_mutex_for_windows {
/* ... */
// -1: free, 0: locked, 1: contention
atomic<int> m_lock_status;
atomic<auto_reset_event *> m_retry_event;
/* ... */
void lock() {
if (m_lock_status.swap(0, msync::acq) >= 0)
slow_lock();
}
bool trylock() {
return m_lock_status.swap(0, msync::acq) >= 0 ?
slow_trylock() : true;
}
bool timedlock(absolute_timeout const & timeout) {
return m_lock_status.swap(0, msync::acq) >= 0 ?
slow_timedlock(timeout) : true;
}
void unlock() {
if (m_lock_status.swap(-1, msync::rel) > 0)
m_retry_event.load(msync::none)->set();
}
void slow_lock() {
auto_reset_event & retry_event = DCSI();
while (m_lock_status.swap(1, msync::acq) >= 0)
retry_event.wait();
}
bool slow_trylock() {
DCSI();
return m_lock_status.swap(1, msync::acq) < 0;
}
bool slow_timedlock(absolute_timeout const & timeout) {
auto_reset_event & retry_event = DCSI();
while (m_lock_status.swap(1, msync::acq) >= 0)
if (!retry_event.timedwait(timeout)) return false;
return true;
}
auto_reset_event & DCSI() {
auto_reset_event * retry_event;
if ((retry_event = m_retry_event.load(msync::none)) == 0) {
named_windows_mutex_trick guard(this);
if ((retry_event = m_retry_event.load(msync::none)) == 0) {
retry_event = new auto_reset_event()
m_retry_event.store(retry_event, msync::rel);
m_lock_status.store(-1, msync::rel);
}
}
return *retry_event;
}
};
regards,
alexander.
--
typedef std::aligned_storage<std::mutex> pthread_mutex_t; // POD
extern "C" int pthread_mutex_destroy(pthread_mutex_t * m) throw() {
m->object().~mutex();
return 0;
}