Topic: N3562 - Some questions
Author: =?UTF-8?Q?Klaim_=2D_Jo=C3=ABl_Lamotte?= <mjklaim@gmail.com>
Date: Thu, 21 Mar 2013 01:27:37 +0100
Raw View
--047d7b3a7f92d855fc04d864676c
Content-Type: text/plain; charset=ISO-8859-1
I have some questions about this proposal:
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3562.pdf which is
very interesting.
1. Why does all the function interfaces proposed are working with pointers?
Is there a specific reason?
Because so far I can't find any and each time I think about replacing them
by references (including the default executor access function return type)
I see only enhancement at least because it makes clearer that null is not a
valid
value.
Am I missing something?
2. Is there a specific reason for having chosen std::chrono::system_clock
instead of high_resolution clock or is it just for example and is there is
no definite choice yet?
3. It is not clear to me what is serial_executor.
The words used in the document suggest that the closure go this path:
closure => seruak_executor.add() =>serial-executor-thread =>
underlying_executor().add()
With with the serial executor thread being just an additional queue of
closures.
Is my understanding correct?
4. If there is a need for an application to use a specific executor from
start to finish,
then setting the default executor also suggest that a default executor is
built before
main() execution, whatever the time spent on building it.
Would it be possible, if necessary, to provide a way to specify the default
executor in
a way that wouldn't trigger the unnecessary construction of the plateform's
default executor?
5. I have a vague idea of the use cases for having
non-default-global-unique executor, but
it would be helpful if there was (maybe in another document or a
non-official article) some examples
of setup using one or more executors which are not the default ones.
For example I feel that the loop_executor and a concrete child class to the
serial_executor would both be good candidates for some GUI systems, but
some remarks in the functions descriptions, in particular the intention to
use them in tests, makes me think I might be missing the real usage
"patterns" of these executors.
Thanks for your time.
Joel Lamotte
--
---
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/?hl=en.
--047d7b3a7f92d855fc04d864676c
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I have some questions about this proposal:=A0<a href=3D"ht=
tp://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3562.pdf">http://www=
..open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3562.pdf</a>=A0which is very=
interesting.<div>
<br></div><div style>1. Why does all the function interfaces proposed are w=
orking with pointers?</div><div style>Is there a specific reason?</div><div=
style><br></div><div style>Because so far I can't find any and each ti=
me I think about replacing them=A0</div>
<div style>by references (including the default executor access function re=
turn type)=A0</div><div style>I see only enhancement at least because it ma=
kes clearer that null is not a valid</div><div style>value.</div><div style=
>
<br></div><div style>Am I missing something?</div><div style><br></div><div=
style>2. Is there a specific reason for having chosen std::chrono::system_=
clock instead of high_resolution clock or is it just for example and is the=
re is no definite choice yet?</div>
<div style><br></div><div style>3. It is not clear to me what is serial_exe=
cutor.</div><div style>The words used in the document suggest that the clos=
ure go this path:</div><div style><br></div><div style>closure =3D> seru=
ak_executor.add() =3D>serial-executor-thread =3D> underlying_executor=
().add()<br>
<br>With with the serial executor thread being just an additional queue of =
closures.</div><div style><br></div><div style>Is my understanding correct?=
</div><div style><br></div><div style>4. If there is a need for an applicat=
ion to use a specific executor from start to finish,=A0</div>
<div style>then setting the default executor also suggest that a default ex=
ecutor is built before</div><div style>main() execution, whatever the time =
spent on building it.=A0</div><div style>Would it be possible, if necessary=
, to provide a way to specify the default executor in=A0</div>
<div style>a way that wouldn't trigger the unnecessary construction of =
the plateform's default executor?</div><div style><br></div><div style>=
5. I have a vague idea of the use cases for having non-default-global-uniqu=
e executor, but=A0</div>
<div style>it would be helpful if there was (maybe in another document or a=
non-official article) some examples</div><div style>of setup using one or =
more executors which are not the default ones.</div><div style>For example =
I feel that the loop_executor and a concrete child class to the serial_exec=
utor would both be good candidates for some GUI systems, but some remarks i=
n the functions descriptions, in particular the intention to use them in te=
sts, makes me think I might be missing the real usage "patterns" =
of these executors.</div>
<div style><br></div><div style><br></div><div style>Thanks for your time.<=
/div><div style><br></div><div style>Joel Lamotte</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" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
<br />
<br />
--047d7b3a7f92d855fc04d864676c--
.
Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Wed, 20 Mar 2013 19:12:45 -0700
Raw View
Pro tip: Include the document subject in comments about it, not just
the document number. That'll get interest from the right people. In
this case, it's Executors.
On Wed, Mar 20, 2013 at 5:27 PM, Klaim - Jo=EBl Lamotte <mjklaim@gmail.com>=
wrote:
> I have some questions about this proposal:
> http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3562.pdf which i=
s
> very interesting.
>
> 1. Why does all the function interfaces proposed are working with pointer=
s?
> Is there a specific reason?
>
> Because so far I can't find any and each time I think about replacing the=
m
> by references (including the default executor access function return type=
)
> I see only enhancement at least because it makes clearer that null is not=
a
> valid
> value.
>
> Am I missing something?
For the function returning executor* (default_executor() and
singleton_inline_executor()), I don't think there's much reason, aside
possibly from the fact that people are more used to making virtual
calls on pointers than references. For set_default_executor(), I think
it's more obvious that a function taking a pointer may capture that
pointer (which this one does). If it took a reference, it would look
more safe to destroy the executor before calling set_default_executor
again. I recognize that's not a strong argument.
Did you have any other functions in mind?
> 2. Is there a specific reason for having chosen std::chrono::system_clock
> instead of high_resolution clock or is it just for example and is there i=
s
> no definite choice yet?
I can see arguments for add_at(chrono::system_clock::time_point)
(running tasks at real-world points in time) and
add_{at,after}(chrono::stable_clock::duration) (timeouts that aren't
affected by system clock adjustments). high_resolution_clock seems
less appropriate because the executor can introduce an arbitrary delay
anyway, negating the high resolution.
> 3. It is not clear to me what is serial_executor.
> The words used in the document suggest that the closure go this path:
>
> closure =3D> seruak_executor.add() =3D>serial-executor-thread =3D>
> underlying_executor().add()
>
> With with the serial executor thread being just an additional queue of
> closures.
>
> Is my understanding correct?
There's no serial-executor-thread; it can be implemented as just a
queue of tasks that get added one at a time to the underlying
executor.
serial_executor provides a happens-before edge between every pair of
closures executed through it. One way to get such a FIFO executor is
to dedicate a thread to it, but serial_executor allows lots of such
closure chains to share a smaller set of underlying threads.
> 4. If there is a need for an application to use a specific executor from
> start to finish,
> then setting the default executor also suggest that a default executor is
> built before
> main() execution, whatever the time spent on building it.
> Would it be possible, if necessary, to provide a way to specify the defau=
lt
> executor in
> a way that wouldn't trigger the unnecessary construction of the plateform=
's
> default executor?
I could imagine default_executor() using something equivalent to
call_once() to create the platform executor at the point it's first
requested. If set_default_executor is called before then, there'd be
no need to incur the construction overhead. This would be a
quality-of-implementation concern; I don't think we need wording to
allow it.
> 5. I have a vague idea of the use cases for having non-default-global-uni=
que
> executor, but
> it would be helpful if there was (maybe in another document or a
> non-official article) some examples
> of setup using one or more executors which are not the default ones.
> For example I feel that the loop_executor and a concrete child class to t=
he
> serial_executor would both be good candidates for some GUI systems, but s=
ome
> remarks in the functions descriptions, in particular the intention to use
> them in tests, makes me think I might be missing the real usage "patterns=
"
> of these executors.
At one point, we used a serial_executor to guarantee that each HTTP
request was served as-if on a single thread. (Thread-local variables
were only used as caches and so didn't affect this.) I don't know if
we still do this: it was a stepping stone between an entirely
single-threaded system and an entirely multi-threaded system.
loop_executor can be very helpful for tests, where you want to check
that a library is in a particular state at controlled stopping points.
It can also be useful as a trivial message loop, but most message-loop
systems need somewhat more behavior on each iteration than it
provides.
You're right that the next version of the paper might be helped by
such examples, although I can't promise anyone will have time to add
them.
HTH,
Jeffrey
--=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/?hl=3Den.
.
Author: =?UTF-8?Q?Klaim_=2D_Jo=C3=ABl_Lamotte?= <mjklaim@gmail.com>
Date: Thu, 21 Mar 2013 13:01:45 +0100
Raw View
--f46d04462b7441c04204d86e1a12
Content-Type: text/plain; charset=ISO-8859-1
On Thu, Mar 21, 2013 at 3:12 AM, Jeffrey Yasskin <jyasskin@google.com>wrote:
> Pro tip: Include the document subject in comments about it, not just
> the document number. That'll get interest from the right people. In
> this case, it's Executors.
>
>
Ah yes sorry.
> For the function returning executor* (default_executor() and
> singleton_inline_executor()), I don't think there's much reason, aside
> possibly from the fact that people are more used to making virtual
> calls on pointers than references.
Ok, but I find it not a good reason as it suggests that in some cases we
should check the pointer
see if it's null before use, while this is forbidden by the requirements.
> For set_default_executor(), I think
> it's more obvious that a function taking a pointer may capture that
> pointer (which this one does). If it took a reference, it would look
> more safe to destroy the executor before calling set_default_executor
> again. I recognize that's not a strong argument.
>
>
I agree it is quite a weak argument, at least in my experience.
So far, a non-const reference function attribute means to me that no null
is acceptable.
If the function name is called set, it also highly suggest to me that there
will not be a copy of the
object so I should keep it alive until it's not set.
Which spawned a related question I forgot to ask: does using smart pointers
in the global/default-executor functions interface have been considered?
With the current C++11 smart pointers available, it would (most of the
time) force the user to use new/make_ to create the executor object
instead of using stack allocated objects (I suppose, in main() ). On the
other hand, it would provide some explicit guarantees on the lifetime of
the default executor,
at least using unique_ptr. Using shared_ptr, there would be an additional
thread safety guarantee if the default executor is set while code is
already running with
the initial default executor.
I suppose there would be other consequences and things to consider, in
particular related to the end of main().
Does this possibility, using shared pointer for these functions, have been
examined already?
> Did you have any other functions in mind?
>
>
I was asking for every pointer appearing in the document, including this:
class serial_executor : public executor {
public:
explicit serial_executor(executor*underlying_executor); // here
> > 2. Is there a specific reason for having chosen std::chrono::system_clock
> > instead of high_resolution clock or is it just for example and is there
> is
> > no definite choice yet?
>
> I can see arguments for add_at(chrono::system_clock::time_point)
> (running tasks at real-world points in time) and
> add_{at,after}(chrono::stable_clock::duration) (timeouts that aren't
> affected by system clock adjustments). high_resolution_clock seems
> less appropriate because the executor can introduce an arbitrary delay
> anyway, negating the high resolution.
>
>
I see.
> > 3. It is not clear to me what is serial_executor.
> > The words used in the document suggest that the closure go this path:
> >
> > closure => seruak_executor.add() =>serial-executor-thread =>
> > underlying_executor().add()
> >
> > With with the serial executor thread being just an additional queue of
> > closures.
> >
> > Is my understanding correct?
>
> There's no serial-executor-thread; it can be implemented as just a
> queue of tasks that get added one at a time to the underlying
> executor.
>
> serial_executor provides a happens-before edge between every pair of
> closures executed through it. One way to get such a FIFO executor is
> to dedicate a thread to it, but serial_executor allows lots of such
> closure chains to share a smaller set of underlying threads.
>
>
Ok so it just force FIFO order of task insertion into another executor.
> > 4. If there is a need for an application to use a specific executor from
> > start to finish,
> > then setting the default executor also suggest that a default executor is
> > built before
> > main() execution, whatever the time spent on building it.
> > Would it be possible, if necessary, to provide a way to specify the
> default
> > executor in
> > a way that wouldn't trigger the unnecessary construction of the
> plateform's
> > default executor?
>
> I could imagine default_executor() using something equivalent to
> call_once() to create the platform executor at the point it's first
> requested. If set_default_executor is called before then, there'd be
> no need to incur the construction overhead. This would be a
> quality-of-implementation concern; I don't think we need wording to
> allow it.
>
>
Right.
> > 5. I have a vague idea of the use cases for having
> non-default-global-unique
> > executor, but
> > it would be helpful if there was (maybe in another document or a
> > non-official article) some examples
> > of setup using one or more executors which are not the default ones.
> > For example I feel that the loop_executor and a concrete child class to
> the
> > serial_executor would both be good candidates for some GUI systems, but
> some
> > remarks in the functions descriptions, in particular the intention to use
> > them in tests, makes me think I might be missing the real usage
> "patterns"
> > of these executors.
>
> At one point, we used a serial_executor to guarantee that each HTTP
> request was served as-if on a single thread. (Thread-local variables
> were only used as caches and so didn't affect this.) I don't know if
> we still do this: it was a stepping stone between an entirely
> single-threaded system and an entirely multi-threaded system.
>
> loop_executor can be very helpful for tests, where you want to check
> that a library is in a particular state at controlled stopping points.
> It can also be useful as a trivial message loop, but most message-loop
> systems need somewhat more behavior on each iteration than it
> provides.
>
>
I'm developing a system which look like it would benefit from it too
because of the
possibility to execute a batch of queued tasks on demand, but not the ones
being added after the function call.
In my context, that's exactly what I do (in a less expert way but I'm
fixing it) because I need
some part of the application to execute such batch at a specific frequency
(which depending on the case can have varied meanings).
I don't know if such setup is common so I don't suggest such executor
implementation but I see this a lot in my context.
> You're right that the next version of the paper might be helped by
> such examples, although I can't promise anyone will have time to add
> them.
>
Yes I think maybe a non-standard article published later would clarify the
use cases for non-committee users.
I have no idea if the committee needs such use case example in papers.
Joel Lamotte
--
---
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/?hl=en.
--f46d04462b7441c04204d86e1a12
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">On Thu, Mar 21, 2013 at 3:12 AM, Jeffrey Yasskin <span dir=3D"ltr">=
<<a href=3D"mailto:jyasskin@google.com" target=3D"_blank">jyasskin@googl=
e.com</a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;p=
adding-left:1ex">Pro tip: Include the document subject in comments about it=
, not just<br>
the document number. That'll get interest from the right people. In<br>
this case, it's Executors.<br>
<div class=3D"im"><br></div></blockquote><div><br></div><div style>Ah yes s=
orry.</div><div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);=
border-left-style:solid;padding-left:1ex">
For the function returning executor* (default_executor() and<br>
singleton_inline_executor()), I don't think there's much reason, as=
ide<br>
possibly from the fact that people are more used to making virtual<br>
calls on pointers than references. </blockquote><div><br></div><div style>O=
k, but I find it not a good reason as it suggests that in some cases we sho=
uld check the pointer</div><div style>see if it's null before use, whil=
e this is forbidden by the requirements.</div>
<div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left=
-style:solid;padding-left:1ex">For set_default_executor(), I think<br>
it's more obvious that a function taking a pointer may capture that<br>
pointer (which this one does). If it took a reference, it would look<br>
more safe to destroy the executor before calling set_default_executor<br>
again. I recognize that's not a strong argument.<br>
<br></blockquote><div><br></div><div style>I agree it is quite a weak argum=
ent, at least in my experience.</div><div style>So far, a non-const referen=
ce function attribute means to me that no null is acceptable.</div><div sty=
le>
If the function name is called set, it also highly suggest to me that there=
will not be a copy of the=A0</div><div style>object so I should keep it al=
ive until it's not set.</div><div style><br></div><div style>Which spaw=
ned a related question I forgot to ask: does using smart pointers in the gl=
obal/default-executor functions interface have been considered?</div>
<div style>With the current C++11 smart pointers available, it would (most =
of the time) force the user to use new/make_ to create the executor object<=
/div><div style>instead of using stack allocated objects (I suppose, in mai=
n() ). On the other hand, it would provide some explicit guarantees on the =
lifetime of the default executor,</div>
<div style>at least using unique_ptr. Using shared_ptr, there would be an a=
dditional thread safety guarantee if the default executor is set while code=
is already running with=A0</div><div style>the initial default executor.</=
div>
<div style>I suppose there would be other consequences and things to consid=
er, in particular related to the end of main().=A0</div><div style>Does thi=
s possibility, using shared pointer for these functions, have been examined=
already?</div>
<div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left=
-style:solid;padding-left:1ex">
Did you have any other functions in mind?<br>
<div class=3D"im"><br></div></blockquote><div><br></div><div style>I was as=
king for every pointer appearing in the document, including this:</div><div=
style><div>=A0 =A0 class serial_executor : public executor {</div><div>=A0=
=A0 =A0 =A0 public:</div>
<div>=A0 =A0 =A0 =A0 explicit serial_executor(executor*underlying_executor)=
; // here</div><div><br></div><div><br></div></div><div>=A0</div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width=
:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-lef=
t:1ex">
<div class=3D"im">
> 2. Is there a specific reason for having chosen std::chrono::system_cl=
ock<br>
> instead of high_resolution clock or is it just for example and is ther=
e is<br>
> no definite choice yet?<br>
<br>
</div>I can see arguments for add_at(chrono::system_clock::time_point)<br>
(running tasks at real-world points in time) and<br>
add_{at,after}(chrono::stable_clock::duration) (timeouts that aren't<br=
>
affected by system clock adjustments). high_resolution_clock seems<br>
less appropriate because the executor can introduce an arbitrary delay<br>
anyway, negating the high resolution.<br>
<div class=3D"im"><br></div></blockquote><div><br></div><div style>I see.</=
div><div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-=
left-style:solid;padding-left:1ex">
<div class=3D"im">
> 3. It is not clear to me what is serial_executor.<br>
> The words used in the document suggest that the closure go this path:<=
br>
><br>
> closure =3D> seruak_executor.add() =3D>serial-executor-thread =
=3D><br>
> underlying_executor().add()<br>
><br>
> With with the serial executor thread being just an additional queue of=
<br>
> closures.<br>
><br>
> Is my understanding correct?<br>
<br>
</div>There's no serial-executor-thread; it can be implemented as just =
a<br>
queue of tasks that get added one at a time to the underlying<br>
executor.<br>
<br>
serial_executor provides a happens-before edge between every pair of<br>
closures executed through it. One way to get such a FIFO executor is<br>
to dedicate a thread to it, but serial_executor allows lots of such<br>
closure chains to share a smaller set of underlying threads.<br>
<div class=3D"im"><br></div></blockquote><div><br></div><div style>Ok so it=
just force FIFO order of task insertion into another executor.</div><div>=
=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-styl=
e:solid;padding-left:1ex">
<div class=3D"im">
> 4. If there is a need for an application to use a specific executor fr=
om<br>
> start to finish,<br>
> then setting the default executor also suggest that a default executor=
is<br>
> built before<br>
> main() execution, whatever the time spent on building it.<br>
> Would it be possible, if necessary, to provide a way to specify the de=
fault<br>
> executor in<br>
> a way that wouldn't trigger the unnecessary construction of the pl=
ateform's<br>
> default executor?<br>
<br>
</div>I could imagine default_executor() using something equivalent to<br>
call_once() to create the platform executor at the point it's first<br>
requested. If set_default_executor is called before then, there'd be<br=
>
no need to incur the construction overhead. This would be a<br>
quality-of-implementation concern; I don't think we need wording to<br>
allow it.<br>
<div class=3D"im"><br></div></blockquote><div><br></div><div style>Right.</=
div><div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-=
left-style:solid;padding-left:1ex">
<div class=3D"im">
> 5. I have a vague idea of the use cases for having non-default-global-=
unique<br>
> executor, but<br>
> it would be helpful if there was (maybe in another document or a<br>
> non-official article) some examples<br>
> of setup using one or more executors which are not the default ones.<b=
r>
> For example I feel that the loop_executor and a concrete child class t=
o the<br>
> serial_executor would both be good candidates for some GUI systems, bu=
t some<br>
> remarks in the functions descriptions, in particular the intention to =
use<br>
> them in tests, makes me think I might be missing the real usage "=
patterns"<br>
> of these executors.<br>
<br>
</div>At one point, we used a serial_executor to guarantee that each HTTP<b=
r>
request was served as-if on a single thread. (Thread-local variables<br>
were only used as caches and so didn't affect this.) I don't know i=
f<br>
we still do this: it was a stepping stone between an entirely<br>
single-threaded system and an entirely multi-threaded system.<br>
<br>
loop_executor can be very helpful for tests, where you want to check<br>
that a library is in a particular state at controlled stopping points.<br>
It can also be useful as a trivial message loop, but most message-loop<br>
systems need somewhat more behavior on each iteration than it<br>
provides.<br>
<br></blockquote><div><br></div><div style>I'm developing a system whic=
h look like it would benefit from it too because of the</div><div style>pos=
sibility to execute a batch of queued tasks on demand, but not the ones bei=
ng added after the function call.</div>
<div style>In my context, that's exactly what I do (in a less expert wa=
y but I'm fixing it) because I need=A0</div><div style>some part of the=
application to execute such batch at a specific frequency (which depending=
on the case can have varied meanings).</div>
<div style>I don't know if such setup is common so I don't suggest =
such executor implementation but I see this a lot in my context.</div><div>=
=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-styl=
e:solid;padding-left:1ex">
You're right that the next version of the paper might be helped by<br>
such examples, although I can't promise anyone will have time to add<br=
>
them.<br></blockquote><div><br></div><div style>Yes I think maybe a non-sta=
ndard article published later would clarify the use cases for non-committee=
users.</div><div style>I have no idea if the committee needs such use case=
example in papers.</div>
<div style><br></div><div style>Joel Lamotte</div><div style><br></div></di=
v></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" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
<br />
<br />
--f46d04462b7441c04204d86e1a12--
.
Author: Matt Austern <austern@google.com>
Date: Thu, 21 Mar 2013 09:36:40 -0700
Raw View
--20cf307d054079a80904d871f1da
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
On Thu, Mar 21, 2013 at 5:01 AM, Klaim - Jo=EBl Lamotte <mjklaim@gmail.com>=
wrote:
>
>
>
> On Thu, Mar 21, 2013 at 3:12 AM, Jeffrey Yasskin <jyasskin@google.com>wro=
te:
>
>> Pro tip: Include the document subject in comments about it, not just
>> the document number. That'll get interest from the right people. In
>> this case, it's Executors.
>>
>>
> Ah yes sorry.
>
>
>> For the function returning executor* (default_executor() and
>> singleton_inline_executor()), I don't think there's much reason, aside
>> possibly from the fact that people are more used to making virtual
>> calls on pointers than references.
>
>
> Ok, but I find it not a good reason as it suggests that in some cases we
> should check the pointer
> see if it's null before use, while this is forbidden by the requirements.
>
>
>> For set_default_executor(), I think
>> it's more obvious that a function taking a pointer may capture that
>> pointer (which this one does). If it took a reference, it would look
>> more safe to destroy the executor before calling set_default_executor
>> again. I recognize that's not a strong argument.
>>
>>
> I agree it is quite a weak argument, at least in my experience.
> So far, a non-const reference function attribute means to me that no null
> is acceptable.
> If the function name is called set, it also highly suggest to me that
> there will not be a copy of the
> object so I should keep it alive until it's not set.
>
Some of this is a consequence of Google C++ style, in which pointers are
used more heavily than non-const references and in which the
pointer/reference distinction may have different connotations than it does
for people whose C++ style is slightly different. Most of the authors of
this proposal are Google programmers, so it's quite possible that we let
our local style creep into it too much.
We should think about that a bit. You may be right that replacing some of
those pointers with references would be clearer.
--Matt
--=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/?hl=3Den.
--20cf307d054079a80904d871f1da
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Thu, Mar 21, 2013 at 5:01 AM, Klaim - Jo=EBl Lamotte <s=
pan dir=3D"ltr"><<a href=3D"mailto:mjklaim@gmail.com" target=3D"_blank">=
mjklaim@gmail.com</a>></span> wrote:<br><div class=3D"gmail_extra"><div =
class=3D"gmail_quote">
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><div class=3D"gmail_ext=
ra"><br><br><div class=3D"gmail_quote"><div class=3D"im">On Thu, Mar 21, 20=
13 at 3:12 AM, Jeffrey Yasskin <span dir=3D"ltr"><<a href=3D"mailto:jyas=
skin@google.com" target=3D"_blank">jyasskin@google.com</a>></span> wrote=
:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;p=
adding-left:1ex">Pro tip: Include the document subject in comments about it=
, not just<br>
the document number. That'll get interest from the right people. In<br>
this case, it's Executors.<br>
<div><br></div></blockquote><div><br></div></div><div>Ah yes sorry.</div><d=
iv class=3D"im"><div>=A0</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,=
204);border-left-style:solid;padding-left:1ex">
For the function returning executor* (default_executor() and<br>
singleton_inline_executor()), I don't think there's much reason, as=
ide<br>
possibly from the fact that people are more used to making virtual<br>
calls on pointers than references. </blockquote><div><br></div></div><div>O=
k, but I find it not a good reason as it suggests that in some cases we sho=
uld check the pointer</div><div>see if it's null before use, while this=
is forbidden by the requirements.</div>
<div class=3D"im">
<div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left=
-style:solid;padding-left:1ex">For set_default_executor(), I think<br>
it's more obvious that a function taking a pointer may capture that<br>
pointer (which this one does). If it took a reference, it would look<br>
more safe to destroy the executor before calling set_default_executor<br>
again. I recognize that's not a strong argument.<br>
<br></blockquote><div><br></div></div><div>I agree it is quite a weak argum=
ent, at least in my experience.</div><div>So far, a non-const reference fun=
ction attribute means to me that no null is acceptable.</div><div>
If the function name is called set, it also highly suggest to me that there=
will not be a copy of the=A0</div><div>object so I should keep it alive un=
til it's not set.</div></div></div></div></blockquote><div><br></div>
<div style>Some of this is a consequence of Google C++ style, in which poin=
ters are used more heavily than non-const references and in which the point=
er/reference distinction may have different connotations than it does for p=
eople whose C++ style is slightly different. Most of the authors of this pr=
oposal are Google programmers, so it's quite possible that we let our l=
ocal style creep into it too much.</div>
<div style><br></div><div style>We should think about that a bit. You may b=
e right that replacing some of those pointers with references would be clea=
rer.</div><div style><br></div><div style>=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0--Matt</div>
</div></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" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
<br />
<br />
--20cf307d054079a80904d871f1da--
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Thu, 21 Mar 2013 16:12:15 -0400
Raw View
More thoughts about executors:
Page 4:
Such a facility has the potential to be dangerous or complicated
because it would require aggregating multiple exceptions thrown by
closures executing simultaneously.
I don't think you actually mention which facility "Such a facility" is
referring to. (Although I can figure out that it is one that gathers
exceptions together and someone communicates them back to the calling
thread(s)).
One other option, besides terminating, is to just ignore the
exception. (In Premiere, we just logged it and kept going.) Not
saying that it is the best option, just an option.
The other option would be to leave it "undefined behaviour". So I
guess that is 2 other options.
But I'm not against termination - the user can always wrap their
closure in one that catches the exception to make sure it doesn't
cause termination if that is what they want. But if we thought that
ignoring was a common case, it would be nice if a derived executor
could do it for us. ie making it UB means a derived executor can
decide how to handle exceptions.
You could also call a virtual exception_occurred(std::exception &); so
as to make it clearly a per-executor decision. (At least for
exceptions that derive from std::exception).
So I guess that is 3 options?
Tony
--
---
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/?hl=en.
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Thu, 21 Mar 2013 16:21:18 -0400
Raw View
On Thu, Mar 21, 2013 at 4:12 PM, Tony V E <tvaneerd@gmail.com> wrote:
> More thoughts about executors:
Page 5-6
executor::~executor()
Effects: Destroys the executor.
Synchronization: All closure initiations happen before the completion
of the executor
destructor. [Note: As a consequence, all closures that will ever
execute will have
completed before the completion of the executor destructor, and programmers can
protect against data races with the destruction of the environment.
Whether or not a
concrete executor initiates all closures is defined by the semantics
defined by that
concrete executor.]
Does it even make sense to be specific about initiation vs completion
of a closure? I don't know how you would define 'initiation'.
--
---
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/?hl=en.
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Thu, 21 Mar 2013 16:24:29 -0400
Raw View
On Thu, Mar 21, 2013 at 4:21 PM, Tony V E <tvaneerd@gmail.com> wrote:
> On Thu, Mar 21, 2013 at 4:12 PM, Tony V E <tvaneerd@gmail.com> wrote:
>> More thoughts about executors:
>
Page 6
does executor::add() throw if the queue is full? Wait? U.B.?
I think the intro said it doesn't wait. Is a fixed-size queue an
acceptable implementation?
--
---
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/?hl=en.
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Thu, 21 Mar 2013 16:31:22 -0400
Raw View
On Thu, Mar 21, 2013 at 4:24 PM, Tony V E <tvaneerd@gmail.com> wrote:
>>> More thoughts about executors:
>>
>
What is the use case behind singleton_inline_executor()?
And that's 2 questions:
- why do I want immediate-execution
- why do I want it to be a singleton (I guess otherwise it is a leak...?)
Would a per-thread inline-executor be OK (not that I see any real
reason for it, but why limit it?)
Is the 'singleton' part of the name important? Would
inline_executor() be enough?
--
---
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/?hl=en.
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Thu, 21 Mar 2013 16:47:57 -0400
Raw View
On Thu, Mar 21, 2013 at 4:31 PM, Tony V E <tvaneerd@gmail.com> wrote:
>>>> More thoughts about executors:
>>>
>>
>
serial executors:
- is it basically a single-threaded executor that wraps added closures
in closures that call add() on the underlying executor? So only the
underlying adding is serialized?
- what does "happen before" mean in "Earlier serial_executor closures
happen before later closures". I think they are only scheduled
before? what does "closures happen" mean?
- if the underlying executor is multi-threaded, I don't think a set of
closures can tell whether the serial_executor really did FIFO or not,
correct? I can only tell if I write the underlying executor?
- how does the destructor wait for the closure (running on the inner
executor) to finish? Every added closure is wrapped in a closure that
has a mutex? (Which is then wrapped in a closure that does the add -
see question 1. (The wrappings could be flattened I suppose))
maybe I'm completely confused. Sorry.
thread_pool::~thread_pool()
Waits for closures to complete *then* joins the threads. 'then'? or
is joining how it waits for completion. I guess the effect is the
same. 'and' might be better? or just semi-colon?
--
---
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/?hl=en.
.
Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Sun, 24 Mar 2013 10:50:46 -0700
Raw View
On Thu, Mar 21, 2013 at 1:12 PM, Tony V E <tvaneerd@gmail.com> wrote:
> More thoughts about executors:
>
> Page 4:
>
> Such a facility has the potential to be dangerous or complicated
> because it would require aggregating multiple exceptions thrown by
> closures executing simultaneously.
>
> I don't think you actually mention which facility "Such a facility" is
> referring to. (Although I can figure out that it is one that gathers
> exceptions together and someone communicates them back to the calling
> thread(s)).
>
> One other option, besides terminating, is to just ignore the
> exception. (In Premiere, we just logged it and kept going.) Not
> saying that it is the best option, just an option.
> The other option would be to leave it "undefined behaviour". So I
> guess that is 2 other options.
>
> But I'm not against termination - the user can always wrap their
> closure in one that catches the exception to make sure it doesn't
> cause termination if that is what they want. But if we thought that
> ignoring was a common case, it would be nice if a derived executor
> could do it for us. ie making it UB means a derived executor can
> decide how to handle exceptions.
Our thought was that it was easy to write a helper function that did
whatever behavior the user wanted when an exception escaped. I'm
nervous about specifying undefined behavior, but maybe that's the
right thing to do on the base executor type, and then we can say that
loop_executor, serial_executor, and inline_executor define that as
terminate().
> You could also call a virtual exception_occurred(std::exception &); so
> as to make it clearly a per-executor decision. (At least for
> exceptions that derive from std::exception).
Ew. :) I don't like this because it encourages implementation
inheritance. If we make the executors [[final]], as I think we should
but didn't make it into the paper, then no code would ever call that
function.
> Page 5-6
>
> executor::~executor()
> Effects: Destroys the executor.
> Synchronization: All closure initiations happen before the completion
> of the executor
> destructor. [Note: As a consequence, all closures that will ever
> execute will have
> completed before the completion of the executor destructor, and programmers can
> protect against data races with the destruction of the environment.
> Whether or not a
> concrete executor initiates all closures is defined by the semantics
> defined by that
> concrete executor.]
>
> Does it even make sense to be specific about initiation vs completion
> of a closure? I don't know how you would define 'initiation'.
I think that this Synchronization clause needs to talk about closure
returns, not initiations, since we don't want it to be possible for a
closure to keep running after its executor is destroyed.
Generally, when creating happens-before edges to or from functions, we
can say that X happens before a function is called (initiated), or
that a function's return (completion) happens before X. Saying that a
function's initiation happens before X isn't implementable because
whatever atomic operation synchronizes with X has to be sequenced
either before or after all of the function, and if it's sequenced
before, the call itself doesn't happen before X.
> Page 6
>
> does executor::add() throw if the queue is full? Wait? U.B.?
>
> I think the intro said it doesn't wait. Is a fixed-size queue an
> acceptable implementation?
A fixed-size queue is not an acceptable implementation. Having add()
wait causes bugs in single-threaded programs or in executors with a
fixed number of worker threads. U.B. is unacceptable because users
can't guarantee that they won't exceed the queue size. Throwing isn't
a good idea again because exceeding a fixed-size queue isn't erroneous
behavior.
> What is the use case behind singleton_inline_executor()?
> And that's 2 questions:
> - why do I want immediate-execution
I've seen it used in a couple places, but the one that comes to mind
right now is the argument to future::then(callback, executor), when
the callback isn't expected to run for very long and so can execute on
the same thread as completes the future. (Note that the executor
argument to future::then doesn't work if executor::add can block.)
> - why do I want it to be a singleton (I guess otherwise it is a leak...?)
> Would a per-thread inline-executor be OK (not that I see any real
> reason for it, but why limit it?)
The inline executor doesn't need any state, so there's no need for
more than one instance.
> Is the 'singleton' part of the name important? Would
> inline_executor() be enough?
Originally, we had an inline_executor() that returned a
unique_ptr<executor>, so singleton_inline_executor distinguished that.
Now that inline_executor is gone, we could re-use its name.
> serial executors:
>
> - is it basically a single-threaded executor that wraps added closures
> in closures that call add() on the underlying executor? So only the
> underlying adding is serialized?
No, the closures themselves are serialized. One closure can't be added
to the underlying executor until the previous one returns. (Although
there can be a small optimization where the serial executor add()s a
looping function to the underlying executor, which runs serial
closures until it runs out and then yields. Fairness, if any, is
either QoI or future work.)
> - what does "happen before" mean in "Earlier serial_executor closures
> happen before later closures". I think they are only scheduled
> before? what does "closures happen" mean?
That's "happen before" from the memory model.
> - if the underlying executor is multi-threaded, I don't think a set of
> closures can tell whether the serial_executor really did FIFO or not,
> correct? I can only tell if I write the underlying executor?
Nope, because the closures on a serial_executor happen-before each
other, it's easy to tell that they ran in order of add().
> - how does the destructor wait for the closure (running on the inner
> executor) to finish? Every added closure is wrapped in a closure that
> has a mutex? (Which is then wrapped in a closure that does the add -
> see question 1. (The wrappings could be flattened I suppose))
Roughly, yes. This is needed anyway in order to serialize the closure
executions.
> thread_pool::~thread_pool()
> Waits for closures to complete *then* joins the threads. 'then'? or
> is joining how it waits for completion. I guess the effect is the
> same. 'and' might be better? or just semi-colon?
The effect is the same, but certainly the closures will return before
any of the threads join, so I think "then" is appropriate. I guess
your interpretation is that this sentence talks about the call to
thread::join(), while I think we meant to talk about the return, or
the OS join event.
You mentioned privately that users actually want to give a system some
characteristics of their task, and that this has to sit somewhat above
the level of executors. Yes. The basic idea is that the user would say
"give me an executor for tasks with properties X, Y, and Z", and then
would add tasks to that executor. We aren't proposing that "give me an
executor" function, because we don't know what it looks like, but
standardizing 'executor' itself makes it easier for libraries to
figure it out.
HTH,
Jeffrey
--
---
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/?hl=en.
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 24 Mar 2013 19:59:48 +0200
Raw View
On 24 March 2013 19:50, Jeffrey Yasskin <jyasskin@google.com> wrote:
>> You could also call a virtual exception_occurred(std::exception &); so
>> as to make it clearly a per-executor decision. (At least for
>> exceptions that derive from std::exception).
> Ew. :) I don't like this because it encourages implementation
> inheritance. If we make the executors [[final]], as I think we should
> but didn't make it into the paper, then no code would ever call that
> function.
For what it's worth, I don't think you should make the executors final, and I
would be opposed to their being final. Preventing inheriting wrappers is unwise.
--
---
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/?hl=en.
.
Author: Peter Sommerlad <peter.sommerlad@hsr.ch>
Date: Thu, 11 Apr 2013 14:08:22 +0200
Raw View
Hi all,
I have some remarks about the design decisions proposed in N3562. I try not=
to repeat all of what has previously been said (e.g., pointers vs. referen=
ces).
First of all: just because it is existing practice and Google or Microsoft =
is doing it, doesn't mean it is inherently good design (for example, Google=
Test's internal design is quite doubtful from a viewpoint of modern C++).
While I believe such a facility is necessary and I can understand most of t=
he argumentation why it is proposed as is, I have a bad gut feeling about i=
ts design.
First of all, it proposes the (two times!) Singleton anti-pattern for the g=
lobal default executor and singleton_inline_executor(). I would strongly op=
pose to the proposal if those globals are kept. Executors should be part of=
an explicit interface and relying on a global default executor encourages =
designing code that is hard to (unit-)test. (as it is given in the async pr=
oposal from N3558).
The same argument about unit-testability also holds for the closure type be=
ing std::function<void()>. In that way, one can not write a test case again=
st a closure without relying on side-effects of the closure code. We might =
recognize that side-effects tend to be evil beasts and after a long time te=
aching students to write good unit tests proposing an API that requires unt=
estable components is hard to swallow for me. I know there are reasons for =
doing so, but I am not convinced that there might not be another way of des=
igning it without the need for a side-effect laden closure.
I like the proposed async() extension to take an executor as an argument (i=
n contrast to a launch policy) in N3558. That should be done by template an=
d reference parameter, but also here the argument of non-templatized versio=
n is mute, because async is inherently template function.
I might be able to go in great detail and would happily discuss that face t=
o face, but due to a family emergency (wife broke her leg) I had to cancel =
my trip to Bristol and am unable to do so right now in an email.
Regards
Peter.
--=20
Prof. Peter Sommerlad
Institut f=FCr Software: Bessere Software - Einfach, Schneller!
HSR Hochschule f=FCr Technik Rapperswil
Oberseestr 10, Postfach 1475, CH-8640 Rapperswil
http://ifs.hsr.ch http://cute-test.com http://linticator.com http://includa=
tor.com
tel:+41 55 222 49 84 =3D=3D mobile:+41 79 432 23 32
fax:+41 55 222 46 29 =3D=3D mailto:peter.sommerlad@hsr.ch
--=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/?hl=3Den.
.