From ba65f29a7238b152b58a4528a8a5a31e72aa0106 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Sun, 29 Jul 2012 21:12:45 +0200 Subject: [PATCH] Fix draining of wake up pipe. This is a bug fix, although not one we'd ever run into as normally there is always just one byte to read, never an EAGAIN and certainly never more than 256 bytes. Anyway, also those cases should work now. --- indra/llmessage/aicurlthread.cpp | 57 ++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/indra/llmessage/aicurlthread.cpp b/indra/llmessage/aicurlthread.cpp index 2bb33e1a5..c75912047 100644 --- a/indra/llmessage/aicurlthread.cpp +++ b/indra/llmessage/aicurlthread.cpp @@ -845,27 +845,50 @@ void AICurlThread::wakeup(AICurlMultiHandle_wat const& multi_handle_w) // If no process has the pipe open for writing, read() shall return 0 to indicate end-of-file. // If some process has the pipe open for writing and O_NONBLOCK is set, read() shall return -1 and set errno to [EAGAIN]. char buf[256]; - ssize_t len; - do + bool got_data = false; + for(;;) { - len = read(mWakeUpFd, buf, sizeof(buf)); - if (len == -1 && errno == EAGAIN) + ssize_t len = read(mWakeUpFd, buf, sizeof(buf)); + if (len > 0) + { + // Data was read from the pipe. + got_data = true; + if (len < sizeof(buf)) + break; + } + else if (len == -1) + { + // An error occurred. + if (errno == EAGAIN) + { + if (got_data) + break; + // There was no data, even though select() said so. If this ever happens at all(?), lets just return and enter select() again. + return; + } + else if (errno == EINTR) + { + continue; + } + else + { + llerrs << "read(3) from mWakeUpFd: " << strerror(errno) << llendl; + return; + } + } + else + { + // pipe(2) returned 0. + llwarns << "read(3) from mWakeUpFd returned 0, indicating that the pipe on the other end was closed! Shutting down curl thread." << llendl; + close(mWakeUpFd); + mWakeUpFd = CURL_SOCKET_BAD; + mRunning = false; return; - } - while(len == -1 && errno == EINTR); - if (len == -1) - { - llerrs << "read(3) from mWakeUpFd: " << strerror(errno) << llendl; - } - if (LL_UNLIKELY(len == 0)) - { - llwarns << "read(3) from mWakeUpFd returned 0, indicating that the pipe on the other end was closed! Shutting down curl thread." << llendl; - close(mWakeUpFd); - mWakeUpFd = CURL_SOCKET_BAD; - mRunning = false; - return; + } } #endif + // Data was received on mWakeUpFd. This means that the main-thread added one + // or more commands to the command queue and called wakeUpCurlThread(). process_commands(multi_handle_w); }