GNU libmicrohttpd  1.0.1
mhd_itc.h
Go to the documentation of this file.
1 /*
2  This file is part of libmicrohttpd
3  Copyright (C) 2016-2023 Karlson2k (Evgeny Grin)
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 
19 */
20 
33 #ifndef MHD_ITC_H
34 #define MHD_ITC_H 1
35 #include "mhd_itc_types.h"
36 
37 #include <fcntl.h>
38 
39 #ifndef MHD_PANIC
40 # include <stdio.h>
41 # ifdef HAVE_STDLIB_H
42 # include <stdlib.h>
43 # endif /* HAVE_STDLIB_H */
44 /* Simple implementation of MHD_PANIC, to be used outside lib */
45 # define MHD_PANIC(msg) \
46  do { fprintf (stderr, \
47  "Abnormal termination at %d line in file %s: %s\n", \
48  (int) __LINE__, __FILE__, msg); abort (); \
49  } while (0)
50 #endif /* ! MHD_PANIC */
51 
52 #if defined(_MHD_ITC_EVENTFD)
53 
54 /* **************** Optimized GNU/Linux ITC implementation by eventfd ********** */
55 #include <sys/eventfd.h>
56 #include <stdint.h> /* for uint64_t */
57 #ifdef HAVE_UNISTD_H
58 #include <unistd.h> /* for read(), write() */
59 #endif /* HAVE_UNISTD_H */
60 #ifdef HAVE_STRING_H
61 #include <string.h> /* for strerror() */
62 #include <errno.h>
63 #endif
64 
68 #define MHD_ITC_NUM_FDS_ (1)
69 
75 #define MHD_itc_init_(itc) \
76  (-1 != ((itc).fd = eventfd (0, EFD_CLOEXEC | EFD_NONBLOCK)))
77 
81 #define MHD_itc_last_strerror_() strerror (errno)
82 
86 static const uint64_t _MHD_itc_wr_data = 1;
87 
94 #define MHD_itc_activate_(itc, str) \
95  ((write ((itc).fd, (const void*) &_MHD_itc_wr_data, \
96  sizeof(_MHD_itc_wr_data)) > 0) || (EAGAIN == errno))
97 
103 #define MHD_itc_r_fd_(itc) ((itc).fd)
104 
110 #define MHD_itc_w_fd_(itc) ((itc).fd)
111 
116 #define MHD_itc_clear_(itc) \
117  do { uint64_t __b; \
118  (void) read ((itc).fd, (void*)&__b, sizeof(__b)); \
119  } while (0)
120 
128 #define MHD_itc_destroy_(itc) \
129  ((0 == close ((itc).fd)) || (EBADF != errno))
130 
140 #define MHD_ITC_IS_VALID_(itc) (-1 != ((itc).fd))
141 
146 #define MHD_itc_set_invalid_(itc) ((itc).fd = -1)
147 
148 
149 #elif defined(_MHD_ITC_PIPE)
150 
151 /* **************** Standard UNIX ITC implementation by pipe ********** */
152 
153 #if defined(HAVE_PIPE2_FUNC) && defined(HAVE_FCNTL_H)
154 # include <fcntl.h> /* for O_CLOEXEC, O_NONBLOCK */
155 #endif /* HAVE_PIPE2_FUNC && HAVE_FCNTL_H */
156 #ifdef HAVE_UNISTD_H
157 #include <unistd.h> /* for read(), write(), errno */
158 #endif /* HAVE_UNISTD_H */
159 #ifdef HAVE_STRING_H
160 #include <string.h> /* for strerror() */
161 #endif
162 
163 
167 #define MHD_ITC_NUM_FDS_ (2)
168 
174 #ifdef HAVE_PIPE2_FUNC
175 # define MHD_itc_init_(itc) (! pipe2 ((itc).fd, O_CLOEXEC | O_NONBLOCK))
176 #else /* ! HAVE_PIPE2_FUNC */
177 # define MHD_itc_init_(itc) \
178  ( (! pipe ((itc).fd)) ? \
179  (MHD_itc_nonblocking_ ((itc)) ? \
180  (! 0) : \
181  (MHD_itc_destroy_ ((itc)), 0) ) \
182  : (0) )
183 #endif /* ! HAVE_PIPE2_FUNC */
184 
188 #define MHD_itc_last_strerror_() strerror (errno)
189 
196 #define MHD_itc_activate_(itc, str) \
197  ((write ((itc).fd[1], (const void*) (str), 1) > 0) || (EAGAIN == errno))
198 
199 
205 #define MHD_itc_r_fd_(itc) ((itc).fd[0])
206 
212 #define MHD_itc_w_fd_(itc) ((itc).fd[1])
213 
218 #define MHD_itc_clear_(itc) do \
219  { long __b; \
220  while (0 < read ((itc).fd[0], (void*) &__b, sizeof(__b))) \
221  {(void)0;} } while (0)
222 
228 #define MHD_itc_destroy_(itc) \
229  ( (0 == close ((itc).fd[0])) ? \
230  (0 == close ((itc).fd[1])) : \
231  ((close ((itc).fd[1])), 0) )
232 
242 #define MHD_ITC_IS_VALID_(itc) (-1 != (itc).fd[0])
243 
248 #define MHD_itc_set_invalid_(itc) ((itc).fd[0] = (itc).fd[1] = -1)
249 
250 #ifndef HAVE_PIPE2_FUNC
257 int
258 MHD_itc_nonblocking_ (struct MHD_itc_ itc);
259 
260 #endif /* ! HAVE_PIPE2_FUNC */
261 
262 
263 #elif defined(_MHD_ITC_SOCKETPAIR)
264 
265 /* **************** ITC implementation by socket pair ********** */
266 
267 #include "mhd_sockets.h"
268 
269 
273 #define MHD_ITC_NUM_FDS_ (2)
274 
280 #ifdef MHD_socket_pair_nblk_
281 # define MHD_itc_init_(itc) MHD_socket_pair_nblk_ ((itc).sk)
282 #else /* ! MHD_socket_pair_nblk_ */
283 # define MHD_itc_init_(itc) \
284  (MHD_socket_pair_ ((itc).sk) ? \
285  (MHD_itc_nonblocking_ ((itc)) ? \
286  (! 0) : \
287  (MHD_itc_destroy_ ((itc)), 0) ) \
288  : (0))
289 #endif /* ! MHD_socket_pair_nblk_ */
290 
294 #define MHD_itc_last_strerror_() MHD_socket_last_strerr_ ()
295 
302 #define MHD_itc_activate_(itc, str) \
303  ((MHD_send_ ((itc).sk[1], (str), 1) > 0) || \
304  (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ())))
305 
311 #define MHD_itc_r_fd_(itc) ((itc).sk[0])
312 
318 #define MHD_itc_w_fd_(itc) ((itc).sk[1])
319 
324 #define MHD_itc_clear_(itc) do \
325  { long __b; \
326  while (0 < recv ((itc).sk[0], (void*) &__b, sizeof(__b), 0)) \
327  {(void)0;} } while (0)
328 
334 #define MHD_itc_destroy_(itc) \
335  (MHD_socket_close_ ((itc).sk[0]) ? \
336  MHD_socket_close_ ((itc).sk[1]) : \
337  ((void) MHD_socket_close_ ((itc).sk[1]), 0) )
338 
339 
349 #define MHD_ITC_IS_VALID_(itc) (MHD_INVALID_SOCKET != (itc).sk[0])
350 
355 #define MHD_itc_set_invalid_(itc) \
356  ((itc).sk[0] = (itc).sk[1] = MHD_INVALID_SOCKET)
357 
358 #ifndef MHD_socket_pair_nblk_
359 # define MHD_itc_nonblocking_(pip) \
360  (MHD_socket_nonblocking_ ((pip).sk[0]) && \
361  MHD_socket_nonblocking_ ((pip).sk[1]))
362 #endif /* ! MHD_socket_pair_nblk_ */
363 
364 #endif /* _MHD_ITC_SOCKETPAIR */
365 
371 #define MHD_itc_destroy_chk_(itc) do { \
372  if (! MHD_itc_destroy_ (itc)) \
373  MHD_PANIC (_ ("Failed to destroy ITC.\n")); \
374 } while (0)
375 
385 #define MHD_ITC_IS_INVALID_(itc) (! MHD_ITC_IS_VALID_ (itc))
386 
387 #endif /* MHD_ITC_H */
Types for platform-independent inter-thread communication.