$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] [thread] synchronized_value: value and move semantics
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2013-06-26 13:55:46
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