Provide a replacement for socklen_t.
[npth.git] / src / npth.h.in
1 /* npth.h - a lightweight implementation of pth over pthread.
2             Configured for: @NPTH_CONFIG_HOST@.
3    Copyright (C) 2011, 2012 g10 Code GmbH
4
5    This file is part of NPTH.
6
7    NPTH is free software; you can redistribute it and/or modify it
8    under the terms of either
9
10    - the GNU Lesser General Public License as published by the Free
11    Software Foundation; either version 3 of the License, or (at
12    your option) any later version.
13
14    or
15
16    - the GNU General Public License as published by the Free
17    Software Foundation; either version 2 of the License, or (at
18    your option) any later version.
19
20    or both in parallel, as here.
21
22    NPTH is distributed in the hope that it will be useful, but WITHOUT
23    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
25    License for more details.
26
27    You should have received a copies of the GNU General Public License
28    and the GNU Lesser General Public License along with this program;
29    if not, see <http://www.gnu.org/licenses/>.  */
30
31 /* Changes to Pth:
32
33    Return value and arguments follow strictly the pthread format:
34
35    * Return the error number instead of setting errno,
36
37    * have timedlock function instead of extra event argument,
38
39    * have trylock function instead of extra event argument.  Can't mix
40    timed and try.
41
42    * No _new functions.  Use _init functions instead.
43
44    * Attributes are set by specific instead of generic getter/setter
45    functions.
46
47    Offers replacement functions for sendmsg and recvmsg.  */
48
49 #ifndef _NPTH_H
50 #define _NPTH_H
51
52 #include <sys/types.h>
53 #include <sys/wait.h>
54 #include <time.h>
55 #include <sys/socket.h>
56 #@INSERT_SOCKLEN_T@
57 #@INSERT_SYS_SELECT_H@
58
59 #include <pthread.h>
60
61 #ifdef __ANDROID__
62 #include <android/api-level.h>
63 #if __ANDROID_API__ < 9
64 /* Android 8 and earlier are missing rwlocks.  We punt to mutexes in
65    that case.  */
66 #define _NPTH_NO_RWLOCK 1
67 #endif
68 #endif
69
70 #ifdef __cplusplus
71 extern "C" {
72 #if 0 /* (Keep Emacsens' auto-indent happy.) */
73 }
74 #endif
75 #endif
76
77
78 \f
79 /* Global Library Management */
80
81 #define npth_t pthread_t
82
83 /* Initialize the library and convert current thread to main thread.
84    Must be first npth function called in a process.  Returns error
85    number on error and 0 on success.  */
86
87 int npth_init(void);
88
89 /* Not needed.  */
90 /* pth_kill, pth_ctrl, pth_version */
91
92 \f
93 /* Thread Attribute Handling */
94
95 /* Can't do that.  */
96 /* pth_attr_of */
97
98 #define npth_attr_t pthread_attr_t
99 #define npth_attr_init pthread_attr_init
100 #define npth_attr_destroy pthread_attr_destroy
101 #define NPTH_CREATE_JOINABLE PTHREAD_CREATE_JOINABLE
102 #define NPTH_CREATE_DETACHED PTHREAD_CREATE_DETACHED
103 #define npth_attr_getdetachstate pthread_attr_getdetachstate
104 #define npth_attr_setdetachstate pthread_attr_setdetachstate
105 int npth_getname_np (npth_t target_thread, char *buf, size_t buflen);
106 int npth_setname_np (npth_t target_thread, const char *name);
107
108 \f
109 /* Thread Control */
110 int npth_create(npth_t *thread, const npth_attr_t *attr,
111                 void *(*start_routine) (void *), void *arg);
112
113
114 /* The Pth version of pth_once supports passing an argument, the
115    pthread version does not.  We would have to reimplement the whole
116    feature with a global table.  Not needed.  */
117 /* pth_once */
118
119 #define npth_self pthread_self
120
121 /* No can do! */
122 /* pth_suspend, pth_resume */
123
124 /* Yield is considered harmful and should never be used in high-level
125    applications.  Use a condition instead to wait for a specific event
126    to happen, or, as a last resort, use npth_usleep to back off a hard
127    busy wait.  */
128 /* pth_yield */
129
130 /* Not needed.  */
131 /* pth_nap */
132
133 /* pth_wait, pth_cancel, pth_abort, pth_raise */
134
135 int npth_join(npth_t thread, void **retval);
136 #define npth_detach pthread_detach
137
138 void npth_exit(void *retval);
139
140 \f
141 /* Utilities */
142
143 /* pth_fdmode, pth_time, pth_timeout, pth_sfiodisc */
144
145 \f
146 /* Cancellation Management */
147
148 /* Not needed.  */
149 /* pth_cancel_state. npth_cancel_point */
150
151 \f
152 /* Event Handling */
153
154 /* No equivalent in pthread.  */
155 /* pth_event, pth_event_typeof, pth_event_extract, pth_event_concat, pth_event_isolate,
156    pth_event_walk, pth_event_status, pth_event_free */
157
158 \f
159 /* Key-Based Storage */
160
161 #define npth_key_t pthread_key_t
162 #define npth_key_create pthread_key_create
163 #define npth_key_delete pthread_key_delete
164 #define npth_setspecific pthread_setspecific
165 #define npth_getspecific pthread_getspecific
166
167 \f
168 /* Message Port Communication */
169
170 /* No equivalent in pthread.  */
171 /* pth_msgport_create, pth_msgport_destroy, pth_msgport_find,
172    pth_msgport_pending, pth_msgport_put, pth_msgport_get,
173    pth_msgport_reply. */
174
175 \f
176 /* Thread Cleanups */
177
178 /* Not needed.  */
179 /* pth_cleanup_push, pth_cleanup_pop */
180
181 \f
182 /* Process Forking */
183
184 /* POSIX only supports a global atfork handler.  So, to implement
185    per-thread handlers like in Pth, we would need to keep the data in
186    thread local storage.  But, neither pthread_self nor
187    pthread_getspecific are standardized as async-signal-safe (what a
188    joke!), and __thread is an ELF extension.  Still, using
189    pthread_self and pthread_getspecific is probably portable
190    enough to implement the atfork handlers, if required.
191
192    pth_fork is only required because fork() is not pth aware.  fork()
193    is pthread aware though, and already only creates a single thread
194    in the child process.  */
195 /* pth_atfork_push, pth_atfork_pop, pth_fork */
196
197 \f
198 /* Synchronization */
199
200 #define npth_mutexattr_t pthread_mutexattr_t
201 #define npth_mutexattr_init pthread_mutexattr_init
202 #define npth_mutexattr_destroy pthread_mutexattr_destroy
203 #define npth_mutexattr_settype pthread_mutexattr_settype
204 #define npth_mutexattr_gettype pthread_mutexattr_gettype
205 #define NPTH_MUTEX_NORMAL PTHREAD_MUTEX_NORMAL
206 #define NPTH_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE
207 #define NPTH_MUTEX_ERRORCHECK PTHREAD_MUTEX_ERRORCHECK
208 #define NPTH_MUTEX_DEFAULT PTHREAD_MUTEX_DEFAULT
209
210 #define npth_mutex_t pthread_mutex_t
211 #define NPTH_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
212 #define NPTH_RECURSIVE_MUTEX_INITIALIZER_NP \
213   PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
214 #define NPTH_ERRORCHECK_MUTEX_INITIALIZER_NP \
215   PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
216 #define npth_mutex_init pthread_mutex_init
217 #define npth_mutex_destroy pthread_mutex_destroy
218 #define npth_mutex_trylock pthread_mutex_trylock
219
220 int npth_mutex_lock(npth_mutex_t *mutex);
221 int npth_mutex_timedlock(npth_mutex_t *mutex, const struct timespec *abstime);
222
223 #define npth_mutex_unlock pthread_mutex_unlock
224
225 #ifdef _NPTH_NO_RWLOCK
226
227 typedef int npth_rwlockattr_t;
228 #define npth_rwlockattr_init(attr)
229 #define npth_rwlockattr_destroy(attr)
230 #define npth_rwlockattr_gettype_np(attr,kind)
231 #define npth_rwlockattr_settype_np(attr,kind)
232 #define NPTH_RWLOCK_PREFER_READER_NP 0
233 #define NPTH_RWLOCK_PREFER_WRITER_NP 0
234 #define NPTH_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP 0
235 #define NPTH_RWLOCK_DEFAULT_NP 0
236 #define NPTH_RWLOCK_INITIALIZER NPTH_MUTEX_INITIALIZER
237 #define NPTH_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP NPTH_MUTEX_INITIALIZER
238 typedef npth_mutex_t npth_rwlock_t;
239 #define npth_rwlock_init(rwlock,attr) npth_mutex_init(rwlock,0)
240 #define npth_rwlock_destroy npth_mutex_destroy
241 #define npth_rwlock_tryrdlock npth_mutex_trylock
242 #define npth_rwlock_rdlock npth_mutex_lock
243 #define npth_rwlock_trywrlock npth_mutex_trylock
244 #define npth_rwlock_timedrdlock npth_mutex_timedlock
245 #define npth_rwlock_wrlock npth_mutex_lock
246 #define npth_rwlock_rdlock npth_mutex_lock
247 #define npth_rwlock_timedwrlock npth_mutex_timedlock
248 #define npth_rwlock_unlock npth_mutex_unlock
249
250 #else /* _NPTH_NO_RWLOCK */
251
252 #define npth_rwlockattr_t pthread_rwlockattr_t
253 #define npth_rwlockattr_init pthread_rwlockattr_init
254 #define npth_rwlockattr_destroy pthread_rwlockattr_destroy
255 #define npth_rwlockattr_gettype_np pthread_rwlockattr_gettype_np
256 #define npth_rwlockattr_settype_np pthread_rwlockattr_settype_np
257 #define NPTH_RWLOCK_PREFER_READER_NP PTHREAD_RWLOCK_PREFER_READER_NP
258 /* Note: The prefer-writer setting is ineffective and the same as
259    prefer-reader.  This is because reader locks are specified to be
260    recursive, but for efficiency reasons we do not keep track of which
261    threads already hold a reader lock.  For this reason, we can not
262    prefer some reader locks over others, and thus a recursive reader
263    lock could be stalled by a pending writer, leading to a dead
264    lock.  */
265 #define NPTH_RWLOCK_PREFER_WRITER_NP PTHREAD_RWLOCK_PREFER_WRITER_NP
266 /* The non-recursive choise is a promise by the application that it
267    does not lock the rwlock for reading recursively.  In this setting,
268    writers are preferred, but note that recursive reader locking is
269    prone to deadlocks in that case.  */
270 #define NPTH_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP \
271   PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
272 #define NPTH_RWLOCK_DEFAULT_NP PTHREAD_RWLOCK_DEFAULT_NP
273 #define NPTH_RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER
274 #define NPTH_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
275   PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
276
277 typedef pthread_rwlock_t npth_rwlock_t;
278 #define npth_rwlock_init pthread_rwlock_init
279 #define npth_rwlock_destroy pthread_rwlock_destroy
280 #define npth_rwlock_tryrdlock pthread_rwlock_tryrdlock
281
282 int npth_rwlock_rdlock (npth_rwlock_t *rwlock);
283
284 int npth_rwlock_timedrdlock (npth_rwlock_t *rwlock,
285                              const struct timespec *abstime);
286
287 #define npth_rwlock_trywrlock pthread_rwlock_trywrlock
288 int npth_rwlock_wrlock (npth_rwlock_t *rwlock);
289 int npth_rwlock_timedwrlock (npth_rwlock_t *rwlock,
290                              const struct timespec *abstime);
291 #define npth_rwlock_unlock  pthread_rwlock_unlock
292
293 #endif /* !_NPTH_NO_RWLOCK */
294
295
296 typedef pthread_cond_t npth_cond_t;
297 #define NPTH_COND_INITIALIZER PTHREAD_COND_INITIALIZER
298 /* For now, we don't support any cond attributes.  */
299 #define npth_cond_init pthread_cond_init
300 #define npth_cond_broadcast pthread_cond_broadcast
301 #define npth_cond_signal pthread_cond_signal
302 #define npth_cond_destroy pthread_cond_destroy
303 int npth_cond_wait(npth_cond_t *cond, npth_mutex_t *mutex);
304 int npth_cond_timedwait(npth_cond_t *cond, npth_mutex_t *mutex,
305                         const struct timespec *abstime);
306
307 /* Not needed.  */
308
309 /* pth_barrier_t, pth_barrier_init, pth_barrier_reach */
310
311 \f
312 /* User-Space Context */
313
314 /* Can not be implemented.  */
315 /* pth_uctx_create, pth_uctx_make, pth_uctx_switch, pth_uctx_destroy */
316
317 \f
318 /* Generalized POSIX Replacement API */
319
320 /* In general, we can not support these easily.  */
321 /* pth_sigwait_ev, pth_accept_ev, pth_connect_ev, pth_select_ev,
322    pth_poll_ev, pth_read_ev, pth_readv_ev, pth_write_ev,
323    pth_writev_ev, pth_recv_ev, pth_recvfrom_ev, pth_send_ev,
324    pth_sendto_ev */
325
326 \f
327 /* Standard POSIX Replacement API */
328
329 /* We will provide a more specific way to handle signals.  */
330 /* pth_sigmask, pth_sigwait */
331
332 /* Not needed.  */
333 /* pth_nanosleep, pth_system, pth_readv, pth_writev, pth_poll,
334    pth_recv, pth_send, pth_recvfrom, pth_sendto */
335
336 int npth_usleep(unsigned int usec);
337 unsigned int npth_sleep(unsigned int sec);
338
339 pid_t npth_waitpid(pid_t pid, int *status, int options);
340 int npth_system(const char *cmd);
341 #define npth_sigmask pthread_sigmask
342 int npth_sigwait(const sigset_t *set, int *sig);
343
344 int npth_connect(int s, const struct sockaddr *addr, _npth_socklen_t addrlen);
345 int npth_accept(int s, struct sockaddr *addr, _npth_socklen_t *addrlen);
346 int npth_select(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds,
347                 struct timeval *timeout);
348 int npth_pselect(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds,
349                  const struct timespec *timeout, const sigset_t *sigmask);
350 ssize_t npth_read(int fd, void *buf, size_t nbytes);
351 ssize_t npth_write(int fd, const void *buf, size_t nbytes);
352 int npth_recvmsg (int fd, struct msghdr *msg, int flags);
353 int npth_sendmsg (int fd, const struct msghdr *msg, int flags);
354
355 /* For anything not covered here, you can enter/leave manually at your
356    own risk.  */
357 void npth_unprotect (void);
358 void npth_protect (void);
359
360 \f
361 /* Because the timed functions work on timespec, we provide a clock
362    interface for convenience and portability.  */
363 int npth_clock_gettime (struct timespec *tp);
364
365 /* CMP may be ==, < or >.  Do not use <= or >=.  */
366 #define npth_timercmp(t1, t2, cmp)                                      \
367   (((t1)->tv_sec == (t2)->tv_sec) ?                                     \
368    ((t1)->tv_nsec cmp (t2)->tv_nsec) :                                  \
369    ((t1)->tv_sec cmp (t2)->tv_sec))
370 #define npth_timeradd(t1, t2, result)                                   \
371   do {                                                                  \
372     (result)->tv_sec = (t1)->tv_sec + (t2)->tv_sec;                     \
373     (result)->tv_nsec = (t1)->tv_nsec + (t2)->tv_nsec;                  \
374     if ((result)->tv_nsec >= 1000000000)                                \
375       {                                                                 \
376         ++(result)->tv_sec;                                             \
377         (result)->tv_nsec -= 1000000000;                                \
378       }                                                                 \
379   } while (0)
380 #define npth_timersub(t1, t2, result)                                   \
381   do {                                                                  \
382     (result)->tv_sec = (t1)->tv_sec - (t2)->tv_sec;                     \
383     (result)->tv_nsec = (t1)->tv_nsec - (t2)->tv_nsec;                  \
384     if ((result)->tv_nsec < 0) {                                        \
385       --(result)->tv_sec;                                               \
386       (result)->tv_nsec += 1000000000;                                  \
387     }                                                                   \
388   } while (0)
389
390 \f
391 /* This is a support interface to make it easier to handle signals.
392
393    The interfaces here support one (and only one) thread (here called
394    "main thread") in the application to monitor several signals while
395    selecting on filedescriptors.
396
397    First, the main thread should call npth_sigev_init.  This
398    initializes some global data structures used to record interesting
399    and pending signals.
400
401    Then, the main thread should call npth_sigev_add for every signal
402    it is interested in observing, and finally npth_sigev_fini.  This
403    will block the signal in the main threads sigmask.  Note that these
404    signals should also be blocked in all other threads.  Since they
405    are blocked in the main thread after calling npth_sigev_add, it is
406    recommended to call npth_sigev_add in the main thread before
407    creating any threads.
408
409    The function npth_sigev_sigmask is a convenient function that
410    returns the sigmask of the thread at time of npth_sigev_init, but
411    with all registered signals unblocked.  It is recommended to do all
412    other changes to the main thread's sigmask before calling
413    npth_sigev_init, so that the return value of npth_sigev_sigmask can
414    be used in the npth_pselect invocation.
415
416    In any case, the main thread should invoke npth_pselect with a
417    sigmask that has all signals that should be monitored unblocked.
418
419    After npth_pselect returns, npth_sigev_get_pending can be called in
420    a loop until it returns 0 to iterate over the list of pending
421    signals.  Each time a signal is returned by that function, its
422    status is reset to non-pending.  */
423
424 /* Start setting up signal event handling.  */
425 void npth_sigev_init (void);
426
427 /* Add signal SIGNUM to the list of watched signals.  */
428 void npth_sigev_add (int signum);
429
430 /* Finish the list of watched signals.  This starts to block them,
431    too.  */
432 void npth_sigev_fini (void);
433
434 /* Get the sigmask as needed for pselect.  */
435 sigset_t *npth_sigev_sigmask (void);
436
437 /* Return the next signal event that occured.  Returns if none are
438    left, 1 on success.  */
439 int npth_sigev_get_pending (int *r_signum);
440
441
442 #if 0 /* (Keep Emacsens' auto-indent happy.) */
443 {
444 #endif
445 #ifdef __cplusplus
446 }
447 #endif
448 #endif /*_NPTH_H*/
449 /*
450 @emacs_local_vars_begin@
451 @emacs_local_vars_read_only@
452 @emacs_local_vars_end@
453 */