[cpp-threads] Re: Thread API interface tweaks
Alexander Terekhov
alexander.terekhov at gmail.com
Wed Aug 30 13:15:58 BST 2006
On 8/30/06, Howard Hinnant <hinnant at twcny.rr.com> wrote:
[...]
> template <class Mutex>
> class recursive_mutex
> {
> private:
> Mutex& mut_;
> unsigned count_;
> thread_id id_;
> public:
> explicit recursive_mutex(Mutex& mut)
> : mut_(mut), count_(0) {} // thread_id default constructed
> to "not a thread"
>
> void lock()
> {
> thread_id self = thread_id::current();
> if (count_ > 0 && id_ == self)
Um, you've got a data race here.
> ++count_;
> else
> {
> mut_.lock();
> id_ = self;
> store_release(&count_, 1);
> }
> }
> ...
> };
>
> I.e. recursive_mutex<Mutex> takes any exclusive Mutex and turns it
> into a recursive mutex. To implement this I needed the notion of
> thread id.
Not really.
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).
regards,
alexander.
More information about the cpp-threads
mailing list