On Wednesday 26 June 2013 08:55:33 Vicente Botet wrote:
Andrey Semashev-2 wrote
1. Why are there strict_lock_ptr and unique_lock_ptr?
These a locking pointers that lock at construction and unlock at destruction. Both classes have pointer semantics.
What are the differences
strict_lock_ptr cannot be unlocked (something like lock_guard) and unique_lock_ptr is a model of Lockable so it provides the lock/unlock functions as unique_lock.
and why we can't have one such ptr (presumably, unique_lock_ptr)?
Sorry I don't understand.
What I mean is that there is no apparent advantage of using strict_lock_ptr instead of unique_lock_ptr. strict_lock_ptr is a bit more limited than unique_lock_ptr but it doesn't provide anything in return. Yet it complicates synchronized_value interface and adds confusion (when should I call synchronize() and when unique_synchronize()?). So I don't see the point in having strict_lock_ptr. Note that although there exist both lock_guard and unique_lock, the former is more efficient when you don't need movability and optional locking of the latter. This is not the case with strict_lock_ptr and unique_lock_ptr since both use unique_lock internally.
3. Am I correct that having strict_lock_ptr/unique_lock_ptr acquired by calling synchronize() will not deadlock with operator-> when a non-recursive mutex is used?
To which operator-> are you referring to? the one from strict_lock_ptr/unique_lock_ptr? synchronize() is used to lock at block scope. The user must use the obtained locking pointer to access to the functions of the synchronized value using the operator->. I'm not sure to understand what could be the issue.
I was referring to synchronized_value<>::operator->. What I mean is this: synchronized_value< foo, mutex > sync_foo; auto locked = sync_foo.synchronize(); sync_foo->bar(); // deadlock?? If I use a non-recursive mutex, like the above, and store the strict_lock_ptr or unique_lock_ptr in locked, will I be able to call bar()? The operator-> is supposed to create a new strict_lock_ptr, which is supposed to attempt to lock the mutex again, isn't it? Perhaps, it would be better to restrict the number of lock_ptrs for a single synchronized_value that can exist concurrently to just one? Then the above code would be invalid and should be written as follows: synchronized_value< foo, mutex > sync_foo; auto locked = sync_foo.synchronize(); // sync_foo->bar(); // <-- assertion failure or exception locked->bar(); // ok