GNU libmicrohttpd 1.0.0
Loading...
Searching...
No Matches
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
86static 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
257int
258MHD_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.