diff options
-rw-r--r-- | file_io/win32/pipe.c | 64 | ||||
-rw-r--r-- | file_io/win32/readwrite.c | 63 | ||||
-rw-r--r-- | include/arch/unix/apr_arch_poll_private.h | 4 | ||||
-rw-r--r-- | include/arch/win32/apr_arch_file_io.h | 8 | ||||
-rw-r--r-- | network_io/os2/sockopt.c | 16 | ||||
-rw-r--r-- | poll/os2/pollset.c | 26 | ||||
-rw-r--r-- | poll/unix/epoll.c | 4 | ||||
-rw-r--r-- | poll/unix/kqueue.c | 4 | ||||
-rw-r--r-- | poll/unix/poll.c | 4 | ||||
-rw-r--r-- | poll/unix/pollcb.c | 11 | ||||
-rw-r--r-- | poll/unix/pollset.c | 11 | ||||
-rw-r--r-- | poll/unix/port.c | 4 | ||||
-rw-r--r-- | poll/unix/select.c | 2 | ||||
-rw-r--r-- | poll/unix/wakeup.c | 26 |
14 files changed, 96 insertions, 151 deletions
diff --git a/file_io/win32/pipe.c b/file_io/win32/pipe.c index 7dcbfb00e..dd8ef1352 100644 --- a/file_io/win32/pipe.c +++ b/file_io/win32/pipe.c @@ -43,7 +43,7 @@ APR_DECLARE(apr_status_t) apr_file_pipe_timeout_set(apr_file_t *thepipe, thepipe->timeout = timeout; return APR_SUCCESS; } - if (thepipe->ftype != APR_FILETYPE_PIPE) { + if (!thepipe->pipe) { return APR_ENOTIMPL; } if (timeout && !(thepipe->pOverlapped)) { @@ -108,7 +108,7 @@ APR_DECLARE(apr_status_t) apr_file_pipe_create_pools(apr_file_t **in, (*in) = (apr_file_t *)apr_pcalloc(pool_in, sizeof(apr_file_t)); (*in)->pool = pool_in; (*in)->fname = NULL; - (*in)->ftype = APR_FILETYPE_PIPE; + (*in)->pipe = 1; (*in)->timeout = -1; (*in)->ungetchar = -1; (*in)->eof_hit = 0; @@ -123,7 +123,7 @@ APR_DECLARE(apr_status_t) apr_file_pipe_create_pools(apr_file_t **in, (*out) = (apr_file_t *)apr_pcalloc(pool_out, sizeof(apr_file_t)); (*out)->pool = pool_out; (*out)->fname = NULL; - (*out)->ftype = APR_FILETYPE_PIPE; + (*out)->pipe = 1; (*out)->timeout = -1; (*out)->ungetchar = -1; (*out)->eof_hit = 0; @@ -250,7 +250,7 @@ APR_DECLARE(apr_status_t) apr_os_pipe_put_ex(apr_file_t **file, { (*file) = apr_pcalloc(pool, sizeof(apr_file_t)); (*file)->pool = pool; - (*file)->ftype = APR_FILETYPE_PIPE; + (*file)->pipe = 1; (*file)->timeout = -1; (*file)->ungetchar = -1; (*file)->filehand = *thefile; @@ -364,28 +364,32 @@ static apr_status_t create_socket_pipe(SOCKET *rd, SOCKET *wr) rv = apr_get_netos_error(); goto cleanup; } - /* Verify the connection by reading/waiting for the identification */ - bm = 0; - if (ioctlsocket(*rd, FIONBIO, &bm) == SOCKET_ERROR) { - rv = apr_get_netos_error(); - goto cleanup; + /* Verify the connection by reading the send identification. + */ + do { + if (nc++) + Sleep(1); + nrd = recv(*rd, (char *)iid, sizeof(iid), 0); + rv = nrd == SOCKET_ERROR ? apr_get_netos_error() : APR_SUCCESS; + } while (APR_STATUS_IS_EAGAIN(rv)); + + if (nrd == sizeof(iid)) { + if (memcmp(uid, iid, sizeof(uid)) == 0) { + /* Wow, we recived what we send. + * Put read side of the pipe to the blocking + * mode and return. + */ + bm = 0; + if (ioctlsocket(*rd, FIONBIO, &bm) == SOCKET_ERROR) { + rv = apr_get_netos_error(); + goto cleanup; + } + break; + } } - nrd = recv(*rd, (char *)iid, sizeof(iid), 0); - if (nrd == SOCKET_ERROR) { - rv = apr_get_netos_error(); + else if (nrd == SOCKET_ERROR) { goto cleanup; } - if (nrd == (int)sizeof(uid) && memcmp(iid, uid, sizeof(uid)) == 0) { - /* Got the right identifier, put the poll()able read side of - * the pipe in nonblocking mode and return. - */ - bm = 1; - if (ioctlsocket(*rd, FIONBIO, &bm) == SOCKET_ERROR) { - rv = apr_get_netos_error(); - goto cleanup; - } - break; - } closesocket(*rd); } /* We don't need the listening socket any more */ @@ -394,7 +398,6 @@ static apr_status_t create_socket_pipe(SOCKET *rd, SOCKET *wr) cleanup: /* Don't leak resources */ - closesocket(ls); if (*rd != INVALID_SOCKET) closesocket(*rd); if (*wr != INVALID_SOCKET) @@ -402,6 +405,7 @@ cleanup: *rd = INVALID_SOCKET; *wr = INVALID_SOCKET; + closesocket(ls); return rv; } @@ -430,21 +434,21 @@ apr_status_t apr_file_socket_pipe_create(apr_file_t **in, (*in) = (apr_file_t *)apr_pcalloc(p, sizeof(apr_file_t)); (*in)->pool = p; (*in)->fname = NULL; - (*in)->ftype = APR_FILETYPE_SOCKET; - (*in)->timeout = 0; /* read end of the pipe is non-blocking */ + (*in)->pipe = 1; + (*in)->timeout = -1; (*in)->ungetchar = -1; (*in)->eof_hit = 0; (*in)->filePtr = 0; (*in)->bufpos = 0; (*in)->dataRead = 0; (*in)->direction = 0; - (*in)->pOverlapped = NULL; + (*in)->pOverlapped = (OVERLAPPED*)apr_pcalloc(p, sizeof(OVERLAPPED)); (*in)->filehand = (HANDLE)rd; (*out) = (apr_file_t *)apr_pcalloc(p, sizeof(apr_file_t)); (*out)->pool = p; (*out)->fname = NULL; - (*out)->ftype = APR_FILETYPE_SOCKET; + (*out)->pipe = 1; (*out)->timeout = -1; (*out)->ungetchar = -1; (*out)->eof_hit = 0; @@ -452,7 +456,7 @@ apr_status_t apr_file_socket_pipe_create(apr_file_t **in, (*out)->bufpos = 0; (*out)->dataRead = 0; (*out)->direction = 0; - (*out)->pOverlapped = NULL; + (*out)->pOverlapped = (OVERLAPPED*)apr_pcalloc(p, sizeof(OVERLAPPED)); (*out)->filehand = (HANDLE)wr; apr_pool_cleanup_register(p, (void *)(*in), socket_pipe_cleanup, @@ -466,7 +470,7 @@ apr_status_t apr_file_socket_pipe_create(apr_file_t **in, apr_status_t apr_file_socket_pipe_close(apr_file_t *file) { apr_status_t stat; - if (file->ftype != APR_FILETYPE_SOCKET) + if (!file->pipe) return apr_file_close(file); if ((stat = socket_pipe_cleanup(file)) == APR_SUCCESS) { apr_pool_cleanup_kill(file->pool, file, socket_pipe_cleanup); diff --git a/file_io/win32/readwrite.c b/file_io/win32/readwrite.c index bd4e87c9e..701bec75b 100644 --- a/file_io/win32/readwrite.c +++ b/file_io/win32/readwrite.c @@ -20,12 +20,10 @@ #include "apr_strings.h" #include "apr_lib.h" #include "apr_errno.h" -#include "apr_arch_networkio.h" +#include <malloc.h> #include "apr_arch_atime.h" #include "apr_arch_misc.h" -#include <malloc.h> - /* * read_with_timeout() * Uses async i/o to emulate unix non-blocking i/o with timeouts. @@ -42,7 +40,7 @@ static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t le /* Peek at the pipe. If there is no data available, return APR_EAGAIN. * If data is available, go ahead and read it. */ - if (file->ftype == APR_FILETYPE_PIPE) { + if (file->pipe) { DWORD bytes; if (!PeekNamedPipe(file->filehand, NULL, 0, NULL, &bytes, NULL)) { rv = apr_get_os_error(); @@ -70,28 +68,13 @@ static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t le } } - if (file->pOverlapped && file->ftype == APR_FILETYPE_FILE) { + if (file->pOverlapped && !file->pipe) { file->pOverlapped->Offset = (DWORD)file->filePtr; file->pOverlapped->OffsetHigh = (DWORD)(file->filePtr >> 32); } - if (file->ftype == APR_FILETYPE_SOCKET) { - WSABUF wsaData; - DWORD flags = 0; - - wsaData.buf = (char*) buf; - wsaData.len = (u_long)len; - if (WSARecv((SOCKET)file->filehand, &wsaData, 1, &bytesread, - &flags, NULL, NULL) == SOCKET_ERROR) { - rv = apr_get_netos_error(); - bytesread = 0; - } - else { - rv = APR_SUCCESS; - } - } - else if (ReadFile(file->filehand, buf, len, - &bytesread, file->pOverlapped)) { + if (ReadFile(file->filehand, buf, len, + &bytesread, file->pOverlapped)) { rv = APR_SUCCESS; } else { @@ -150,7 +133,7 @@ static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t le if (rv == APR_SUCCESS && bytesread == 0) rv = APR_EOF; - if (rv == APR_SUCCESS && file->pOverlapped && file->ftype == APR_FILETYPE_FILE) { + if (rv == APR_SUCCESS && file->pOverlapped && !file->pipe) { file->filePtr += bytesread; } *nbytes = bytesread; @@ -263,7 +246,7 @@ APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_size APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, apr_size_t *nbytes) { apr_status_t rv; - DWORD bwrote = 0; + DWORD bwrote; /* If the file is open for xthread support, allocate and * initialize the overlapped and io completion event (hEvent). @@ -315,29 +298,9 @@ APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, a if (thefile->flags & APR_FOPEN_XTHREAD) { apr_thread_mutex_unlock(thefile->mutex); } - } - else if (thefile->ftype == APR_FILETYPE_SOCKET) { - WSABUF wsaData; - DWORD flags = 0; - - wsaData.buf = (char*) buf; - wsaData.len = (u_long)*nbytes; - if (WSASend((SOCKET)thefile->filehand, &wsaData, 1, &bwrote, - flags, NULL, NULL) == SOCKET_ERROR) { - rv = apr_get_netos_error(); - bwrote = 0; - } - else { - rv = APR_SUCCESS; - } - *nbytes = bwrote; - } - else { - if (thefile->ftype != APR_FILETYPE_FILE) { - rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote, - thefile->pOverlapped); - } - else { + return rv; + } else { + if (!thefile->pipe) { apr_off_t offset = 0; apr_status_t rc; if (thefile->append) { @@ -369,6 +332,10 @@ APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, a apr_thread_mutex_unlock(thefile->mutex); } } + else { + rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote, + thefile->pOverlapped); + } if (rv) { *nbytes = bwrote; rv = APR_SUCCESS; @@ -415,7 +382,7 @@ APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, a } } } - if (rv == APR_SUCCESS && thefile->pOverlapped && thefile->ftype == APR_FILETYPE_FILE) { + if (rv == APR_SUCCESS && thefile->pOverlapped && !thefile->pipe) { thefile->filePtr += *nbytes; } } diff --git a/include/arch/unix/apr_arch_poll_private.h b/include/arch/unix/apr_arch_poll_private.h index 8dd97d1ad..4c2aaa704 100644 --- a/include/arch/unix/apr_arch_poll_private.h +++ b/include/arch/unix/apr_arch_poll_private.h @@ -123,7 +123,6 @@ struct apr_pollset_t /* Pipe descriptors used for wakeup */ apr_file_t *wakeup_pipe[2]; apr_pollfd_t wakeup_pfd; - volatile apr_uint32_t wakeup_set; apr_pollset_private_t *p; const apr_pollset_provider_t *provider; }; @@ -152,7 +151,6 @@ struct apr_pollcb_t { /* Pipe descriptors used for wakeup */ apr_file_t *wakeup_pipe[2]; apr_pollfd_t wakeup_pfd; - volatile apr_uint32_t wakeup_set; int fd; apr_pollcb_pset pollset; apr_pollfd_t **copyset; @@ -184,6 +182,6 @@ struct apr_pollcb_provider_t { apr_status_t apr_poll_create_wakeup_pipe(apr_pool_t *pool, apr_pollfd_t *pfd, apr_file_t **wakeup_pipe); apr_status_t apr_poll_close_wakeup_pipe(apr_file_t **wakeup_pipe); -void apr_poll_drain_wakeup_pipe(volatile apr_uint32_t *wakeup_set, apr_file_t **wakeup_pipe); +void apr_poll_drain_wakeup_pipe(apr_file_t **wakeup_pipe); #endif /* APR_ARCH_POLL_PRIVATE_H */ diff --git a/include/arch/win32/apr_arch_file_io.h b/include/arch/win32/apr_arch_file_io.h index bef536450..9fb8df19a 100644 --- a/include/arch/win32/apr_arch_file_io.h +++ b/include/arch/win32/apr_arch_file_io.h @@ -159,16 +159,10 @@ apr_status_t more_finfo(apr_finfo_t *finfo, const void *ufile, /* for apr_poll.c */ #define filedes filehand -typedef enum { - APR_FILETYPE_FILE = 0, - APR_FILETYPE_PIPE, - APR_FILETYPE_SOCKET -} apr_filetype_e; - struct apr_file_t { apr_pool_t *pool; HANDLE filehand; - apr_filetype_e ftype; /* Is this a pipe, a socket or a file? */ + BOOLEAN pipe; /* Is this a pipe of a file? */ OVERLAPPED *pOverlapped; apr_interval_time_t timeout; apr_int32_t flags; diff --git a/network_io/os2/sockopt.c b/network_io/os2/sockopt.c index 6e97b49a6..094cd24ea 100644 --- a/network_io/os2/sockopt.c +++ b/network_io/os2/sockopt.c @@ -32,22 +32,8 @@ APR_DECLARE(apr_status_t) apr_socket_timeout_set(apr_socket_t *sock, apr_interval_time_t t) { - apr_status_t rv = APR_SUCCESS; - - /* If our new timeout is non-negative and our old timeout was - * negative, then we need to ensure that we are non-blocking. - * Conversely, if our new timeout is negative and we had - * non-negative timeout, we must make sure our socket is blocking. - */ - if (t == 0 && sock->timeout != 0) { - rv = apr_socket_opt_set(sock, APR_SO_NONBLOCK, 1); - } - else if (t != 0 && sock->timeout == 0) { - rv = apr_socket_opt_set(sock, APR_SO_NONBLOCK, 0); - } - sock->timeout = t; - return rv; + return APR_SUCCESS; } diff --git a/poll/os2/pollset.c b/poll/os2/pollset.c index c407f5d98..2ec848105 100644 --- a/poll/os2/pollset.c +++ b/poll/os2/pollset.c @@ -67,6 +67,7 @@ APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset, if (rc == APR_SUCCESS) { apr_sockaddr_t *listen_address; + apr_socket_timeout_set((*pollset)->wake_listen, 0); apr_sockaddr_info_get(&listen_address, "", APR_UNIX, 0, 0, p); rc = apr_socket_bind((*pollset)->wake_listen, listen_address); @@ -79,7 +80,6 @@ APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset, wake_poll_fd.client_data = NULL; apr_pollset_add(*pollset, &wake_poll_fd); apr_socket_addr_get(&(*pollset)->wake_address, APR_LOCAL, (*pollset)->wake_listen); - apr_socket_timeout_set((*pollset)->wake_listen, 0); rc = apr_socket_create(&(*pollset)->wake_sender, APR_UNIX, SOCK_DGRAM, 0, p); } @@ -263,14 +263,17 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, if (rtnevents) { if (i == 0 && pollset->wake_listen != NULL) { - char ch; - apr_size_t len = 1; struct apr_sockaddr_t from_addr; - rv = apr_socket_recvfrom(&from_addr, pollset->wake_listen, - MSG_DONTWAIT, &ch, &len); - if (rv == APR_SUCCESS) { - /* Woken up, senders can fill the pipe again */ - apr_atomic_set32(&pollset->wakeup_set, 0); + char buffer[16]; + apr_size_t buflen; + for (;;) { + buflen = sizeof(buffer); + rv = apr_socket_recvfrom(&from_addr, pollset->wake_listen, + MSG_DONTWAIT, buffer, &buflen); + if (rv != APR_SUCCESS) { + break; + } + /* Woken up, drain the pipe still. */ rc = APR_EINTR; } } @@ -295,15 +298,12 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, APR_DECLARE(apr_status_t) apr_pollset_wakeup(apr_pollset_t *pollset) { - if (!pollset->wake_sender) - return APR_EINIT; - - if (apr_atomic_cas32(&pollset->wakeup_set, 1, 0) == 0) { + if (pollset->wake_sender) { apr_size_t len = 1; return apr_socket_sendto(pollset->wake_sender, pollset->wake_address, 0, "", &len); } - return APR_SUCCESS; + return APR_EINIT; } diff --git a/poll/unix/epoll.c b/poll/unix/epoll.c index c00a1094d..4ab03f67c 100644 --- a/poll/unix/epoll.c +++ b/poll/unix/epoll.c @@ -289,7 +289,7 @@ static apr_status_t impl_pollset_poll(apr_pollset_t *pollset, if ((pollset->flags & APR_POLLSET_WAKEABLE) && fdptr->desc_type == APR_POLL_FILE && fdptr->desc.f == pollset->wakeup_pipe[0]) { - apr_poll_drain_wakeup_pipe(&pollset->wakeup_set, pollset->wakeup_pipe); + apr_poll_drain_wakeup_pipe(pollset->wakeup_pipe); rv = APR_EINTR; } else { @@ -460,7 +460,7 @@ static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb, if ((pollcb->flags & APR_POLLSET_WAKEABLE) && pollfd->desc_type == APR_POLL_FILE && pollfd->desc.f == pollcb->wakeup_pipe[0]) { - apr_poll_drain_wakeup_pipe(&pollcb->wakeup_set, pollcb->wakeup_pipe); + apr_poll_drain_wakeup_pipe(pollcb->wakeup_pipe); return APR_EINTR; } diff --git a/poll/unix/kqueue.c b/poll/unix/kqueue.c index e8a1ef95b..548464db1 100644 --- a/poll/unix/kqueue.c +++ b/poll/unix/kqueue.c @@ -286,7 +286,7 @@ static apr_status_t impl_pollset_poll(apr_pollset_t *pollset, if ((pollset->flags & APR_POLLSET_WAKEABLE) && fd->desc_type == APR_POLL_FILE && fd->desc.f == pollset->wakeup_pipe[0]) { - apr_poll_drain_wakeup_pipe(&pollset->wakeup_set, pollset->wakeup_pipe); + apr_poll_drain_wakeup_pipe(pollset->wakeup_pipe); rv = APR_EINTR; } else { @@ -473,7 +473,7 @@ static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb, if ((pollcb->flags & APR_POLLSET_WAKEABLE) && pollfd->desc_type == APR_POLL_FILE && pollfd->desc.f == pollcb->wakeup_pipe[0]) { - apr_poll_drain_wakeup_pipe(&pollcb->wakeup_set, pollcb->wakeup_pipe); + apr_poll_drain_wakeup_pipe(pollcb->wakeup_pipe); return APR_EINTR; } diff --git a/poll/unix/poll.c b/poll/unix/poll.c index 51c94c7d1..f148f5e50 100644 --- a/poll/unix/poll.c +++ b/poll/unix/poll.c @@ -279,7 +279,7 @@ static apr_status_t impl_pollset_poll(apr_pollset_t *pollset, if ((pollset->flags & APR_POLLSET_WAKEABLE) && pollset->p->query_set[i].desc_type == APR_POLL_FILE && pollset->p->query_set[i].desc.f == pollset->wakeup_pipe[0]) { - apr_poll_drain_wakeup_pipe(&pollset->wakeup_set, pollset->wakeup_pipe); + apr_poll_drain_wakeup_pipe(pollset->wakeup_pipe); rv = APR_EINTR; } else { @@ -431,7 +431,7 @@ static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb, if ((pollcb->flags & APR_POLLSET_WAKEABLE) && pollfd->desc_type == APR_POLL_FILE && pollfd->desc.f == pollcb->wakeup_pipe[0]) { - apr_poll_drain_wakeup_pipe(&pollcb->wakeup_set, pollcb->wakeup_pipe); + apr_poll_drain_wakeup_pipe(pollcb->wakeup_pipe); return APR_EINTR; } diff --git a/poll/unix/pollcb.c b/poll/unix/pollcb.c index 103ab9fa6..a63ad5c9c 100644 --- a/poll/unix/pollcb.c +++ b/poll/unix/pollcb.c @@ -23,7 +23,6 @@ #include "apr_poll.h" #include "apr_time.h" #include "apr_portable.h" -#include "apr_atomic.h" #include "apr_arch_file_io.h" #include "apr_arch_networkio.h" #include "apr_arch_poll_private.h" @@ -135,7 +134,6 @@ APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **ret_pollcb, pollcb->flags = flags; pollcb->pool = p; pollcb->provider = provider; - pollcb->wakeup_set = 0; rv = (*provider->create)(pollcb, size, p, flags); if (rv == APR_ENOTIMPL) { @@ -214,13 +212,10 @@ APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, APR_DECLARE(apr_status_t) apr_pollcb_wakeup(apr_pollcb_t *pollcb) { - if (!(pollcb->flags & APR_POLLSET_WAKEABLE)) - return APR_EINIT; - - if (apr_atomic_cas32(&pollcb->wakeup_set, 1, 0) == 0) + if (pollcb->flags & APR_POLLSET_WAKEABLE) return apr_file_putc(1, pollcb->wakeup_pipe[1]); - - return APR_SUCCESS; + else + return APR_EINIT; } APR_DECLARE(const char *) apr_pollcb_method_name(apr_pollcb_t *pollcb) diff --git a/poll/unix/pollset.c b/poll/unix/pollset.c index 57374a5e7..8fa817330 100644 --- a/poll/unix/pollset.c +++ b/poll/unix/pollset.c @@ -23,7 +23,6 @@ #include "apr_poll.h" #include "apr_time.h" #include "apr_portable.h" -#include "apr_atomic.h" #include "apr_arch_file_io.h" #include "apr_arch_networkio.h" #include "apr_arch_poll_private.h" @@ -145,7 +144,6 @@ APR_DECLARE(apr_status_t) apr_pollset_create_ex(apr_pollset_t **ret_pollset, pollset->pool = p; pollset->flags = flags; pollset->provider = provider; - pollset->wakeup_set = 0; rv = (*provider->create)(pollset, size, p, flags); if (rv == APR_ENOTIMPL) { @@ -222,13 +220,10 @@ APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t * pollset) APR_DECLARE(apr_status_t) apr_pollset_wakeup(apr_pollset_t *pollset) { - if (!(pollset->flags & APR_POLLSET_WAKEABLE)) - return APR_EINIT; - - if (apr_atomic_cas32(&pollset->wakeup_set, 1, 0) == 0) + if (pollset->flags & APR_POLLSET_WAKEABLE) return apr_file_putc(1, pollset->wakeup_pipe[1]); - - return APR_SUCCESS; + else + return APR_EINIT; } APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, diff --git a/poll/unix/port.c b/poll/unix/port.c index 638a8cba7..c1e599412 100644 --- a/poll/unix/port.c +++ b/poll/unix/port.c @@ -411,7 +411,7 @@ static apr_status_t impl_pollset_poll(apr_pollset_t *pollset, if ((pollset->flags & APR_POLLSET_WAKEABLE) && ep->pfd.desc_type == APR_POLL_FILE && ep->pfd.desc.f == pollset->wakeup_pipe[0]) { - apr_poll_drain_wakeup_pipe(&pollset->wakeup_set, pollset->wakeup_pipe); + apr_poll_drain_wakeup_pipe(pollset->wakeup_pipe); rv = APR_EINTR; } else { @@ -563,7 +563,7 @@ static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb, if ((pollcb->flags & APR_POLLSET_WAKEABLE) && pollfd->desc_type == APR_POLL_FILE && pollfd->desc.f == pollcb->wakeup_pipe[0]) { - apr_poll_drain_wakeup_pipe(&pollcb->wakeup_set, pollcb->wakeup_pipe); + apr_poll_drain_wakeup_pipe(pollcb->wakeup_pipe); return APR_EINTR; } diff --git a/poll/unix/select.c b/poll/unix/select.c index f2c1a1328..51be3c1cd 100644 --- a/poll/unix/select.c +++ b/poll/unix/select.c @@ -401,7 +401,7 @@ static apr_status_t impl_pollset_poll(apr_pollset_t *pollset, else { if ((pollset->flags & APR_POLLSET_WAKEABLE) && pollset->p->query_set[i].desc.f == pollset->wakeup_pipe[0]) { - apr_poll_drain_wakeup_pipe(&pollset->wakeup_set, pollset->wakeup_pipe); + apr_poll_drain_wakeup_pipe(pollset->wakeup_pipe); rv = APR_EINTR; continue; } diff --git a/poll/unix/wakeup.c b/poll/unix/wakeup.c index b7e9efd45..6c3dcd6fb 100644 --- a/poll/unix/wakeup.c +++ b/poll/unix/wakeup.c @@ -18,7 +18,6 @@ #include "apr_poll.h" #include "apr_time.h" #include "apr_portable.h" -#include "apr_atomic.h" #include "apr_arch_file_io.h" #include "apr_arch_networkio.h" #include "apr_arch_poll_private.h" @@ -34,7 +33,7 @@ apr_status_t apr_poll_create_wakeup_pipe(apr_pool_t *pool, apr_pollfd_t *pfd, apr_status_t rv; if ((rv = apr_file_socket_pipe_create(&wakeup_pipe[0], &wakeup_pipe[1], - pool)) != APR_SUCCESS) + pool)) != APR_SUCCESS) return rv; pfd->reqevents = APR_POLLIN; @@ -81,9 +80,9 @@ apr_status_t apr_poll_create_wakeup_pipe(apr_pool_t *pool, apr_pollfd_t *pfd, { apr_status_t rv; - /* Read end of the pipe is non-blocking */ if ((rv = apr_file_pipe_create_ex(&wakeup_pipe[0], &wakeup_pipe[1], - APR_WRITE_BLOCK, pool))) + APR_WRITE_BLOCK, + pool)) != APR_SUCCESS) return rv; pfd->p = pool; @@ -136,11 +135,18 @@ apr_status_t apr_poll_close_wakeup_pipe(apr_file_t **wakeup_pipe) /* Read and discard whatever is in the wakeup pipe. */ -void apr_poll_drain_wakeup_pipe(volatile apr_uint32_t *wakeup_set, apr_file_t **wakeup_pipe) +void apr_poll_drain_wakeup_pipe(apr_file_t **wakeup_pipe) { - char ch; - - (void)apr_file_getc(&ch, wakeup_pipe[0]); - apr_atomic_set32(wakeup_set, 0); + char rb[512]; + apr_size_t nr = sizeof(rb); + + while (apr_file_read(wakeup_pipe[0], rb, &nr) == APR_SUCCESS) { + /* Although we write just one byte to the other end of the pipe + * during wakeup, multiple threads could call the wakeup. + * So simply drain out from the input side of the pipe all + * the data. + */ + if (nr != sizeof(rb)) + break; + } } - |