GNU libmicrohttpd  0.9.72
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 # include <stdlib.h>
42 /* Simple implementation of MHD_PANIC, to be used outside lib */
43 # define MHD_PANIC(msg) do { fprintf (stderr, \
44  "Abnormal termination at %d line in file %s: %s\n", \
45  (int) __LINE__, __FILE__, msg); abort (); \
46 } while (0)
47 #endif /* ! MHD_PANIC */
48 
49 #if defined(_MHD_ITC_EVENTFD)
50 
51 /* **************** Optimized GNU/Linux ITC implementation by eventfd ********** */
52 #include <sys/eventfd.h>
53 #include <stdint.h> /* for uint64_t */
54 #ifdef HAVE_UNISTD_H
55 #include <unistd.h> /* for read(), write(), errno */
56 #endif /* HAVE_UNISTD_H */
57 #ifdef HAVE_STRING_H
58 #include <string.h> /* for strerror() */
59 #endif
60 
61 
67 #define MHD_itc_init_(itc) (-1 != ((itc).fd = eventfd (0, EFD_CLOEXEC \
68  | EFD_NONBLOCK)))
69 
73 #define MHD_itc_last_strerror_() strerror (errno)
74 
78 static const uint64_t _MHD_itc_wr_data = 1;
79 
86 #define MHD_itc_activate_(itc, str) \
87  ((write ((itc).fd, (const void*) &_MHD_itc_wr_data, 8) > 0) || (EAGAIN == \
88  errno))
89 
95 #define MHD_itc_r_fd_(itc) ((itc).fd)
96 
102 #define MHD_itc_w_fd_(itc) ((itc).fd)
103 
108 #define MHD_itc_clear_(itc) \
109  do { uint64_t __b; int __r; \
110  __r = read ((itc).fd, &__b, sizeof(__b)); \
111  (void) __r; } while (0)
112 
120 #define MHD_itc_destroy_(itc) ((0 == close ((itc).fd)) || (EBADF != errno))
121 
131 #define MHD_ITC_IS_VALID_(itc) (-1 != ((itc).fd))
132 
137 #define MHD_itc_set_invalid_(itc) ((itc).fd = -1)
138 
139 
140 #elif defined(_MHD_ITC_PIPE)
141 
142 /* **************** Standard UNIX ITC implementation by pipe ********** */
143 
144 #if defined(HAVE_PIPE2_FUNC) && defined(HAVE_FCNTL_H)
145 # include <fcntl.h> /* for O_CLOEXEC, O_NONBLOCK */
146 #endif /* HAVE_PIPE2_FUNC && HAVE_FCNTL_H */
147 #ifdef HAVE_UNISTD_H
148 #include <unistd.h> /* for read(), write(), errno */
149 #endif /* HAVE_UNISTD_H */
150 #ifdef HAVE_STRING_H
151 #include <string.h> /* for strerror() */
152 #endif
153 
154 
160 #ifdef HAVE_PIPE2_FUNC
161 # define MHD_itc_init_(itc) (! pipe2 ((itc).fd, O_CLOEXEC | O_NONBLOCK))
162 #else /* ! HAVE_PIPE2_FUNC */
163 # define MHD_itc_init_(itc) \
164  ( (! pipe ((itc).fd)) ? \
165  (MHD_itc_nonblocking_ ((itc)) ? \
166  (! 0) : \
167  (MHD_itc_destroy_ ((itc)), 0) ) \
168  : (0) )
169 #endif /* ! HAVE_PIPE2_FUNC */
170 
174 #define MHD_itc_last_strerror_() strerror (errno)
175 
182 #define MHD_itc_activate_(itc, str) \
183  ((write ((itc).fd[1], (const void*) (str), 1) > 0) || (EAGAIN == errno))
184 
185 
191 #define MHD_itc_r_fd_(itc) ((itc).fd[0])
192 
198 #define MHD_itc_w_fd_(itc) ((itc).fd[1])
199 
204 #define MHD_itc_clear_(itc) do \
205  { long __b; \
206  while (0 < read ((itc).fd[0], &__b, sizeof(__b))) \
207  {} } while (0)
208 
214 #define MHD_itc_destroy_(itc) \
215  ( (0 == close ((itc).fd[0])) ? \
216  (0 == close ((itc).fd[1])) : \
217  ((close ((itc).fd[1])), 0) )
218 
228 #define MHD_ITC_IS_VALID_(itc) (-1 != (itc).fd[0])
229 
234 #define MHD_itc_set_invalid_(itc) ((itc).fd[0] = (itc).fd[1] = -1)
235 
236 #ifndef HAVE_PIPE2_FUNC
243 int
244 MHD_itc_nonblocking_ (struct MHD_itc_ itc);
245 
246 #endif /* ! HAVE_PIPE2_FUNC */
247 
248 
249 #elif defined(_MHD_ITC_SOCKETPAIR)
250 
251 /* **************** ITC implementation by socket pair ********** */
252 
253 #include "mhd_sockets.h"
254 
255 
261 #ifdef MHD_socket_pair_nblk_
262 # define MHD_itc_init_(itc) MHD_socket_pair_nblk_ ((itc).sk)
263 #else /* ! MHD_socket_pair_nblk_ */
264 # define MHD_itc_init_(itc) \
265  (MHD_socket_pair_ ((itc).sk) ? \
266  (MHD_itc_nonblocking_ ((itc)) ? \
267  (! 0) : \
268  (MHD_itc_destroy_ ((itc)), 0) ) \
269  : (0))
270 #endif /* ! MHD_socket_pair_nblk_ */
271 
275 #define MHD_itc_last_strerror_() MHD_socket_last_strerr_ ()
276 
283 #define MHD_itc_activate_(itc, str) \
284  ((MHD_send_ ((itc).sk[1], (str), 1) > 0) || \
285  (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ())))
286 
292 #define MHD_itc_r_fd_(itc) ((itc).sk[0])
293 
299 #define MHD_itc_w_fd_(itc) ((itc).sk[1])
300 
305 #define MHD_itc_clear_(itc) do \
306  { long __b; \
307  while (0 < recv ((itc).sk[0], \
308  (char*) &__b, \
309  sizeof(__b), 0)) \
310  {} } while (0)
311 
317 #define MHD_itc_destroy_(itc) \
318  (MHD_socket_close_ ((itc).sk[0]) ? \
319  MHD_socket_close_ ((itc).sk[1]) : \
320  ((void) MHD_socket_close_ ((itc).sk[1]), 0) )
321 
322 
332 #define MHD_ITC_IS_VALID_(itc) (MHD_INVALID_SOCKET != (itc).sk[0])
333 
338 #define MHD_itc_set_invalid_(itc) ((itc).sk[0] = (itc).sk[1] = \
339  MHD_INVALID_SOCKET)
340 
341 #ifndef MHD_socket_pair_nblk_
342 # define MHD_itc_nonblocking_(pip) (MHD_socket_nonblocking_ ((pip).sk[0]) && \
343  MHD_socket_nonblocking_ ((pip).sk[1]))
344 #endif /* ! MHD_socket_pair_nblk_ */
345 
346 #endif /* _MHD_ITC_SOCKETPAIR */
347 
353 #define MHD_itc_destroy_chk_(itc) do { \
354  if (! MHD_itc_destroy_ (itc)) \
355  MHD_PANIC (_ ("Failed to destroy ITC.\n")); \
356 } while (0)
357 
367 #define MHD_ITC_IS_INVALID_(itc) (! MHD_ITC_IS_VALID_ (itc))
368 
369 #endif /* MHD_ITC_H */
Types for platform-independent inter-thread communication.