Coverage Report

Created: 2023-03-26 06:28

/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