Opened 13 years ago
Last modified 13 years ago
#3627 new Feature Requests
boost::asio::async_read() cannot be used with null_buffers()
Reported by: | Owned by: | chris_kohlhoff | |
---|---|---|---|
Milestone: | To Be Determined | Component: | asio |
Version: | Boost 1.40.0 | Severity: | Not Applicable |
Keywords: | asio async_read null_buffers | Cc: |
Description
An attempt to use async_read() with null_buffers() causes the handler to be invoked even when the underlying file descriptor is not yet available for reading.
The following test demonstrates the problem
void test_async_read() {
struct local {
static void on_ready(boost::system::error_code const& error, int* invoked) {
BOOST_CHECK(!error); *invoked = 1;
}
};
int p[2]; int const s = pipe(p); BOOST_CHECK(0 == s);
boost::asio::io_service ios; boost::asio::posix::stream_descriptor sd(ios, p[0]); ios.reset(); int invoked = 0; boost::asio::async_read(sd, boost::asio::null_buffers(), boost::bind(&local::on_ready, _1, &invoked)); ios.poll_one(); BOOST_CHECK(!invoked); doesn't pass
}
This test doesn't pass on linux using either epoll or select multiplexing mechanism. This test also doesn't pass on freebsd using either kqueue or select multiplexing mechanism.
Change History (3)
comment:1 by , 13 years ago
Severity: | Problem → Regression |
---|
comment:2 by , 13 years ago
Severity: | Regression → Problem |
---|
Not a regression. The null_buffers() type never worked with async_read().
You may confirm that it doesn't work by making the following changes to the nonblocking example:
@@ -117,7 +117,8 @@
if (session_impl_.want_read() && !read_in_progress_) {
read_in_progress_ = true;
- socket_.async_read_some(
+ boost::asio::async_read(socket_, + socket_.async_read_some(
boost::asio::null_buffers(), boost::bind(&connection::handle_read,
shared_from_this(),
@@ -138,6 +139,8 @@
void handle_read(boost::system::error_code ec) {
+ printf("handle_read\n"); +
read_in_progress_ = false;
Notify third party library that it can perform a read.
I just checked against 1.39.
comment:3 by , 13 years ago
Milestone: | Boost 1.41.0 → To Be Determined |
---|---|
Severity: | Problem → Not Applicable |
Type: | Bugs → Feature Requests |
The null_buffers type is only intended for use with async_read_some() and async_write_some() on the "lowest layer", i.e. the socket or descriptor. It is not part of any of the stream type requirements, and so not supported by composed operations such as async_read.
If it worked with the buffered*_stream<> templates then that was just a side effect of the 0-byte read/write bug.
It may or may not be useful to support null_buffers as part of the stream type requirements. I'm reclassifying this as a feature request as something to think about in the future.
In any case:
Right now I have no way to check for data (async) without reading it off the socket.
is not correct. It works just fine if you use async_read_some() on the socket.
I can also confirm that this is the case on OS X. The question I have is whether the change is intended? The new documentation seems to imply it is:
Also, the changelist for 1.40.0 says the following:
It's unclear what the intendended behaviour is from these two snippets. Certainly pre 1.40.0 you could call async_read with null_buffers and get a callback when some new data had arrived. This is extremely useful functionality, esp for code that has layered other streams on-top of the asio ones. Right now I have no way to check for data (async) without reading it off the socket.