Boost logo

Boost :

From: Alexander Terekhov (terekhov_at_[hidden])
Date: 2004-07-13 09:37:40


Peter Dimov wrote:
[...]
> That's how Boost.Threads behaves, but (AFAICS) it doesn't protect itself
> against a thread switch and lock immediately after freeing the mutex for the
> wait, so it doesn't meet the "correctly" requirement. ;-)

I think it saves the lock count on the stack prior to releasing
internal "real" [non-recursive, in a way, because it's never used
recursively] mutex and restores the count on exit from cv.wait
after acquiring the "real" mutex. In a way, the scheme is really
similar to:

http://groups.google.com/groups?selm=3BA5B950.6E21D198%40web.de
http://groups.google.com/groups?selm=408E48E8.D67F1EA5%40web.de

---
Per-thread flags can be used to turn nonrecursive locks into 
recursive ones.
given:
key - tsd flag key 
lock - mutex (non-recursive lock)
count - unsigned
init {
  tsd::init(&key);              
  lock::init(&lock);
  count = 0;
}
destroy {
  lock::destroy(&lock);
  tsd::destroy(&key);
}
lock {
  if (!tsd::get(&key)) { 
    tsd::set(&key, true); 
    lock.acquire();  // assume throw()-nothing
    count = 1;
  }
  else {
    ++count;
  } 
}
unlock {
  if (!--count ) {
    lock.release(); // throw()-nothing
    tsd::set(&key, false); 
  } 
}
Note that if you need "posix safety" with respect to 
unlock/destroy of this lock, "tsd::set(&key, false);" 
shall be done before "lock.release();" (and of course 
the underlying nonrecursive lock itself shall be safe 
with respect to unlock/destroy).
---
where you just need to save-on-stack-and-reset/restore the lock 
count before-cv.enter_wait()/after-cv.exit_wait().
The problem I meant before was something else (don't recall now).
regards,
alexander.

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk