1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include "apr_portable.h"
21 #include "apr_arch_file_io.h"
22 #include "apr_arch_networkio.h"
23 #include "apr_arch_poll_private.h"
24 #include "apr_arch_inherit.h"
26 #if !APR_FILES_AS_SOCKETS
30 apr_status_t apr_poll_create_wakeup_pipe(apr_pool_t *pool, apr_pollfd_t *pfd,
31 apr_file_t **wakeup_pipe)
35 if ((rv = apr_file_socket_pipe_create(&wakeup_pipe[0], &wakeup_pipe[1],
36 pool)) != APR_SUCCESS)
39 pfd->reqevents = APR_POLLIN;
40 pfd->desc_type = APR_POLL_FILE;
41 pfd->desc.f = wakeup_pipe[0];
45 apr_status_t apr_poll_close_wakeup_pipe(apr_file_t **wakeup_pipe)
47 apr_status_t rv0 = APR_SUCCESS;
48 apr_status_t rv1 = APR_SUCCESS;
50 /* Close both sides of the wakeup pipe */
52 rv0 = apr_file_socket_pipe_close(wakeup_pipe[0]);
53 wakeup_pipe[0] = NULL;
56 rv1 = apr_file_socket_pipe_close(wakeup_pipe[1]);
57 wakeup_pipe[1] = NULL;
59 return rv0 ? rv0 : rv1;
64 apr_status_t apr_poll_create_wakeup_pipe(apr_pollfd_t *pfd, apr_file_t **wakeup_pipe)
69 apr_status_t apr_poll_close_wakeup_pipe(apr_file_t **wakeup_pipe)
76 #else /* APR_FILES_AS_SOCKETS */
78 apr_status_t apr_poll_create_wakeup_pipe(apr_pool_t *pool, apr_pollfd_t *pfd,
79 apr_file_t **wakeup_pipe)
83 if ((rv = apr_file_pipe_create(&wakeup_pipe[0], &wakeup_pipe[1],
84 pool)) != APR_SUCCESS)
88 pfd->reqevents = APR_POLLIN;
89 pfd->desc_type = APR_POLL_FILE;
90 pfd->desc.f = wakeup_pipe[0];
95 if ((flags = fcntl(wakeup_pipe[0]->filedes, F_GETFD)) == -1)
99 if (fcntl(wakeup_pipe[0]->filedes, F_SETFD, flags) == -1)
105 if ((flags = fcntl(wakeup_pipe[1]->filedes, F_GETFD)) == -1)
109 if (fcntl(wakeup_pipe[1]->filedes, F_SETFD, flags) == -1)
116 apr_status_t apr_poll_close_wakeup_pipe(apr_file_t **wakeup_pipe)
118 apr_status_t rv0 = APR_SUCCESS;
119 apr_status_t rv1 = APR_SUCCESS;
121 /* Close both sides of the wakeup pipe */
122 if (wakeup_pipe[0]) {
123 rv0 = apr_file_close(wakeup_pipe[0]);
124 wakeup_pipe[0] = NULL;
126 if (wakeup_pipe[1]) {
127 rv1 = apr_file_close(wakeup_pipe[1]);
128 wakeup_pipe[1] = NULL;
130 return rv0 ? rv0 : rv1;
133 #endif /* APR_FILES_AS_SOCKETS */
135 /* Read and discard whatever is in the wakeup pipe.
137 void apr_poll_drain_wakeup_pipe(apr_file_t **wakeup_pipe)
140 apr_size_t nr = sizeof(rb);
142 while (apr_file_read(wakeup_pipe[0], rb, &nr) == APR_SUCCESS) {
143 /* Although we write just one byte to the other end of the pipe
144 * during wakeup, multiple threads could call the wakeup.
145 * So simply drain out from the input side of the pipe all
148 if (nr != sizeof(rb))