/src/httpd/srclib/apr/poll/unix/wakeup.c
Line | Count | Source (jump to first uncovered line) |
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 |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
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. |
15 | | */ |
16 | | |
17 | | #include "apr.h" |
18 | | #include "apr_poll.h" |
19 | | #include "apr_time.h" |
20 | | #include "apr_portable.h" |
21 | | #include "apr_atomic.h" |
22 | | #include "apr_arch_file_io.h" |
23 | | #include "apr_arch_networkio.h" |
24 | | #include "apr_arch_poll_private.h" |
25 | | #include "apr_arch_inherit.h" |
26 | | |
27 | | #if !APR_FILES_AS_SOCKETS |
28 | | |
29 | | #ifdef WIN32 |
30 | | |
31 | | apr_status_t apr_poll_create_wakeup_socket(apr_pool_t *pool, apr_pollfd_t *pfd, |
32 | | apr_socket_t **wakeup_socket) |
33 | | { |
34 | | apr_status_t rv; |
35 | | |
36 | | if ((rv = apr_socket_pipe_create(&wakeup_socket[0], &wakeup_socket[1], |
37 | | pool)) != APR_SUCCESS) |
38 | | return rv; |
39 | | |
40 | | pfd->reqevents = APR_POLLIN; |
41 | | pfd->desc_type = APR_POLL_SOCKET; |
42 | | pfd->desc.s = wakeup_socket[0]; |
43 | | return APR_SUCCESS; |
44 | | } |
45 | | |
46 | | apr_status_t apr_poll_close_wakeup_socket(apr_socket_t **wakeup_socket) |
47 | | { |
48 | | apr_status_t rv0 = APR_SUCCESS; |
49 | | apr_status_t rv1 = APR_SUCCESS; |
50 | | |
51 | | /* Close both sides of the wakeup pipe */ |
52 | | if (wakeup_socket[0]) { |
53 | | rv0 = apr_socket_pipe_close(wakeup_socket[0]); |
54 | | wakeup_socket[0] = NULL; |
55 | | } |
56 | | if (wakeup_socket[1]) { |
57 | | rv1 = apr_socket_pipe_close(wakeup_socket[1]); |
58 | | wakeup_socket[1] = NULL; |
59 | | } |
60 | | return rv0 ? rv0 : rv1; |
61 | | } |
62 | | |
63 | | #else /* !WIN32 */ |
64 | | |
65 | | apr_status_t apr_poll_create_wakeup_pipe(apr_pollfd_t *pfd, apr_file_t **wakeup_pipe) |
66 | | { |
67 | | return APR_ENOTIMPL; |
68 | | } |
69 | | |
70 | | apr_status_t apr_poll_close_wakeup_pipe(apr_file_t **wakeup_pipe) |
71 | | { |
72 | | return APR_ENOTIMPL; |
73 | | } |
74 | | |
75 | | #endif /* !WIN32 */ |
76 | | |
77 | | #else /* APR_FILES_AS_SOCKETS */ |
78 | | |
79 | | apr_status_t apr_poll_create_wakeup_pipe(apr_pool_t *pool, apr_pollfd_t *pfd, |
80 | | apr_file_t **wakeup_pipe) |
81 | 0 | { |
82 | 0 | apr_status_t rv; |
83 | | |
84 | | /* Read end of the pipe is non-blocking */ |
85 | 0 | if ((rv = apr_file_pipe_create_ex(&wakeup_pipe[0], &wakeup_pipe[1], |
86 | 0 | APR_WRITE_BLOCK, pool))) |
87 | 0 | return rv; |
88 | | |
89 | 0 | pfd->p = pool; |
90 | 0 | pfd->reqevents = APR_POLLIN; |
91 | 0 | pfd->desc_type = APR_POLL_FILE; |
92 | 0 | pfd->desc.f = wakeup_pipe[0]; |
93 | |
|
94 | 0 | { |
95 | 0 | int flags; |
96 | |
|
97 | 0 | if ((flags = fcntl(wakeup_pipe[0]->filedes, F_GETFD)) == -1) |
98 | 0 | return errno; |
99 | | |
100 | 0 | flags |= FD_CLOEXEC; |
101 | 0 | if (fcntl(wakeup_pipe[0]->filedes, F_SETFD, flags) == -1) |
102 | 0 | return errno; |
103 | 0 | } |
104 | 0 | { |
105 | 0 | int flags; |
106 | |
|
107 | 0 | if ((flags = fcntl(wakeup_pipe[1]->filedes, F_GETFD)) == -1) |
108 | 0 | return errno; |
109 | | |
110 | 0 | flags |= FD_CLOEXEC; |
111 | 0 | if (fcntl(wakeup_pipe[1]->filedes, F_SETFD, flags) == -1) |
112 | 0 | return errno; |
113 | 0 | } |
114 | | |
115 | 0 | return APR_SUCCESS; |
116 | 0 | } |
117 | | |
118 | | apr_status_t apr_poll_close_wakeup_pipe(apr_file_t **wakeup_pipe) |
119 | 0 | { |
120 | 0 | apr_status_t rv0 = APR_SUCCESS; |
121 | 0 | apr_status_t rv1 = APR_SUCCESS; |
122 | | |
123 | | /* Close both sides of the wakeup pipe */ |
124 | 0 | if (wakeup_pipe[0]) { |
125 | 0 | rv0 = apr_file_close(wakeup_pipe[0]); |
126 | 0 | wakeup_pipe[0] = NULL; |
127 | 0 | } |
128 | 0 | if (wakeup_pipe[1]) { |
129 | 0 | rv1 = apr_file_close(wakeup_pipe[1]); |
130 | 0 | wakeup_pipe[1] = NULL; |
131 | 0 | } |
132 | 0 | return rv0 ? rv0 : rv1; |
133 | 0 | } |
134 | | |
135 | | #endif /* APR_FILES_AS_SOCKETS */ |
136 | | |
137 | | #if WAKEUP_USES_PIPE |
138 | | /* Read and discard whatever is in the wakeup pipe. |
139 | | */ |
140 | | void apr_poll_drain_wakeup_pipe(volatile apr_uint32_t *wakeup_set, apr_file_t **wakeup_pipe) |
141 | 0 | { |
142 | 0 | char ch; |
143 | |
|
144 | 0 | (void)apr_file_getc(&ch, wakeup_pipe[0]); |
145 | 0 | apr_atomic_set32(wakeup_set, 0); |
146 | 0 | } |
147 | | #else |
148 | | /* Read and discard whatever is in the wakeup socket. |
149 | | */ |
150 | | void apr_poll_drain_wakeup_socket(volatile apr_uint32_t *wakeup_set, apr_socket_t **wakeup_socket) |
151 | | { |
152 | | char ch; |
153 | | apr_size_t len; |
154 | | |
155 | | (void)apr_socket_recv(wakeup_socket[0], &ch, &len); |
156 | | apr_atomic_set32(wakeup_set, 0); |
157 | | } |
158 | | #endif |