diff options
author | cleeland <cleeland@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2009-10-28 20:03:48 +0000 |
---|---|---|
committer | cleeland <cleeland@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2009-10-28 20:03:48 +0000 |
commit | f1949efed011ef43de0879bbf009e5e9df35f379 (patch) | |
tree | 29783ff2924a9fd4778e8a86dd01ddf4e1d95535 /ACE/ace/Select_Reactor_Base.cpp | |
parent | 85c978c5c0a04b92955931b1ebb8bed7683c054b (diff) | |
download | ATCD-f1949efed011ef43de0879bbf009e5e9df35f379.tar.gz |
Wed Oct 28 19:49:39 UTC 2009 Chris Cleeland <cleeland@ociweb.com>
* ace/Select_Reactor_Base.h:
* ace/Select_Reactor_Base.cpp:
Changed the second recv() that is used in case of a short first
read to be a recv_n(), blocking until the rest of the buffer can
be received on the pipe. The problem was discovered during
routine testing (Notify_Performance_Test) on VxWorks 6.7 on a P3
platform, but could occur on any platform. [Bugzilla 3754]
Diffstat (limited to 'ACE/ace/Select_Reactor_Base.cpp')
-rw-r--r-- | ACE/ace/Select_Reactor_Base.cpp | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/ACE/ace/Select_Reactor_Base.cpp b/ACE/ace/Select_Reactor_Base.cpp index 771a5b49d90..7f37dc89808 100644 --- a/ACE/ace/Select_Reactor_Base.cpp +++ b/ACE/ace/Select_Reactor_Base.cpp @@ -869,6 +869,25 @@ ACE_Select_Reactor_Notify::read_notify_pipe (ACE_HANDLE handle, { ACE_TRACE ("ACE_Select_Reactor_Notify::read_notify_pipe"); + // This is kind of a weird, fragile beast. We first read with a + // regular read. The read side of this socket is non-blocking, so + // the read may end up being short. + // + // If the read is short, then we do a recv_n to insure that we block + // and read the rest of the buffer. + // + // Now, you might be tempted to say, "why don't we just replace the + // first recv with a recv_n?" I was, too. But that doesn't work + // because of how the calling code in handle_input() works. In + // handle_input, the event will only be dispatched if the return + // value from read_notify_pipe() is > 0. That means that we can't + // return zero from this func unless it's an EOF condition. + // + // Thus, the return value semantics for this are: + // -1: nothing read, fatal, unrecoverable error + // 0: nothing read at all + // 1: complete buffer read + ssize_t const n = ACE::recv (handle, (char *) &buffer, sizeof buffer); if (n > 0) @@ -882,9 +901,9 @@ ACE_Select_Reactor_Notify::read_notify_pipe (ACE_HANDLE handle, // doesn't work we're in big trouble since the input stream // won't be aligned correctly. I'm not sure quite what to // do at this point. It's probably best just to return -1. - if (ACE::recv (handle, - ((char *) &buffer) + n, - remainder) != remainder) + if (ACE::recv_n (handle, + ((char *) &buffer) + n, + remainder) != remainder) return -1; } @@ -911,6 +930,9 @@ ACE_Select_Reactor_Notify::handle_input (ACE_HANDLE handle) int result = 0; ACE_Notification_Buffer buffer; + // If there is only one buffer in the pipe, this will loop and call + // read_notify_pipe() twice. The first time will read the buffer, and + // the second will read the fact that the pipe is empty. while ((result = this->read_notify_pipe (handle, buffer)) > 0) { // Dispatch the buffer |