Topic: std::lock and std::lock_guard for SharedLockable's lock_shared


Author: "'Bernd' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 12 Jul 2016 12:09:42 -0700 (PDT)
Raw View
------=_Part_3844_639236661.1468350582376
Content-Type: multipart/alternative;
 boundary="----=_Part_3845_1007165780.1468350582376"

------=_Part_3845_1007165780.1468350582376
Content-Type: text/plain; charset=UTF-8

In discussions on Andrei's NDC talk about folly/Synchronized [1] the
question came up why his deadlock prevention [2] did not just use
std::lock(). It was pointed out that this is due to using
SharedLockable::lock_shared(), making std::lock() the wrong thing. There is
the workaround of

    std::shared_mutex a, b;
    std::shared_lock<> lock_a (a, std::defer_lock);
    std::shared_lock<> lock_b (b, std::defer_lock);
    std::lock (lock_a, lock_b);

using the shared_lock adapter exposing SharedLockable as Lockable. Note
that the inverse order of std::lock and std::shared_lock (using
std::adopt_lock) requires manual deadlock prevention. Note that the locks
also have to be non-const which is undesirable.

I propose adding std::lock_shared (SharedLockable&...) to allow said
inverse order, for consistency:

    std::shared_mutex a, b;
    std::lock_shared (a, b);
    std::shared_lock<> const lock_a (a, std::adopt_lock);
    std::shared_lock<> const lock_b (b, std::adopt_lock);

On the same note, C++17 added std::lock_guard<Lockable...>, which has no
SharedLockable variant either, which would make the above code even easier:

    std::shared_lock_guard<> const lock_both (a, b);

The biggest issue I can see with it is that combining locking a Lockable
and a SharedLockable at once, which still requires the defer_lock approach
or manual deadlock prevention. It feels like this was an oversight when
adding SharedLockable and an easy addition of basically "do as std::lock,
but use _shared methods".

-- Bernd

[1]
https://www.reddit.com/r/programming/comments/4sb7h8/facebook_synchronized_c_library_by_andrei/
[2] https://github.com/facebook/folly/blob/master/folly/Synchronized.h#L1030

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/8d4cc002-f0f2-465f-b856-841adc1ecffd%40isocpp.org.

------=_Part_3845_1007165780.1468350582376
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">In discussions on Andrei&#39;s NDC talk about folly/Synchr=
onized [1] the question came up why his deadlock prevention [2] did not jus=
t use std::lock(). It was pointed out that this is due to using SharedLocka=
ble::lock_shared(), making std::lock() the wrong thing. There is the workar=
ound of<div><br></div><div>=C2=A0 =C2=A0 std::shared_mutex a, b;</div><div>=
=C2=A0 =C2=A0 std::shared_lock&lt;&gt; lock_a (a, std::defer_lock);<br>=C2=
=A0 =C2=A0 std::shared_lock&lt;&gt; lock_b (b, std::defer_lock);</div><div>=
=C2=A0 =C2=A0 std::lock (lock_a, lock_b);</div><div><br></div><div>using th=
e shared_lock adapter exposing SharedLockable as Lockable. Note that the in=
verse order of std::lock and std::shared_lock (using std::adopt_lock) requi=
res manual deadlock prevention. Note that the locks also have to be non-con=
st which is undesirable.</div><div><br></div><div>I propose adding std::loc=
k_shared (SharedLockable&amp;...) to allow said inverse order, for consiste=
ncy:</div><div><br></div><div><div>=C2=A0 =C2=A0 std::shared_mutex a, b;</d=
iv>=C2=A0 =C2=A0 std::lock_shared (a, b);<div>=C2=A0 =C2=A0 std::shared_loc=
k&lt;&gt; const lock_a (a, std::adopt_lock);</div><div>=C2=A0 =C2=A0 std::s=
hared_lock&lt;&gt; const lock_b (b, std::adopt_lock);</div></div><div><br><=
/div><div>On the same note, C++17 added std::lock_guard&lt;Lockable...&gt;,=
 which has no SharedLockable variant either, which would make the above cod=
e even easier:</div><div><br></div><div>=C2=A0 =C2=A0 std::shared_lock_guar=
d&lt;&gt; const lock_both (a, b);</div><div><div><br></div><div>The biggest=
 issue I can see with it is that combining locking a Lockable and a SharedL=
ockable at once, which still requires the defer_lock approach or manual dea=
dlock prevention. It feels like this was an oversight when adding SharedLoc=
kable and an easy addition of basically &quot;do as std::lock, but use _sha=
red methods&quot;.</div><div><br></div><div>-- Bernd</div><div><br></div><d=
iv>[1] https://www.reddit.com/r/programming/comments/4sb7h8/facebook_synchr=
onized_c_library_by_andrei/<br></div></div><div>[2]=C2=A0https://github.com=
/facebook/folly/blob/master/folly/Synchronized.h#L1030</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/8d4cc002-f0f2-465f-b856-841adc1ecffd%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/8d4cc002-f0f2-465f-b856-841adc1ecffd=
%40isocpp.org</a>.<br />

------=_Part_3845_1007165780.1468350582376--

------=_Part_3844_639236661.1468350582376--

.