Post by Bjorn ReesePost by Dale WilsonStrand was not designed to provide the type of thread-safety you are
looking for. It only ensures that only one handler/callback method can
execute at any time.
I disagree, but let us leave multi-threading out of the picture, because
that is not the problem here.
Just for the record, if you are doing async operations you cannot leave
multithreading out of the picture. But I agree multithreading is not
the problem.
Post by Bjorn ReeseI have modified the sender to be single-threaded. Now it performs two
sequential async_write() operations per callback. It exposes the exact
same behavior as I have described before, which is...
So in other words you have given ASIO a second asynchronous write
request while the first one was still active. Because, as you have
noted, asynchronous write is not atomic (and because strand does not
magically make it atomic) this is invalid behavior from your application
and the results will be indeterminate.
Post by Bjorn ReeseNormally it will send the entire A package, and then the entire B
package.
Let me rephrase that. "Accidentally if everything goes well it will
send the entire contents of A package then the entire B package."
This behavior is not guaranteed, nor should it be.
Post by Bjorn ReeseHowever, if the receiver buffer is full, then it will send
half of the A package, then the entire B package, and finally the
rest of the A package.
To provide some context, I use this in a messaging middleware (currently
based on the ZeroMQ protocol), where each package contains a length
followed by a payload. The abovementioned behavior means that the
middleware will fail under heavy load. There is no way that the receiver
can compensate for the strange behavior of the sender.
I understand the problem. In fact I just recently solved a similar
one. However my solution was -- and your solution must be --in the
application code, not in ASIO.
async_write is composed on top of async_write_some. Most of the time
async_write some will write all of the data requested. That's the
"accidentally correct" behavior you are seeing. However, sometimes it
won't. When it doesn't it schedules another request to finish writing
the "package". At this point you have two requests in ASIO for the
same socket. One will write some or all of package B, the other will
write the second portion of package A. How is ASIO supposed to know
which one it should start next?
It could do FIFO --- but that would fail because the Package B request
was placed before the second Package A request was placed. Or it could
have an elaborate mechanism to mark the socket busy servicing the
package A request(s) and have the Package B (and C and D and E?)
requests wait patiently for their turn. That mechanism does not
presently exist in ASIO, and it would be a major redesign to add it.
Request scheduling is certainly not the intent of strand. Strand lets
you write "single threaded" code in your handlers. It has no impact on
choosing which of multiple outstanding requests for the same socket
should be started next. Hoping that strand will solve the problem for
you will not work (sorry) -- it's the wrong tool for the job. Strand
solves multithreading issues, and as you have pointed out, this is not a
multithreading problem.
So you have two choices -- switch to synchronous blocking requests. Your
single threaded code will block until package A is completely delivered
before attempting to send package B. Or provide your own queuing
mechanism so package B is not presented to ASIO until package A has been
completely sent. Either of these will work. Which one you choose
depends on a trade-off between throughput needs and code complexity.
Blocking is (much!) simpler, but it may be slower overall.
Dale
Post by Bjorn Reese------------------------------------------------------------------------------
Start Your Social Network Today - Download eXo Platform
Build your Enterprise Intranet with eXo Platform Software
Java Based Open Source Intranet - Social, Extensible, Cloud Ready
Get Started Now And Turn Your Intranet Into A Collaboration Platform
http://p.sf.net/sfu/ExoPlatform
_______________________________________________
asio-users mailing list
https://lists.sourceforge.net/lists/listinfo/asio-users
_______________________________________________
Using Asio? List your project at
http://think-async.com/Asio/WhoIsUsingAsio
--
Dale Wilson
Principal Software Engineer
Object Computing, Inc.