GNU libmicrohttpd 0.9.77
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 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) do { fprintf (stderr, \
46 "Abnormal termination at %d line in file %s: %s\n", \
47 (int) __LINE__, __FILE__, msg); abort (); \
48} while (0)
49#endif /* ! MHD_PANIC */
50
51#if defined(_MHD_ITC_EVENTFD)
52
53/* **************** Optimized GNU/Linux ITC implementation by eventfd ********** */
54#include <sys/eventfd.h>
55#include <stdint.h> /* for uint64_t */
56#ifdef HAVE_UNISTD_H
57#include <unistd.h> /* for read(), write(), errno */
58#endif /* HAVE_UNISTD_H */
59#ifdef HAVE_STRING_H
60#include <string.h> /* for strerror() */
61#endif
62
63
69#define MHD_itc_init_(itc) (-1 != ((itc).fd = eventfd (0, EFD_CLOEXEC \
70 | EFD_NONBLOCK)))
71
75#define MHD_itc_last_strerror_() strerror (errno)
76
80static const uint64_t _MHD_itc_wr_data = 1;
81
88#define MHD_itc_activate_(itc, str) \
89 ((write ((itc).fd, (const void*) &_MHD_itc_wr_data, 8) > 0) || (EAGAIN == \
90 errno))
91
97#define MHD_itc_r_fd_(itc) ((itc).fd)
98
104#define MHD_itc_w_fd_(itc) ((itc).fd)
105
110#define MHD_itc_clear_(itc) \
111 do { uint64_t __b; int __r; \
112 __r = read ((itc).fd, &__b, sizeof(__b)); \
113 (void) __r; } while (0)
114
122#define MHD_itc_destroy_(itc) ((0 == close ((itc).fd)) || (EBADF != errno))
123
133#define MHD_ITC_IS_VALID_(itc) (-1 != ((itc).fd))
134
139#define MHD_itc_set_invalid_(itc) ((itc).fd = -1)
140
141
142#elif defined(_MHD_ITC_PIPE)
143
144/* **************** Standard UNIX ITC implementation by pipe ********** */
145
146#if defined(HAVE_PIPE2_FUNC) && defined(HAVE_FCNTL_H)
147# include <fcntl.h> /* for O_CLOEXEC, O_NONBLOCK */
148#endif /* HAVE_PIPE2_FUNC && HAVE_FCNTL_H */
149#ifdef HAVE_UNISTD_H
150#include <unistd.h> /* for read(), write(), errno */
151#endif /* HAVE_UNISTD_H */
152#ifdef HAVE_STRING_H
153#include <string.h> /* for strerror() */
154#endif
155
156
162#ifdef HAVE_PIPE2_FUNC
163# define MHD_itc_init_(itc) (! pipe2 ((itc).fd, O_CLOEXEC | O_NONBLOCK))
164#else /* ! HAVE_PIPE2_FUNC */
165# define MHD_itc_init_(itc) \
166 ( (! pipe ((itc).fd)) ? \
167 (MHD_itc_nonblocking_ ((itc)) ? \
168 (! 0) : \
169 (MHD_itc_destroy_ ((itc)), 0) ) \
170 : (0) )
171#endif /* ! HAVE_PIPE2_FUNC */
172
176#define MHD_itc_last_strerror_() strerror (errno)
177
184#define MHD_itc_activate_(itc, str) \
185 ((write ((itc).fd[1], (const void*) (str), 1) > 0) || (EAGAIN == errno))
186
187
193#define MHD_itc_r_fd_(itc) ((itc).fd[0])
194
200#define MHD_itc_w_fd_(itc) ((itc).fd[1])
201
206#define MHD_itc_clear_(itc) do \
207 { long __b; \
208 while (0 < read ((itc).fd[0], &__b, sizeof(__b))) \
209 {} } while (0)
210
216#define MHD_itc_destroy_(itc) \
217 ( (0 == close ((itc).fd[0])) ? \
218 (0 == close ((itc).fd[1])) : \
219 ((close ((itc).fd[1])), 0) )
220
230#define MHD_ITC_IS_VALID_(itc) (-1 != (itc).fd[0])
231
236#define MHD_itc_set_invalid_(itc) ((itc).fd[0] = (itc).fd[1] = -1)
237
238#ifndef HAVE_PIPE2_FUNC
245int
246MHD_itc_nonblocking_ (struct MHD_itc_ itc);
247
248#endif /* ! HAVE_PIPE2_FUNC */
249
250
251#elif defined(_MHD_ITC_SOCKETPAIR)
252
253/* **************** ITC implementation by socket pair ********** */
254
255#include "mhd_sockets.h"
256
257
263#ifdef MHD_socket_pair_nblk_
264# define MHD_itc_init_(itc) MHD_socket_pair_nblk_ ((itc).sk)
265#else /* ! MHD_socket_pair_nblk_ */
266# define MHD_itc_init_(itc) \
267 (MHD_socket_pair_ ((itc).sk) ? \
268 (MHD_itc_nonblocking_ ((itc)) ? \
269 (! 0) : \
270 (MHD_itc_destroy_ ((itc)), 0) ) \
271 : (0))
272#endif /* ! MHD_socket_pair_nblk_ */
273
277#define MHD_itc_last_strerror_() MHD_socket_last_strerr_ ()
278
285#define MHD_itc_activate_(itc, str) \
286 ((MHD_send_ ((itc).sk[1], (str), 1) > 0) || \
287 (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ())))
288
294#define MHD_itc_r_fd_(itc) ((itc).sk[0])
295
301#define MHD_itc_w_fd_(itc) ((itc).sk[1])
302
307#define MHD_itc_clear_(itc) do \
308 { long __b; \
309 while (0 < recv ((itc).sk[0], \
310 (char*) &__b, \
311 sizeof(__b), 0)) \
312 {} } while (0)
313
319#define MHD_itc_destroy_(itc) \
320 (MHD_socket_close_ ((itc).sk[0]) ? \
321 MHD_socket_close_ ((itc).sk[1]) : \
322 ((void) MHD_socket_close_ ((itc).sk[1]), 0) )
323
324
334#define MHD_ITC_IS_VALID_(itc) (MHD_INVALID_SOCKET != (itc).sk[0])
335
340#define MHD_itc_set_invalid_(itc) ((itc).sk[0] = (itc).sk[1] = \
341 MHD_INVALID_SOCKET)
342
343#ifndef MHD_socket_pair_nblk_
344# define MHD_itc_nonblocking_(pip) (MHD_socket_nonblocking_ ((pip).sk[0]) && \
345 MHD_socket_nonblocking_ ((pip).sk[1]))
346#endif /* ! MHD_socket_pair_nblk_ */
347
348#endif /* _MHD_ITC_SOCKETPAIR */
349
355#define MHD_itc_destroy_chk_(itc) do { \
356 if (! MHD_itc_destroy_ (itc)) \
357 MHD_PANIC (_ ("Failed to destroy ITC.\n")); \
358} while (0)
359
369#define MHD_ITC_IS_INVALID_(itc) (! MHD_ITC_IS_VALID_ (itc))
370
371#endif /* MHD_ITC_H */
Types for platform-independent inter-thread communication.