/src/httpd/srclib/apr/support/unix/waitio.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_arch_file_io.h" |
18 | | #include "apr_arch_networkio.h" |
19 | | #include "apr_poll.h" |
20 | | #include "apr_errno.h" |
21 | | #include "apr_support.h" |
22 | | |
23 | | /* The only case where we don't use wait_for_io_or_timeout is on |
24 | | * pre-BONE BeOS, so this check should be sufficient and simpler */ |
25 | | #if !defined(BEOS_R5) && !defined(OS2) && APR_FILES_AS_SOCKETS |
26 | | #define USE_WAIT_FOR_IO |
27 | | #endif |
28 | | |
29 | | #ifdef USE_WAIT_FOR_IO |
30 | | |
31 | | #ifdef WAITIO_USES_POLL |
32 | | |
33 | | #if HAVE_POLL_H |
34 | | #include <poll.h> |
35 | | #elif HAVE_SYS_POLL_H |
36 | | #include <sys/poll.h> |
37 | | #endif |
38 | | |
39 | | apr_status_t apr_wait_for_io_or_timeout(apr_file_t *f, apr_socket_t *s, |
40 | | int for_read) |
41 | 0 | { |
42 | 0 | struct pollfd pfd; |
43 | 0 | int rc, timeout; |
44 | |
|
45 | 0 | timeout = f ? f->timeout : s->timeout; |
46 | 0 | pfd.fd = f ? f->filedes : s->socketdes; |
47 | 0 | pfd.events = for_read ? POLLIN : POLLOUT; |
48 | |
|
49 | 0 | if (timeout > 0) { |
50 | 0 | timeout = (timeout + 999) / 1000; |
51 | 0 | } |
52 | 0 | do { |
53 | 0 | rc = poll(&pfd, 1, timeout); |
54 | 0 | } while (rc == -1 && errno == EINTR); |
55 | 0 | if (rc == 0) { |
56 | 0 | return APR_TIMEUP; |
57 | 0 | } |
58 | 0 | else if (rc > 0) { |
59 | 0 | return APR_SUCCESS; |
60 | 0 | } |
61 | 0 | else { |
62 | 0 | return errno; |
63 | 0 | } |
64 | 0 | } |
65 | | |
66 | | #else /* !WAITIO_USES_POLL */ |
67 | | |
68 | | apr_status_t apr_wait_for_io_or_timeout(apr_file_t *f, apr_socket_t *s, |
69 | | int for_read) |
70 | | { |
71 | | apr_interval_time_t timeout; |
72 | | apr_pollfd_t pfd; |
73 | | int type = for_read ? APR_POLLIN : APR_POLLOUT; |
74 | | apr_pollset_t *pollset; |
75 | | apr_status_t status; |
76 | | |
77 | | /* TODO - timeout should be less each time through this loop */ |
78 | | if (f) { |
79 | | pfd.desc_type = APR_POLL_FILE; |
80 | | pfd.desc.f = f; |
81 | | |
82 | | pollset = f->pollset; |
83 | | if (pollset == NULL) { |
84 | | status = apr_pollset_create(&(f->pollset), 1, f->pool, 0); |
85 | | if (status != APR_SUCCESS) { |
86 | | return status; |
87 | | } |
88 | | pollset = f->pollset; |
89 | | } |
90 | | timeout = f->timeout; |
91 | | } |
92 | | else { |
93 | | pfd.desc_type = APR_POLL_SOCKET; |
94 | | pfd.desc.s = s; |
95 | | |
96 | | pollset = s->pollset; |
97 | | timeout = s->timeout; |
98 | | } |
99 | | pfd.reqevents = type; |
100 | | |
101 | | /* Remove the object if it was in the pollset, then add in the new |
102 | | * object with the correct reqevents value. Ignore the status result |
103 | | * on the remove, because it might not be in there (yet). |
104 | | */ |
105 | | (void) apr_pollset_remove(pollset, &pfd); |
106 | | |
107 | | /* ### check status code */ |
108 | | (void) apr_pollset_add(pollset, &pfd); |
109 | | |
110 | | do { |
111 | | int numdesc; |
112 | | const apr_pollfd_t *pdesc; |
113 | | |
114 | | status = apr_pollset_poll(pollset, timeout, &numdesc, &pdesc); |
115 | | |
116 | | if (numdesc == 1 && (pdesc[0].rtnevents & type) != 0) { |
117 | | return APR_SUCCESS; |
118 | | } |
119 | | } while (APR_STATUS_IS_EINTR(status)); |
120 | | |
121 | | return status; |
122 | | } |
123 | | #endif /* WAITIO_USES_POLL */ |
124 | | |
125 | | #endif /* USE_WAIT_FOR_IO */ |