summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorivan <ivan@13f79535-47bb-0310-9956-ffa450edef68>2022-02-15 13:05:37 +0000
committerivan <ivan@13f79535-47bb-0310-9956-ffa450edef68>2022-02-15 13:05:37 +0000
commit67b11d5368e123a33ae727275df59939af15403c (patch)
tree0c918c8508555eb177419aea175c19bb78df6086
parent3577c4d2cdbef7a64b32f514cd355cf95b7a1aa1 (diff)
downloadlibapr-1.8.x-r1897895.tar.gz
On '1.8.x-r1897895' branch: Backport r1897895 from trunk.1.8.x-r1897895
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/1.8.x-r1897895@1898104 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CMakeLists.txt1
-rw-r--r--file_io/win32/pipe.c208
-rw-r--r--file_io/win32/readwrite.c42
-rw-r--r--include/arch/unix/apr_arch_poll_private.h23
-rw-r--r--include/arch/win32/apr_arch_file_io.h11
-rw-r--r--include/arch/win32/apr_arch_networkio.h8
-rw-r--r--network_io/win32/socket_pipe.c195
-rw-r--r--poll/unix/poll.c25
-rw-r--r--poll/unix/pollcb.c25
-rw-r--r--poll/unix/pollset.c22
-rw-r--r--poll/unix/select.c35
-rw-r--r--poll/unix/wakeup.c36
12 files changed, 338 insertions, 293 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b4632c3c0..87f4ea8c6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -174,6 +174,7 @@ SET(APR_SOURCES
network_io/unix/sockaddr.c
network_io/unix/socket_util.c
network_io/win32/sendrecv.c
+ network_io/win32/socket_pipe.c
network_io/win32/sockets.c
network_io/win32/sockopt.c
passwd/apr_getpass.c
diff --git a/file_io/win32/pipe.c b/file_io/win32/pipe.c
index 7dcbfb00e..e898b2d13 100644
--- a/file_io/win32/pipe.c
+++ b/file_io/win32/pipe.c
@@ -272,211 +272,3 @@ APR_DECLARE(apr_status_t) apr_os_pipe_put(apr_file_t **file,
{
return apr_os_pipe_put_ex(file, thefile, 0, pool);
}
-
-static apr_status_t create_socket_pipe(SOCKET *rd, SOCKET *wr)
-{
- static int id = 0;
- FD_SET rs;
- SOCKET ls;
- struct timeval socktm;
- struct sockaddr_in pa;
- struct sockaddr_in la;
- struct sockaddr_in ca;
- int nrd;
- apr_status_t rv = APR_SUCCESS;
- int ll = sizeof(la);
- int lc = sizeof(ca);
- unsigned long bm = 1;
- int uid[2];
- int iid[2];
-
- *rd = INVALID_SOCKET;
- *wr = INVALID_SOCKET;
-
- /* Create the unique socket identifier
- * so that we know the connection originated
- * from us.
- */
- uid[0] = getpid();
- uid[1] = id++;
- if ((ls = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
- return apr_get_netos_error();
- }
-
- pa.sin_family = AF_INET;
- pa.sin_port = 0;
- pa.sin_addr.s_addr = inet_addr("127.0.0.1");
-
- if (bind(ls, (SOCKADDR *)&pa, sizeof(pa)) == SOCKET_ERROR) {
- rv = apr_get_netos_error();
- goto cleanup;
- }
- if (getsockname(ls, (SOCKADDR *)&la, &ll) == SOCKET_ERROR) {
- rv = apr_get_netos_error();
- goto cleanup;
- }
- if (listen(ls, 1) == SOCKET_ERROR) {
- rv = apr_get_netos_error();
- goto cleanup;
- }
- if ((*wr = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
- rv = apr_get_netos_error();
- goto cleanup;
- }
- if (connect(*wr, (SOCKADDR *)&la, sizeof(la)) == SOCKET_ERROR) {
- rv = apr_get_netos_error();
- goto cleanup;
- }
- if (send(*wr, (char *)uid, sizeof(uid), 0) != sizeof(uid)) {
- if ((rv = apr_get_netos_error()) == 0) {
- rv = APR_EINVAL;
- }
- goto cleanup;
- }
- if (ioctlsocket(ls, FIONBIO, &bm) == SOCKET_ERROR) {
- rv = apr_get_netos_error();
- goto cleanup;
- }
- for (;;) {
- int ns;
- int nc = 0;
- /* Listening socket is nonblocking by now.
- * The accept should create the socket
- * immediatelly because we are connected already.
- * However on buys systems this can take a while
- * until winsock gets a chance to handle the events.
- */
- FD_ZERO(&rs);
- FD_SET(ls, &rs);
-
- socktm.tv_sec = 1;
- socktm.tv_usec = 0;
- if ((ns = select(0, &rs, NULL, NULL, &socktm)) == SOCKET_ERROR) {
- /* Accept still not signaled */
- Sleep(100);
- continue;
- }
- if (ns == 0) {
- /* No connections in the last second */
- continue;
- }
- if ((*rd = accept(ls, (SOCKADDR *)&ca, &lc)) == INVALID_SOCKET) {
- 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;
- }
- nrd = recv(*rd, (char *)iid, sizeof(iid), 0);
- if (nrd == SOCKET_ERROR) {
- rv = apr_get_netos_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 */
- closesocket(ls);
- return 0;
-
-cleanup:
- /* Don't leak resources */
- closesocket(ls);
- if (*rd != INVALID_SOCKET)
- closesocket(*rd);
- if (*wr != INVALID_SOCKET)
- closesocket(*wr);
-
- *rd = INVALID_SOCKET;
- *wr = INVALID_SOCKET;
- return rv;
-}
-
-static apr_status_t socket_pipe_cleanup(void *thefile)
-{
- apr_file_t *file = thefile;
- if (file->filehand != INVALID_HANDLE_VALUE) {
- shutdown((SOCKET)file->filehand, SD_BOTH);
- closesocket((SOCKET)file->filehand);
- file->filehand = INVALID_HANDLE_VALUE;
- }
- return APR_SUCCESS;
-}
-
-apr_status_t apr_file_socket_pipe_create(apr_file_t **in,
- apr_file_t **out,
- apr_pool_t *p)
-{
- apr_status_t rv;
- SOCKET rd;
- SOCKET wr;
-
- if ((rv = create_socket_pipe(&rd, &wr)) != APR_SUCCESS) {
- return rv;
- }
- (*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)->ungetchar = -1;
- (*in)->eof_hit = 0;
- (*in)->filePtr = 0;
- (*in)->bufpos = 0;
- (*in)->dataRead = 0;
- (*in)->direction = 0;
- (*in)->pOverlapped = NULL;
- (*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)->timeout = -1;
- (*out)->ungetchar = -1;
- (*out)->eof_hit = 0;
- (*out)->filePtr = 0;
- (*out)->bufpos = 0;
- (*out)->dataRead = 0;
- (*out)->direction = 0;
- (*out)->pOverlapped = NULL;
- (*out)->filehand = (HANDLE)wr;
-
- apr_pool_cleanup_register(p, (void *)(*in), socket_pipe_cleanup,
- apr_pool_cleanup_null);
- apr_pool_cleanup_register(p, (void *)(*out), socket_pipe_cleanup,
- apr_pool_cleanup_null);
-
- return rv;
-}
-
-apr_status_t apr_file_socket_pipe_close(apr_file_t *file)
-{
- apr_status_t stat;
- if (file->ftype != APR_FILETYPE_SOCKET)
- return apr_file_close(file);
- if ((stat = socket_pipe_cleanup(file)) == APR_SUCCESS) {
- apr_pool_cleanup_kill(file->pool, file, socket_pipe_cleanup);
-
- if (file->mutex) {
- apr_thread_mutex_destroy(file->mutex);
- }
-
- return APR_SUCCESS;
- }
- return stat;
-}
-
diff --git a/file_io/win32/readwrite.c b/file_io/win32/readwrite.c
index bd4e87c9e..79a4b2b17 100644
--- a/file_io/win32/readwrite.c
+++ b/file_io/win32/readwrite.c
@@ -20,7 +20,6 @@
#include "apr_strings.h"
#include "apr_lib.h"
#include "apr_errno.h"
-#include "apr_arch_networkio.h"
#include "apr_arch_atime.h"
#include "apr_arch_misc.h"
@@ -75,23 +74,8 @@ static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t le
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 {
@@ -315,25 +299,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) {
+ return rv;
+ } else {
+ if (thefile->ftype == APR_FILETYPE_PIPE) {
rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote,
thefile->pOverlapped);
}
diff --git a/include/arch/unix/apr_arch_poll_private.h b/include/arch/unix/apr_arch_poll_private.h
index 8dd97d1ad..7b91963a6 100644
--- a/include/arch/unix/apr_arch_poll_private.h
+++ b/include/arch/unix/apr_arch_poll_private.h
@@ -81,6 +81,12 @@
#endif
#endif
+#ifdef WIN32
+#define WAKEUP_USES_PIPE 0
+#else
+#define WAKEUP_USES_PIPE 1
+#endif
+
#if defined(POLLSET_USES_KQUEUE) || defined(POLLSET_USES_EPOLL) || defined(POLLSET_USES_PORT) || defined(POLLSET_USES_AIO_MSGQ)
#include "apr_ring.h"
@@ -121,7 +127,11 @@ struct apr_pollset_t
apr_uint32_t nalloc;
apr_uint32_t flags;
/* Pipe descriptors used for wakeup */
+#if WAKEUP_USES_PIPE
apr_file_t *wakeup_pipe[2];
+#else
+ apr_socket_t *wakeup_socket[2];
+#endif
apr_pollfd_t wakeup_pfd;
volatile apr_uint32_t wakeup_set;
apr_pollset_private_t *p;
@@ -150,7 +160,11 @@ struct apr_pollcb_t {
apr_uint32_t nalloc;
apr_uint32_t flags;
/* Pipe descriptors used for wakeup */
+#if WAKEUP_USES_PIPE
apr_file_t *wakeup_pipe[2];
+#else
+ apr_socket_t *wakeup_socket[2];
+#endif
apr_pollfd_t wakeup_pfd;
volatile apr_uint32_t wakeup_set;
int fd;
@@ -181,9 +195,16 @@ struct apr_pollcb_provider_t {
* Private functions used for the implementation of both apr_pollcb_* and
* apr_pollset_*
*/
-apr_status_t apr_poll_create_wakeup_pipe(apr_pool_t *pool, apr_pollfd_t *pfd,
+#if WAKEUP_USES_PIPE
+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);
+#else
+apr_status_t apr_poll_create_wakeup_socket(apr_pool_t *pool, apr_pollfd_t *pfd,
+ apr_socket_t **wakeup_socket);
+apr_status_t apr_poll_close_wakeup_socket(apr_socket_t **wakeup_socket);
+void apr_poll_drain_wakeup_socket(volatile apr_uint32_t *wakeup_set, apr_socket_t **wakeup_socket);
+#endif
#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..ad8153946 100644
--- a/include/arch/win32/apr_arch_file_io.h
+++ b/include/arch/win32/apr_arch_file_io.h
@@ -161,8 +161,7 @@ apr_status_t more_finfo(apr_finfo_t *finfo, const void *ufile,
typedef enum {
APR_FILETYPE_FILE = 0,
- APR_FILETYPE_PIPE,
- APR_FILETYPE_SOCKET
+ APR_FILETYPE_PIPE
} apr_filetype_e;
struct apr_file_t {
@@ -261,12 +260,4 @@ apr_status_t filepath_root_case(char **rootpath, char *root, apr_pool_t *p);
apr_status_t file_cleanup(void *);
-extern apr_status_t
-apr_file_socket_pipe_create(apr_file_t **in,
- apr_file_t **out,
- apr_pool_t *p);
-
-extern apr_status_t
-apr_file_socket_pipe_close(apr_file_t *file);
-
#endif /* ! FILE_IO_H */
diff --git a/include/arch/win32/apr_arch_networkio.h b/include/arch/win32/apr_arch_networkio.h
index 04be55595..dabe35ca1 100644
--- a/include/arch/win32/apr_arch_networkio.h
+++ b/include/arch/win32/apr_arch_networkio.h
@@ -86,5 +86,13 @@ void apr_sockaddr_vars_set(apr_sockaddr_t *, int, apr_port_t);
(skt)->options &= ~(option); \
} while (0)
+extern apr_status_t
+apr_socket_pipe_create(apr_socket_t **in,
+ apr_socket_t **out,
+ apr_pool_t *p);
+
+extern apr_status_t
+apr_socket_pipe_close(apr_socket_t *socket);
+
#endif /* ! NETWORK_IO_H */
diff --git a/network_io/win32/socket_pipe.c b/network_io/win32/socket_pipe.c
new file mode 100644
index 000000000..d9cac504b
--- /dev/null
+++ b/network_io/win32/socket_pipe.c
@@ -0,0 +1,195 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_arch_networkio.h"
+#include "apr_portable.h"
+
+static apr_status_t create_socket_pipe(SOCKET *rd, SOCKET *wr)
+{
+ FD_SET rs;
+ SOCKET ls;
+ struct timeval socktm;
+ struct sockaddr_in pa;
+ struct sockaddr_in la;
+ struct sockaddr_in ca;
+ int nrd;
+ apr_status_t rv;
+ int ll = sizeof(la);
+ int lc = sizeof(ca);
+ unsigned long bm = 1;
+ char uid[8];
+ char iid[8];
+
+ *rd = INVALID_SOCKET;
+ *wr = INVALID_SOCKET;
+
+ /* Create the unique socket identifier
+ * so that we know the connection originated
+ * from us.
+ */
+ rv = apr_generate_random_bytes(uid, sizeof(uid));
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
+
+ if ((ls = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
+ return apr_get_netos_error();
+ }
+
+ pa.sin_family = AF_INET;
+ pa.sin_port = 0;
+ pa.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+ if (bind(ls, (SOCKADDR *)&pa, sizeof(pa)) == SOCKET_ERROR) {
+ rv = apr_get_netos_error();
+ goto cleanup;
+ }
+ if (getsockname(ls, (SOCKADDR *)&la, &ll) == SOCKET_ERROR) {
+ rv = apr_get_netos_error();
+ goto cleanup;
+ }
+ if (listen(ls, 1) == SOCKET_ERROR) {
+ rv = apr_get_netos_error();
+ goto cleanup;
+ }
+ if ((*wr = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
+ rv = apr_get_netos_error();
+ goto cleanup;
+ }
+ if (connect(*wr, (SOCKADDR *)&la, sizeof(la)) == SOCKET_ERROR) {
+ rv = apr_get_netos_error();
+ goto cleanup;
+ }
+ if (send(*wr, uid, sizeof(uid), 0) != sizeof(uid)) {
+ if ((rv = apr_get_netos_error()) == 0) {
+ rv = APR_EINVAL;
+ }
+ goto cleanup;
+ }
+ if (ioctlsocket(ls, FIONBIO, &bm) == SOCKET_ERROR) {
+ rv = apr_get_netos_error();
+ goto cleanup;
+ }
+ for (;;) {
+ int ns;
+ int nc = 0;
+ /* Listening socket is nonblocking by now.
+ * The accept should create the socket
+ * immediatelly because we are connected already.
+ * However on buys systems this can take a while
+ * until winsock gets a chance to handle the events.
+ */
+ FD_ZERO(&rs);
+ FD_SET(ls, &rs);
+
+ socktm.tv_sec = 1;
+ socktm.tv_usec = 0;
+ if ((ns = select(0, &rs, NULL, NULL, &socktm)) == SOCKET_ERROR) {
+ /* Accept still not signaled */
+ Sleep(100);
+ continue;
+ }
+ if (ns == 0) {
+ /* No connections in the last second */
+ continue;
+ }
+ if ((*rd = accept(ls, (SOCKADDR *)&ca, &lc)) == INVALID_SOCKET) {
+ 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;
+ }
+ nrd = recv(*rd, iid, sizeof(iid), 0);
+ if (nrd == SOCKET_ERROR) {
+ rv = apr_get_netos_error();
+ goto cleanup;
+ }
+ if (nrd == (int)sizeof(uid) && memcmp(iid, uid, sizeof(uid)) == 0) {
+ /* Got the right identifier, return. */
+ break;
+ }
+ closesocket(*rd);
+ }
+ /* We don't need the listening socket any more */
+ closesocket(ls);
+ return 0;
+
+cleanup:
+ /* Don't leak resources */
+ closesocket(ls);
+ if (*rd != INVALID_SOCKET)
+ closesocket(*rd);
+ if (*wr != INVALID_SOCKET)
+ closesocket(*wr);
+
+ *rd = INVALID_SOCKET;
+ *wr = INVALID_SOCKET;
+ return rv;
+}
+
+static apr_status_t socket_pipe_cleanup(void *thefile)
+{
+ apr_socket_t *file = thefile;
+ if (file->socketdes != INVALID_SOCKET) {
+ shutdown(file->socketdes, SD_BOTH);
+ closesocket(file->socketdes);
+ file->socketdes = INVALID_SOCKET;
+ }
+ return APR_SUCCESS;
+}
+
+apr_status_t apr_socket_pipe_create(apr_socket_t **in,
+ apr_socket_t **out,
+ apr_pool_t *p)
+{
+ apr_status_t rv;
+ SOCKET rd;
+ SOCKET wr;
+
+ *in = NULL;
+ *out = NULL;
+
+ if ((rv = create_socket_pipe(&rd, &wr)) != APR_SUCCESS) {
+ return rv;
+ }
+ apr_os_sock_put(in, &rd, p);
+ apr_os_sock_put(out, &wr, p);
+
+ /* read end of the pipe is non-blocking */
+ apr_socket_timeout_set(*in, 0);
+
+ apr_pool_cleanup_register(p, (void *)(*in), socket_pipe_cleanup,
+ apr_pool_cleanup_null);
+ apr_pool_cleanup_register(p, (void *)(*out), socket_pipe_cleanup,
+ apr_pool_cleanup_null);
+
+ return rv;
+}
+
+apr_status_t apr_socket_pipe_close(apr_socket_t *socket)
+{
+ apr_status_t stat;
+ if ((stat = socket_pipe_cleanup(socket)) == APR_SUCCESS) {
+ apr_pool_cleanup_kill(socket->pool, socket, socket_pipe_cleanup);
+
+ return APR_SUCCESS;
+ }
+ return stat;
+}
diff --git a/poll/unix/poll.c b/poll/unix/poll.c
index 9b6a539e0..fdfece536 100644
--- a/poll/unix/poll.c
+++ b/poll/unix/poll.c
@@ -191,11 +191,7 @@ static apr_status_t impl_pollset_add(apr_pollset_t *pollset,
#if APR_FILES_AS_SOCKETS
pollset->p->pollset[pollset->nelts].fd = descriptor->desc.f->filedes;
#else
- if ((pollset->flags & APR_POLLSET_WAKEABLE) &&
- descriptor->desc.f == pollset->wakeup_pipe[0])
- pollset->p->pollset[pollset->nelts].fd = (SOCKET)descriptor->desc.f->filedes;
- else
- return APR_EBADF;
+ return APR_EBADF;
#endif
}
pollset->p->pollset[pollset->nelts].events =
@@ -276,12 +272,21 @@ static apr_status_t impl_pollset_poll(apr_pollset_t *pollset,
/* Check if the polled descriptor is our
* wakeup pipe. In that case do not put it result set.
*/
+#if WAKEUP_USES_PIPE
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);
rv = APR_EINTR;
}
+#else
+ if ((pollset->flags & APR_POLLSET_WAKEABLE) &&
+ pollset->p->query_set[i].desc_type == APR_POLL_SOCKET &&
+ pollset->p->query_set[i].desc.s == pollset->wakeup_socket[0]) {
+ apr_poll_drain_wakeup_socket(&pollset->wakeup_set, pollset->wakeup_socket);
+ rv = APR_EINTR;
+ }
+#endif
else {
pollset->p->result_set[j] = pollset->p->query_set[i];
pollset->p->result_set[j].rtnevents =
@@ -428,13 +433,21 @@ static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb,
if (pollcb->pollset.ps[i].revents != 0) {
apr_pollfd_t *pollfd = pollcb->copyset[i];
+#if WAKEUP_USES_PIPE
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);
return APR_EINTR;
}
-
+#else
+ if ((pollcb->flags & APR_POLLSET_WAKEABLE) &&
+ pollfd->desc_type == APR_POLL_SOCKET &&
+ pollfd->desc.s == pollcb->wakeup_socket[0]) {
+ apr_poll_drain_wakeup_socket(&pollcb->wakeup_set, pollcb->wakeup_socket);
+ return APR_EINTR;
+ }
+#endif
pollfd->rtnevents = get_revent(pollcb->pollset.ps[i].revents);
rv = func(baton, pollfd);
if (rv) {
diff --git a/poll/unix/pollcb.c b/poll/unix/pollcb.c
index 103ab9fa6..144669629 100644
--- a/poll/unix/pollcb.c
+++ b/poll/unix/pollcb.c
@@ -82,7 +82,11 @@ static apr_status_t pollcb_cleanup(void *p)
(*pollcb->provider->cleanup)(pollcb);
}
if (pollcb->flags & APR_POLLSET_WAKEABLE) {
+#if WAKEUP_USES_PIPE
apr_poll_close_wakeup_pipe(pollcb->wakeup_pipe);
+#else
+ apr_poll_close_wakeup_socket(pollcb->wakeup_socket);
+#endif
}
return APR_SUCCESS;
@@ -163,12 +167,21 @@ APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **ret_pollcb,
}
if (flags & APR_POLLSET_WAKEABLE) {
+#if WAKEUP_USES_PIPE
/* Create wakeup pipe */
if ((rv = apr_poll_create_wakeup_pipe(pollcb->pool, &pollcb->wakeup_pfd,
- pollcb->wakeup_pipe))
- != APR_SUCCESS) {
+ pollcb->wakeup_pipe))
+ != APR_SUCCESS) {
+ return rv;
+ }
+#else
+ /* Create wakeup socket */
+ if ((rv = apr_poll_create_wakeup_socket(pollcb->pool, &pollcb->wakeup_pfd,
+ pollcb->wakeup_socket))
+ != APR_SUCCESS) {
return rv;
}
+#endif
if ((rv = apr_pollcb_add(pollcb, &pollcb->wakeup_pfd)) != APR_SUCCESS) {
return rv;
@@ -217,8 +230,14 @@ 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 (apr_atomic_cas32(&pollcb->wakeup_set, 1, 0) == 0) {
+#if WAKEUP_USES_PIPE
return apr_file_putc(1, pollcb->wakeup_pipe[1]);
+#else
+ apr_size_t len = 1;
+ return apr_socket_send(pollcb->wakeup_socket[1], "\1", &len);
+#endif
+ }
return APR_SUCCESS;
}
diff --git a/poll/unix/pollset.c b/poll/unix/pollset.c
index 57374a5e7..6a2013637 100644
--- a/poll/unix/pollset.c
+++ b/poll/unix/pollset.c
@@ -38,7 +38,11 @@ static apr_status_t pollset_cleanup(void *p)
(*pollset->provider->cleanup)(pollset);
}
if (pollset->flags & APR_POLLSET_WAKEABLE) {
+#if WAKEUP_USES_PIPE
apr_poll_close_wakeup_pipe(pollset->wakeup_pipe);
+#else
+ apr_poll_close_wakeup_socket(pollset->wakeup_socket);
+#endif
}
return APR_SUCCESS;
@@ -166,13 +170,21 @@ APR_DECLARE(apr_status_t) apr_pollset_create_ex(apr_pollset_t **ret_pollset,
return rv;
}
if (flags & APR_POLLSET_WAKEABLE) {
+#if WAKEUP_USES_PIPE
/* Create wakeup pipe */
if ((rv = apr_poll_create_wakeup_pipe(pollset->pool, &pollset->wakeup_pfd,
pollset->wakeup_pipe))
!= APR_SUCCESS) {
return rv;
}
-
+#else
+ /* Create wakeup socket */
+ if ((rv = apr_poll_create_wakeup_socket(pollset->pool, &pollset->wakeup_pfd,
+ pollset->wakeup_socket))
+ != APR_SUCCESS) {
+ return rv;
+ }
+#endif
if ((rv = apr_pollset_add(pollset, &pollset->wakeup_pfd)) != APR_SUCCESS) {
return rv;
}
@@ -225,8 +237,14 @@ 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 (apr_atomic_cas32(&pollset->wakeup_set, 1, 0) == 0) {
+#if WAKEUP_USES_PIPE
return apr_file_putc(1, pollset->wakeup_pipe[1]);
+#else
+ apr_size_t len = 1;
+ return apr_socket_send(pollset->wakeup_socket[1], "\1", &len);
+#endif
+ }
return APR_SUCCESS;
}
diff --git a/poll/unix/select.c b/poll/unix/select.c
index f2c1a1328..562ced7f6 100644
--- a/poll/unix/select.c
+++ b/poll/unix/select.c
@@ -248,11 +248,7 @@ static apr_status_t impl_pollset_add(apr_pollset_t *pollset,
}
else {
#if !APR_FILES_AS_SOCKETS
- if ((pollset->flags & APR_POLLSET_WAKEABLE) &&
- descriptor->desc.f == pollset->wakeup_pipe[0])
- fd = (apr_os_sock_t)descriptor->desc.f->filedes;
- else
- return APR_EBADF;
+ return APR_EBADF;
#else
#ifdef NETWARE
/* NetWare can't handle mixed descriptor types in select() */
@@ -395,23 +391,34 @@ static apr_status_t impl_pollset_poll(apr_pollset_t *pollset,
j = 0;
for (i = 0; i < pollset->nelts; i++) {
apr_os_sock_t fd;
- if (pollset->p->query_set[i].desc_type == APR_POLL_SOCKET) {
- fd = pollset->p->query_set[i].desc.s->socketdes;
- }
- else {
- if ((pollset->flags & APR_POLLSET_WAKEABLE) &&
+
+ if (pollset->flags & APR_POLLSET_WAKEABLE) {
+#if WAKEUP_USES_PIPE
+ if (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);
rv = APR_EINTR;
continue;
}
- else {
+#else
+ if (pollset->p->query_set[i].desc_type == APR_POLL_SOCKET &&
+ pollset->p->query_set[i].desc.s == pollset->wakeup_socket[0]) {
+ apr_poll_drain_wakeup_socket(&pollset->wakeup_set, pollset->wakeup_socket);
+ rv = APR_EINTR;
+ continue;
+ }
+#endif
+ }
+
+ if (pollset->p->query_set[i].desc_type == APR_POLL_SOCKET) {
+ fd = pollset->p->query_set[i].desc.s->socketdes;
+ }
+ else {
#if !APR_FILES_AS_SOCKETS
- return APR_EBADF;
+ return APR_EBADF;
#else
- fd = pollset->p->query_set[i].desc.f->filedes;
+ fd = pollset->p->query_set[i].desc.f->filedes;
#endif
- }
}
if (FD_ISSET(fd, &readset) || FD_ISSET(fd, &writeset) ||
FD_ISSET(fd, &exceptset)) {
diff --git a/poll/unix/wakeup.c b/poll/unix/wakeup.c
index b7e9efd45..bb0356444 100644
--- a/poll/unix/wakeup.c
+++ b/poll/unix/wakeup.c
@@ -28,34 +28,34 @@
#ifdef WIN32
-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_create_wakeup_socket(apr_pool_t *pool, apr_pollfd_t *pfd,
+ apr_socket_t **wakeup_socket)
{
apr_status_t rv;
- if ((rv = apr_file_socket_pipe_create(&wakeup_pipe[0], &wakeup_pipe[1],
+ if ((rv = apr_socket_pipe_create(&wakeup_socket[0], &wakeup_socket[1],
pool)) != APR_SUCCESS)
return rv;
pfd->reqevents = APR_POLLIN;
- pfd->desc_type = APR_POLL_FILE;
- pfd->desc.f = wakeup_pipe[0];
+ pfd->desc_type = APR_POLL_SOCKET;
+ pfd->desc.s = wakeup_socket[0];
return APR_SUCCESS;
}
-apr_status_t apr_poll_close_wakeup_pipe(apr_file_t **wakeup_pipe)
+apr_status_t apr_poll_close_wakeup_socket(apr_socket_t **wakeup_socket)
{
apr_status_t rv0 = APR_SUCCESS;
apr_status_t rv1 = APR_SUCCESS;
/* Close both sides of the wakeup pipe */
- if (wakeup_pipe[0]) {
- rv0 = apr_file_socket_pipe_close(wakeup_pipe[0]);
- wakeup_pipe[0] = NULL;
+ if (wakeup_socket[0]) {
+ rv0 = apr_socket_pipe_close(wakeup_socket[0]);
+ wakeup_socket[0] = NULL;
}
- if (wakeup_pipe[1]) {
- rv1 = apr_file_socket_pipe_close(wakeup_pipe[1]);
- wakeup_pipe[1] = NULL;
+ if (wakeup_socket[1]) {
+ rv1 = apr_socket_pipe_close(wakeup_socket[1]);
+ wakeup_socket[1] = NULL;
}
return rv0 ? rv0 : rv1;
}
@@ -134,6 +134,7 @@ apr_status_t apr_poll_close_wakeup_pipe(apr_file_t **wakeup_pipe)
#endif /* APR_FILES_AS_SOCKETS */
+#if WAKEUP_USES_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)
@@ -143,4 +144,15 @@ void apr_poll_drain_wakeup_pipe(volatile apr_uint32_t *wakeup_set, apr_file_t **
(void)apr_file_getc(&ch, wakeup_pipe[0]);
apr_atomic_set32(wakeup_set, 0);
}
+#else
+/* Read and discard whatever is in the wakeup socket.
+ */
+void apr_poll_drain_wakeup_socket(volatile apr_uint32_t *wakeup_set, apr_socket_t **wakeup_socket)
+{
+ char ch;
+ apr_size_t len;
+ (void)apr_socket_recv(wakeup_socket[0], &ch, &len);
+ apr_atomic_set32(wakeup_set, 0);
+}
+#endif \ No newline at end of file