Discussion:
[asio-users] Strange strand dispatch issue on windows
Wade Berrier
2014-06-30 22:26:07 UTC
Permalink
Hello,

Attached is a test program testing strand::dispatch().

First question: is it reasonable to depend on the ordering of the
print statements?

Assuming that is the case (which it seems to be, according to the
documentation regarding dispatch()), I'm seeing a case on Windows
where this isn't happening. #2 and #3 get swapped when either:

a. asio is compiled as a shared library according to the
documentation (ie: compiling boost/asio/impl/src.hpp and defining
BOOST_ASIO_DYN_LINK)

b. asio is being used as header only, but my executable is loading a
dll that is calling dispatch on a strand allocated by the host
executable.

Second question: is this a bug?

My Windows setup:
-Visual Studio 2010 SP1 32bit
-Windows XP (seeing the same behavior on Windows 7)
-Boost 1.55 variant=release thread=multi link=shared

Also, I've run depends.exe on the .dll and .exe to verify that I'm not
mixing release/debug runtime .dlls, which seemed like it could have
been the culprit.

Note, both of these cases work as expected on linux.

In tracing the code, it seems to come down to callstack::contains
returning false when it should be returning true, and callstack is
using thread local storage to maintain that data.

Any thoughts, pointers, or fixes would be greatly appreciated.

Wade Berrier
Roger Austin (Australia)
2014-07-01 01:37:38 UTC
Permalink
Hi Wade,

strand::dispatch guarantees only that the handlers will not execute concurrently, not the order of execution. strand::post guarantees that handlers will execute in the order they were posted. This is still not well-documented despite having been noted many years ago: http://boost.2283326.n4.nabble.com/asio-Order-of-handler-processing-within-a-strand-td2617483.html. It is sort-of-implied by the documentation in that strand::dispatch is allowed to call the handler directly if the calling thread meets the requirements of the strand, while strand::post is not (i.e. the handler is always put on the queue).

Roger Austin

-----Original Message-----
From: Wade Berrier [mailto:***@gmail.com]
Sent: Tuesday, 1 July 2014 8:26 AM
To: asio-***@lists.sourceforge.net
Subject: [asio-users] Strange strand dispatch issue on windows

Hello,

Attached is a test program testing strand::dispatch().

First question: is it reasonable to depend on the ordering of the print statements?

Assuming that is the case (which it seems to be, according to the documentation regarding dispatch()), I'm seeing a case on Windows where this isn't happening. #2 and #3 get swapped when either:

a. asio is compiled as a shared library according to the documentation (ie: compiling boost/asio/impl/src.hpp and defining
BOOST_ASIO_DYN_LINK)

b. asio is being used as header only, but my executable is loading a dll that is calling dispatch on a strand allocated by the host executable.

Second question: is this a bug?

My Windows setup:
-Visual Studio 2010 SP1 32bit
-Windows XP (seeing the same behavior on Windows 7) -Boost 1.55 variant=release thread=multi link=shared

Also, I've run depends.exe on the .dll and .exe to verify that I'm not mixing release/debug runtime .dlls, which seemed like it could have been the culprit.

Note, both of these cases work as expected on linux.

In tracing the code, it seems to come down to callstack::contains returning false when it should be returning true, and callstack is using thread local storage to maintain that data.

Any thoughts, pointers, or fixes would be greatly appreciated.

Wade Berrier
Wade Berrier
2014-07-01 18:51:09 UTC
Permalink
Hi,

Thanks for the reply, and for the reference about order of execution
with strands.

I guess my issue deals more with .dispatch(), both regarding a strand
and an io_service.

I've attached another test program that is the same as the first,
except it shows the behavior with only an io_service, ie: without a
strand involved.

Given the following documentation[1]:

"The io_service guarantees that the handler will only be called in a
thread in which the run(), run_one(), poll() or poll_one() member
functions is currently being invoked. The handler may be executed
inside this function if the guarantee can be met."

It appears that this guarantee in the attached test program is being
met, yet in the cases as described in the previous email the handler
isn't being called inside the function.

It makes sense that the two programs behave the same, with or without
a strand, because dispatch() in both cases is relying on the
"callstack" mechanism.

Is this expected behavior?

Or is the documentation implying it's better not to depend on this
guarantee? If that is the case, maybe the documentation should say
something like, "this guarantee may not be achievable depending on the
implementation and build configuration of your particular platform".

Thoughts, ideas?

Wade

1. http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference/io_service/dispatch.html
Post by Roger Austin (Australia)
Hi Wade,
strand::dispatch guarantees only that the handlers will not execute concurrently, not the order of execution. strand::post guarantees that handlers will execute in the order they were posted. This is still not well-documented despite having been noted many years ago: http://boost.2283326.n4.nabble.com/asio-Order-of-handler-processing-within-a-strand-td2617483.html. It is sort-of-implied by the documentation in that strand::dispatch is allowed to call the handler directly if the calling thread meets the requirements of the strand, while strand::post is not (i.e. the handler is always put on the queue).
Roger Austin
-----Original Message-----
Sent: Tuesday, 1 July 2014 8:26 AM
Subject: [asio-users] Strange strand dispatch issue on windows
Hello,
Attached is a test program testing strand::dispatch().
First question: is it reasonable to depend on the ordering of the print statements?
a. asio is compiled as a shared library according to the documentation (ie: compiling boost/asio/impl/src.hpp and defining
BOOST_ASIO_DYN_LINK)
b. asio is being used as header only, but my executable is loading a dll that is calling dispatch on a strand allocated by the host executable.
Second question: is this a bug?
-Visual Studio 2010 SP1 32bit
-Windows XP (seeing the same behavior on Windows 7) -Boost 1.55 variant=release thread=multi link=shared
Also, I've run depends.exe on the .dll and .exe to verify that I'm not mixing release/debug runtime .dlls, which seemed like it could have been the culprit.
Note, both of these cases work as expected on linux.
In tracing the code, it seems to come down to callstack::contains returning false when it should be returning true, and callstack is using thread local storage to maintain that data.
Any thoughts, pointers, or fixes would be greatly appreciated.
Wade Berrier
------------------------------------------------------------------------------
Open source business process management suite built on Java and Eclipse
Turn processes into business applications with Bonita BPM Community Edition
Quickly connect people, data, and systems into organized workflows
Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
_______________________________________________
asio-users mailing list
https://lists.sourceforge.net/lists/listinfo/asio-users
_______________________________________________
Using Asio? List your project at
http://think-async.com/Asio/WhoIsUsingAsio
Roger Austin (Australia)
2014-07-01 22:46:18 UTC
Permalink
Hi Wade,

It seems to me that the guarantees (which are slightly different between strand::dispatch and io_service::dispatch) are being met in all your tests. Note that the documentation only says that "The handler _may_ be executed inside this function". Clearly it isn't in some cases on Windows, but that doesn't break the guarantee.

To answer the question posed in your original post - it is not reasonable to depend on the ordering of the print statements when using dispatch. If you want reliable ordering then use post (which will always give 1,3,2,4 in your examples).

Cheers,
Roger

-----Original Message-----
From: Wade Berrier [mailto:***@gmail.com]
Sent: Wednesday, 2 July 2014 4:51 AM
To: asio-***@lists.sourceforge.net
Subject: Re: [asio-users] Strange strand dispatch issue on windows

Hi,

Thanks for the reply, and for the reference about order of execution with strands.

I guess my issue deals more with .dispatch(), both regarding a strand and an io_service.

I've attached another test program that is the same as the first, except it shows the behavior with only an io_service, ie: without a strand involved.

Given the following documentation[1]:

"The io_service guarantees that the handler will only be called in a thread in which the run(), run_one(), poll() or poll_one() member functions is currently being invoked. The handler may be executed inside this function if the guarantee can be met."

It appears that this guarantee in the attached test program is being met, yet in the cases as described in the previous email the handler isn't being called inside the function.

It makes sense that the two programs behave the same, with or without a strand, because dispatch() in both cases is relying on the "callstack" mechanism.

Is this expected behavior?

Or is the documentation implying it's better not to depend on this guarantee? If that is the case, maybe the documentation should say something like, "this guarantee may not be achievable depending on the implementation and build configuration of your particular platform".

Thoughts, ideas?

Wade

1. http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference/io_service/dispatch.html
Post by Roger Austin (Australia)
Hi Wade,
strand::dispatch guarantees only that the handlers will not execute concurrently, not the order of execution. strand::post guarantees that handlers will execute in the order they were posted. This is still not well-documented despite having been noted many years ago: http://boost.2283326.n4.nabble.com/asio-Order-of-handler-processing-within-a-strand-td2617483.html. It is sort-of-implied by the documentation in that strand::dispatch is allowed to call the handler directly if the calling thread meets the requirements of the strand, while strand::post is not (i.e. the handler is always put on the queue).
Roger Austin
-----Original Message-----
Sent: Tuesday, 1 July 2014 8:26 AM
Subject: [asio-users] Strange strand dispatch issue on windows
Hello,
Attached is a test program testing strand::dispatch().
First question: is it reasonable to depend on the ordering of the print statements?
a. asio is compiled as a shared library according to the
documentation (ie: compiling boost/asio/impl/src.hpp and defining
BOOST_ASIO_DYN_LINK)
b. asio is being used as header only, but my executable is loading a dll that is calling dispatch on a strand allocated by the host executable.
Second question: is this a bug?
-Visual Studio 2010 SP1 32bit
-Windows XP (seeing the same behavior on Windows 7) -Boost 1.55
variant=release thread=multi link=shared
Also, I've run depends.exe on the .dll and .exe to verify that I'm not mixing release/debug runtime .dlls, which seemed like it could have been the culprit.
Note, both of these cases work as expected on linux.
In tracing the code, it seems to come down to callstack::contains returning false when it should be returning true, and callstack is using thread local storage to maintain that data.
Any thoughts, pointers, or fixes would be greatly appreciated.
Wade Berrier
----------------------------------------------------------------------
-------- Open source business process management suite built on Java
and Eclipse Turn processes into business applications with Bonita BPM
Community Edition Quickly connect people, data, and systems into
organized workflows Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
_______________________________________________
asio-users mailing list
https://lists.sourceforge.net/lists/listinfo/asio-users
_______________________________________________
Using Asio? List your project at
http://think-async.com/Asio/WhoIsUsingAsio
Wade Berrier
2014-07-03 00:04:31 UTC
Permalink
Hello,

Thanks again for your feedback. After some further investigation I'm
convinced this is a bug, which I logged here:

https://svn.boost.org/trac/boost/ticket/10174

Basically it's a windows specific static storage issue when dealing
with .dlls. The bug report has an attached patch to work around one
of the cases, but a better general fix is needed.

Thanks again for the feedback,

Wade
Post by Roger Austin (Australia)
Hi Wade,
It seems to me that the guarantees (which are slightly different between strand::dispatch and io_service::dispatch) are being met in all your tests. Note that the documentation only says that "The handler _may_ be executed inside this function". Clearly it isn't in some cases on Windows, but that doesn't break the guarantee.
To answer the question posed in your original post - it is not reasonable to depend on the ordering of the print statements when using dispatch. If you want reliable ordering then use post (which will always give 1,3,2,4 in your examples).
Cheers,
Roger
-----Original Message-----
Sent: Wednesday, 2 July 2014 4:51 AM
Subject: Re: [asio-users] Strange strand dispatch issue on windows
Hi,
Thanks for the reply, and for the reference about order of execution with strands.
I guess my issue deals more with .dispatch(), both regarding a strand and an io_service.
I've attached another test program that is the same as the first, except it shows the behavior with only an io_service, ie: without a strand involved.
"The io_service guarantees that the handler will only be called in a thread in which the run(), run_one(), poll() or poll_one() member functions is currently being invoked. The handler may be executed inside this function if the guarantee can be met."
It appears that this guarantee in the attached test program is being met, yet in the cases as described in the previous email the handler isn't being called inside the function.
It makes sense that the two programs behave the same, with or without a strand, because dispatch() in both cases is relying on the "callstack" mechanism.
Is this expected behavior?
Or is the documentation implying it's better not to depend on this guarantee? If that is the case, maybe the documentation should say something like, "this guarantee may not be achievable depending on the implementation and build configuration of your particular platform".
Thoughts, ideas?
Wade
1. http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference/io_service/dispatch.html
Post by Roger Austin (Australia)
Hi Wade,
strand::dispatch guarantees only that the handlers will not execute concurrently, not the order of execution. strand::post guarantees that handlers will execute in the order they were posted. This is still not well-documented despite having been noted many years ago: http://boost.2283326.n4.nabble.com/asio-Order-of-handler-processing-within-a-strand-td2617483.html. It is sort-of-implied by the documentation in that strand::dispatch is allowed to call the handler directly if the calling thread meets the requirements of the strand, while strand::post is not (i.e. the handler is always put on the queue).
Roger Austin
-----Original Message-----
Sent: Tuesday, 1 July 2014 8:26 AM
Subject: [asio-users] Strange strand dispatch issue on windows
Hello,
Attached is a test program testing strand::dispatch().
First question: is it reasonable to depend on the ordering of the print statements?
a. asio is compiled as a shared library according to the
documentation (ie: compiling boost/asio/impl/src.hpp and defining
BOOST_ASIO_DYN_LINK)
b. asio is being used as header only, but my executable is loading a dll that is calling dispatch on a strand allocated by the host executable.
Second question: is this a bug?
-Visual Studio 2010 SP1 32bit
-Windows XP (seeing the same behavior on Windows 7) -Boost 1.55
variant=release thread=multi link=shared
Also, I've run depends.exe on the .dll and .exe to verify that I'm not mixing release/debug runtime .dlls, which seemed like it could have been the culprit.
Note, both of these cases work as expected on linux.
In tracing the code, it seems to come down to callstack::contains returning false when it should be returning true, and callstack is using thread local storage to maintain that data.
Any thoughts, pointers, or fixes would be greatly appreciated.
Wade Berrier
----------------------------------------------------------------------
-------- Open source business process management suite built on Java
and Eclipse Turn processes into business applications with Bonita BPM
Community Edition Quickly connect people, data, and systems into
organized workflows Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
_______________________________________________
asio-users mailing list
https://lists.sourceforge.net/lists/listinfo/asio-users
_______________________________________________
Using Asio? List your project at
http://think-async.com/Asio/WhoIsUsingAsio
------------------------------------------------------------------------------
Open source business process management suite built on Java and Eclipse
Turn processes into business applications with Bonita BPM Community Edition
Quickly connect people, data, and systems into organized workflows
Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
_______________________________________________
asio-users mailing list
https://lists.sourceforge.net/lists/listinfo/asio-users
_______________________________________________
Using Asio? List your project at
http://think-async.com/Asio/WhoIsUsingAsio
Roger Austin (Australia)
2014-07-03 03:16:37 UTC
Permalink
Hi,

Fair enough. Clearly there are linkage issues that could be improved on Windows. However:

(a) These linkage issues don't actually break the guarantee, as you have noted, and
(b) Fixing these issues does not mean you can depend on the ordering of calls when using dispatch as the asio maintainers are free to make changes to Windows and other implementations that may change the ordering without breaking the guarantee.

If you want reliable ordering I am curious to know why you are not either calling handler2 directly from handler1 (to give 1,2,3,4) or using post (to give 1,3,2,4).

Roger

-----Original Message-----
From: Wade Berrier [mailto:***@gmail.com]
Sent: Thursday, 3 July 2014 10:05 AM
To: asio-***@lists.sourceforge.net
Subject: Re: [asio-users] Strange strand dispatch issue on windows

Hello,

Thanks again for your feedback. After some further investigation I'm convinced this is a bug, which I logged here:

https://svn.boost.org/trac/boost/ticket/10174

Basically it's a windows specific static storage issue when dealing with .dlls. The bug report has an attached patch to work around one of the cases, but a better general fix is needed.

Thanks again for the feedback,

Wade
Post by Roger Austin (Australia)
Hi Wade,
It seems to me that the guarantees (which are slightly different between strand::dispatch and io_service::dispatch) are being met in all your tests. Note that the documentation only says that "The handler _may_ be executed inside this function". Clearly it isn't in some cases on Windows, but that doesn't break the guarantee.
To answer the question posed in your original post - it is not reasonable to depend on the ordering of the print statements when using dispatch. If you want reliable ordering then use post (which will always give 1,3,2,4 in your examples).
Cheers,
Roger
-----Original Message-----
Sent: Wednesday, 2 July 2014 4:51 AM
Subject: Re: [asio-users] Strange strand dispatch issue on windows
Hi,
Thanks for the reply, and for the reference about order of execution with strands.
I guess my issue deals more with .dispatch(), both regarding a strand and an io_service.
I've attached another test program that is the same as the first, except it shows the behavior with only an io_service, ie: without a strand involved.
"The io_service guarantees that the handler will only be called in a thread in which the run(), run_one(), poll() or poll_one() member functions is currently being invoked. The handler may be executed inside this function if the guarantee can be met."
It appears that this guarantee in the attached test program is being met, yet in the cases as described in the previous email the handler isn't being called inside the function.
It makes sense that the two programs behave the same, with or without a strand, because dispatch() in both cases is relying on the "callstack" mechanism.
Is this expected behavior?
Or is the documentation implying it's better not to depend on this guarantee? If that is the case, maybe the documentation should say something like, "this guarantee may not be achievable depending on the implementation and build configuration of your particular platform".
Thoughts, ideas?
Wade
1.
http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference/io_
service/dispatch.html
Post by Roger Austin (Australia)
Hi Wade,
strand::dispatch guarantees only that the handlers will not execute concurrently, not the order of execution. strand::post guarantees that handlers will execute in the order they were posted. This is still not well-documented despite having been noted many years ago: http://boost.2283326.n4.nabble.com/asio-Order-of-handler-processing-within-a-strand-td2617483.html. It is sort-of-implied by the documentation in that strand::dispatch is allowed to call the handler directly if the calling thread meets the requirements of the strand, while strand::post is not (i.e. the handler is always put on the queue).
Roger Austin
-----Original Message-----
Sent: Tuesday, 1 July 2014 8:26 AM
Subject: [asio-users] Strange strand dispatch issue on windows
Hello,
Attached is a test program testing strand::dispatch().
First question: is it reasonable to depend on the ordering of the print statements?
a. asio is compiled as a shared library according to the
documentation (ie: compiling boost/asio/impl/src.hpp and defining
BOOST_ASIO_DYN_LINK)
b. asio is being used as header only, but my executable is loading a dll that is calling dispatch on a strand allocated by the host executable.
Second question: is this a bug?
-Visual Studio 2010 SP1 32bit
-Windows XP (seeing the same behavior on Windows 7) -Boost 1.55
variant=release thread=multi link=shared
Also, I've run depends.exe on the .dll and .exe to verify that I'm not mixing release/debug runtime .dlls, which seemed like it could have been the culprit.
Note, both of these cases work as expected on linux.
In tracing the code, it seems to come down to callstack::contains returning false when it should be returning true, and callstack is using thread local storage to maintain that data.
Any thoughts, pointers, or fixes would be greatly appreciated.
Wade Berrier
--------------------------------------------------------------------
--
-------- Open source business process management suite built on Java
and Eclipse Turn processes into business applications with Bonita
BPM Community Edition Quickly connect people, data, and systems into
organized workflows Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
_______________________________________________
asio-users mailing list
https://lists.sourceforge.net/lists/listinfo/asio-users
_______________________________________________
Using Asio? List your project at
http://think-async.com/Asio/WhoIsUsingAsio
----------------------------------------------------------------------
-------- Open source business process management suite built on Java
and Eclipse Turn processes into business applications with Bonita BPM
Community Edition Quickly connect people, data, and systems into
organized workflows Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
_______________________________________________
asio-users mailing list
https://lists.sourceforge.net/lists/listinfo/asio-users
_______________________________________________
Using Asio? List your project at
http://think-async.com/Asio/WhoIsUsingAsio
Continue reading on narkive:
Loading...