Topic: Comments on N4470 "Variadic lock_guard


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Thu, 30 Apr 2015 03:13:59 -0700 (PDT)
Raw View
------=_Part_4912_152999425.1430388839533
Content-Type: multipart/alternative;
 boundary="----=_Part_4913_923410516.1430388839533"

------=_Part_4913_923410516.1430388839533
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I was just reading Mike Spertus' N4470 "Variadic lock_guard":
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4470.html

My first impression was, "Wow, this is a slam-dunk obvious proposal... of=
=20
course lock_guard should be able to take multiple arguments!"
But the further I read, the uglier it seems, both in syntax and in=20
semantics.

The state of the art is:

    std::mutex mtx1, mtx2;
    ...
    std::lock_guard<std::mutex> guard1(mtx1);
    std::lock_guard<std::mutex> guard2(mtx2);  // deadlocks if somebody=20
else tries to lock mtx2 and then mtx1

or

    std::lock(mtx1, mtx2);  // cannot deadlock, per [thread.lock.algorithm]
    // if anything here throws, we forget to unlock =E2=80=94 yikes!
    std::lock_guard<std::mutex> guard1(mtx1, std::adopt_lock), guard2(mtx2,=
=20
std::adopt_lock);

What I'd like to see is:

    std::lock_guard<std::mutex> guard(mtx1, mtx2);
    // cannot deadlock and is exception-safe

But what N4470 actually proposes is:

    std::lock_guard<std::mutex, std::mutex> guard(mtx1, mtx2);
    // can still deadlock, because it fails to use [thread.lock.algorithm]=
=20
for the internals

The repetition of "std::mutex, std::mutex" is ugly syntax.
The potential for deadlock is ugly semantics.

I haven't given the question *too* much thought, but perhaps all that's=20
needed here is a "tuple of locks" concept.
(std::apply borrowed from N3829=20
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3829.pdf>.)

template<class... Mutex>
class lock_tuple {
    std::tuple<Mutex&...> mutexes;
  public:
    explicit lock_tuple(Mutex&... mtx) : mutexes(mtx...) {}
    void lock() {
        auto locker =3D [](auto&... mtx) { std::lock(mtx...); };
        std::apply(locker, this->mutexes);
    }
    void unlock() {
        // doesn't really matter in what order we unlock them
        auto unlocker =3D [](auto&... mtx) { auto _ { ((void)mtx.unlock(), =
0
)... }; };
        std::apply(unlocker, this->mutexes);
    }
};

template<class... Mutex>
lock_tuple<Mutex...> make_lock_tuple(Mutex&... mtx) {
   return lock_tuple(mtx...);
}

Then what we end up with is

    std::mutex mtx1, mtx2;
    ...
    auto both =3D make_lock_tuple(mtx1, mtx2);
    std::lock_guard<decltype(both)> guard(both);  // exception-safe AND=20
cannot deadlock

This strikes me as a cleaner syntax AND cleaner semantics, AND can be=20
implemented by adding one new class to the standard library instead of=20
having to replace an existing class.

One reason not to adopt either of these proposals (neither N4470=20
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4470.html> nor=20
lock_tuple) is that they're both coming from the POV of, "I use a lot of=20
raw locking primitives and I run into deadlock a lot, and I want to make=20
deadlock less likely."  A very valid response would be, "Stop trying to use=
=20
raw locking primitives, then!"

"C++ makes it harder for you to shoot yourself in the foot, but when you=20
do, it blows your whole leg off."=20
<http://programmers.stackexchange.com/questions/92126/what-did-bjarne-strou=
strup-mean-by-his-characterization-of-c-and-c>=20
 Any addition to <mutex>, IMHO, has to prove that it's not simply=20
contributing to the problem of C++ programmers blowing off their legs.

my $.02,
=E2=80=93Arthur

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<div dir=3D"ltr"><div>I was just reading Mike Spertus' N4470 "Variadic lock=
_guard":</div><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers=
/2015/n4470.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n=
4470.html</a><br><div><br></div><div>My first impression was, "Wow, this is=
 a slam-dunk obvious proposal... of course lock_guard should be able to tak=
e multiple arguments!"</div><div>But the further I read, the uglier it seem=
s, both in syntax and in semantics.</div><div><br></div><div>The state of t=
he art is:</div><div><br></div><div class=3D"prettyprint" style=3D"backgrou=
nd-color: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187); word-wr=
ap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span style=3D"color: #000;" class=3D"styled-by-prettify">&nbsp; &nbsp; std=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">mutex mtx1</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> mtx2</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">...</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">lock_guard</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">mutex</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> guard1</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">mtx1<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; s=
td</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">lock_guard</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">mutex</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> guard2</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">mtx2</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> &nbsp;</span><span style=3D"color: #800;" class=3D"styled-by-prettify">/=
/ deadlocks if somebody else tries to lock mtx2 and then mtx1</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></code>=
</div><div><br></div><div>or</div><div><br></div><div class=3D"prettyprint"=
 style=3D"background-color: rgb(250, 250, 250); border: 1px solid rgb(187, =
187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">&nbsp; &nbsp; std</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">::</span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">lock</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">mtx1</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> mtx2</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> &nbsp;</span><span style=3D"color: #800;=
" class=3D"styled-by-prettify">// cannot deadlock, per [thread.lock.algorit=
hm]</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nb=
sp; &nbsp; </span><span style=3D"color: #800;" class=3D"styled-by-prettify"=
>// if anything here throws, we forget to unlock =E2=80=94 yikes!</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; st=
d</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">lock_guard</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">mutex</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> guard1</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">mtx1</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">adopt_lock</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">),</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> guard2</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">mtx2</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify">adopt_lock</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br></span></div></code></div><div><br></div><div>What I'd like to see=
 is:</div><div><br></div><div class=3D"prettyprint" style=3D"background-col=
or: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: br=
eak-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span =
style=3D"color: #000;" class=3D"styled-by-prettify">&nbsp; &nbsp; std</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">lock_guard</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">mutex</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> guard</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">mtx1</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> mtx2</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </=
span><span style=3D"color: #800;" class=3D"styled-by-prettify">// cannot de=
adlock and is exception-safe</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span></div></code></div><div><br></div><div>But wha=
t N4470 actually proposes is:</div><div><br></div><div class=3D"prettyprint=
" style=3D"background-color: rgb(250, 250, 250); border: 1px solid rgb(187,=
 187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">&nbsp; &nbsp; std</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">lock_guard</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">std<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">mutex</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">mutex</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> guard</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">mtx1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> mtx2</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </spa=
n><span style=3D"color: #800;" class=3D"styled-by-prettify">// can still de=
adlock, because it fails to use [thread.lock.algorithm] for the internals</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
/div></code></div><div><br></div><div>The repetition of "<font face=3D"cour=
ier new, monospace">std::mutex, std::mutex</font>" is ugly syntax.</div><di=
v>The potential for deadlock is ugly semantics.</div><div><br></div><div>I =
haven't given the question <i>too</i> much thought, but perhaps all that's =
needed here is a "tuple of locks" concept.</div><div>(std::apply borrowed f=
rom&nbsp;<a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014=
/n3829.pdf">N3829</a>.)</div><div><br></div><div class=3D"prettyprint" styl=
e=3D"background-color: rgb(250, 250, 250); border: 1px solid rgb(187, 187, =
187); word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"sub=
prettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">temp=
late</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">class</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">...</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">Mutex</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> lock_tuple </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>&nbsp; &nbsp; std</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">tuple</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">&lt;</span><span style=3D"color: #606;" class=3D"styled-by-pre=
ttify">Mutex</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&amp;...&gt;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> mutexes</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nb=
sp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">public=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">explicit</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> lock_tuple</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #606;" class=3D"styled-by-prettify">Mutex</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&amp;...</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> mtx</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> mutexes</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">mtx</span><span style=3D"color: #660;" class=3D"styled-by-prettify">...=
)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">{}</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">lock</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> locker </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">[](</span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>auto</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;=
....</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> mtx</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">::</span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">lock</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">mtx</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.=
...);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp=
; &nbsp; std</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">apply<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">locker</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">this</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">-&gt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">mutexes</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> unlock</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbs=
p; &nbsp; &nbsp; </span><span style=3D"color: #800;" class=3D"styled-by-pre=
ttify">// doesn't really matter in what order we unlock them</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp; =
&nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">aut=
o</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> unlocker=
 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">[](</span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">&amp;...</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> mtx</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> _ </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">((</span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">void</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">mtx</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">u=
nlock</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(),</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)...</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br>&nbsp; &nbsp; &nbsp; &nbsp; std</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">apply</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">unlocker</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">this</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">-&gt;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">mutexes</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">template</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">class</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">...</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Mut=
ex</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>lock_tuple=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span=
><span style=3D"color: #606;" class=3D"styled-by-prettify">Mutex</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">...&gt;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> make_lock_tuple</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #606;" class=3D"styled-by-prettify">Mutex</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">&amp;...</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> mtx</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br>&nbsp; &nbsp;</span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> lock_tuple</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">mtx</span><span style=3D"color: #660;" class=3D"styled-by-prettify">...)=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></code>=
</div><div><br></div><div>Then what we end up with is</div><div><br></div><=
div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bo=
rder: 1px solid rgb(187, 187, 187); word-wrap: break-word;"><code class=3D"=
prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">&nbsp; &nbsp; std</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">mutex mtx1</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> mtx2</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>&nbsp; &nbsp; </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">...</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> both </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> make_=
lock_tuple</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">mtx1</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> mtx2</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; std</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">lock_guard</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">decltype</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">both</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">)&gt;</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> guard</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>both</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> &nbsp;</span=
><span style=3D"color: #800;" class=3D"styled-by-prettify">// exception-saf=
e AND cannot deadlock</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span></div></code></div><div><span class=3D"styled-by-pret=
tify" style=3D"font-family: monospace; color: rgb(0, 0, 0);"><br></span>Thi=
s strikes me as a cleaner syntax AND cleaner semantics, AND can be implemen=
ted by adding one new class to the standard library instead of having to re=
place an existing class.</div><div><br></div><div>One reason not to adopt e=
ither of these proposals (neither <a href=3D"http://www.open-std.org/jtc1/s=
c22/wg21/docs/papers/2015/n4470.html">N4470</a> nor <font face=3D"courier n=
ew, monospace">lock_tuple</font>) is that they're both coming from the POV =
of, "I use a lot of raw locking primitives and I run into deadlock a lot, a=
nd I want to make deadlock less likely." &nbsp;A very valid response would =
be, "Stop trying to use raw locking primitives, then!"</div><div><br></div>=
<div><a href=3D"http://programmers.stackexchange.com/questions/92126/what-d=
id-bjarne-stroustrup-mean-by-his-characterization-of-c-and-c">"C++ makes it=
 harder for you to shoot yourself in the foot, but when you do, it blows yo=
ur whole leg off."</a> &nbsp;Any addition to <font face=3D"courier new, mon=
ospace">&lt;mutex&gt;</font>, IMHO, has to prove that it's not simply contr=
ibuting to the problem of C++ programmers blowing off their legs.</div><div=
><br></div><div>my $.02,</div><div>=E2=80=93Arthur</div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_4913_923410516.1430388839533--
------=_Part_4912_152999425.1430388839533--

.


Author: Michael Spertus <mike_spertus@symantec.com>
Date: Thu, 30 Apr 2015 06:44:26 -0700
Raw View
--_000_9A3E0561DCF227429F72080EA81ADBC95084453ECATUS1XCHEVSPIN_
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Thanks for your comments.  Arthur,

1.       Absolutely, the proposal is meant to be deadlock-free, and I just =
embarrassingly put in the wording wrong. Corrected wording will be on the w=
iki. (I realized this right after submitting, but it was too late=E2=80=A6 =
I did give my students an extra credit problem to find the mistake in the p=
aper).

2.       I considered requiring that all the mutex types be the same as you=
 suggest, but some of the most important use cases require different lock t=
ypes (like Howard=E2=80=99s operator=3D example in the paper), and it just =
seems inaccurate to do otherwise.

3.       If N4471 is adopted, then you don=E2=80=99t need to worry about te=
mplate arguments.
auto guard =3D lock_guard(mtx1, mtx2);

4.       Even without N4471, since all of the common use cases we could thi=
nk of involve 0, 1, or 2 mutexes (note that 0 locks is useful as well), the=
 notational overhead isn=E2=80=99t excessive.

5.       It seems like unique_lock might also want to work with any number =
of mutexes. In that case, a make_unique_lock(=E2=80=A6) would be another wa=
y to avoid specifying the template arguments. (Since lock_guard is not mova=
ble, you can=E2=80=99t do this with lock_guards).

6.       While I sympathize with your desire to avoid raw locking primitive=
s, I think the use cases in the paper are appropriate and of course, explic=
it locks are common in practices. C++ in general has the philosophy of offe=
ring both low-level primitives and high-level abstractions. In any case, if=
 we choose to provide raw locking primitives, I think the relevant question=
 is whether or not they are better if variadic (also see #8 below).

7.       In particular, I think the built-in deadlock avoidance (Once the w=
ording embarrassment from #1 above is fixed!) will result in more reliable =
programs in practice, if only because many user-defined types follow the ru=
le of three=E2=80=99s imprecation to provide assignment operators.

8.       I=E2=80=99m having trouble seeing any reason we shouldn=E2=80=99t =
allow lock_guard to be variadic. The proposal is easy to ignore if you don=
=E2=80=99t like it, and IMO doesn=E2=80=99t add conceptual complexity. =E2=
=80=9Cstd::lock_guard can manage a set of locks of diverse types, just like=
 std::lock=E2=80=9D. I=E2=80=99ve never heard any of my students or coworke=
rs say that std::lock is more confusing because it was variadic.

What do you think,

Mike

From: Arthur O'Dwyer [mailto:arthur.j.odwyer@gmail.com]
Sent: Thursday, April 30, 2015 5:14 AM
To: std-proposals@isocpp.org
Cc: Michael Spertus
Subject: Comments on N4470 "Variadic lock_guard"

I was just reading Mike Spertus' N4470 "Variadic lock_guard":
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4470.html

My first impression was, "Wow, this is a slam-dunk obvious proposal... of c=
ourse lock_guard should be able to take multiple arguments!"
But the further I read, the uglier it seems, both in syntax and in semantic=
s.

The state of the art is:

    std::mutex mtx1, mtx2;
    ...
    std::lock_guard<std::mutex> guard1(mtx1);
    std::lock_guard<std::mutex> guard2(mtx2);  // deadlocks if somebody els=
e tries to lock mtx2 and then mtx1

or

    std::lock(mtx1, mtx2);  // cannot deadlock, per [thread.lock.algorithm]
    // if anything here throws, we forget to unlock =E2=80=94 yikes!
    std::lock_guard<std::mutex> guard1(mtx1, std::adopt_lock), guard2(mtx2,=
 std::adopt_lock);

What I'd like to see is:

    std::lock_guard<std::mutex> guard(mtx1, mtx2);
    // cannot deadlock and is exception-safe

But what N4470 actually proposes is:

    std::lock_guard<std::mutex, std::mutex> guard(mtx1, mtx2);
    // can still deadlock, because it fails to use [thread.lock.algorithm] =
for the internals

The repetition of "std::mutex, std::mutex" is ugly syntax.
The potential for deadlock is ugly semantics.

I haven't given the question too much thought, but perhaps all that's neede=
d here is a "tuple of locks" concept.
(std::apply borrowed from N3829<http://www.open-std.org/jtc1/sc22/wg21/docs=
/papers/2014/n3829.pdf>.)

template<class... Mutex>
class lock_tuple {
    std::tuple<Mutex&...> mutexes;
  public:
    explicit lock_tuple(Mutex&... mtx) : mutexes(mtx...) {}
    void lock() {
        auto locker =3D [](auto&... mtx) { std::lock(mtx...); };
        std::apply(locker, this->mutexes);
    }
    void unlock() {
        // doesn't really matter in what order we unlock them
        auto unlocker =3D [](auto&... mtx) { auto _ { ((void)mtx.unlock(), =
0)... }; };
        std::apply(unlocker, this->mutexes);
    }
};

template<class... Mutex>
lock_tuple<Mutex...> make_lock_tuple(Mutex&... mtx) {
   return lock_tuple(mtx...);
}

Then what we end up with is

    std::mutex mtx1, mtx2;
    ...
    auto both =3D make_lock_tuple(mtx1, mtx2);
    std::lock_guard<decltype(both)> guard(both);  // exception-safe AND can=
not deadlock

This strikes me as a cleaner syntax AND cleaner semantics, AND can be imple=
mented by adding one new class to the standard library instead of having to=
 replace an existing class.

One reason not to adopt either of these proposals (neither N4470<http://www=
..open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4470.html> nor lock_tuple) i=
s that they're both coming from the POV of, "I use a lot of raw locking pri=
mitives and I run into deadlock a lot, and I want to make deadlock less lik=
ely."  A very valid response would be, "Stop trying to use raw locking prim=
itives, then!"

"C++ makes it harder for you to shoot yourself in the foot, but when you do=
, it blows your whole leg off."<http://programmers.stackexchange.com/questi=
ons/92126/what-did-bjarne-stroustrup-mean-by-his-characterization-of-c-and-=
c>  Any addition to <mutex>, IMHO, has to prove that it's not simply contri=
buting to the problem of C++ programmers blowing off their legs.

my $.02,
=E2=80=93Arthur

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<html xmlns:v=3D"urn:schemas-microsoft-com:vml" xmlns:o=3D"urn:schemas-micr=
osoft-com:office:office" xmlns:w=3D"urn:schemas-microsoft-com:office:word" =
xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" xmlns=3D"http:=
//www.w3.org/TR/REC-html40"><head><meta http-equiv=3DContent-Type content=
=3D"text/html; charset=3Dutf-8"><meta name=3DGenerator content=3D"Microsoft=
 Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
 {font-family:"Cambria Math";
 panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
 {font-family:Calibri;
 panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
 {margin:0in;
 margin-bottom:.0001pt;
 font-size:12.0pt;
 font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
 {mso-style-priority:99;
 color:blue;
 text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
 {mso-style-priority:99;
 color:purple;
 text-decoration:underline;}
code
 {mso-style-priority:99;
 font-family:"Courier New";}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
 {mso-style-priority:34;
 margin-top:0in;
 margin-right:0in;
 margin-bottom:0in;
 margin-left:.5in;
 margin-bottom:.0001pt;
 font-size:12.0pt;
 font-family:"Times New Roman",serif;}
span.styled-by-prettify
 {mso-style-name:styled-by-prettify;}
span.EmailStyle19
 {mso-style-type:personal;
 font-family:"Calibri",sans-serif;
 color:#1F497D;}
span.EmailStyle20
 {mso-style-type:personal-compose;
 font-family:"Calibri",sans-serif;
 color:windowtext;}
..MsoChpDefault
 {mso-style-type:export-only;
 font-family:"Calibri",sans-serif;}
@page WordSection1
 {size:8.5in 11.0in;
 margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
 {page:WordSection1;}
/* List Definitions */
@list l0
 {mso-list-id:1165976073;
 mso-list-type:hybrid;
 mso-list-template-ids:-1723669748 67698703 67698713 67698715 67698703 6769=
8713 67698715 67698703 67698713 67698715;}
@list l0:level1
 {mso-level-tab-stop:none;
 mso-level-number-position:left;
 text-indent:-.25in;}
@list l0:level2
 {mso-level-number-format:alpha-lower;
 mso-level-tab-stop:none;
 mso-level-number-position:left;
 text-indent:-.25in;}
@list l0:level3
 {mso-level-number-format:roman-lower;
 mso-level-tab-stop:none;
 mso-level-number-position:right;
 text-indent:-9.0pt;}
@list l0:level4
 {mso-level-tab-stop:none;
 mso-level-number-position:left;
 text-indent:-.25in;}
@list l0:level5
 {mso-level-number-format:alpha-lower;
 mso-level-tab-stop:none;
 mso-level-number-position:left;
 text-indent:-.25in;}
@list l0:level6
 {mso-level-number-format:roman-lower;
 mso-level-tab-stop:none;
 mso-level-number-position:right;
 text-indent:-9.0pt;}
@list l0:level7
 {mso-level-tab-stop:none;
 mso-level-number-position:left;
 text-indent:-.25in;}
@list l0:level8
 {mso-level-number-format:alpha-lower;
 mso-level-tab-stop:none;
 mso-level-number-position:left;
 text-indent:-.25in;}
@list l0:level9
 {mso-level-number-format:roman-lower;
 mso-level-tab-stop:none;
 mso-level-number-position:right;
 text-indent:-9.0pt;}
ol
 {margin-bottom:0in;}
ul
 {margin-bottom:0in;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext=3D"edit">
<o:idmap v:ext=3D"edit" data=3D"1" />
</o:shapelayout></xml><![endif]--></head><body lang=3DEN-US link=3Dblue vli=
nk=3Dpurple><div class=3DWordSection1><p class=3DMsoNormal><span style=3D'f=
ont-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'>Thanks for =
your comments. =C2=A0Arthur,<o:p></o:p></span></p><p class=3DMsoListParagra=
ph style=3D'text-indent:-.25in;mso-list:l0 level1 lfo1'><![if !supportLists=
]><span style=3D'font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1=
F497D'><span style=3D'mso-list:Ignore'>1.<span style=3D'font:7.0pt "Times N=
ew Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><![end=
if]><span style=3D'font-size:11.0pt;font-family:"Calibri",sans-serif;color:=
#1F497D'>Absolutely, the proposal is meant to be deadlock-free, and I just =
embarrassingly put in the wording wrong. Corrected wording will be on the w=
iki. (I realized this right after submitting, but it was too late=E2=80=A6 =
I did give my students an extra credit problem to find the mistake in the p=
aper).<o:p></o:p></span></p><p class=3DMsoListParagraph style=3D'text-inden=
t:-.25in;mso-list:l0 level1 lfo1'><![if !supportLists]><span style=3D'font-=
size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'><span style=3D'=
mso-list:Ignore'>2.<span style=3D'font:7.0pt "Times New Roman"'>&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><![endif]><span style=3D'fon=
t-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'>I considered =
requiring that all the mutex types be the same as you suggest, but some of =
the most important use cases require different lock types (like Howard=E2=
=80=99s operator=3D example in the paper), and it just seems inaccurate to =
do otherwise.<o:p></o:p></span></p><p class=3DMsoListParagraph style=3D'tex=
t-indent:-.25in;mso-list:l0 level1 lfo1'><![if !supportLists]><span style=
=3D'font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'><span =
style=3D'mso-list:Ignore'>3.<span style=3D'font:7.0pt "Times New Roman"'>&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><![endif]><span sty=
le=3D'font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'>If N=
4471 is adopted, then you don=E2=80=99t need to worry about template argume=
nts.<br>auto guard =3D lock_guard(mtx1, mtx2);<o:p></o:p></span></p><p clas=
s=3DMsoListParagraph style=3D'text-indent:-.25in;mso-list:l0 level1 lfo1'><=
![if !supportLists]><span style=3D'font-size:11.0pt;font-family:"Calibri",s=
ans-serif;color:#1F497D'><span style=3D'mso-list:Ignore'>4.<span style=3D'f=
ont:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></=
span></span><![endif]><span style=3D'font-size:11.0pt;font-family:"Calibri"=
,sans-serif;color:#1F497D'>Even without N4471, since all of the common use =
cases we could think of involve 0, 1, or 2 mutexes (note that 0 locks is us=
eful as well), the notational overhead isn=E2=80=99t excessive.<o:p></o:p><=
/span></p><p class=3DMsoListParagraph style=3D'text-indent:-.25in;mso-list:=
l0 level1 lfo1'><![if !supportLists]><span style=3D'font-size:11.0pt;font-f=
amily:"Calibri",sans-serif;color:#1F497D'><span style=3D'mso-list:Ignore'>5=
..<span style=3D'font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp; </span></span></span><![endif]><span style=3D'font-size:11.0pt;font=
-family:"Calibri",sans-serif;color:#1F497D'>It seems like unique_lock might=
 also want to work with any number of mutexes. In that case, a make_unique_=
lock(=E2=80=A6) would be another way to avoid specifying the template argum=
ents. (Since lock_guard is not movable, you can=E2=80=99t do this with lock=
_guards).<o:p></o:p></span></p><p class=3DMsoListParagraph style=3D'text-in=
dent:-.25in;mso-list:l0 level1 lfo1'><![if !supportLists]><span style=3D'fo=
nt-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'><span style=
=3D'mso-list:Ignore'>6.<span style=3D'font:7.0pt "Times New Roman"'>&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><![endif]><span style=3D=
'font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'>While I s=
ympathize with your desire to avoid raw locking primitives, I think the use=
 cases in the paper are appropriate and of course, explicit locks are commo=
n in practices. C++ in general has the philosophy of offering both low-leve=
l primitives and high-level abstractions. In any case, if we choose to prov=
ide raw locking primitives, I think the relevant question is whether or not=
 they are better if variadic (also see #8 below).<o:p></o:p></span></p><p c=
lass=3DMsoListParagraph style=3D'text-indent:-.25in;mso-list:l0 level1 lfo1=
'><![if !supportLists]><span style=3D'font-size:11.0pt;font-family:"Calibri=
",sans-serif;color:#1F497D'><span style=3D'mso-list:Ignore'>7.<span style=
=3D'font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </sp=
an></span></span><![endif]><span style=3D'font-size:11.0pt;font-family:"Cal=
ibri",sans-serif;color:#1F497D'>In particular, I think the built-in deadloc=
k avoidance (Once the wording embarrassment from #1 above is fixed!) will r=
esult in more reliable programs in practice, if only because many user-defi=
ned types follow the rule of three=E2=80=99s imprecation to provide assignm=
ent operators.<o:p></o:p></span></p><p class=3DMsoListParagraph style=3D'te=
xt-indent:-.25in;mso-list:l0 level1 lfo1'><![if !supportLists]><span style=
=3D'font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'><span =
style=3D'mso-list:Ignore'>8.<span style=3D'font:7.0pt "Times New Roman"'>&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><![endif]><span sty=
le=3D'font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'>I=E2=
=80=99m having trouble seeing any reason we shouldn=E2=80=99t allow lock_gu=
ard to be variadic. The proposal is easy to ignore if you don=E2=80=99t lik=
e it, and IMO doesn=E2=80=99t add conceptual complexity. =E2=80=9Cstd::lock=
_guard can manage a set of locks of diverse types, just like std::lock=E2=
=80=9D. I=E2=80=99ve never heard any of my students or coworkers say that s=
td::lock is more confusing because it was variadic.<o:p></o:p></span></p><p=
 class=3DMsoNormal><span style=3D'font-size:11.0pt;font-family:"Calibri",sa=
ns-serif;color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=3DMsoNormal><s=
pan style=3D'font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497=
D'>What do you think,<o:p></o:p></span></p><p class=3DMsoNormal><span style=
=3D'font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'><o:p>&=
nbsp;</o:p></span></p><p class=3DMsoNormal><span style=3D'font-size:11.0pt;=
font-family:"Calibri",sans-serif;color:#1F497D'>Mike<o:p></o:p></span></p><=
p class=3DMsoNormal><span style=3D'font-size:11.0pt;font-family:"Calibri",s=
ans-serif;color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=3DMsoNormal><=
b><span style=3D'font-size:11.0pt;font-family:"Calibri",sans-serif'>From:</=
span></b><span style=3D'font-size:11.0pt;font-family:"Calibri",sans-serif'>=
 Arthur O'Dwyer [mailto:arthur.j.odwyer@gmail.com] <br><b>Sent:</b> Thursda=
y, April 30, 2015 5:14 AM<br><b>To:</b> std-proposals@isocpp.org<br><b>Cc:<=
/b> Michael Spertus<br><b>Subject:</b> Comments on N4470 &quot;Variadic loc=
k_guard&quot;<o:p></o:p></span></p><p class=3DMsoNormal><o:p>&nbsp;</o:p></=
p><div><div><p class=3DMsoNormal>I was just reading Mike Spertus' N4470 &qu=
ot;Variadic lock_guard&quot;:<o:p></o:p></p></div><p class=3DMsoNormal><a h=
ref=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4470.html">=
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4470.html</a><o:p>=
</o:p></p><div><p class=3DMsoNormal><o:p>&nbsp;</o:p></p></div><div><p clas=
s=3DMsoNormal>My first impression was, &quot;Wow, this is a slam-dunk obvio=
us proposal... of course lock_guard should be able to take multiple argumen=
ts!&quot;<o:p></o:p></p></div><div><p class=3DMsoNormal>But the further I r=
ead, the uglier it seems, both in syntax and in semantics.<o:p></o:p></p></=
div><div><p class=3DMsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=3DMs=
oNormal>The state of the art is:<o:p></o:p></p></div><div><p class=3DMsoNor=
mal><o:p>&nbsp;</o:p></p></div><div style=3D'border:solid #BBBBBB 1.0pt;pad=
ding:0in 0in 0in 0in;word-wrap: break-word'><div><p class=3DMsoNormal style=
=3D'background:#FAFAFA'><span class=3Dstyled-by-prettify><span style=3D'fon=
t-size:10.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp; std</spa=
n></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;f=
ont-family:"Courier New";color:#666600'>::</span></span><span class=3Dstyle=
d-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";col=
or:black'>mutex mtx1</span></span><span class=3Dstyled-by-prettify><span st=
yle=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>,</span></=
span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-=
family:"Courier New";color:black'> mtx2</span></span><span class=3Dstyled-b=
y-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:=
#666600'>;</span></span><span style=3D'font-size:10.0pt;font-family:"Courie=
r New";color:black'><br><span class=3Dstyled-by-prettify>&nbsp; &nbsp; </sp=
an></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;=
font-family:"Courier New";color:#666600'>...</span></span><span style=3D'fo=
nt-size:10.0pt;font-family:"Courier New";color:black'><br><span class=3Dsty=
led-by-prettify>&nbsp; &nbsp; std</span></span><span class=3Dstyled-by-pret=
tify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#66660=
0'>::</span></span><span class=3Dstyled-by-prettify><span style=3D'font-siz=
e:10.0pt;font-family:"Courier New";color:black'>lock_guard</span></span><sp=
an class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"=
Courier New";color:#666600'>&lt;</span></span><span class=3Dstyled-by-prett=
ify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:black'>=
std</span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:=
10.0pt;font-family:"Courier New";color:#666600'>::</span></span><span class=
=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier =
New";color:black'>mutex</span></span><span class=3Dstyled-by-prettify><span=
 style=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>&gt;</s=
pan></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt=
;font-family:"Courier New";color:black'> guard1</span></span><span class=3D=
styled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New=
";color:#666600'>(</span></span><span class=3Dstyled-by-prettify><span styl=
e=3D'font-size:10.0pt;font-family:"Courier New";color:black'>mtx1</span></s=
pan><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-f=
amily:"Courier New";color:#666600'>);</span></span><span style=3D'font-size=
:10.0pt;font-family:"Courier New";color:black'><br><span class=3Dstyled-by-=
prettify>&nbsp; &nbsp; std</span></span><span class=3Dstyled-by-prettify><s=
pan style=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>::</=
span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0p=
t;font-family:"Courier New";color:black'>lock_guard</span></span><span clas=
s=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier=
 New";color:#666600'>&lt;</span></span><span class=3Dstyled-by-prettify><sp=
an style=3D'font-size:10.0pt;font-family:"Courier New";color:black'>std</sp=
an></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;=
font-family:"Courier New";color:#666600'>::</span></span><span class=3Dstyl=
ed-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";co=
lor:black'>mutex</span></span><span class=3Dstyled-by-prettify><span style=
=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>&gt;</span></=
span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-=
family:"Courier New";color:black'> guard2</span></span><span class=3Dstyled=
-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";colo=
r:#666600'>(</span></span><span class=3Dstyled-by-prettify><span style=3D'f=
ont-size:10.0pt;font-family:"Courier New";color:black'>mtx2</span></span><s=
pan class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:=
"Courier New";color:#666600'>);</span></span><span class=3Dstyled-by-pretti=
fy><span style=3D'font-size:10.0pt;font-family:"Courier New";color:black'> =
&nbsp;</span></span><span class=3Dstyled-by-prettify><span style=3D'font-si=
ze:10.0pt;font-family:"Courier New";color:#880000'>// deadlocks if somebody=
 else tries to lock mtx2 and then mtx1</span></span><span style=3D'font-siz=
e:10.0pt;font-family:"Courier New"'><o:p></o:p></span></p></div></div><div>=
<p class=3DMsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=3DMsoNormal>o=
r<o:p></o:p></p></div><div><p class=3DMsoNormal><o:p>&nbsp;</o:p></p></div>=
<div style=3D'border:solid #BBBBBB 1.0pt;padding:0in 0in 0in 0in;word-wrap:=
 break-word'><div><p class=3DMsoNormal style=3D'background:#FAFAFA'><span c=
lass=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Cour=
ier New";color:black'>&nbsp; &nbsp; std</span></span><span class=3Dstyled-b=
y-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:=
#666600'>::</span></span><span class=3Dstyled-by-prettify><span style=3D'fo=
nt-size:10.0pt;font-family:"Courier New";color:#000088'>lock</span></span><=
span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family=
:"Courier New";color:#666600'>(</span></span><span class=3Dstyled-by-pretti=
fy><span style=3D'font-size:10.0pt;font-family:"Courier New";color:black'>m=
tx1</span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:=
10.0pt;font-family:"Courier New";color:#666600'>,</span></span><span class=
=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier =
New";color:black'> mtx2</span></span><span class=3Dstyled-by-prettify><span=
 style=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>);</spa=
n></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;f=
ont-family:"Courier New";color:black'> &nbsp;</span></span><span class=3Dst=
yled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";=
color:#880000'>// cannot deadlock, per [thread.lock.algorithm]</span></span=
><span style=3D'font-size:10.0pt;font-family:"Courier New";color:black'><br=
><span class=3Dstyled-by-prettify>&nbsp; &nbsp; </span></span><span class=
=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier =
New";color:#880000'>// if anything here throws, we forget to unlock =E2=80=
=94 yikes!</span></span><span style=3D'font-size:10.0pt;font-family:"Courie=
r New";color:black'><br><span class=3Dstyled-by-prettify>&nbsp; &nbsp; std<=
/span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0=
pt;font-family:"Courier New";color:#666600'>::</span></span><span class=3Ds=
tyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New"=
;color:black'>lock_guard</span></span><span class=3Dstyled-by-prettify><spa=
n style=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>&lt;</=
span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0p=
t;font-family:"Courier New";color:black'>std</span></span><span class=3Dsty=
led-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";c=
olor:#666600'>::</span></span><span class=3Dstyled-by-prettify><span style=
=3D'font-size:10.0pt;font-family:"Courier New";color:black'>mutex</span></s=
pan><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-f=
amily:"Courier New";color:#666600'>&gt;</span></span><span class=3Dstyled-b=
y-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:=
black'> guard1</span></span><span class=3Dstyled-by-prettify><span style=3D=
'font-size:10.0pt;font-family:"Courier New";color:#666600'>(</span></span><=
span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family=
:"Courier New";color:black'>mtx1</span></span><span class=3Dstyled-by-prett=
ify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#666600=
'>,</span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:=
10.0pt;font-family:"Courier New";color:black'> std</span></span><span class=
=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier =
New";color:#666600'>::</span></span><span class=3Dstyled-by-prettify><span =
style=3D'font-size:10.0pt;font-family:"Courier New";color:black'>adopt_lock=
</span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.=
0pt;font-family:"Courier New";color:#666600'>),</span></span><span class=3D=
styled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New=
";color:black'> guard2</span></span><span class=3Dstyled-by-prettify><span =
style=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>(</span>=
</span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;fon=
t-family:"Courier New";color:black'>mtx2</span></span><span class=3Dstyled-=
by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";color=
:#666600'>,</span></span><span class=3Dstyled-by-prettify><span style=3D'fo=
nt-size:10.0pt;font-family:"Courier New";color:black'> std</span></span><sp=
an class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"=
Courier New";color:#666600'>::</span></span><span class=3Dstyled-by-prettif=
y><span style=3D'font-size:10.0pt;font-family:"Courier New";color:black'>ad=
opt_lock</span></span><span class=3Dstyled-by-prettify><span style=3D'font-=
size:10.0pt;font-family:"Courier New";color:#666600'>);</span></span><span =
style=3D'font-size:10.0pt;font-family:"Courier New"'><o:p></o:p></span></p>=
</div></div><div><p class=3DMsoNormal><o:p>&nbsp;</o:p></p></div><div><p cl=
ass=3DMsoNormal>What I'd like to see is:<o:p></o:p></p></div><div><p class=
=3DMsoNormal><o:p>&nbsp;</o:p></p></div><div style=3D'border:solid #BBBBBB =
1.0pt;padding:0in 0in 0in 0in;word-wrap: break-word'><div><p class=3DMsoNor=
mal style=3D'background:#FAFAFA'><span class=3Dstyled-by-prettify><span sty=
le=3D'font-size:10.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp;=
 std</span></span><span class=3Dstyled-by-prettify><span style=3D'font-size=
:10.0pt;font-family:"Courier New";color:#666600'>::</span></span><span clas=
s=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier=
 New";color:black'>lock_guard</span></span><span class=3Dstyled-by-prettify=
><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>&=
lt;</span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:=
10.0pt;font-family:"Courier New";color:black'>std</span></span><span class=
=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier =
New";color:#666600'>::</span></span><span class=3Dstyled-by-prettify><span =
style=3D'font-size:10.0pt;font-family:"Courier New";color:black'>mutex</spa=
n></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;f=
ont-family:"Courier New";color:#666600'>&gt;</span></span><span class=3Dsty=
led-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";c=
olor:black'> guard</span></span><span class=3Dstyled-by-prettify><span styl=
e=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>(</span></sp=
an><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-fa=
mily:"Courier New";color:black'>mtx1</span></span><span class=3Dstyled-by-p=
rettify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#66=
6600'>,</span></span><span class=3Dstyled-by-prettify><span style=3D'font-s=
ize:10.0pt;font-family:"Courier New";color:black'> mtx2</span></span><span =
class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Cou=
rier New";color:#666600'>);</span></span><span style=3D'font-size:10.0pt;fo=
nt-family:"Courier New";color:black'><br><span class=3Dstyled-by-prettify>&=
nbsp; &nbsp; </span></span><span class=3Dstyled-by-prettify><span style=3D'=
font-size:10.0pt;font-family:"Courier New";color:#880000'>// cannot deadloc=
k and is exception-safe</span></span><span style=3D'font-size:10.0pt;font-f=
amily:"Courier New"'><o:p></o:p></span></p></div></div><div><p class=3DMsoN=
ormal><o:p>&nbsp;</o:p></p></div><div><p class=3DMsoNormal>But what N4470 a=
ctually proposes is:<o:p></o:p></p></div><div><p class=3DMsoNormal><o:p>&nb=
sp;</o:p></p></div><div style=3D'border:solid #BBBBBB 1.0pt;padding:0in 0in=
 0in 0in;word-wrap: break-word'><div><p class=3DMsoNormal style=3D'backgrou=
nd:#FAFAFA'><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0p=
t;font-family:"Courier New";color:black'>&nbsp; &nbsp; std</span></span><sp=
an class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"=
Courier New";color:#666600'>::</span></span><span class=3Dstyled-by-prettif=
y><span style=3D'font-size:10.0pt;font-family:"Courier New";color:black'>lo=
ck_guard</span></span><span class=3Dstyled-by-prettify><span style=3D'font-=
size:10.0pt;font-family:"Courier New";color:#666600'>&lt;</span></span><spa=
n class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"C=
ourier New";color:black'>std</span></span><span class=3Dstyled-by-prettify>=
<span style=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>::=
</span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.=
0pt;font-family:"Courier New";color:black'>mutex</span></span><span class=
=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier =
New";color:#666600'>,</span></span><span class=3Dstyled-by-prettify><span s=
tyle=3D'font-size:10.0pt;font-family:"Courier New";color:black'> std</span>=
</span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;fon=
t-family:"Courier New";color:#666600'>::</span></span><span class=3Dstyled-=
by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";color=
:black'>mutex</span></span><span class=3Dstyled-by-prettify><span style=3D'=
font-size:10.0pt;font-family:"Courier New";color:#666600'>&gt;</span></span=
><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-fami=
ly:"Courier New";color:black'> guard</span></span><span class=3Dstyled-by-p=
rettify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#66=
6600'>(</span></span><span class=3Dstyled-by-prettify><span style=3D'font-s=
ize:10.0pt;font-family:"Courier New";color:black'>mtx1</span></span><span c=
lass=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Cour=
ier New";color:#666600'>,</span></span><span class=3Dstyled-by-prettify><sp=
an style=3D'font-size:10.0pt;font-family:"Courier New";color:black'> mtx2</=
span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0p=
t;font-family:"Courier New";color:#666600'>);</span></span><span style=3D'f=
ont-size:10.0pt;font-family:"Courier New";color:black'><br><span class=3Dst=
yled-by-prettify>&nbsp; &nbsp; </span></span><span class=3Dstyled-by-pretti=
fy><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#880000'=
>// can still deadlock, because it fails to use [thread.lock.algorithm] for=
 the internals</span></span><span style=3D'font-size:10.0pt;font-family:"Co=
urier New"'><o:p></o:p></span></p></div></div><div><p class=3DMsoNormal><o:=
p>&nbsp;</o:p></p></div><div><p class=3DMsoNormal>The repetition of &quot;<=
span style=3D'font-family:"Courier New"'>std::mutex, std::mutex</span>&quot=
; is ugly syntax.<o:p></o:p></p></div><div><p class=3DMsoNormal>The potenti=
al for deadlock is ugly semantics.<o:p></o:p></p></div><div><p class=3DMsoN=
ormal><o:p>&nbsp;</o:p></p></div><div><p class=3DMsoNormal>I haven't given =
the question <i>too</i> much thought, but perhaps all that's needed here is=
 a &quot;tuple of locks&quot; concept.<o:p></o:p></p></div><div><p class=3D=
MsoNormal>(std::apply borrowed from&nbsp;<a href=3D"http://www.open-std.org=
/jtc1/sc22/wg21/docs/papers/2014/n3829.pdf">N3829</a>.)<o:p></o:p></p></div=
><div><p class=3DMsoNormal><o:p>&nbsp;</o:p></p></div><div style=3D'border:=
solid #BBBBBB 1.0pt;padding:0in 0in 0in 0in;word-wrap: break-word'><div><p =
class=3DMsoNormal style=3D'background:#FAFAFA'><span class=3Dstyled-by-pret=
tify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#00008=
8'>template</span></span><span class=3Dstyled-by-prettify><span style=3D'fo=
nt-size:10.0pt;font-family:"Courier New";color:#666600'>&lt;</span></span><=
span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family=
:"Courier New";color:#000088'>class</span></span><span class=3Dstyled-by-pr=
ettify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#666=
600'>...</span></span><span class=3Dstyled-by-prettify><span style=3D'font-=
size:10.0pt;font-family:"Courier New";color:black'> </span></span><span cla=
ss=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courie=
r New";color:#660066'>Mutex</span></span><span class=3Dstyled-by-prettify><=
span style=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>&gt=
;</span></span><span style=3D'font-size:10.0pt;font-family:"Courier New";co=
lor:black'><br></span><span class=3Dstyled-by-prettify><span style=3D'font-=
size:10.0pt;font-family:"Courier New";color:#000088'>class</span></span><sp=
an class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"=
Courier New";color:black'> lock_tuple </span></span><span class=3Dstyled-by=
-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#=
666600'>{</span></span><span style=3D'font-size:10.0pt;font-family:"Courier=
 New";color:black'><br><span class=3Dstyled-by-prettify>&nbsp; &nbsp; std</=
span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0p=
t;font-family:"Courier New";color:#666600'>::</span></span><span class=3Dst=
yled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";=
color:black'>tuple</span></span><span class=3Dstyled-by-prettify><span styl=
e=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>&lt;</span><=
/span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font=
-family:"Courier New";color:#660066'>Mutex</span></span><span class=3Dstyle=
d-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";col=
or:#666600'>&amp;...&gt;</span></span><span class=3Dstyled-by-prettify><spa=
n style=3D'font-size:10.0pt;font-family:"Courier New";color:black'> mutexes=
</span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.=
0pt;font-family:"Courier New";color:#666600'>;</span></span><span style=3D'=
font-size:10.0pt;font-family:"Courier New";color:black'><br><span class=3Ds=
tyled-by-prettify>&nbsp; </span></span><span class=3Dstyled-by-prettify><sp=
an style=3D'font-size:10.0pt;font-family:"Courier New";color:#000088'>publi=
c</span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10=
..0pt;font-family:"Courier New";color:#666600'>:</span></span><span style=3D=
'font-size:10.0pt;font-family:"Courier New";color:black'><br><span class=3D=
styled-by-prettify>&nbsp; &nbsp; </span></span><span class=3Dstyled-by-pret=
tify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#00008=
8'>explicit</span></span><span class=3Dstyled-by-prettify><span style=3D'fo=
nt-size:10.0pt;font-family:"Courier New";color:black'> lock_tuple</span></s=
pan><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-f=
amily:"Courier New";color:#666600'>(</span></span><span class=3Dstyled-by-p=
rettify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#66=
0066'>Mutex</span></span><span class=3Dstyled-by-prettify><span style=3D'fo=
nt-size:10.0pt;font-family:"Courier New";color:#666600'>&amp;...</span></sp=
an><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-fa=
mily:"Courier New";color:black'> mtx</span></span><span class=3Dstyled-by-p=
rettify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#66=
6600'>)</span></span><span class=3Dstyled-by-prettify><span style=3D'font-s=
ize:10.0pt;font-family:"Courier New";color:black'> </span></span><span clas=
s=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier=
 New";color:#666600'>:</span></span><span class=3Dstyled-by-prettify><span =
style=3D'font-size:10.0pt;font-family:"Courier New";color:black'> mutexes</=
span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0p=
t;font-family:"Courier New";color:#666600'>(</span></span><span class=3Dsty=
led-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";c=
olor:black'>mtx</span></span><span class=3Dstyled-by-prettify><span style=
=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>...)</span></=
span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-=
family:"Courier New";color:black'> </span></span><span class=3Dstyled-by-pr=
ettify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#666=
600'>{}</span></span><span style=3D'font-size:10.0pt;font-family:"Courier N=
ew";color:black'><br><span class=3Dstyled-by-prettify>&nbsp; &nbsp; </span>=
</span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;fon=
t-family:"Courier New";color:#000088'>void</span></span><span class=3Dstyle=
d-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";col=
or:black'> </span></span><span class=3Dstyled-by-prettify><span style=3D'fo=
nt-size:10.0pt;font-family:"Courier New";color:#000088'>lock</span></span><=
span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family=
:"Courier New";color:#666600'>()</span></span><span class=3Dstyled-by-prett=
ify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:black'>=
 </span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10=
..0pt;font-family:"Courier New";color:#666600'>{</span></span><span style=3D=
'font-size:10.0pt;font-family:"Courier New";color:black'><br><span class=3D=
styled-by-prettify>&nbsp; &nbsp; &nbsp; &nbsp; </span></span><span class=3D=
styled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New=
";color:#000088'>auto</span></span><span class=3Dstyled-by-prettify><span s=
tyle=3D'font-size:10.0pt;font-family:"Courier New";color:black'> locker </s=
pan></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt=
;font-family:"Courier New";color:#666600'>=3D</span></span><span class=3Dst=
yled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";=
color:black'> </span></span><span class=3Dstyled-by-prettify><span style=3D=
'font-size:10.0pt;font-family:"Courier New";color:#666600'>[](</span></span=
><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-fami=
ly:"Courier New";color:#000088'>auto</span></span><span class=3Dstyled-by-p=
rettify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#66=
6600'>&amp;...</span></span><span class=3Dstyled-by-prettify><span style=3D=
'font-size:10.0pt;font-family:"Courier New";color:black'> mtx</span></span>=
<span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-famil=
y:"Courier New";color:#666600'>)</span></span><span class=3Dstyled-by-prett=
ify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:black'>=
 </span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10=
..0pt;font-family:"Courier New";color:#666600'>{</span></span><span class=3D=
styled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New=
";color:black'> std</span></span><span class=3Dstyled-by-prettify><span sty=
le=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>::</span></=
span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-=
family:"Courier New";color:#000088'>lock</span></span><span class=3Dstyled-=
by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";color=
:#666600'>(</span></span><span class=3Dstyled-by-prettify><span style=3D'fo=
nt-size:10.0pt;font-family:"Courier New";color:black'>mtx</span></span><spa=
n class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"C=
ourier New";color:#666600'>...);</span></span><span class=3Dstyled-by-prett=
ify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:black'>=
 </span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10=
..0pt;font-family:"Courier New";color:#666600'>};</span></span><span style=
=3D'font-size:10.0pt;font-family:"Courier New";color:black'><br><span class=
=3Dstyled-by-prettify>&nbsp; &nbsp; &nbsp; &nbsp; std</span></span><span cl=
ass=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Couri=
er New";color:#666600'>::</span></span><span class=3Dstyled-by-prettify><sp=
an style=3D'font-size:10.0pt;font-family:"Courier New";color:black'>apply</=
span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0p=
t;font-family:"Courier New";color:#666600'>(</span></span><span class=3Dsty=
led-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";c=
olor:black'>locker</span></span><span class=3Dstyled-by-prettify><span styl=
e=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>,</span></sp=
an><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-fa=
mily:"Courier New";color:black'> </span></span><span class=3Dstyled-by-pret=
tify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#00008=
8'>this</span></span><span class=3Dstyled-by-prettify><span style=3D'font-s=
ize:10.0pt;font-family:"Courier New";color:#666600'>-&gt;</span></span><spa=
n class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"C=
ourier New";color:black'>mutexes</span></span><span class=3Dstyled-by-prett=
ify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#666600=
'>);</span></span><span style=3D'font-size:10.0pt;font-family:"Courier New"=
;color:black'><br><span class=3Dstyled-by-prettify>&nbsp; &nbsp; </span></s=
pan><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-f=
amily:"Courier New";color:#666600'>}</span></span><span style=3D'font-size:=
10.0pt;font-family:"Courier New";color:black'><br><span class=3Dstyled-by-p=
rettify>&nbsp; &nbsp; </span></span><span class=3Dstyled-by-prettify><span =
style=3D'font-size:10.0pt;font-family:"Courier New";color:#000088'>void</sp=
an></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;=
font-family:"Courier New";color:black'> unlock</span></span><span class=3Ds=
tyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New"=
;color:#666600'>()</span></span><span class=3Dstyled-by-prettify><span styl=
e=3D'font-size:10.0pt;font-family:"Courier New";color:black'> </span></span=
><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-fami=
ly:"Courier New";color:#666600'>{</span></span><span style=3D'font-size:10.=
0pt;font-family:"Courier New";color:black'><br><span class=3Dstyled-by-pret=
tify>&nbsp; &nbsp; &nbsp; &nbsp; </span></span><span class=3Dstyled-by-pret=
tify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#88000=
0'>// doesn't really matter in what order we unlock them</span></span><span=
 style=3D'font-size:10.0pt;font-family:"Courier New";color:black'><br><span=
 class=3Dstyled-by-prettify>&nbsp; &nbsp; &nbsp; &nbsp; </span></span><span=
 class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Co=
urier New";color:#000088'>auto</span></span><span class=3Dstyled-by-prettif=
y><span style=3D'font-size:10.0pt;font-family:"Courier New";color:black'> u=
nlocker </span></span><span class=3Dstyled-by-prettify><span style=3D'font-=
size:10.0pt;font-family:"Courier New";color:#666600'>=3D</span></span><span=
 class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Co=
urier New";color:black'> </span></span><span class=3Dstyled-by-prettify><sp=
an style=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>[](</=
span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0p=
t;font-family:"Courier New";color:#000088'>auto</span></span><span class=3D=
styled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New=
";color:#666600'>&amp;...</span></span><span class=3Dstyled-by-prettify><sp=
an style=3D'font-size:10.0pt;font-family:"Courier New";color:black'> mtx</s=
pan></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt=
;font-family:"Courier New";color:#666600'>)</span></span><span class=3Dstyl=
ed-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";co=
lor:black'> </span></span><span class=3Dstyled-by-prettify><span style=3D'f=
ont-size:10.0pt;font-family:"Courier New";color:#666600'>{</span></span><sp=
an class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"=
Courier New";color:black'> </span></span><span class=3Dstyled-by-prettify><=
span style=3D'font-size:10.0pt;font-family:"Courier New";color:#000088'>aut=
o</span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10=
..0pt;font-family:"Courier New";color:black'> _ </span></span><span class=3D=
styled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New=
";color:#666600'>{</span></span><span class=3Dstyled-by-prettify><span styl=
e=3D'font-size:10.0pt;font-family:"Courier New";color:black'> </span></span=
><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-fami=
ly:"Courier New";color:#666600'>((</span></span><span class=3Dstyled-by-pre=
ttify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#0000=
88'>void</span></span><span class=3Dstyled-by-prettify><span style=3D'font-=
size:10.0pt;font-family:"Courier New";color:#666600'>)</span></span><span c=
lass=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Cour=
ier New";color:black'>mtx</span></span><span class=3Dstyled-by-prettify><sp=
an style=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>.</sp=
an></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;=
font-family:"Courier New";color:black'>unlock</span></span><span class=3Dst=
yled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";=
color:#666600'>(),</span></span><span class=3Dstyled-by-prettify><span styl=
e=3D'font-size:10.0pt;font-family:"Courier New";color:black'> </span></span=
><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-fami=
ly:"Courier New";color:#006666'>0</span></span><span class=3Dstyled-by-pret=
tify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#66660=
0'>)...</span></span><span class=3Dstyled-by-prettify><span style=3D'font-s=
ize:10.0pt;font-family:"Courier New";color:black'> </span></span><span clas=
s=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier=
 New";color:#666600'>};</span></span><span class=3Dstyled-by-prettify><span=
 style=3D'font-size:10.0pt;font-family:"Courier New";color:black'> </span><=
/span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font=
-family:"Courier New";color:#666600'>};</span></span><span style=3D'font-si=
ze:10.0pt;font-family:"Courier New";color:black'><br><span class=3Dstyled-b=
y-prettify>&nbsp; &nbsp; &nbsp; &nbsp; std</span></span><span class=3Dstyle=
d-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";col=
or:#666600'>::</span></span><span class=3Dstyled-by-prettify><span style=3D=
'font-size:10.0pt;font-family:"Courier New";color:black'>apply</span></span=
><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-fami=
ly:"Courier New";color:#666600'>(</span></span><span class=3Dstyled-by-pret=
tify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:black'=
>unlocker</span></span><span class=3Dstyled-by-prettify><span style=3D'font=
-size:10.0pt;font-family:"Courier New";color:#666600'>,</span></span><span =
class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Cou=
rier New";color:black'> </span></span><span class=3Dstyled-by-prettify><spa=
n style=3D'font-size:10.0pt;font-family:"Courier New";color:#000088'>this</=
span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0p=
t;font-family:"Courier New";color:#666600'>-&gt;</span></span><span class=
=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier =
New";color:black'>mutexes</span></span><span class=3Dstyled-by-prettify><sp=
an style=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>);</s=
pan></span><span style=3D'font-size:10.0pt;font-family:"Courier New";color:=
black'><br><span class=3Dstyled-by-prettify>&nbsp; &nbsp; </span></span><sp=
an class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"=
Courier New";color:#666600'>}</span></span><span style=3D'font-size:10.0pt;=
font-family:"Courier New";color:black'><br></span><span class=3Dstyled-by-p=
rettify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#66=
6600'>};</span></span><span style=3D'font-size:10.0pt;font-family:"Courier =
New";color:black'><br><br></span><span class=3Dstyled-by-prettify><span sty=
le=3D'font-size:10.0pt;font-family:"Courier New";color:#000088'>template</s=
pan></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt=
;font-family:"Courier New";color:#666600'>&lt;</span></span><span class=3Ds=
tyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New"=
;color:#000088'>class</span></span><span class=3Dstyled-by-prettify><span s=
tyle=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>...</span=
></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;fo=
nt-family:"Courier New";color:black'> </span></span><span class=3Dstyled-by=
-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#=
660066'>Mutex</span></span><span class=3Dstyled-by-prettify><span style=3D'=
font-size:10.0pt;font-family:"Courier New";color:#666600'>&gt;</span></span=
><span style=3D'font-size:10.0pt;font-family:"Courier New";color:black'><br=
><span class=3Dstyled-by-prettify>lock_tuple</span></span><span class=3Dsty=
led-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";c=
olor:#666600'>&lt;</span></span><span class=3Dstyled-by-prettify><span styl=
e=3D'font-size:10.0pt;font-family:"Courier New";color:#660066'>Mutex</span>=
</span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;fon=
t-family:"Courier New";color:#666600'>...&gt;</span></span><span class=3Dst=
yled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";=
color:black'> make_lock_tuple</span></span><span class=3Dstyled-by-prettify=
><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>(=
</span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.=
0pt;font-family:"Courier New";color:#660066'>Mutex</span></span><span class=
=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier =
New";color:#666600'>&amp;...</span></span><span class=3Dstyled-by-prettify>=
<span style=3D'font-size:10.0pt;font-family:"Courier New";color:black'> mtx=
</span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.=
0pt;font-family:"Courier New";color:#666600'>)</span></span><span class=3Ds=
tyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New"=
;color:black'> </span></span><span class=3Dstyled-by-prettify><span style=
=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>{</span></spa=
n><span style=3D'font-size:10.0pt;font-family:"Courier New";color:black'><b=
r><span class=3Dstyled-by-prettify>&nbsp; &nbsp;</span></span><span class=
=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier =
New";color:#000088'>return</span></span><span class=3Dstyled-by-prettify><s=
pan style=3D'font-size:10.0pt;font-family:"Courier New";color:black'> lock_=
tuple</span></span><span class=3Dstyled-by-prettify><span style=3D'font-siz=
e:10.0pt;font-family:"Courier New";color:#666600'>(</span></span><span clas=
s=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier=
 New";color:black'>mtx</span></span><span class=3Dstyled-by-prettify><span =
style=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>...);</s=
pan></span><span style=3D'font-size:10.0pt;font-family:"Courier New";color:=
black'><br></span><span class=3Dstyled-by-prettify><span style=3D'font-size=
:10.0pt;font-family:"Courier New";color:#666600'>}</span></span><span style=
=3D'font-size:10.0pt;font-family:"Courier New"'><o:p></o:p></span></p></div=
></div><div><p class=3DMsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=
=3DMsoNormal>Then what we end up with is<o:p></o:p></p></div><div><p class=
=3DMsoNormal><o:p>&nbsp;</o:p></p></div><div style=3D'border:solid #BBBBBB =
1.0pt;padding:0in 0in 0in 0in;word-wrap: break-word'><div><p class=3DMsoNor=
mal style=3D'background:#FAFAFA'><span class=3Dstyled-by-prettify><span sty=
le=3D'font-size:10.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp;=
 std</span></span><span class=3Dstyled-by-prettify><span style=3D'font-size=
:10.0pt;font-family:"Courier New";color:#666600'>::</span></span><span clas=
s=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier=
 New";color:black'>mutex mtx1</span></span><span class=3Dstyled-by-prettify=
><span style=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>,=
</span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.=
0pt;font-family:"Courier New";color:black'> mtx2</span></span><span class=
=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier =
New";color:#666600'>;</span></span><span style=3D'font-size:10.0pt;font-fam=
ily:"Courier New";color:black'><br><span class=3Dstyled-by-prettify>&nbsp; =
&nbsp; </span></span><span class=3Dstyled-by-prettify><span style=3D'font-s=
ize:10.0pt;font-family:"Courier New";color:#666600'>...</span></span><span =
style=3D'font-size:10.0pt;font-family:"Courier New";color:black'><br><span =
class=3Dstyled-by-prettify>&nbsp; &nbsp; </span></span><span class=3Dstyled=
-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";colo=
r:#000088'>auto</span></span><span class=3Dstyled-by-prettify><span style=
=3D'font-size:10.0pt;font-family:"Courier New";color:black'> both </span></=
span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-=
family:"Courier New";color:#666600'>=3D</span></span><span class=3Dstyled-b=
y-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";color:=
black'> make_lock_tuple</span></span><span class=3Dstyled-by-prettify><span=
 style=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>(</span=
></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;fo=
nt-family:"Courier New";color:black'>mtx1</span></span><span class=3Dstyled=
-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";colo=
r:#666600'>,</span></span><span class=3Dstyled-by-prettify><span style=3D'f=
ont-size:10.0pt;font-family:"Courier New";color:black'> mtx2</span></span><=
span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family=
:"Courier New";color:#666600'>);</span></span><span style=3D'font-size:10.0=
pt;font-family:"Courier New";color:black'><br><span class=3Dstyled-by-prett=
ify>&nbsp; &nbsp; std</span></span><span class=3Dstyled-by-prettify><span s=
tyle=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>::</span>=
</span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;fon=
t-family:"Courier New";color:black'>lock_guard</span></span><span class=3Ds=
tyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New"=
;color:#666600'>&lt;</span></span><span class=3Dstyled-by-prettify><span st=
yle=3D'font-size:10.0pt;font-family:"Courier New";color:#000088'>decltype</=
span></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0p=
t;font-family:"Courier New";color:#666600'>(</span></span><span class=3Dsty=
led-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";c=
olor:black'>both</span></span><span class=3Dstyled-by-prettify><span style=
=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>)&gt;</span><=
/span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font=
-family:"Courier New";color:black'> guard</span></span><span class=3Dstyled=
-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";colo=
r:#666600'>(</span></span><span class=3Dstyled-by-prettify><span style=3D'f=
ont-size:10.0pt;font-family:"Courier New";color:black'>both</span></span><s=
pan class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:=
"Courier New";color:#666600'>);</span></span><span class=3Dstyled-by-pretti=
fy><span style=3D'font-size:10.0pt;font-family:"Courier New";color:black'> =
&nbsp;</span></span><span class=3Dstyled-by-prettify><span style=3D'font-si=
ze:10.0pt;font-family:"Courier New";color:#880000'>// exception-safe AND ca=
nnot deadlock</span></span><span style=3D'font-size:10.0pt;font-family:"Cou=
rier New"'><o:p></o:p></span></p></div></div><div><p class=3DMsoNormal><spa=
n style=3D'font-family:"Courier New";color:black'><br></span>This strikes m=
e as a cleaner syntax AND cleaner semantics, AND can be implemented by addi=
ng one new class to the standard library instead of having to replace an ex=
isting class.<o:p></o:p></p></div><div><p class=3DMsoNormal><o:p>&nbsp;</o:=
p></p></div><div><p class=3DMsoNormal>One reason not to adopt either of the=
se proposals (neither <a href=3D"http://www.open-std.org/jtc1/sc22/wg21/doc=
s/papers/2015/n4470.html">N4470</a> nor <span style=3D'font-family:"Courier=
 New"'>lock_tuple</span>) is that they're both coming from the POV of, &quo=
t;I use a lot of raw locking primitives and I run into deadlock a lot, and =
I want to make deadlock less likely.&quot; &nbsp;A very valid response woul=
d be, &quot;Stop trying to use raw locking primitives, then!&quot;<o:p></o:=
p></p></div><div><p class=3DMsoNormal><o:p>&nbsp;</o:p></p></div><div><p cl=
ass=3DMsoNormal><a href=3D"http://programmers.stackexchange.com/questions/9=
2126/what-did-bjarne-stroustrup-mean-by-his-characterization-of-c-and-c">&q=
uot;C++ makes it harder for you to shoot yourself in the foot, but when you=
 do, it blows your whole leg off.&quot;</a> &nbsp;Any addition to <span sty=
le=3D'font-family:"Courier New"'>&lt;mutex&gt;</span>, IMHO, has to prove t=
hat it's not simply contributing to the problem of C++ programmers blowing =
off their legs.<o:p></o:p></p></div><div><p class=3DMsoNormal><o:p>&nbsp;</=
o:p></p></div><div><p class=3DMsoNormal>my $.02,<o:p></o:p></p></div><div><=
p class=3DMsoNormal>=E2=80=93Arthur<o:p></o:p></p></div></div></div></body>=
</html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--_000_9A3E0561DCF227429F72080EA81ADBC95084453ECATUS1XCHEVSPIN_--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Thu, 30 Apr 2015 16:54:38 +0200
Raw View
This is a multi-part message in MIME format.
--------------020900090504040809090600
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 30/04/15 15:44, Michael Spertus a =C3=A9crit :
>
> Thanks for your comments.  Arthur,
>
> 1.Absolutely, the proposal is meant to be deadlock-free, and I just=20
> embarrassingly put in the wording wrong. Corrected wording will be on=20
> the wiki. (I realized this right after submitting, but it was too=20
> late=E2=80=A6 I did give my students an extra credit problem to find the=
=20
> mistake in the paper).
>
> 2.I considered requiring that all the mutex types be the same as you=20
> suggest, but some of the most important use cases require different=20
> lock types (like Howard=E2=80=99s operator=3D example in the paper), and =
it just=20
> seems inaccurate to do otherwise.
>
Agreed. This should work with any Lockable.
>
> 3.If N4471 is adopted, then you don=E2=80=99t need to worry about templat=
e=20
> arguments.
> auto guard =3D lock_guard(mtx1, mtx2);
>
Wouldn't this syntax request at least that lock_guard be Movable?

I have a make_lock_guard in Boost.Thread that returns a lock_guard. It=20
is NOT A CORRECT implementation as I think it needs RVO.

The usage is as

     auto&& lg =3D boost::make_lock_guard(m);

The implementation is

   template <typename Lockable>
   lock_guard<Lockable> make_lock_guard(Lockable& mtx)
   {
     return { thread_detail::lockable_wrapper<Lockable>(mtx) };
   }


The implicit constructor from this internal type=20
thread_detail::lockable_wrapper<Lockable> is private and the=20
make_lock_guard is a friend function of lock_guard class.

> 4.Even without N4471, since all of the common use cases we could think=20
> of involve 0, 1, or 2 mutexes (note that 0 locks is useful as well),=20
> the notational overhead isn=E2=80=99t excessive.
>
I would like to be able to write thing like

     synchronize(m) {
         // ....
     };

But, this would need to have some kind of templates having statements as=20
parameters ;-)

The closer we can do now is using lambdas

     synchronize(m, []() {
         // ....
     });

but has a some limitations.
>
> 5.It seems like unique_lock might also want to work with any number of=20
> mutexes. In that case, a make_unique_lock(=E2=80=A6) would be another way=
 to=20
> avoid specifying the template arguments. (Since lock_guard is not=20
> movable, you can=E2=80=99t do this with lock_guards).
>
Yes,  unique_lock hasn't the Movable issue and so there is no need for=20
the wrapper trick.

     auto lks =3D boost::make_unique_locks(m1,m2,m3);

Vicente

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<html>
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">Le 30/04/15 15:44, Michael Spertus a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
cite=3D"mid:9A3E0561DCF227429F72080EA81ADBC95084453ECA@TUS1XCHEVSPIN42.SYMC=
..SYMANTEC.COM"
      type=3D"cite">
      <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf=
-8">
      <meta name=3D"Generator" content=3D"Microsoft Word 15 (filtered
        medium)">
      <style><!--
/* Font Definitions */
@font-face
 {font-family:"Cambria Math";
 panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
 {font-family:Calibri;
 panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
 {margin:0in;
 margin-bottom:.0001pt;
 font-size:12.0pt;
 font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
 {mso-style-priority:99;
 color:blue;
 text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
 {mso-style-priority:99;
 color:purple;
 text-decoration:underline;}
code
 {mso-style-priority:99;
 font-family:"Courier New";}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
 {mso-style-priority:34;
 margin-top:0in;
 margin-right:0in;
 margin-bottom:0in;
 margin-left:.5in;
 margin-bottom:.0001pt;
 font-size:12.0pt;
 font-family:"Times New Roman",serif;}
span.styled-by-prettify
 {mso-style-name:styled-by-prettify;}
span.EmailStyle19
 {mso-style-type:personal;
 font-family:"Calibri",sans-serif;
 color:#1F497D;}
span.EmailStyle20
 {mso-style-type:personal-compose;
 font-family:"Calibri",sans-serif;
 color:windowtext;}
..MsoChpDefault
 {mso-style-type:export-only;
 font-family:"Calibri",sans-serif;}
@page WordSection1
 {size:8.5in 11.0in;
 margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
 {page:WordSection1;}
/* List Definitions */
@list l0
 {mso-list-id:1165976073;
 mso-list-type:hybrid;
 mso-list-template-ids:-1723669748 67698703 67698713 67698715 67698703 6769=
8713 67698715 67698703 67698713 67698715;}
@list l0:level1
 {mso-level-tab-stop:none;
 mso-level-number-position:left;
 text-indent:-.25in;}
@list l0:level2
 {mso-level-number-format:alpha-lower;
 mso-level-tab-stop:none;
 mso-level-number-position:left;
 text-indent:-.25in;}
@list l0:level3
 {mso-level-number-format:roman-lower;
 mso-level-tab-stop:none;
 mso-level-number-position:right;
 text-indent:-9.0pt;}
@list l0:level4
 {mso-level-tab-stop:none;
 mso-level-number-position:left;
 text-indent:-.25in;}
@list l0:level5
 {mso-level-number-format:alpha-lower;
 mso-level-tab-stop:none;
 mso-level-number-position:left;
 text-indent:-.25in;}
@list l0:level6
 {mso-level-number-format:roman-lower;
 mso-level-tab-stop:none;
 mso-level-number-position:right;
 text-indent:-9.0pt;}
@list l0:level7
 {mso-level-tab-stop:none;
 mso-level-number-position:left;
 text-indent:-.25in;}
@list l0:level8
 {mso-level-number-format:alpha-lower;
 mso-level-tab-stop:none;
 mso-level-number-position:left;
 text-indent:-.25in;}
@list l0:level9
 {mso-level-number-format:roman-lower;
 mso-level-tab-stop:none;
 mso-level-number-position:right;
 text-indent:-9.0pt;}
ol
 {margin-bottom:0in;}
ul
 {margin-bottom:0in;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext=3D"edit">
<o:idmap v:ext=3D"edit" data=3D"1" />
</o:shapelayout></xml><![endif]-->
      <div class=3D"WordSection1">
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:=
#1F497D">Thanks
            for your comments. =C2=A0Arthur,<o:p></o:p></span></p>
        <p class=3D"MsoListParagraph"
          style=3D"text-indent:-.25in;mso-list:l0 level1 lfo1"><!--[if !sup=
portLists]--><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:=
#1F497D"><span
              style=3D"mso-list:Ignore">1.<span style=3D"font:7.0pt
                &quot;Times New Roman&quot;">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 </span></span></span><!--[endif]--><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:=
#1F497D">Absolutely,
            the proposal is meant to be deadlock-free, and I just
            embarrassingly put in the wording wrong. Corrected wording
            will be on the wiki. (I realized this right after
            submitting, but it was too late=E2=80=A6 I did give my students=
 an
            extra credit problem to find the mistake in the paper).<o:p></o=
:p></span></p>
        <p class=3D"MsoListParagraph"
          style=3D"text-indent:-.25in;mso-list:l0 level1 lfo1"><!--[if !sup=
portLists]--><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:=
#1F497D"><span
              style=3D"mso-list:Ignore">2.<span style=3D"font:7.0pt
                &quot;Times New Roman&quot;">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 </span></span></span><!--[endif]--><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:=
#1F497D">I
            considered requiring that all the mutex types be the same as
            you suggest, but some of the most important use cases
            require different lock types (like Howard=E2=80=99s operator=3D
            example in the paper), and it just seems inaccurate to do
            otherwise.</span></p>
      </div>
    </blockquote>
    Agreed. This should work with any Lockable.<br>
    <blockquote
cite=3D"mid:9A3E0561DCF227429F72080EA81ADBC95084453ECA@TUS1XCHEVSPIN42.SYMC=
..SYMANTEC.COM"
      type=3D"cite">
      <div class=3D"WordSection1">
        <p class=3D"MsoListParagraph"
          style=3D"text-indent:-.25in;mso-list:l0 level1 lfo1"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:=
#1F497D"><o:p></o:p></span></p>
        <p class=3D"MsoListParagraph"
          style=3D"text-indent:-.25in;mso-list:l0 level1 lfo1"><!--[if !sup=
portLists]--><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:=
#1F497D"><span
              style=3D"mso-list:Ignore">3.<span style=3D"font:7.0pt
                &quot;Times New Roman&quot;">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 </span></span></span><!--[endif]--><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:=
#1F497D">If
            N4471 is adopted, then you don=E2=80=99t need to worry about
            template arguments.<br>
            auto guard =3D lock_guard(mtx1, mtx2);</span></p>
      </div>
    </blockquote>
    Wouldn't this syntax request at least that lock_guard be Movable?<br>
    <br>
    I have a make_lock_guard in Boost.Thread that returns a lock_guard.
    It is NOT A CORRECT implementation as I think it needs RVO.<br>
    <br>
    The usage is as<br>
    <br>
    =C2=A0=C2=A0=C2=A0 auto&amp;&amp; lg =3D boost::make_lock_guard(m);<br>
    <br>
    The implementation is<br>
    <br>
    =C2=A0 template &lt;typename Lockable&gt;<br>
    =C2=A0 lock_guard&lt;Lockable&gt; make_lock_guard(Lockable&amp; mtx)<br=
>
    =C2=A0 {<br>
    =C2=A0=C2=A0=C2=A0 return { thread_detail::lockable_wrapper&lt;Lockable=
&gt;(mtx) };<br>
    =C2=A0 }<br>
    <br>
    <br>
    The implicit constructor from this internal type
    thread_detail::lockable_wrapper&lt;Lockable&gt; is private and the
    make_lock_guard is a friend function of lock_guard class.<br>
    <br>
    <blockquote
cite=3D"mid:9A3E0561DCF227429F72080EA81ADBC95084453ECA@TUS1XCHEVSPIN42.SYMC=
..SYMANTEC.COM"
      type=3D"cite">
      <div class=3D"WordSection1">
        <p class=3D"MsoListParagraph"
          style=3D"text-indent:-.25in;mso-list:l0 level1 lfo1"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:=
#1F497D"><o:p></o:p></span></p>
        <p class=3D"MsoListParagraph"
          style=3D"text-indent:-.25in;mso-list:l0 level1 lfo1"><!--[if !sup=
portLists]--><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:=
#1F497D"><span
              style=3D"mso-list:Ignore">4.<span style=3D"font:7.0pt
                &quot;Times New Roman&quot;">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 </span></span></span><!--[endif]--><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:=
#1F497D">Even
            without N4471, since all of the common use cases we could
            think of involve 0, 1, or 2 mutexes (note that 0 locks is
            useful as well), the notational overhead isn=E2=80=99t excessiv=
e.</span></p>
      </div>
    </blockquote>
    I would like to be able to write thing like<br>
    <br>
    =C2=A0=C2=A0=C2=A0 synchronize(m) {<br>
    =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 // ....<br>
    =C2=A0=C2=A0=C2=A0 };<br>
    <br>
    But, this would need to have some kind of templates having
    statements as parameters ;-)<br>
    <br>
    The closer we can do now is using lambdas<br>
    <br>
    =C2=A0=C2=A0=C2=A0 synchronize(m, []() {<br>
    =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 // ....<br>
    =C2=A0=C2=A0=C2=A0 });<br>
    <br>
    but has a some limitations.<br>
    <span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:=
#1F497D"><o:p></o:p></span>
    <blockquote
cite=3D"mid:9A3E0561DCF227429F72080EA81ADBC95084453ECA@TUS1XCHEVSPIN42.SYMC=
..SYMANTEC.COM"
      type=3D"cite">
      <div class=3D"WordSection1">
        <p class=3D"MsoListParagraph"
          style=3D"text-indent:-.25in;mso-list:l0 level1 lfo1"><!--[if !sup=
portLists]--><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:=
#1F497D"><span
              style=3D"mso-list:Ignore">5.<span style=3D"font:7.0pt
                &quot;Times New Roman&quot;">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 </span></span></span><!--[endif]--><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:=
#1F497D">It
            seems like unique_lock might also want to work with any
            number of mutexes. In that case, a make_unique_lock(=E2=80=A6) =
would
            be another way to avoid specifying the template arguments.
            (Since lock_guard is not movable, you can=E2=80=99t do this wit=
h
            lock_guards).</span></p>
      </div>
    </blockquote>
    Yes,=C2=A0 unique_lock hasn't the Movable issue and so there is no need
    for the wrapper trick.<br>
    <br>
    =C2=A0=C2=A0=C2=A0 auto lks =3D boost::make_unique_locks(m1,m2,m3);<br>
    <br>
    Vicente<br>
  </body>
</html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--------------020900090504040809090600--

.


Author: Edward Catmur <ed@catmur.co.uk>
Date: Thu, 30 Apr 2015 08:21:25 -0700 (PDT)
Raw View
------=_Part_5971_1588851785.1430407286004
Content-Type: multipart/alternative;
 boundary="----=_Part_5972_2020283697.1430407286004"

------=_Part_5972_2020283697.1430407286004
Content-Type: text/plain; charset=UTF-8

On Thursday, 30 April 2015 15:54:40 UTC+1, Vicente J. Botet Escriba wrote:
>
>  I have a make_lock_guard in Boost.Thread that returns a lock_guard. It
> is NOT A CORRECT implementation as I think it needs RVO.
>
> The usage is as
>
>     auto&& lg = boost::make_lock_guard(m);
>
> The implementation is
>
>   template <typename Lockable>
>   lock_guard<Lockable> make_lock_guard(Lockable& mtx)
>   {
>     return { thread_detail::lockable_wrapper<Lockable>(mtx) };
>   }
>

Return by braced-init-list doesn't require RVO; the returned object is
copy-list-initialized directly ([stmt.return]/2). But you're correct that
auto&& is required; AFAICT N4471 would also require auto&&.

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

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

<div dir=3D"ltr">On Thursday, 30 April 2015 15:54:40 UTC+1, Vicente J. Bote=
t Escriba  wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div>I have a make_lock_guard in Boost.Thread that returns a lock_guard=
..
    It is NOT A CORRECT implementation as I think it needs RVO.<br></div>
    <br>
    The usage is as<br>
    <br>
    &nbsp;&nbsp;&nbsp; auto&amp;&amp; lg =3D boost::make_lock_guard(m);<br>
    <br>
    The implementation is<br>
    <br>
    &nbsp; template &lt;typename Lockable&gt;<br>
    &nbsp; lock_guard&lt;Lockable&gt; make_lock_guard(Lockable&amp; mtx)<br=
>
    &nbsp; {<br>
    &nbsp;&nbsp;&nbsp; return { thread_detail::lockable_<wbr>wrapper&lt;Loc=
kable&gt;(mtx) };<br>
    &nbsp; }<br></div></blockquote><div><br></div><div>Return by braced-ini=
t-list doesn't require RVO; the returned object is copy-list-initialized di=
rectly ([stmt.return]/2). But you're correct that auto&amp;&amp; is require=
d; AFAICT N4471 would also require auto&amp;&amp;.</div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_5972_2020283697.1430407286004--
------=_Part_5971_1588851785.1430407286004--

.


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Thu, 30 Apr 2015 13:55:05 -0700 (PDT)
Raw View
------=_Part_172_1778772745.1430427305083
Content-Type: multipart/alternative;
 boundary="----=_Part_173_713675328.1430427305083"

------=_Part_173_713675328.1430427305083
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Thursday, April 30, 2015 at 6:44:50 AM UTC-7, Michael Spertus wrote:
>
> Thanks for your comments.  Arthur,
>
> 1.       Absolutely, the proposal is meant to be deadlock-free, and I=20
> just embarrassingly put in the wording wrong. Corrected wording will be o=
n=20
> the wiki. (I realized this right after submitting, but it was too late=E2=
=80=A6 I=20
> did give my students an extra credit problem to find the mistake in the=
=20
> paper).
>
Aha. This definitely removes 70% of my objection to the proposal. :)

=20

> 2.       I considered requiring that all the mutex types be the same as=
=20
> you suggest, but some of the most important use cases require different=
=20
> lock types (like Howard=E2=80=99s operator=3D example in the paper), and =
it just=20
> seems inaccurate to do otherwise.
>
I wasn't necessarily suggesting that all the Mutexes... should *have* to be=
=20
the same; I was just pointing out that in the most common case, where they=
=20
*are* the same, it's ugly to force the user to write the same type many=20
times in a row.  I deliberately didn't go down the rabbit hole of how to=20
implement the prettier syntax, because I figured I had a strictly better=20
idea with lock_tuple =E2=80=94 but you can certainly use SFINAE to allow=20
lock_guard<M>'s constructor to take any number of arguments as long as all=
=20
of them are of type M, or you could have lock_guard do type erasure so that=
=20
the type inside the angle brackets no longer particularly matters... Those=
=20
both have obvious hurdles (where do you keep the extra arguments? type=20
erasure requires heap allocation) but that's the general direction in which=
=20
the rabbit hole would take us.


=20

> 3.       If N4471 is adopted, then you don=E2=80=99t need to worry about =
template=20
> arguments.
> auto guard =3D lock_guard(mtx1, mtx2);
>
N4471 (type deduction for constructors) is astronomically unlikely to get=
=20
accepted IMHO, due to the "Challenges" identified in the proposal and the=
=20
lack of implementations or proposed wording.
Without N4471, we could propose making lock_guard move-constructible (which=
 *I=20
think* is fine in practice because a lock_guard is just a bundle of=20
references, right?), and then we'd have this syntax:

    auto guard =3D make_lock_guard(mtx1, mtx2);

=20

> 4.       Even without N4471, since all of the common use cases we could=
=20
> think of involve 0, 1, or 2 mutexes (note that 0 locks is useful as well)=
,=20
> the notational overhead isn=E2=80=99t excessive.
>
IMHO the notational overhead for 2 mutexes *is* excessive =E2=80=94 that's =
what I=20
meant by "ugly syntax". But this is a minor point, and could be solved by=
=20
make_lock_guard above.


5.       It seems like unique_lock might also want to work with any number=
=20
> of mutexes. In that case, a make_unique_lock(=E2=80=A6) would be another =
way to=20
> avoid specifying the template arguments. (Since lock_guard is not movable=
,=20
> you can=E2=80=99t do this with lock_guards).
>
Your proposal doesn't actually specify a variadic unique_lock, though, does=
=20
it?  If the concepts are coupled, maybe they should be proposed together.

=20

> 6.       While I sympathize with your desire to avoid raw locking=20
> primitives, I think the use cases in the paper are appropriate and of=20
> course, explicit locks are common in practices. C++ in general has the=20
> philosophy of offering both low-level primitives and high-level=20
> abstractions. In any case, if we choose to provide raw locking primitives=
,=20
> I think the relevant question is whether or not they are better if variad=
ic=20
> (also see #8 below).
>
> 7.       In particular, I think the built-in deadlock avoidance (Once the=
=20
> wording embarrassment from #1 above is fixed!) will result in more reliab=
le=20
> programs in practice, if only because many user-defined types follow the=
=20
> rule of three=E2=80=99s imprecation to provide assignment operators.
>
Can you elaborate on what you mean by "if only because ... assignment=20
operators"?  I don't see how assignment operators and the Rule of Three are=
=20
related to the lock_guard proposal at all...?
=20

> 8.       I=E2=80=99m having trouble seeing any reason we shouldn=E2=80=99=
t allow=20
> lock_guard to be variadic. The proposal is easy to ignore if you don=E2=
=80=99t like=20
> it, and IMO doesn=E2=80=99t add conceptual complexity. =E2=80=9Cstd::lock=
_guard can manage=20
> a set of locks of diverse types, just like std::lock=E2=80=9D. I=E2=80=99=
ve never heard any=20
> of my students or coworkers say that std::lock is more confusing because =
it=20
> was variadic.
>
std::lock is confusing because it's underspecified. ;)  This is way=20
off-topic, but I wonder how many people trust std::lock in practice, and=20
how many simply roll their own lock-ordering scheme and/or exponential=20
backoff scheme and/or whatever other schemes are popular for avoiding=20
deadlock. I don't do synchronization stuff myself, but I wonder whether=20
people who do, actually trust their standard library's std::lock to avoid=
=20
livelock. And when they move to a different platform, do they see the same=
=20
performance characteristics?

The value of std::lock_guard is that it's super simple, just like std::mute=
x.=20
If I want a super simple thing, I use lock_guard; if I want a super robust=
=20
and DWIM thing, I use some higher-level system that supports transactions=
=20
or whatever, instead of continuing to mess around with raw locks. The=20
question is whether this proposal is making lock_guard *look more like* a=
=20
super robust and DWIM thing and attractive to newbies, when *in fact* it's=
=20
still very dangerous under the hood.

=E2=80=93Arthur

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<div dir=3D"ltr">On Thursday, April 30, 2015 at 6:44:50 AM UTC-7, Michael S=
pertus wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">    <div><p><span=
 style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color=
:#1f497d">Thanks for your comments. &nbsp;Arthur,</span></p><p><span style=
=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:#1f49=
7d"><span>1.<span style=3D"font:7.0pt &quot;Times New Roman&quot;">&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style=3D"font-size:=
11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:#1f497d">Absolutely=
, the proposal is meant to be deadlock-free, and I just embarrassingly put =
in the wording wrong. Corrected wording will be on the wiki. (I realized th=
is right after submitting, but it was too late=E2=80=A6 I did give my stude=
nts an extra credit problem to find the mistake in the paper).</span></p></=
div></blockquote><div>Aha. This definitely removes 70% of my objection to t=
he proposal. :)</div><div><br></div><div>&nbsp;</div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div><p><span style=3D"font-size:11.0pt;font-family:=
&quot;Calibri&quot;,sans-serif;color:#1f497d"><span>2.<span style=3D"font:7=
..0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </sp=
an></span></span><span style=3D"font-size:11.0pt;font-family:&quot;Calibri&=
quot;,sans-serif;color:#1f497d">I considered requiring that all the mutex t=
ypes be the same as you suggest, but some of the most important use cases r=
equire different lock types (like Howard=E2=80=99s operator=3D example in t=
he paper), and it just seems inaccurate to do otherwise.</span></p></div></=
blockquote><div>I wasn't necessarily suggesting that all the <font face=3D"=
courier new, monospace">Mutexes...</font> should <i>have</i> to be the same=
; I was just pointing out that in the most common case, where they <i>are</=
i> the same, it's ugly to force the user to write the same type many times =
in a row. &nbsp;I deliberately didn't go down the rabbit hole of how to imp=
lement the prettier syntax, because I figured I had a strictly better idea =
with <font face=3D"courier new, monospace">lock_tuple</font> =E2=80=94 but =
you can certainly use SFINAE to allow <font face=3D"courier new, monospace"=
>lock_guard&lt;M&gt;</font>'s constructor to take any number of arguments a=
s long as all of them are of type <font face=3D"courier new, monospace">M</=
font>, or you could have <font face=3D"courier new, monospace">lock_guard</=
font> do type erasure so that the type inside the angle brackets no longer =
particularly matters... Those both have obvious hurdles (where do you keep =
the extra arguments? type erasure requires heap allocation) but that's the =
general direction in which the rabbit hole would take us.</div><div><br></d=
iv><div><br></div><div>&nbsp;</div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div><p><span style=3D"font-size:11.0pt;font-family:&quot;Calibri&quo=
t;,sans-serif;color:#1f497d"><span>3.<span style=3D"font:7.0pt &quot;Times =
New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>=
<span style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;=
color:#1f497d">If N4471 is adopted, then you don=E2=80=99t need to worry ab=
out template arguments.<br>auto guard =3D lock_guard(mtx1, mtx2);</span></p=
></div></blockquote><div>N4471 (type deduction for constructors) is astrono=
mically unlikely to get accepted IMHO, due to the "Challenges" identified i=
n the proposal and the lack of implementations or proposed wording.</div><d=
iv>Without N4471, we could propose making <font face=3D"courier new, monosp=
ace">lock_guard</font> move-constructible (which <i>I think</i> is fine in =
practice because a <font face=3D"courier new, monospace">lock_guard</font> =
is just a bundle of references, right?), and then we'd have this syntax:</d=
iv><div><br></div><div class=3D"prettyprint" style=3D"background-color: rgb=
(250, 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: break-wor=
d;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #000;" class=3D"styled-by-prettify">&nbsp; &nbsp; </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> guard </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> make_lock_guard</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">mtx1</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> mtx2</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span></div></code></div><div><br>&nbsp;<br></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px =
#ccc solid;padding-left: 1ex;"><div><p><span style=3D"font-size:11.0pt;font=
-family:&quot;Calibri&quot;,sans-serif;color:#1f497d"><span>4.<span style=
=3D"font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp; </span></span></span><span style=3D"font-size:11.0pt;font-family:&quo=
t;Calibri&quot;,sans-serif;color:#1f497d">Even without N4471, since all of =
the common use cases we could think of involve 0, 1, or 2 mutexes (note tha=
t 0 locks is useful as well), the notational overhead isn=E2=80=99t excessi=
ve.</span></p></div></blockquote><div>IMHO the notational overhead for 2 mu=
texes <i>is</i> excessive =E2=80=94 that's what I meant by "ugly syntax". B=
ut this is a minor point, and could be solved by <font face=3D"courier new,=
 monospace">make_lock_guard</font> above.</div><div><br></div><div><br></di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div><p><span style=3D"font-=
size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:#1f497d"><span=
>5.<span style=3D"font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp; </span></span></span><span style=3D"font-size:11.0pt;fo=
nt-family:&quot;Calibri&quot;,sans-serif;color:#1f497d">It seems like uniqu=
e_lock might also want to work with any number of mutexes. In that case, a =
make_unique_lock(=E2=80=A6) would be another way to avoid specifying the te=
mplate arguments. (Since lock_guard is not movable, you can=E2=80=99t do th=
is with lock_guards).</span></p></div></blockquote><div>Your proposal doesn=
't actually specify a variadic <font face=3D"courier new, monospace">unique=
_lock</font>, though, does it? &nbsp;If the concepts are coupled, maybe the=
y should be proposed together.</div><div><br></div><div>&nbsp;</div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;"><div><p><span style=3D"font-size:11.0=
pt;font-family:&quot;Calibri&quot;,sans-serif;color:#1f497d"><span>6.<span =
style=3D"font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp; </span></span></span><span style=3D"font-size:11.0pt;font-family=
:&quot;Calibri&quot;,sans-serif;color:#1f497d">While I sympathize with your=
 desire to avoid raw locking primitives, I think the use cases in the paper=
 are appropriate and of course, explicit locks are common in practices. C++=
 in general has the philosophy of offering both low-level primitives and hi=
gh-level abstractions. In any case, if we choose to provide raw locking pri=
mitives, I think the relevant question is whether or not they are better if=
 variadic (also see #8 below).</span></p><p><span style=3D"font-size:11.0pt=
;font-family:&quot;Calibri&quot;,sans-serif;color:#1f497d"><span>7.<span st=
yle=3D"font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp; </span></span></span><span style=3D"font-size:11.0pt;font-family:&=
quot;Calibri&quot;,sans-serif;color:#1f497d">In particular, I think the bui=
lt-in deadlock avoidance (Once the wording embarrassment from #1 above is f=
ixed!) will result in more reliable programs in practice, if only because m=
any user-defined types follow the rule of three=E2=80=99s imprecation to pr=
ovide assignment operators.</span></p></div></blockquote><div>Can you elabo=
rate on what you mean by "if only because ... assignment operators"? &nbsp;=
I don't see how assignment operators and the Rule of Three are related to t=
he lock_guard proposal at all...?</div><div>&nbsp;</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div><p><span style=3D"font-size:11.0pt;font-fa=
mily:&quot;Calibri&quot;,sans-serif;color:#1f497d"><span>8.<span style=3D"f=
ont:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
 </span></span></span><span style=3D"font-size:11.0pt;font-family:&quot;Cal=
ibri&quot;,sans-serif;color:#1f497d">I=E2=80=99m having trouble seeing any =
reason we shouldn=E2=80=99t allow lock_guard to be variadic. The proposal i=
s easy to ignore if you don=E2=80=99t like it, and IMO doesn=E2=80=99t add =
conceptual complexity. =E2=80=9Cstd::lock_guard can manage a set of locks o=
f diverse types, just like std::lock=E2=80=9D. I=E2=80=99ve never heard any=
 of my students or coworkers say that std::lock is more confusing because i=
t was variadic.</span></p></div></blockquote><div><font face=3D"courier new=
, monospace">std::lock</font> is confusing because it's underspecified. ;) =
&nbsp;This is way off-topic, but I wonder how many people trust <font face=
=3D"courier new, monospace">std::lock</font> in practice, and how many simp=
ly roll their own lock-ordering scheme and/or exponential backoff scheme an=
d/or whatever other schemes are popular for avoiding deadlock. I don't do s=
ynchronization stuff myself, but I wonder whether people who do, actually t=
rust their standard library's <font face=3D"courier new, monospace">std::lo=
ck</font> to avoid livelock. And when they move to a different platform, do=
 they see the same performance characteristics?</div><div><br></div><div>Th=
e value of <font face=3D"courier new, monospace">std::lock_guard</font> is =
that it's super simple, just like <font face=3D"courier new, monospace">std=
::mutex</font>. If I want a super simple thing, I use <font face=3D"courier=
 new, monospace">lock_guard</font>; if I want a super robust and DWIM thing=
, I use some higher-level system that supports transactions or whatever, in=
stead of continuing to mess around with raw locks. The question is whether =
this proposal is making <font face=3D"courier new, monospace">lock_guard</f=
ont> <i>look more like</i> a super robust and DWIM thing and attractive to =
newbies, when <i>in fact</i> it's still very dangerous under the hood.</div=
><div><br></div><div>=E2=80=93Arthur</div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_173_713675328.1430427305083--
------=_Part_172_1778772745.1430427305083--

.


Author: Michael Spertus <mike_spertus@symantec.com>
Date: Thu, 30 Apr 2015 14:12:35 -0700
Raw View
--_000_9A3E0561DCF227429F72080EA81ADBC95084454075TUS1XCHEVSPIN_
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Comments in Green

From: Arthur O'Dwyer [mailto:arthur.j.odwyer@gmail.com]
Sent: Thursday, April 30, 2015 3:55 PM
To: std-proposals@isocpp.org
Cc: Michael Spertus; arthur.j.odwyer@gmail.com
Subject: Re: Comments on N4470 "Variadic lock_guard"

On Thursday, April 30, 2015 at 6:44:50 AM UTC-7, Michael Spertus wrote:

Thanks for your comments.  Arthur,

1.       Absolutely, the proposal is meant to be deadlock-free, and I just =
embarrassingly put in the wording wrong. Corrected wording will be on the w=
iki. (I realized this right after submitting, but it was too late=E2=80=A6 =
I did give my students an extra credit problem to find the mistake in the p=
aper).
Aha. This definitely removes 70% of my objection to the proposal. :)

 Great. I would object to the proposal without this as well =E2=98=BA

2.       I considered requiring that all the mutex types be the same as you=
 suggest, but some of the most important use cases require different lock t=
ypes (like Howard=E2=80=99s operator=3D example in the paper), and it just =
seems inaccurate to do otherwise.
I wasn't necessarily suggesting that all the Mutexes... should have to be t=
he same; I was just pointing out that in the most common case, where they a=
re the same, it's ugly to force the user to write the same type many times =
in a row.  I deliberately didn't go down the rabbit hole of how to implemen=
t the prettier syntax, because I figured I had a strictly better idea with =
lock_tuple =E2=80=94 but you can certainly use SFINAE to allow lock_guard<M=
>'s constructor to take any number of arguments as long as all of them are =
of type M, or you could have lock_guard do type erasure so that the type in=
side the angle brackets no longer particularly matters... Those both have o=
bvious hurdles (where do you keep the extra arguments? type erasure require=
s heap allocation) but that's the general direction in which the rabbit hol=
e would take us.




3.       If N4471 is adopted, then you don=E2=80=99t need to worry about te=
mplate arguments.
auto guard =3D lock_guard(mtx1, mtx2);
N4471 (type deduction for constructors) is astronomically unlikely to get a=
ccepted IMHO, due to the "Challenges" identified in the proposal and the la=
ck of implementations or proposed wording.
Without N4471, we could propose making lock_guard move-constructible (which=
 I think is fine in practice because a lock_guard is just a bundle of refer=
ences, right?), and then we'd have this syntax:

    auto guard =3D make_lock_guard(mtx1, mtx2);


4.       Even without N4471, since all of the common use cases we could thi=
nk of involve 0, 1, or 2 mutexes (note that 0 locks is useful as well), the=
 notational overhead isn=E2=80=99t excessive.
IMHO the notational overhead for 2 mutexes is excessive =E2=80=94 that's wh=
at I meant by "ugly syntax". But this is a minor point, and could be solved=
 by make_lock_guard above.


I=E2=80=99m not averse to making lock_guard movable.


5.       It seems like unique_lock might also want to work with any number =
of mutexes. In that case, a make_unique_lock(=E2=80=A6) would be another wa=
y to avoid specifying the template arguments. (Since lock_guard is not mova=
ble, you can=E2=80=99t do this with lock_guards).
Your proposal doesn't actually specify a variadic unique_lock, though, does=
 it?  If the concepts are coupled, maybe they should be proposed together.
I didn=E2=80=99t get around to including unique_lock in this proposal, as t=
here are some subtleties, but I may do a proposal later


6.       While I sympathize with your desire to avoid raw locking primitive=
s, I think the use cases in the paper are appropriate and of course, explic=
it locks are common in practices. C++ in general has the philosophy of offe=
ring both low-level primitives and high-level abstractions. In any case, if=
 we choose to provide raw locking primitives, I think the relevant question=
 is whether or not they are better if variadic (also see #8 below).

7.       In particular, I think the built-in deadlock avoidance (Once the w=
ording embarrassment from #1 above is fixed!) will result in more reliable =
programs in practice, if only because many user-defined types follow the ru=
le of three=E2=80=99s imprecation to provide assignment operators.
Can you elaborate on what you mean by "if only because ... assignment opera=
tors"?  I don't see how assignment operators and the Rule of Three are rela=
ted to the lock_guard proposal at all...?
 Here is a typical example from the paper due Howard, which I think occurs =
more often than not when a programmer writes a =E2=80=9Csynchronized class=
=E2=80=9D

class X {
  using Mutex =3D std::shared_timed_mutex;
 using ReadLock =3D std::shared_lock<Mutex>;
  mutable Mutex mut_;
  // more data
public: // ...
 X& operator=3D(const X& x) {
    if (this !=3D&x) {
      ReadLock rl(x.mut_, std::defer_lock);
      std::lock_guard<Mutex, ReadLock> lck(mut_, rl);
      // assign data ...
    }
    return *this;
  }
  // ...
};

8.       I=E2=80=99m having trouble seeing any reason we shouldn=E2=80=99t =
allow lock_guard to be variadic. The proposal is easy to ignore if you don=
=E2=80=99t like it, and IMO doesn=E2=80=99t add conceptual complexity. =E2=
=80=9Cstd::lock_guard can manage a set of locks of diverse types, just like=
 std::lock=E2=80=9D. I=E2=80=99ve never heard any of my students or coworke=
rs say that std::lock is more confusing because it was variadic.
std::lock is confusing because it's underspecified. ;)  This is way off-top=
ic, but I wonder how many people trust std::lock in practice, and how many =
simply roll their own lock-ordering scheme and/or exponential backoff schem=
e and/or whatever other schemes are popular for avoiding deadlock. I don't =
do synchronization stuff myself, but I wonder whether people who do, actual=
ly trust their standard library's std::lock to avoid livelock. And when the=
y move to a different platform, do they see the same performance characteri=
stics?

I think std::lock is a lot better for the vast majority of people than roll=
ing their own, but agree this is off topic, so let=E2=80=99s discuss over b=
eer in Lenexa=E2=80=A6

The value of std::lock_guard is that it's super simple, just like std::mute=
x. If I want a super simple thing, I use lock_guard; if I want a super robu=
st and DWIM thing, I use some higher-level system that supports transaction=
s or whatever, instead of continuing to mess around with raw locks. The que=
stion is whether this proposal is making lock_guard look more like a super =
robust and DWIM thing and attractive to newbies, when in fact it's still ve=
ry dangerous under the hood.

=E2=80=93Arthur

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<html xmlns:v=3D"urn:schemas-microsoft-com:vml" xmlns:o=3D"urn:schemas-micr=
osoft-com:office:office" xmlns:w=3D"urn:schemas-microsoft-com:office:word" =
xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" xmlns=3D"http:=
//www.w3.org/TR/REC-html40"><head><meta http-equiv=3DContent-Type content=
=3D"text/html; charset=3Dutf-8"><meta name=3DGenerator content=3D"Microsoft=
 Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
 {font-family:Wingdings;
 panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
 {font-family:"Cambria Math";
 panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
 {font-family:Calibri;
 panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
 {margin:0in;
 margin-bottom:.0001pt;
 font-size:12.0pt;
 font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
 {mso-style-priority:99;
 color:#0563C1;
 text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
 {mso-style-priority:99;
 color:#954F72;
 text-decoration:underline;}
p
 {mso-style-priority:99;
 mso-margin-top-alt:auto;
 margin-right:0in;
 mso-margin-bottom-alt:auto;
 margin-left:0in;
 font-size:12.0pt;
 font-family:"Times New Roman",serif;}
code
 {mso-style-priority:99;
 font-family:"Courier New";}
span.styled-by-prettify
 {mso-style-name:styled-by-prettify;}
span.EmailStyle20
 {mso-style-type:personal-reply;
 font-family:"Calibri",sans-serif;
 color:#1F497D;}
..MsoChpDefault
 {mso-style-type:export-only;
 font-family:"Calibri",sans-serif;}
@page WordSection1
 {size:8.5in 11.0in;
 margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
 {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext=3D"edit">
<o:idmap v:ext=3D"edit" data=3D"1" />
</o:shapelayout></xml><![endif]--></head><body lang=3DEN-US link=3D"#0563C1=
" vlink=3D"#954F72"><div class=3DWordSection1><p class=3DMsoNormal><span st=
yle=3D'font-size:11.0pt;font-family:"Calibri",sans-serif;color:#00B050'>Com=
ments in Green<o:p></o:p></span></p><p class=3DMsoNormal><span style=3D'fon=
t-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'><o:p>&nbsp;</=
o:p></span></p><p class=3DMsoNormal><b><span style=3D'font-size:11.0pt;font=
-family:"Calibri",sans-serif'>From:</span></b><span style=3D'font-size:11.0=
pt;font-family:"Calibri",sans-serif'> Arthur O'Dwyer [mailto:arthur.j.odwye=
r@gmail.com] <br><b>Sent:</b> Thursday, April 30, 2015 3:55 PM<br><b>To:</b=
> std-proposals@isocpp.org<br><b>Cc:</b> Michael Spertus; arthur.j.odwyer@g=
mail.com<br><b>Subject:</b> Re: Comments on N4470 &quot;Variadic lock_guard=
&quot;<o:p></o:p></span></p><p class=3DMsoNormal><o:p>&nbsp;</o:p></p><div>=
<p class=3DMsoNormal>On Thursday, April 30, 2015 at 6:44:50 AM UTC-7, Micha=
el Spertus wrote:<o:p></o:p></p><blockquote style=3D'border:none;border-lef=
t:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-ri=
ght:0in'><div><p><span style=3D'font-size:11.0pt;font-family:"Calibri",sans=
-serif;color:#1F497D'>Thanks for your comments. &nbsp;Arthur,</span><o:p></=
o:p></p><p><span style=3D'font-size:11.0pt;font-family:"Calibri",sans-serif=
;color:#1F497D'>1.</span><span style=3D'font-size:7.0pt;color:#1F497D'>&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style=3D'font-size:11.0pt;fon=
t-family:"Calibri",sans-serif;color:#1F497D'>Absolutely, the proposal is me=
ant to be deadlock-free, and I just embarrassingly put in the wording wrong=
.. Corrected wording will be on the wiki. (I realized this right after submi=
tting, but it was too late=E2=80=A6 I did give my students an extra credit =
problem to find the mistake in the paper).</span><o:p></o:p></p></div></blo=
ckquote><div><p class=3DMsoNormal>Aha. This definitely removes 70% of my ob=
jection to the proposal. :)<o:p></o:p></p></div><div><p class=3DMsoNormal><=
o:p>&nbsp;</o:p></p></div><div><p class=3DMsoNormal>&nbsp;<span style=3D'co=
lor:#00B050'>Great. I would object to the proposal without this as well </s=
pan><span style=3D'font-family:Wingdings;color:#00B050'>J</span><span style=
=3D'color:#00B050'><o:p></o:p></span></p></div><blockquote style=3D'border:=
none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:=
4.8pt;margin-right:0in'><div><p><span style=3D'font-size:11.0pt;font-family=
:"Calibri",sans-serif;color:#1F497D'>2.</span><span style=3D'font-size:7.0p=
t;color:#1F497D'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style=3D=
'font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'>I conside=
red requiring that all the mutex types be the same as you suggest, but some=
 of the most important use cases require different lock types (like Howard=
=E2=80=99s operator=3D example in the paper), and it just seems inaccurate =
to do otherwise.</span><o:p></o:p></p></div></blockquote><div><p class=3DMs=
oNormal>I wasn't necessarily suggesting that all the <span style=3D'font-fa=
mily:"Courier New"'>Mutexes...</span> should <i>have</i> to be the same; I =
was just pointing out that in the most common case, where they <i>are</i> t=
he same, it's ugly to force the user to write the same type many times in a=
 row. &nbsp;I deliberately didn't go down the rabbit hole of how to impleme=
nt the prettier syntax, because I figured I had a strictly better idea with=
 <span style=3D'font-family:"Courier New"'>lock_tuple</span> =E2=80=94 but =
you can certainly use SFINAE to allow <span style=3D'font-family:"Courier N=
ew"'>lock_guard&lt;M&gt;</span>'s constructor to take any number of argumen=
ts as long as all of them are of type <span style=3D'font-family:"Courier N=
ew"'>M</span>, or you could have <span style=3D'font-family:"Courier New"'>=
lock_guard</span> do type erasure so that the type inside the angle bracket=
s no longer particularly matters... Those both have obvious hurdles (where =
do you keep the extra arguments? type erasure requires heap allocation) but=
 that's the general direction in which the rabbit hole would take us.<o:p><=
/o:p></p></div><div><p class=3DMsoNormal><o:p>&nbsp;</o:p></p></div><div><p=
 class=3DMsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=3DMsoNormal>&nb=
sp;<o:p></o:p></p></div><blockquote style=3D'border:none;border-left:solid =
#CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in'=
><div><p><span style=3D'font-size:11.0pt;font-family:"Calibri",sans-serif;c=
olor:#1F497D'>3.</span><span style=3D'font-size:7.0pt;color:#1F497D'>&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style=3D'font-size:11.0pt;font-=
family:"Calibri",sans-serif;color:#1F497D'>If N4471 is adopted, then you do=
n=E2=80=99t need to worry about template arguments.<br>auto guard =3D lock_=
guard(mtx1, mtx2);</span><o:p></o:p></p></div></blockquote><div><p class=3D=
MsoNormal>N4471 (type deduction for constructors) is astronomically unlikel=
y to get accepted IMHO, due to the &quot;Challenges&quot; identified in the=
 proposal and the lack of implementations or proposed wording.<o:p></o:p></=
p></div><div><p class=3DMsoNormal>Without N4471, we could propose making <s=
pan style=3D'font-family:"Courier New"'>lock_guard</span> move-constructibl=
e (which <i>I think</i> is fine in practice because a <span style=3D'font-f=
amily:"Courier New"'>lock_guard</span> is just a bundle of references, righ=
t?), and then we'd have this syntax:<o:p></o:p></p></div><div><p class=3DMs=
oNormal><o:p>&nbsp;</o:p></p></div><div style=3D'border:solid #BBBBBB 1.0pt=
;padding:0in 0in 0in 0in;word-wrap: break-word'><div><p class=3DMsoNormal s=
tyle=3D'background:#FAFAFA'><span class=3Dstyled-by-prettify><span style=3D=
'font-size:10.0pt;font-family:"Courier New";color:black'>&nbsp; &nbsp; </sp=
an></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;=
font-family:"Courier New";color:#000088'>auto</span></span><span class=3Dst=
yled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";=
color:black'> guard </span></span><span class=3Dstyled-by-prettify><span st=
yle=3D'font-size:10.0pt;font-family:"Courier New";color:#666600'>=3D</span>=
</span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;fon=
t-family:"Courier New";color:black'> make_lock_guard</span></span><span cla=
ss=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courie=
r New";color:#666600'>(</span></span><span class=3Dstyled-by-prettify><span=
 style=3D'font-size:10.0pt;font-family:"Courier New";color:black'>mtx1</spa=
n></span><span class=3Dstyled-by-prettify><span style=3D'font-size:10.0pt;f=
ont-family:"Courier New";color:#666600'>,</span></span><span class=3Dstyled=
-by-prettify><span style=3D'font-size:10.0pt;font-family:"Courier New";colo=
r:black'> mtx2</span></span><span class=3Dstyled-by-prettify><span style=3D=
'font-size:10.0pt;font-family:"Courier New";color:#666600'>);</span></span>=
<span style=3D'font-size:10.0pt;font-family:"Courier New"'><o:p></o:p></spa=
n></p></div></div><div><p class=3DMsoNormal><span style=3D'color:#1F497D'><=
o:p>&nbsp;</o:p></span></p><p class=3DMsoNormal><span style=3D'color:#00B05=
0'> <o:p></o:p></span></p></div><blockquote style=3D'border:none;border-lef=
t:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-ri=
ght:0in'><div><p><span style=3D'font-size:11.0pt;font-family:"Calibri",sans=
-serif;color:#1F497D'>4.</span><span style=3D'font-size:7.0pt;color:#1F497D=
'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style=3D'font-size:11.0=
pt;font-family:"Calibri",sans-serif;color:#1F497D'>Even without N4471, sinc=
e all of the common use cases we could think of involve 0, 1, or 2 mutexes =
(note that 0 locks is useful as well), the notational overhead isn=E2=80=99=
t excessive.</span><o:p></o:p></p></div></blockquote><div><p class=3DMsoNor=
mal>IMHO the notational overhead for 2 mutexes <i>is</i> excessive =E2=80=
=94 that's what I meant by &quot;ugly syntax&quot;. But this is a minor poi=
nt, and could be solved by <span style=3D'font-family:"Courier New"'>make_l=
ock_guard</span> above.<o:p></o:p></p></div><div><p class=3DMsoNormal><span=
 style=3D'color:#00B050'><o:p>&nbsp;</o:p></span></p><p class=3DMsoNormal><=
span style=3D'font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F49=
7D'><o:p>&nbsp;</o:p></span></p><p class=3DMsoNormal><span style=3D'color:#=
00B050'>I=E2=80=99m not averse to making lock_guard movable.<o:p></o:p></sp=
an></p></div><div><p class=3DMsoNormal><o:p>&nbsp;</o:p></p></div><blockquo=
te style=3D'border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in=
 6.0pt;margin-left:4.8pt;margin-right:0in'><div><p><span style=3D'font-size=
:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'>5.</span><span styl=
e=3D'font-size:7.0pt;color:#1F497D'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </=
span><span style=3D'font-size:11.0pt;font-family:"Calibri",sans-serif;color=
:#1F497D'>It seems like unique_lock might also want to work with any number=
 of mutexes. In that case, a make_unique_lock(=E2=80=A6) would be another w=
ay to avoid specifying the template arguments. (Since lock_guard is not mov=
able, you can=E2=80=99t do this with lock_guards).</span><o:p></o:p></p></d=
iv></blockquote><div><p class=3DMsoNormal>Your proposal doesn't actually sp=
ecify a variadic <span style=3D'font-family:"Courier New"'>unique_lock</spa=
n>, though, does it? &nbsp;If the concepts are coupled, maybe they should b=
e proposed together.<o:p></o:p></p></div><div><p class=3DMsoNormal><span st=
yle=3D'color:#00B050'>I didn=E2=80=99t get around to including unique_lock =
in this proposal, as there are some subtleties, but I may do a proposal lat=
er<o:p></o:p></span></p></div><div><p class=3DMsoNormal>&nbsp;<o:p></o:p></=
p></div><blockquote style=3D'border:none;border-left:solid #CCCCCC 1.0pt;pa=
dding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in'><div><p><span s=
tyle=3D'font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'>6.=
</span><span style=3D'font-size:7.0pt;color:#1F497D'>&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp; </span><span style=3D'font-size:11.0pt;font-family:"Calibri"=
,sans-serif;color:#1F497D'>While I sympathize with your desire to avoid raw=
 locking primitives, I think the use cases in the paper are appropriate and=
 of course, explicit locks are common in practices. C++ in general has the =
philosophy of offering both low-level primitives and high-level abstraction=
s. In any case, if we choose to provide raw locking primitives, I think the=
 relevant question is whether or not they are better if variadic (also see =
#8 below).</span><o:p></o:p></p><p><span style=3D'font-size:11.0pt;font-fam=
ily:"Calibri",sans-serif;color:#1F497D'>7.</span><span style=3D'font-size:7=
..0pt;color:#1F497D'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style=
=3D'font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'>In par=
ticular, I think the built-in deadlock avoidance (Once the wording embarras=
sment from #1 above is fixed!) will result in more reliable programs in pra=
ctice, if only because many user-defined types follow the rule of three=E2=
=80=99s imprecation to provide assignment operators.</span><o:p></o:p></p><=
/div></blockquote><div><p class=3DMsoNormal>Can you elaborate on what you m=
ean by &quot;if only because ... assignment operators&quot;? &nbsp;I don't =
see how assignment operators and the Rule of Three are related to the lock_=
guard proposal at all...?<o:p></o:p></p></div><div><p class=3DMsoNormal>&nb=
sp;<span style=3D'color:#00B050'>Here is a typical example from the paper d=
ue Howard, which I think occurs more often than not when a programmer write=
s a =E2=80=9Csynchronized class=E2=80=9D<o:p></o:p></span></p><p class=3DMs=
oNormal><span style=3D'font-size:11.0pt;font-family:"Calibri",sans-serif;co=
lor:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=3DMsoNormal><span style=
=3D'font-size:11.0pt;font-family:"Courier New";color:#00B050'>class X { <o:=
p></o:p></span></p><p class=3DMsoNormal><span style=3D'font-size:11.0pt;fon=
t-family:"Courier New";color:#00B050'>=C2=A0=C2=A0using Mutex =3D std::shar=
ed_timed_mutex;<o:p></o:p></span></p><p class=3DMsoNormal><span style=3D'fo=
nt-size:11.0pt;font-family:"Courier New";color:#00B050'> =C2=A0using ReadLo=
ck =3D std::shared_lock&lt;Mutex&gt;;<o:p></o:p></span></p><p class=3DMsoNo=
rmal><span style=3D'font-size:11.0pt;font-family:"Courier New";color:#00B05=
0'>=C2=A0 mutable Mutex mut_; <o:p></o:p></span></p><p class=3DMsoNormal><s=
pan style=3D'font-size:11.0pt;font-family:"Courier New";color:#00B050'>=C2=
=A0=C2=A0// more data<o:p></o:p></span></p><p class=3DMsoNormal><span style=
=3D'font-size:11.0pt;font-family:"Courier New";color:#00B050'>public: // ..=
..<o:p></o:p></span></p><p class=3DMsoNormal><span style=3D'font-size:11.0pt=
;font-family:"Courier New";color:#00B050'> =C2=A0X&amp; operator=3D(const X=
&amp; x) {<o:p></o:p></span></p><p class=3DMsoNormal><span style=3D'font-si=
ze:11.0pt;font-family:"Courier New";color:#00B050'>=C2=A0=C2=A0 =C2=A0if (t=
his !=3D&amp;x) {<o:p></o:p></span></p><p class=3DMsoNormal><span style=3D'=
font-size:11.0pt;font-family:"Courier New";color:#00B050'>=C2=A0=C2=A0=C2=
=A0=C2=A0 =C2=A0ReadLock rl(x.mut_, std::defer_lock);<o:p></o:p></span></p>=
<p class=3DMsoNormal><span style=3D'font-size:11.0pt;font-family:"Courier N=
ew";color:#00B050'>=C2=A0=C2=A0=C2=A0=C2=A0 =C2=A0std::lock_guard&lt;Mutex,=
 ReadLock&gt; lck(mut_, rl);<o:p></o:p></span></p><p class=3DMsoNormal><spa=
n style=3D'font-size:11.0pt;font-family:"Courier New";color:#00B050'>=C2=A0=
=C2=A0=C2=A0=C2=A0 =C2=A0// assign data ...<o:p></o:p></span></p><p class=
=3DMsoNormal><span style=3D'font-size:11.0pt;font-family:"Courier New";colo=
r:#00B050'>=C2=A0=C2=A0=C2=A0 }<o:p></o:p></span></p><p class=3DMsoNormal><=
span style=3D'font-size:11.0pt;font-family:"Courier New";color:#00B050'>=C2=
=A0 =C2=A0=C2=A0return *this; <o:p></o:p></span></p><p class=3DMsoNormal><s=
pan style=3D'font-size:11.0pt;font-family:"Courier New";color:#00B050'>=C2=
=A0=C2=A0} <o:p></o:p></span></p><p class=3DMsoNormal><span style=3D'font-s=
ize:11.0pt;font-family:"Courier New";color:#00B050'>=C2=A0=C2=A0// ... <o:p=
></o:p></span></p><p class=3DMsoNormal><span style=3D'font-size:11.0pt;font=
-family:"Courier New";color:#00B050'>};<o:p></o:p></span></p></div><blockqu=
ote style=3D'border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0i=
n 6.0pt;margin-left:4.8pt;margin-right:0in'><div><p><span style=3D'font-siz=
e:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D'>8.</span><span sty=
le=3D'font-size:7.0pt;color:#1F497D'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <=
/span><span style=3D'font-size:11.0pt;font-family:"Calibri",sans-serif;colo=
r:#1F497D'>I=E2=80=99m having trouble seeing any reason we shouldn=E2=80=99=
t allow lock_guard to be variadic. The proposal is easy to ignore if you do=
n=E2=80=99t like it, and IMO doesn=E2=80=99t add conceptual complexity. =E2=
=80=9Cstd::lock_guard can manage a set of locks of diverse types, just like=
 std::lock=E2=80=9D. I=E2=80=99ve never heard any of my students or coworke=
rs say that std::lock is more confusing because it was variadic.</span><o:p=
></o:p></p></div></blockquote><div><p class=3DMsoNormal><span style=3D'font=
-family:"Courier New"'>std::lock</span> is confusing because it's underspec=
ified. ;) &nbsp;This is way off-topic, but I wonder how many people trust <=
span style=3D'font-family:"Courier New"'>std::lock</span> in practice, and =
how many simply roll their own lock-ordering scheme and/or exponential back=
off scheme and/or whatever other schemes are popular for avoiding deadlock.=
 I don't do synchronization stuff myself, but I wonder whether people who d=
o, actually trust their standard library's <span style=3D'font-family:"Cour=
ier New"'>std::lock</span> to avoid livelock. And when they move to a diffe=
rent platform, do they see the same performance characteristics?<o:p></o:p>=
</p></div><div><p class=3DMsoNormal><span style=3D'color:#1F497D'><o:p>&nbs=
p;</o:p></span></p><p class=3DMsoNormal><span style=3D'font-size:11.0pt;fon=
t-family:"Calibri",sans-serif;color:#00B050'>I think std::lock is a lot bet=
ter for the vast majority of people than rolling their own, but agree this =
is off topic, so let=E2=80=99s discuss over beer in Lenexa=E2=80=A6<o:p></o=
:p></span></p><p class=3DMsoNormal><span style=3D'font-size:11.0pt;font-fam=
ily:"Calibri",sans-serif;color:#00B050'><o:p>&nbsp;</o:p></span></p></div><=
div><p class=3DMsoNormal>The value of <span style=3D'font-family:"Courier N=
ew"'>std::lock_guard</span> is that it's super simple, just like <span styl=
e=3D'font-family:"Courier New"'>std::mutex</span>. If I want a super simple=
 thing, I use <span style=3D'font-family:"Courier New"'>lock_guard</span>; =
if I want a super robust and DWIM thing, I use some higher-level system tha=
t supports transactions or whatever, instead of continuing to mess around w=
ith raw locks. The question is whether this proposal is making <span style=
=3D'font-family:"Courier New"'>lock_guard</span> <i>look more like</i> a su=
per robust and DWIM thing and attractive to newbies, when <i>in fact</i> it=
's still very dangerous under the hood.<o:p></o:p></p></div><div><p class=
=3DMsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=3DMsoNormal>=E2=80=93=
Arthur<o:p></o:p></p></div></div></div></body></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--_000_9A3E0561DCF227429F72080EA81ADBC95084454075TUS1XCHEVSPIN_--

.


Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Thu, 30 Apr 2015 17:25:19 -0400
Raw View
On Apr 30, 2015, at 5:12 PM, Michael Spertus <mike_spertus@symantec.com> wr=
ote:
>=20
>> IMHO the notational overhead for 2 mutexes is excessive =E2=80=94 that's=
 what I meant by "ugly syntax". But this is a minor point, and could be sol=
ved by make_lock_guard above.
>> =20
> =20
> I=E2=80=99m not averse to making lock_guard movable.
>=20

The raisons d=E2=80=99=C3=AAtre for lock_guard is that it *always* owns the=
 mutex(es) it refers to, and thus in ~lock_guard(), there is no check like =
there is in ~unique_lock():

    ~unique_lock()
    {
        if (__owns_)
            __m_->unlock();
    }

vs:

    ~lock_guard() {__m_.unlock();}

If this detail of lock_guard disappears, then all differences between lock_=
guard and unique_lock disappear.

If lock_guard becomes movable, then it must have a moved-from state.  Presu=
mably that moved-from state would not unlock anything when destructed (lest=
 unlock() would be called too many times).

I don=E2=80=99t see how to make lock_guard movable without turning it into =
unique_lock.

If we need to make lock_guard movable, perhaps then it is better to make un=
ique_lock variadic instead of lock_guard.

I will strongly argue against putting an if-statement in ~lock_guard().  An=
d I suspect Lawrence Crowl will too.  He is the one who convinced me that w=
e needed lock_guard in addition to unique_lock for this very reason.

Howard

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Thu, 30 Apr 2015 17:42:21 -0400
Raw View
On Apr 30, 2015, at 5:25 PM, Howard Hinnant <howard.hinnant@gmail.com> wrot=
e:
>=20
> The raisons d=E2=80=99=C3=AAtre for lock_guard is that it *always* owns t=
he mutex(es) it refers to, and thus in ~lock_guard(), there is no check lik=
e there is in ~unique_lock():
>=20
>    ~unique_lock()
>    {
>        if (__owns_)
>            __m_->unlock();
>    }
>=20
> vs:
>=20
>    ~lock_guard() {__m_.unlock();}
>=20
> If this detail of lock_guard disappears, then all differences between loc=
k_guard and unique_lock disappear.
>=20
> If lock_guard becomes movable, then it must have a moved-from state.  Pre=
sumably that moved-from state would not unlock anything when destructed (le=
st unlock() would be called too many times).
>=20
> I don=E2=80=99t see how to make lock_guard movable without turning it int=
o unique_lock.
>=20
> If we need to make lock_guard movable, perhaps then it is better to make =
unique_lock variadic instead of lock_guard.
>=20
> I will strongly argue against putting an if-statement in ~lock_guard().  =
And I suspect Lawrence Crowl will too.  He is the one who convinced me that=
 we needed lock_guard in addition to unique_lock for this very reason.
>=20

<sigh> I just noticed a flaw that I failed to previously spot.

In C++11/14 lock_guard<M> requires M to meet the BasicLockable requirements=
..  I.e. M must have lock() and unlock().

lock(m0, m1, =E2=80=A6) requires the m[i] to be Lockable.  Lockable means i=
t meets BasicLockable, plus has try_lock().

This proposal ups the requirements of lock_guard<M> on M from BasicLockable=
 to Lockable, making it a breaking change.

I think this can be fixed by retaining only the BasicLockable requirements =
on the single-arg version of lock_guard<M>, but requiring Lockable for the =
version taking two or more M=E2=80=99s.  This same issue is still in place =
if we want to transfer the application of this proposal to unique_lock.

This can also be fixed by just naming the variadic version to some other na=
me.

Howard

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Fri, 01 May 2015 16:57:39 +0200
Raw View
This is a multi-part message in MIME format.
--------------060202000608020801030605
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 30/04/15 23:25, Howard Hinnant a =C3=A9crit :
> On Apr 30, 2015, at 5:12 PM, Michael Spertus <mike_spertus@symantec.com> =
wrote:
>>> IMHO the notational overhead for 2 mutexes is excessive =E2=80=94 that'=
s what I meant by "ugly syntax". But this is a minor point, and could be so=
lved by make_lock_guard above.
>>>  =20
>>  =20
>> I=E2=80=99m not averse to making lock_guard movable.
>>
> The raisons d=E2=80=99=C3=AAtre for lock_guard is that it *always* owns t=
he mutex(es) it refers to, and thus in ~lock_guard(), there is no check lik=
e there is in ~unique_lock():
>
>      ~unique_lock()
>      {
>          if (__owns_)
>              __m_->unlock();
>      }
>
> vs:
>
>      ~lock_guard() {__m_.unlock();}
>
> If this detail of lock_guard disappears, then all differences between loc=
k_guard and unique_lock disappear.
>
> If lock_guard becomes movable, then it must have a moved-from state.  Pre=
sumably that moved-from state would not unlock anything when destructed (le=
st unlock() would be called too many times).
>
> I don=E2=80=99t see how to make lock_guard movable without turning it int=
o unique_lock.
>
> If we need to make lock_guard movable, perhaps then it is better to make =
unique_lock variadic instead of lock_guard.
>
> I will strongly argue against putting an if-statement in ~lock_guard().  =
And I suspect Lawrence Crowl will too.  He is the one who convinced me that=
 we needed lock_guard in addition to unique_lock for this very reason.
>
>
I understand and share your concern completely.

I have a beginner's question: Shouldn't the move operation be deleted=20
explicitly

       lock_guard(lock_guard &&) =3D delete;
       lock_guard& operator=3D(lock_guard &&) =3D delete;

C++ International Standard
as it is already the case for the copy operations [30.4.2.1]=20
[thread.lock.guard] C++ International Standard

       lock_guard(lock_guard const&) =3D delete;
       lock_guard& operator=3D(lock_guard const&) =3D delete;

?


Vicente
C++ International Standard




--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<html>
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">Le 30/04/15 23:25, Howard Hinnant a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:693A683C-64B5-47F7-832A-B7644B1E07D5@gmail.com"
      type=3D"cite">
      <pre wrap=3D"">On Apr 30, 2015, at 5:12 PM, Michael Spertus <a class=
=3D"moz-txt-link-rfc2396E" href=3D"mailto:mike_spertus@symantec.com">&lt;mi=
ke_spertus@symantec.com&gt;</a> wrote:
</pre>
      <blockquote type=3D"cite">
        <pre wrap=3D"">
</pre>
        <blockquote type=3D"cite">
          <pre wrap=3D"">IMHO the notational overhead for 2 mutexes is exce=
ssive =E2=80=94 that's what I meant by "ugly syntax". But this is a minor p=
oint, and could be solved by make_lock_guard above.
=20
</pre>
        </blockquote>
        <pre wrap=3D"">=20
I=E2=80=99m not averse to making lock_guard movable.

</pre>
      </blockquote>
      <pre wrap=3D"">
The raisons d=E2=80=99=C3=AAtre for lock_guard is that it *always* owns the=
 mutex(es) it refers to, and thus in ~lock_guard(), there is no check like =
there is in ~unique_lock():

    ~unique_lock()
    {
        if (__owns_)
            __m_-&gt;unlock();
    }

vs:

    ~lock_guard() {__m_.unlock();}

If this detail of lock_guard disappears, then all differences between lock_=
guard and unique_lock disappear.

If lock_guard becomes movable, then it must have a moved-from state.  Presu=
mably that moved-from state would not unlock anything when destructed (lest=
 unlock() would be called too many times).

I don=E2=80=99t see how to make lock_guard movable without turning it into =
unique_lock.

If we need to make lock_guard movable, perhaps then it is better to make un=
ique_lock variadic instead of lock_guard.

I will strongly argue against putting an if-statement in ~lock_guard().  An=
d I suspect Lawrence Crowl will too.  He is the one who convinced me that w=
e needed lock_guard in addition to unique_lock for this very reason.


</pre>
    </blockquote>
    I understand and share your concern completely. <br>
    <br>
    I have a beginner's question: Shouldn't the move operation be
    deleted explicitly <br>
    <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8=
">
    <pre><span style=3D"font-size: 9.000000pt; font-family: 'LMMono9'">    =
  lock_guard(lock_guard &amp;&amp;) =3D delete;
      lock_guard&amp; operator=3D(lock_guard &amp;&amp;) =3D delete;
</span></pre>
    <title>C++ International Standard</title>
    <br>
    as it is already the case for the copy operations [30.4.2.1]
    <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8=
">
    <span style=3D"font-size: 10.000000pt; font-family: 'LMRoman10';
      font-weight: 700">[thread.lock.guard] </span>
    <title>C++ International Standard</title>
    <br>
    <br>
    <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8=
">
    <pre><span style=3D"font-size: 9.000000pt; font-family: 'LMMono9'">    =
  lock_guard(lock_guard const&amp;) =3D delete;
      lock_guard&amp; operator=3D(lock_guard const&amp;) =3D delete;
</span></pre>
    ?<br>
    <br>
    <br>
    Vicente<br>
    <title>C++ International Standard</title>
    <br>
    <br>
    <br>
    <br>
    <br>
  </body>
</html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--------------060202000608020801030605--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 1 May 2015 17:59:51 +0300
Raw View
On 1 May 2015 at 17:57, Vicente J. Botet Escriba
<vicente.botet@wanadoo.fr> wrote:
> I have a beginner's question: Shouldn't the move operation be deleted
> explicitly
>
>       lock_guard(lock_guard &&) = delete;
>       lock_guard& operator=(lock_guard &&) = delete;
>
>
> as it is already the case for the copy operations [30.4.2.1]
> [thread.lock.guard]
>
>       lock_guard(lock_guard const&) = delete;
>       lock_guard& operator=(lock_guard const&) = delete;


It doesn't necessarily need to be deleted, because the declared copy
operation (even if declared
deleted) will suppress it.

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Fri, 01 May 2015 17:01:02 +0200
Raw View
This is a multi-part message in MIME format.
--------------090108090006010106070200
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 30/04/15 17:21, Edward Catmur a =C3=A9crit :
> On Thursday, 30 April 2015 15:54:40 UTC+1, Vicente J. Botet Escriba=20
> wrote:
>
>     I have a make_lock_guard in Boost.Thread that returns a
>     lock_guard. It is NOT A CORRECT implementation as I think it needs
>     RVO.
>
>     The usage is as
>
>         auto&& lg =3D boost::make_lock_guard(m);
>
>     The implementation is
>
>       template <typename Lockable>
>       lock_guard<Lockable> make_lock_guard(Lockable& mtx)
>       {
>         return { thread_detail::lockable_wrapper<Lockable>(mtx) };
>       }
>
>
> Return by braced-init-list doesn't require RVO; the returned object is=20
> copy-list-initialized directly ([stmt.return]/2). But you're correct=20
> that auto&& is required; AFAICT N4471 would also require auto&&.
>
Thanks for the information. I have found this answer [1] to=20
StackOverflow post related.
Would the following be also correct

     auto& lg =3D boost::make_lock_guard(m);
?

Vicente

[1]=20
http://stackoverflow.com/questions/22621786/constructing-a-non-copyable-non=
-movable-type-into-a-function-parameter-without

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<html>
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">Le 30/04/15 17:21, Edward Catmur a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
      cite=3D"mid:aa15f62d-2eac-425d-ba40-e7661e225429@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">On Thursday, 30 April 2015 15:54:40 UTC+1, Vicente
        J. Botet Escriba wrote:
        <blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div text=3D"#000000" bgcolor=3D"#FFFFFF">
            <div>I have a make_lock_guard in Boost.Thread that returns a
              lock_guard. It is NOT A CORRECT implementation as I think
              it needs RVO.<br>
            </div>
            <br>
            The usage is as<br>
            <br>
            =C2=A0=C2=A0=C2=A0 auto&amp;&amp; lg =3D boost::make_lock_guard=
(m);<br>
            <br>
            The implementation is<br>
            <br>
            =C2=A0 template &lt;typename Lockable&gt;<br>
            =C2=A0 lock_guard&lt;Lockable&gt; make_lock_guard(Lockable&amp;
            mtx)<br>
            =C2=A0 {<br>
            =C2=A0=C2=A0=C2=A0 return { thread_detail::lockable_<wbr>wrappe=
r&lt;Lockable&gt;(mtx)
            };<br>
            =C2=A0 }<br>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>Return by braced-init-list doesn't require RVO; the
          returned object is copy-list-initialized directly
          ([stmt.return]/2). But you're correct that auto&amp;&amp; is
          required; AFAICT N4471 would also require auto&amp;&amp;.</div>
      </div>
      <br>
    </blockquote>
    Thanks for the information. I have found this answer [1] to
    StackOverflow post related. <br>
    <small>W</small><font size=3D"+1"><small>ould the following be also
        correct<br>
      </small><br>
    </font>
    =C2=A0=C2=A0=C2=A0 auto&amp; lg =3D boost::make_lock_guard(m);<br>
    ?<br>
    <br>
    Vicente<br>
    <br>
    [1] <font size=3D"+1"><a class=3D"moz-txt-link-freetext" href=3D"http:/=
/stackoverflow.com/questions/22621786/constructing-a-non-copyable-non-movab=
le-type-into-a-function-parameter-without">http://stackoverflow.com/questio=
ns/22621786/constructing-a-non-copyable-non-movable-type-into-a-function-pa=
rameter-without</a><br>
    </font><br>
  </body>
</html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--------------090108090006010106070200--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Fri, 01 May 2015 17:02:10 +0200
Raw View
This is a multi-part message in MIME format.
--------------010500000302060601030106
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 01/05/15 16:59, Ville Voutilainen a =C3=A9crit :
> On 1 May 2015 at 17:57, Vicente J. Botet Escriba
> <vicente.botet@wanadoo.fr> wrote:
>> I have a beginner's question: Shouldn't the move operation be deleted
>> explicitly
>>
>>        lock_guard(lock_guard &&) =3D delete;
>>        lock_guard& operator=3D(lock_guard &&) =3D delete;
>>
>>
>> as it is already the case for the copy operations [30.4.2.1]
>> [thread.lock.guard]
>>
>>        lock_guard(lock_guard const&) =3D delete;
>>        lock_guard& operator=3D(lock_guard const&) =3D delete;
>
> It doesn't necessarily need to be deleted, because the declared copy
> operation (even if declared
> deleted) will suppress it.
>
Thanks,
Vicente

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<html>
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">Le 01/05/15 16:59, Ville Voutilainen a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
cite=3D"mid:CAFk2RUaaQn43pUGpT9bEfGe=3DnduDeehEmTm4pJS23_6uwfXWdQ@mail.gmai=
l.com"
      type=3D"cite">
      <pre wrap=3D"">On 1 May 2015 at 17:57, Vicente J. Botet Escriba
<a class=3D"moz-txt-link-rfc2396E" href=3D"mailto:vicente.botet@wanadoo.fr"=
>&lt;vicente.botet@wanadoo.fr&gt;</a> wrote:
</pre>
      <blockquote type=3D"cite">
        <pre wrap=3D"">I have a beginner's question: Shouldn't the move ope=
ration be deleted
explicitly

      lock_guard(lock_guard &amp;&amp;) =3D delete;
      lock_guard&amp; operator=3D(lock_guard &amp;&amp;) =3D delete;


as it is already the case for the copy operations [30.4.2.1]
[thread.lock.guard]

      lock_guard(lock_guard const&amp;) =3D delete;
      lock_guard&amp; operator=3D(lock_guard const&amp;) =3D delete;
</pre>
      </blockquote>
      <pre wrap=3D"">

It doesn't necessarily need to be deleted, because the declared copy
operation (even if declared
deleted) will suppress it.

</pre>
    </blockquote>
    <font size=3D"+1">Thanks,<br>
      Vicente<br>
    </font>
  </body>
</html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--------------010500000302060601030106--

.


Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Fri, 1 May 2015 11:26:21 -0400
Raw View
On May 1, 2015, at 10:57 AM, Vicente J. Botet Escriba <vicente.botet@wanado=
o.fr> wrote:
>=20
> Le 30/04/15 23:25, Howard Hinnant a =C3=A9crit :
>> On Apr 30, 2015, at 5:12 PM, Michael Spertus <mike_spertus@symantec.com>
>>  wrote:
>>=20
>>>> IMHO the notational overhead for 2 mutexes is excessive =E2=80=94 that=
's what I meant by "ugly syntax". But this is a minor point, and could be s=
olved by make_lock_guard above.
>>>> =20
>>>>=20
>>> =20
>>> I=E2=80=99m not averse to making lock_guard movable.
>>>=20
>>>=20
>> The raisons d=E2=80=99=C3=AAtre for lock_guard is that it *always* owns =
the mutex(es) it refers to, and thus in ~lock_guard(), there is no check li=
ke there is in ~unique_lock():
>>=20
>>     ~unique_lock()
>>     {
>>         if (__owns_)
>>             __m_->unlock();
>>     }
>>=20
>> vs:
>>=20
>>     ~lock_guard() {__m_.unlock();}
>>=20
>> If this detail of lock_guard disappears, then all differences between lo=
ck_guard and unique_lock disappear.
>>=20
>> If lock_guard becomes movable, then it must have a moved-from state.  Pr=
esumably that moved-from state would not unlock anything when destructed (l=
est unlock() would be called too many times).
>>=20
>> I don=E2=80=99t see how to make lock_guard movable without turning it in=
to unique_lock.
>>=20
>> If we need to make lock_guard movable, perhaps then it is better to make=
 unique_lock variadic instead of lock_guard.
>>=20
>> I will strongly argue against putting an if-statement in ~lock_guard(). =
 And I suspect Lawrence Crowl will too.  He is the one who convinced me tha=
t we needed lock_guard in addition to unique_lock for this very reason.
>>=20
>>=20
>>=20
> I understand and share your concern completely.=20
>=20
> I have a beginner's question: Shouldn't the move operation be deleted exp=
licitly=20
>       lock_guard(lock_guard &&) =3D delete;
>       lock_guard& operator=3D(lock_guard &&) =3D delete;
>=20
>=20
> as it is already the case for the copy operations [30.4.2.1] [thread.lock=
..guard]=20
>=20
>       lock_guard(lock_guard const&) =3D delete;
>       lock_guard& operator=3D(lock_guard const&) =3D delete;
>=20
> ?

Ville is completely correct.  However I wanted to add something more:

      ** Never, ever delete the special move members **

If you see it done in somebody else=E2=80=99s code during review, jump up a=
nd down while making lots of irritating noises.

Now I=E2=80=99m the fist one to say =E2=80=9Cnever say never=E2=80=9D.  So =
I will admit: Someday someone is going to come up with a good use for delet=
ed move members.  But that someone is going to be an expert in move semanti=
cs, and it hasn=E2=80=99t happened yet.  Be suspicious if you or your colle=
ague is the first to discover a good use case.

Rationale:  At best, deleted move members are redundant, as they are in thi=
s case, and as Ville pointed out.  You can=E2=80=99t move a lock_guard with=
 or without the deleted move members.  If they aren=E2=80=99t explicitly de=
clared, the compiler won=E2=80=99t generate them because of the user-declar=
ed copy members.

At worst, deleted move members don=E2=80=99t do what you think they do:

struct A
{
    A(const A&);
    A& operator=3D(const A&);

    // I just want A to be copyable, not moveable
    A(A&&) =3D delete;
    A& operator=3D(A&&) =3D delete;
};

This A is no longer very useful at all.  It can not be returned by value fr=
om a factory function.  If a container (such as vector or deque during inse=
rt or erase) tries to move the A, it will fail at compile time. std::swap o=
n this A will fail at compile time.  You can=E2=80=99t std::sort a sequence=
 of these A=E2=80=99s.

=E2=80=9CMove=E2=80=9D means move-if-you-can-else-copy from an rvalue.  And=
 C++03 classes happily and correctly copy from rvalues.  When you add delet=
ed move members to these C++03 classes, they just stop working everywhere t=
hey used to work fine.

Howard

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 1 May 2015 18:36:28 +0300
Raw View
On 1 May 2015 at 18:26, Howard Hinnant <howard.hinnant@gmail.com> wrote:
> Ville is completely correct.  However I wanted to add something more:
>
>       ** Never, ever delete the special move members **
>
> If you see it done in somebody else=E2=80=99s code during review, jump up=
 and down while making lots of irritating noises.
>
> Now I=E2=80=99m the fist one to say =E2=80=9Cnever say never=E2=80=9D.  S=
o I will admit: Someday someone is going to come up with a good use for del=
eted move members.  But that someone is going to be an expert in move seman=
tics, and it hasn=E2=80=99t happened yet.  Be suspicious if you or your col=
league is the first to discover a good use case.
>
> Rationale:  At best, deleted move members are redundant, as they are in t=
his case, and as Ville pointed out.  You can=E2=80=99t move a lock_guard wi=
th or without the deleted move members.  If they aren=E2=80=99t explicitly =
declared, the compiler won=E2=80=99t generate them because of the user-decl=
ared copy members.
>
> At worst, deleted move members don=E2=80=99t do what you think they do:
>
> struct A
> {
>     A(const A&);
>     A& operator=3D(const A&);
>
>     // I just want A to be copyable, not moveable
>     A(A&&) =3D delete;
>     A& operator=3D(A&&) =3D delete;
> };
>
> This A is no longer very useful at all.  It can not be returned by value =
from a factory function.  If a container (such as vector or deque during in=
sert or erase) tries to move the A, it will fail at compile time. std::swap=
 on this A will fail at compile time.  You can=E2=80=99t std::sort a sequen=
ce of these A=E2=80=99s.
>
> =E2=80=9CMove=E2=80=9D means move-if-you-can-else-copy from an rvalue.  A=
nd C++03 classes happily and correctly copy from rvalues.  When you add del=
eted move members to these C++03 classes, they just stop working everywhere=
 they used to work fine.


Well, lock_guard is already "not transferable" as its copy operations
are deleted and move
operations suppressed, so declaring the move operations deleted would
not really remove
functionality. It's not a _good use_ of a deleted special member
function, but it does no
harm in this case.

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Fri, 1 May 2015 11:40:53 -0400
Raw View
On May 1, 2015, at 11:36 AM, Ville Voutilainen <ville.voutilainen@gmail.com=
> wrote:
>=20
> On 1 May 2015 at 18:26, Howard Hinnant <howard.hinnant@gmail.com> wrote:
>> Ville is completely correct.  However I wanted to add something more:
>>=20
>>      ** Never, ever delete the special move members **
>>=20
>> If you see it done in somebody else=E2=80=99s code during review, jump u=
p and down while making lots of irritating noises.
>>=20
>> Now I=E2=80=99m the fist one to say =E2=80=9Cnever say never=E2=80=9D.  =
So I will admit: Someday someone is going to come up with a good use for de=
leted move members.  But that someone is going to be an expert in move sema=
ntics, and it hasn=E2=80=99t happened yet.  Be suspicious if you or your co=
lleague is the first to discover a good use case.
>>=20
>> Rationale:  At best, deleted move members are redundant, as they are in =
this case, and as Ville pointed out.  You can=E2=80=99t move a lock_guard w=
ith or without the deleted move members.  If they aren=E2=80=99t explicitly=
 declared, the compiler won=E2=80=99t generate them because of the user-dec=
lared copy members.
>>=20
>> At worst, deleted move members don=E2=80=99t do what you think they do:
>>=20
>> struct A
>> {
>>    A(const A&);
>>    A& operator=3D(const A&);
>>=20
>>    // I just want A to be copyable, not moveable
>>    A(A&&) =3D delete;
>>    A& operator=3D(A&&) =3D delete;
>> };
>>=20
>> This A is no longer very useful at all.  It can not be returned by value=
 from a factory function.  If a container (such as vector or deque during i=
nsert or erase) tries to move the A, it will fail at compile time. std::swa=
p on this A will fail at compile time.  You can=E2=80=99t std::sort a seque=
nce of these A=E2=80=99s.
>>=20
>> =E2=80=9CMove=E2=80=9D means move-if-you-can-else-copy from an rvalue.  =
And C++03 classes happily and correctly copy from rvalues.  When you add de=
leted move members to these C++03 classes, they just stop working everywher=
e they used to work fine.
>=20
>=20
> Well, lock_guard is already "not transferable" as its copy operations
> are deleted and move
> operations suppressed, so declaring the move operations deleted would
> not really remove
> functionality. It's not a _good use_ of a deleted special member
> function, but it does no
> harm in this case.

    ** At best redundant, at worst incorrect **

I should have clearly stated that my advice is a style guide.

Howard

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 1 May 2015 18:55:05 +0300
Raw View
On 1 May 2015 at 18:40, Howard Hinnant <howard.hinnant@gmail.com> wrote:
>     ** At best redundant, at worst incorrect **
>
> I should have clearly stated that my advice is a style guide.


Sure. I would say that the case of already-non-transferable type is a
somewhat rare
and somewhat pointless/useless exception to that style rule, an
exception under which
one can get away with a deleted move operation. :)

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Michael Spertus <mike_spertus@symantec.com>
Date: Mon, 4 May 2015 11:19:50 -0700
Raw View
--_000_6C4493F2142D417EA30CAC4A4D53BFA5symanteccom_
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Update version is on the wiki and we will discuss right after lunch

Sent from my iPhone

On Apr 30, 2015, at 3:55 PM, Arthur O'Dwyer <arthur.j.odwyer@gmail.com<mail=
to:arthur.j.odwyer@gmail.com>> wrote:

On Thursday, April 30, 2015 at 6:44:50 AM UTC-7, Michael Spertus wrote:

Thanks for your comments.  Arthur,

1.       Absolutely, the proposal is meant to be deadlock-free, and I just =
embarrassingly put in the wording wrong. Corrected wording will be on the w=
iki. (I realized this right after submitting, but it was too late=E2=80=A6 =
I did give my students an extra credit problem to find the mistake in the p=
aper).

Aha. This definitely removes 70% of my objection to the proposal. :)



2.       I considered requiring that all the mutex types be the same as you=
 suggest, but some of the most important use cases require different lock t=
ypes (like Howard=E2=80=99s operator=3D example in the paper), and it just =
seems inaccurate to do otherwise.

I wasn't necessarily suggesting that all the Mutexes... should have to be t=
he same; I was just pointing out that in the most common case, where they a=
re the same, it's ugly to force the user to write the same type many times =
in a row.  I deliberately didn't go down the rabbit hole of how to implemen=
t the prettier syntax, because I figured I had a strictly better idea with =
lock_tuple =E2=80=94 but you can certainly use SFINAE to allow lock_guard<M=
>'s constructor to take any number of arguments as long as all of them are =
of type M, or you could have lock_guard do type erasure so that the type in=
side the angle brackets no longer particularly matters... Those both have o=
bvious hurdles (where do you keep the extra arguments? type erasure require=
s heap allocation) but that's the general direction in which the rabbit hol=
e would take us.




3.       If N4471 is adopted, then you don=E2=80=99t need to worry about te=
mplate arguments.
auto guard =3D lock_guard(mtx1, mtx2);

N4471 (type deduction for constructors) is astronomically unlikely to get a=
ccepted IMHO, due to the "Challenges" identified in the proposal and the la=
ck of implementations or proposed wording.
Without N4471, we could propose making lock_guard move-constructible (which=
 I think is fine in practice because a lock_guard is just a bundle of refer=
ences, right?), and then we'd have this syntax:

    auto guard =3D make_lock_guard(mtx1, mtx2);



4.       Even without N4471, since all of the common use cases we could thi=
nk of involve 0, 1, or 2 mutexes (note that 0 locks is useful as well), the=
 notational overhead isn=E2=80=99t excessive.

IMHO the notational overhead for 2 mutexes is excessive =E2=80=94 that's wh=
at I meant by "ugly syntax". But this is a minor point, and could be solved=
 by make_lock_guard above.



5.       It seems like unique_lock might also want to work with any number =
of mutexes. In that case, a make_unique_lock(=E2=80=A6) would be another wa=
y to avoid specifying the template arguments. (Since lock_guard is not mova=
ble, you can=E2=80=99t do this with lock_guards).

Your proposal doesn't actually specify a variadic unique_lock, though, does=
 it?  If the concepts are coupled, maybe they should be proposed together.



6.       While I sympathize with your desire to avoid raw locking primitive=
s, I think the use cases in the paper are appropriate and of course, explic=
it locks are common in practices. C++ in general has the philosophy of offe=
ring both low-level primitives and high-level abstractions. In any case, if=
 we choose to provide raw locking primitives, I think the relevant question=
 is whether or not they are better if variadic (also see #8 below).

7.       In particular, I think the built-in deadlock avoidance (Once the w=
ording embarrassment from #1 above is fixed!) will result in more reliable =
programs in practice, if only because many user-defined types follow the ru=
le of three=E2=80=99s imprecation to provide assignment operators.

Can you elaborate on what you mean by "if only because ... assignment opera=
tors"?  I don't see how assignment operators and the Rule of Three are rela=
ted to the lock_guard proposal at all...?


8.       I=E2=80=99m having trouble seeing any reason we shouldn=E2=80=99t =
allow lock_guard to be variadic. The proposal is easy to ignore if you don=
=E2=80=99t like it, and IMO doesn=E2=80=99t add conceptual complexity. =E2=
=80=9Cstd::lock_guard can manage a set of locks of diverse types, just like=
 std::lock=E2=80=9D. I=E2=80=99ve never heard any of my students or coworke=
rs say that std::lock is more confusing because it was variadic.

std::lock is confusing because it's underspecified. ;)  This is way off-top=
ic, but I wonder how many people trust std::lock in practice, and how many =
simply roll their own lock-ordering scheme and/or exponential backoff schem=
e and/or whatever other schemes are popular for avoiding deadlock. I don't =
do synchronization stuff myself, but I wonder whether people who do, actual=
ly trust their standard library's std::lock to avoid livelock. And when the=
y move to a different platform, do they see the same performance characteri=
stics?

The value of std::lock_guard is that it's super simple, just like std::mute=
x. If I want a super simple thing, I use lock_guard; if I want a super robu=
st and DWIM thing, I use some higher-level system that supports transaction=
s or whatever, instead of continuing to mess around with raw locks. The que=
stion is whether this proposal is making lock_guard look more like a super =
robust and DWIM thing and attractive to newbies, when in fact it's still ve=
ry dangerous under the hood.

=E2=80=93Arthur

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<html><head><meta http-equiv=3D"content-type" content=3D"text/html; charset=
=3Dutf-8"></head><body dir=3D"auto"><div>Update version is on the wiki and =
we will discuss right after lunch<br><br>Sent from my iPhone</div><div><br>=
On Apr 30, 2015, at 3:55 PM, Arthur O'Dwyer &lt;<a href=3D"mailto:arthur.j.=
odwyer@gmail.com">arthur.j.odwyer@gmail.com</a>&gt; wrote:<br><br></div><bl=
ockquote type=3D"cite"><div><div dir=3D"ltr">On Thursday, April 30, 2015 at=
 6:44:50 AM UTC-7, Michael Spertus wrote:<blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;">    <div><p><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,sans-serif;color:#1f497d">Thanks for your comments. &nbsp;Arthu=
r,</span></p><p><span style=3D"font-size:11.0pt;font-family:&quot;Calibri&q=
uot;,sans-serif;color:#1f497d"><span>1.<span style=3D"font:7.0pt &quot;Time=
s New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></spa=
n><span style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-seri=
f;color:#1f497d">Absolutely, the proposal is meant to be deadlock-free, and=
 I just embarrassingly put in the wording wrong. Corrected wording will be =
on the wiki. (I realized this right after submitting, but it was too late=
=E2=80=A6 I did give my students an extra credit problem to find the mistak=
e in the paper).</span></p></div></blockquote><div>Aha. This definitely rem=
oves 70% of my objection to the proposal. :)</div><div><br></div><div>&nbsp=
;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><p><span style=3D"=
font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:#1f497d">=
<span>2.<span style=3D"font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style=3D"font-size:11.0=
pt;font-family:&quot;Calibri&quot;,sans-serif;color:#1f497d">I considered r=
equiring that all the mutex types be the same as you suggest, but some of t=
he most important use cases require different lock types (like Howard=E2=80=
=99s operator=3D example in the paper), and it just seems inaccurate to do =
otherwise.</span></p></div></blockquote><div>I wasn't necessarily suggestin=
g that all the <font face=3D"courier new, monospace">Mutexes...</font> shou=
ld <i>have</i> to be the same; I was just pointing out that in the most com=
mon case, where they <i>are</i> the same, it's ugly to force the user to wr=
ite the same type many times in a row. &nbsp;I deliberately didn't go down =
the rabbit hole of how to implement the prettier syntax, because I figured =
I had a strictly better idea with <font face=3D"courier new, monospace">loc=
k_tuple</font> =E2=80=94 but you can certainly use SFINAE to allow <font fa=
ce=3D"courier new, monospace">lock_guard&lt;M&gt;</font>'s constructor to t=
ake any number of arguments as long as all of them are of type <font face=
=3D"courier new, monospace">M</font>, or you could have <font face=3D"couri=
er new, monospace">lock_guard</font> do type erasure so that the type insid=
e the angle brackets no longer particularly matters... Those both have obvi=
ous hurdles (where do you keep the extra arguments? type erasure requires h=
eap allocation) but that's the general direction in which the rabbit hole w=
ould take us.</div><div><br></div><div><br></div><div>&nbsp;</div><blockquo=
te class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left:=
 1px #ccc solid;padding-left: 1ex;"><div><p><span style=3D"font-size:11.0pt=
;font-family:&quot;Calibri&quot;,sans-serif;color:#1f497d"><span>3.<span st=
yle=3D"font:7.0pt &quot;Times New Roman&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp; </span></span></span><span style=3D"font-size:11.0pt;font-family:&=
quot;Calibri&quot;,sans-serif;color:#1f497d">If N4471 is adopted, then you =
don=E2=80=99t need to worry about template arguments.<br>auto guard =3D loc=
k_guard(mtx1, mtx2);</span></p></div></blockquote><div>N4471 (type deductio=
n for constructors) is astronomically unlikely to get accepted IMHO, due to=
 the "Challenges" identified in the proposal and the lack of implementation=
s or proposed wording.</div><div>Without N4471, we could propose making <fo=
nt face=3D"courier new, monospace">lock_guard</font> move-constructible (wh=
ich <i>I think</i> is fine in practice because a <font face=3D"courier new,=
 monospace">lock_guard</font> is just a bundle of references, right?), and =
then we'd have this syntax:</div><div><br></div><div class=3D"prettyprint" =
style=3D"background-color: rgb(250, 250, 250); border: 1px solid rgb(187, 1=
87, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D=
"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">=
&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> g=
uard </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> make_lock_g=
uard</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">mtx1</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> mtx2</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span></div></code></div><div><br>&n=
bsp;<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><p><span st=
yle=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:#1=
f497d"><span>4.<span style=3D"font:7.0pt &quot;Times New Roman&quot;">&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style=3D"font-si=
ze:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:#1f497d">Even wi=
thout N4471, since all of the common use cases we could think of involve 0,=
 1, or 2 mutexes (note that 0 locks is useful as well), the notational over=
head isn=E2=80=99t excessive.</span></p></div></blockquote><div>IMHO the no=
tational overhead for 2 mutexes <i>is</i> excessive =E2=80=94 that's what I=
 meant by "ugly syntax". But this is a minor point, and could be solved by =
<font face=3D"courier new, monospace">make_lock_guard</font> above.</div><d=
iv><br></div><div><br></div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv><p><span style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-=
serif;color:#1f497d"><span>5.<span style=3D"font:7.0pt &quot;Times New Roma=
n&quot;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span st=
yle=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:#1=
f497d">It seems like unique_lock might also want to work with any number of=
 mutexes. In that case, a make_unique_lock(=E2=80=A6) would be another way =
to avoid specifying the template arguments. (Since lock_guard is not movabl=
e, you can=E2=80=99t do this with lock_guards).</span></p></div></blockquot=
e><div>Your proposal doesn't actually specify a variadic <font face=3D"cour=
ier new, monospace">unique_lock</font>, though, does it? &nbsp;If the conce=
pts are coupled, maybe they should be proposed together.</div><div><br></di=
v><div>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><p><sp=
an style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;col=
or:#1f497d"><span>6.<span style=3D"font:7.0pt &quot;Times New Roman&quot;">=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style=3D"fo=
nt-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:#1f497d">Wh=
ile I sympathize with your desire to avoid raw locking primitives, I think =
the use cases in the paper are appropriate and of course, explicit locks ar=
e common in practices. C++ in general has the philosophy of offering both l=
ow-level primitives and high-level abstractions. In any case, if we choose =
to provide raw locking primitives, I think the relevant question is whether=
 or not they are better if variadic (also see #8 below).</span></p><p><span=
 style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color=
:#1f497d"><span>7.<span style=3D"font:7.0pt &quot;Times New Roman&quot;">&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style=3D"font=
-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:#1f497d">In p=
articular, I think the built-in deadlock avoidance (Once the wording embarr=
assment from #1 above is fixed!) will result in more reliable programs in p=
ractice, if only because many user-defined types follow the rule of three=
=E2=80=99s imprecation to provide assignment operators.</span></p></div></b=
lockquote><div>Can you elaborate on what you mean by "if only because ... a=
ssignment operators"? &nbsp;I don't see how assignment operators and the Ru=
le of Three are related to the lock_guard proposal at all...?</div><div>&nb=
sp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><p><span style=
=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:#1f49=
7d"><span>8.<span style=3D"font:7.0pt &quot;Times New Roman&quot;">&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style=3D"font-size:=
11.0pt;font-family:&quot;Calibri&quot;,sans-serif;color:#1f497d">I=E2=80=99=
m having trouble seeing any reason we shouldn=E2=80=99t allow lock_guard to=
 be variadic. The proposal is easy to ignore if you don=E2=80=99t like it, =
and IMO doesn=E2=80=99t add conceptual complexity. =E2=80=9Cstd::lock_guard=
 can manage a set of locks of diverse types, just like std::lock=E2=80=9D. =
I=E2=80=99ve never heard any of my students or coworkers say that std::lock=
 is more confusing because it was variadic.</span></p></div></blockquote><d=
iv><font face=3D"courier new, monospace">std::lock</font> is confusing beca=
use it's underspecified. ;) &nbsp;This is way off-topic, but I wonder how m=
any people trust <font face=3D"courier new, monospace">std::lock</font> in =
practice, and how many simply roll their own lock-ordering scheme and/or ex=
ponential backoff scheme and/or whatever other schemes are popular for avoi=
ding deadlock. I don't do synchronization stuff myself, but I wonder whethe=
r people who do, actually trust their standard library's <font face=3D"cour=
ier new, monospace">std::lock</font> to avoid livelock. And when they move =
to a different platform, do they see the same performance characteristics?<=
/div><div><br></div><div>The value of <font face=3D"courier new, monospace"=
>std::lock_guard</font> is that it's super simple, just like <font face=3D"=
courier new, monospace">std::mutex</font>. If I want a super simple thing, =
I use <font face=3D"courier new, monospace">lock_guard</font>; if I want a =
super robust and DWIM thing, I use some higher-level system that supports t=
ransactions or whatever, instead of continuing to mess around with raw lock=
s. The question is whether this proposal is making <font face=3D"courier ne=
w, monospace">lock_guard</font> <i>look more like</i> a super robust and DW=
IM thing and attractive to newbies, when <i>in fact</i> it's still very dan=
gerous under the hood.</div><div><br></div><div>=E2=80=93Arthur</div></div>=
</div></blockquote></body></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--_000_6C4493F2142D417EA30CAC4A4D53BFA5symanteccom_--

.