Blame src/npth.h

Packit 5e354d
/* npth.h - a lightweight implementation of pth over pthread.
Packit 5e354d
 *          Configured for: x86_64-pc-linux-gnu.
Packit 5e354d
 * Copyright (C) 2011, 2012, 2015, 2017 g10 Code GmbH
Packit 5e354d
 *
Packit 5e354d
 * This file is part of nPth.
Packit 5e354d
 *
Packit 5e354d
 * nPth is free software; you can redistribute it and/or modify
Packit 5e354d
 * it under the terms of the GNU Lesser General Public License as
Packit 5e354d
 * published by the Free Software Foundation; either version 2.1 of
Packit 5e354d
 * the License, or (at your option) any later version.
Packit 5e354d
 *
Packit 5e354d
 * nPth is distributed in the hope that it will be useful, but
Packit 5e354d
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 5e354d
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
Packit 5e354d
 * the GNU Lesser General Public License for more details.
Packit 5e354d
 *
Packit 5e354d
 * You should have received a copy of the GNU Lesser General Public
Packit 5e354d
 * License along with this program; if not, see <https://www.gnu.org/licenses/>.
Packit 5e354d
 */
Packit 5e354d
Packit 5e354d
/* Changes to GNU Pth:
Packit 5e354d
 *
Packit 5e354d
 * Return value and arguments follow strictly the pthread format:
Packit 5e354d
 *
Packit 5e354d
 * - Return the error number instead of setting errno,
Packit 5e354d
 *
Packit 5e354d
 * - have timedlock function instead of extra event argument,
Packit 5e354d
 *
Packit 5e354d
 * - have trylock function instead of extra event argument.  Can't mix
Packit 5e354d
 *   timed and try.
Packit 5e354d
 *
Packit 5e354d
 * - No _new functions.  Use _init functions instead.
Packit 5e354d
 *
Packit 5e354d
 * - Attributes are set by specific instead of generic getter/setter
Packit 5e354d
 *   functions.
Packit 5e354d
 *
Packit 5e354d
 * - Offers replacement functions for sendmsg and recvmsg.
Packit 5e354d
 */
Packit 5e354d
Packit 5e354d
#ifndef _NPTH_H
Packit 5e354d
#define _NPTH_H
Packit 5e354d
Packit 5e354d
#include <sys/types.h>
Packit 5e354d
#include <sys/wait.h>
Packit 5e354d
#include <sys/time.h>
Packit 5e354d
#include <time.h>
Packit 5e354d
#include <sys/socket.h>
Packit 5e354d
#define _npth_socklen_t socklen_t
Packit 5e354d
#include <sys/select.h>
Packit 5e354d
#include <signal.h>
Packit 5e354d
Packit 5e354d
#include <pthread.h>
Packit 5e354d
Packit 5e354d
#ifdef __ANDROID__
Packit 5e354d
#include <android/api-level.h>
Packit 5e354d
#if __ANDROID_API__ < 9
Packit 5e354d
/* Android 8 and earlier are missing rwlocks.  We punt to mutexes in
Packit 5e354d
   that case.  */
Packit 5e354d
#define _NPTH_NO_RWLOCK 1
Packit 5e354d
#endif
Packit 5e354d
#endif
Packit 5e354d
Packit 5e354d
#ifdef __cplusplus
Packit 5e354d
extern "C" {
Packit 5e354d
#if 0 /* (Keep Emacsens' auto-indent happy.) */
Packit 5e354d
}
Packit 5e354d
#endif
Packit 5e354d
#endif
Packit 5e354d
Packit 5e354d
Packit 5e354d

Packit 5e354d
/* Global Library Management */
Packit 5e354d
Packit 5e354d
#define npth_t pthread_t
Packit 5e354d
Packit 5e354d
/* Initialize the library and convert current thread to main thread.
Packit 5e354d
   Must be first npth function called in a process.  Returns error
Packit 5e354d
   number on error and 0 on success.  */
Packit 5e354d
Packit 5e354d
int npth_init(void);
Packit 5e354d
Packit 5e354d
/* Not needed.  */
Packit 5e354d
/* pth_kill, pth_ctrl, pth_version */
Packit 5e354d
Packit 5e354d

Packit 5e354d
/* Thread Attribute Handling */
Packit 5e354d
Packit 5e354d
/* Can't do that.  */
Packit 5e354d
/* pth_attr_of */
Packit 5e354d
Packit 5e354d
#define npth_attr_t pthread_attr_t
Packit 5e354d
#define npth_attr_init pthread_attr_init
Packit 5e354d
#define npth_attr_destroy pthread_attr_destroy
Packit 5e354d
#define NPTH_CREATE_JOINABLE PTHREAD_CREATE_JOINABLE
Packit 5e354d
#define NPTH_CREATE_DETACHED PTHREAD_CREATE_DETACHED
Packit 5e354d
#define npth_attr_getdetachstate pthread_attr_getdetachstate
Packit 5e354d
#define npth_attr_setdetachstate pthread_attr_setdetachstate
Packit 5e354d
int npth_getname_np (npth_t target_thread, char *buf, size_t buflen);
Packit 5e354d
int npth_setname_np (npth_t target_thread, const char *name);
Packit 5e354d
Packit 5e354d

Packit 5e354d
/* Thread Control */
Packit 5e354d
int npth_create(npth_t *thread, const npth_attr_t *attr,
Packit 5e354d
		void *(*start_routine) (void *), void *arg);
Packit 5e354d
Packit 5e354d
Packit 5e354d
/* The Pth version of pth_once supports passing an argument, the
Packit 5e354d
   pthread version does not.  We would have to reimplement the whole
Packit 5e354d
   feature with a global table.  Not needed.  */
Packit 5e354d
/* pth_once */
Packit 5e354d
Packit 5e354d
#define npth_self pthread_self
Packit 5e354d
Packit 5e354d
/* No can do! */
Packit 5e354d
/* pth_suspend, pth_resume */
Packit 5e354d
Packit 5e354d
/* Yield is considered harmful and should never be used in high-level
Packit 5e354d
   applications.  Use a condition instead to wait for a specific event
Packit 5e354d
   to happen, or, as a last resort, use npth_usleep to back off a hard
Packit 5e354d
   busy wait.  */
Packit 5e354d
/* pth_yield */
Packit 5e354d
Packit 5e354d
/* Not needed.  */
Packit 5e354d
/* pth_nap */
Packit 5e354d
Packit 5e354d
/* pth_wait, pth_cancel, pth_abort, pth_raise */
Packit 5e354d
Packit 5e354d
int npth_join(npth_t thread, void **retval);
Packit 5e354d
#define npth_detach pthread_detach
Packit 5e354d
Packit 5e354d
void npth_exit(void *retval);
Packit 5e354d
Packit 5e354d

Packit 5e354d
/* Utilities */
Packit 5e354d
Packit 5e354d
/* pth_fdmode, pth_time, pth_timeout, pth_sfiodisc */
Packit 5e354d
Packit 5e354d

Packit 5e354d
/* Cancellation Management */
Packit 5e354d
Packit 5e354d
/* Not needed.  */
Packit 5e354d
/* pth_cancel_state. npth_cancel_point */
Packit 5e354d
Packit 5e354d

Packit 5e354d
/* Event Handling */
Packit 5e354d
Packit 5e354d
/* No equivalent in pthread.  */
Packit 5e354d
/* pth_event, pth_event_typeof, pth_event_extract, pth_event_concat, pth_event_isolate,
Packit 5e354d
   pth_event_walk, pth_event_status, pth_event_free */
Packit 5e354d
Packit 5e354d

Packit 5e354d
/* Key-Based Storage */
Packit 5e354d
Packit 5e354d
#define npth_key_t pthread_key_t
Packit 5e354d
#define npth_key_create pthread_key_create
Packit 5e354d
#define npth_key_delete pthread_key_delete
Packit 5e354d
#define npth_setspecific pthread_setspecific
Packit 5e354d
#define npth_getspecific pthread_getspecific
Packit 5e354d
Packit 5e354d

Packit 5e354d
/* Message Port Communication */
Packit 5e354d
Packit 5e354d
/* No equivalent in pthread.  */
Packit 5e354d
/* pth_msgport_create, pth_msgport_destroy, pth_msgport_find,
Packit 5e354d
   pth_msgport_pending, pth_msgport_put, pth_msgport_get,
Packit 5e354d
   pth_msgport_reply. */
Packit 5e354d
Packit 5e354d

Packit 5e354d
/* Thread Cleanups */
Packit 5e354d
Packit 5e354d
/* Not needed.  */
Packit 5e354d
/* pth_cleanup_push, pth_cleanup_pop */
Packit 5e354d
Packit 5e354d

Packit 5e354d
/* Process Forking */
Packit 5e354d
Packit 5e354d
/* POSIX only supports a global atfork handler.  So, to implement
Packit 5e354d
   per-thread handlers like in Pth, we would need to keep the data in
Packit 5e354d
   thread local storage.  But, neither pthread_self nor
Packit 5e354d
   pthread_getspecific are standardized as async-signal-safe (what a
Packit 5e354d
   joke!), and __thread is an ELF extension.  Still, using
Packit 5e354d
   pthread_self and pthread_getspecific is probably portable
Packit 5e354d
   enough to implement the atfork handlers, if required.
Packit 5e354d
Packit 5e354d
   pth_fork is only required because fork() is not pth aware.  fork()
Packit 5e354d
   is pthread aware though, and already only creates a single thread
Packit 5e354d
   in the child process.  */
Packit 5e354d
/* pth_atfork_push, pth_atfork_pop, pth_fork */
Packit 5e354d
Packit 5e354d

Packit 5e354d
/* Synchronization */
Packit 5e354d
Packit 5e354d
#define npth_mutexattr_t pthread_mutexattr_t
Packit 5e354d
#define npth_mutexattr_init pthread_mutexattr_init
Packit 5e354d
#define npth_mutexattr_destroy pthread_mutexattr_destroy
Packit 5e354d
#define npth_mutexattr_settype pthread_mutexattr_settype
Packit 5e354d
#define npth_mutexattr_gettype pthread_mutexattr_gettype
Packit 5e354d
#define NPTH_MUTEX_NORMAL PTHREAD_MUTEX_NORMAL
Packit 5e354d
#define NPTH_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE
Packit 5e354d
#define NPTH_MUTEX_ERRORCHECK PTHREAD_MUTEX_ERRORCHECK
Packit 5e354d
#define NPTH_MUTEX_DEFAULT PTHREAD_MUTEX_DEFAULT
Packit 5e354d
Packit 5e354d
#define npth_mutex_t pthread_mutex_t
Packit 5e354d
#define NPTH_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
Packit 5e354d
#define NPTH_RECURSIVE_MUTEX_INITIALIZER_NP \
Packit 5e354d
  PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
Packit 5e354d
#define NPTH_ERRORCHECK_MUTEX_INITIALIZER_NP \
Packit 5e354d
  PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
Packit 5e354d
#define npth_mutex_init pthread_mutex_init
Packit 5e354d
#define npth_mutex_destroy pthread_mutex_destroy
Packit 5e354d
#define npth_mutex_trylock pthread_mutex_trylock
Packit 5e354d
Packit 5e354d
int npth_mutex_lock(npth_mutex_t *mutex);
Packit 5e354d
int npth_mutex_timedlock(npth_mutex_t *mutex, const struct timespec *abstime);
Packit 5e354d
Packit 5e354d
#define npth_mutex_unlock pthread_mutex_unlock
Packit 5e354d
Packit 5e354d
#ifdef _NPTH_NO_RWLOCK
Packit 5e354d
Packit 5e354d
typedef int npth_rwlockattr_t;
Packit 5e354d
#define npth_rwlockattr_init(attr)
Packit 5e354d
#define npth_rwlockattr_destroy(attr)
Packit 5e354d
#define npth_rwlockattr_gettype_np(attr,kind)
Packit 5e354d
#define npth_rwlockattr_settype_np(attr,kind)
Packit 5e354d
#define NPTH_RWLOCK_PREFER_READER_NP 0
Packit 5e354d
#define NPTH_RWLOCK_PREFER_WRITER_NP 0
Packit 5e354d
#define NPTH_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP 0
Packit 5e354d
#define NPTH_RWLOCK_DEFAULT_NP 0
Packit 5e354d
#define NPTH_RWLOCK_INITIALIZER NPTH_MUTEX_INITIALIZER
Packit 5e354d
#define NPTH_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP NPTH_MUTEX_INITIALIZER
Packit 5e354d
typedef npth_mutex_t npth_rwlock_t;
Packit 5e354d
#define npth_rwlock_init(rwlock,attr) npth_mutex_init(rwlock,0)
Packit 5e354d
#define npth_rwlock_destroy npth_mutex_destroy
Packit 5e354d
#define npth_rwlock_tryrdlock npth_mutex_trylock
Packit 5e354d
#define npth_rwlock_rdlock npth_mutex_lock
Packit 5e354d
#define npth_rwlock_trywrlock npth_mutex_trylock
Packit 5e354d
#define npth_rwlock_timedrdlock npth_mutex_timedlock
Packit 5e354d
#define npth_rwlock_wrlock npth_mutex_lock
Packit 5e354d
#define npth_rwlock_rdlock npth_mutex_lock
Packit 5e354d
#define npth_rwlock_timedwrlock npth_mutex_timedlock
Packit 5e354d
#define npth_rwlock_unlock npth_mutex_unlock
Packit 5e354d
Packit 5e354d
#else /* _NPTH_NO_RWLOCK */
Packit 5e354d
Packit 5e354d
#define npth_rwlockattr_t pthread_rwlockattr_t
Packit 5e354d
#define npth_rwlockattr_init pthread_rwlockattr_init
Packit 5e354d
#define npth_rwlockattr_destroy pthread_rwlockattr_destroy
Packit 5e354d
#define npth_rwlockattr_gettype_np pthread_rwlockattr_gettype_np
Packit 5e354d
#define npth_rwlockattr_settype_np pthread_rwlockattr_settype_np
Packit 5e354d
#define NPTH_RWLOCK_PREFER_READER_NP PTHREAD_RWLOCK_PREFER_READER_NP
Packit 5e354d
/* Note: The prefer-writer setting is ineffective and the same as
Packit 5e354d
   prefer-reader.  This is because reader locks are specified to be
Packit 5e354d
   recursive, but for efficiency reasons we do not keep track of which
Packit 5e354d
   threads already hold a reader lock.  For this reason, we can not
Packit 5e354d
   prefer some reader locks over others, and thus a recursive reader
Packit 5e354d
   lock could be stalled by a pending writer, leading to a dead
Packit 5e354d
   lock.  */
Packit 5e354d
#define NPTH_RWLOCK_PREFER_WRITER_NP PTHREAD_RWLOCK_PREFER_WRITER_NP
Packit 5e354d
/* The non-recursive choise is a promise by the application that it
Packit 5e354d
   does not lock the rwlock for reading recursively.  In this setting,
Packit 5e354d
   writers are preferred, but note that recursive reader locking is
Packit 5e354d
   prone to deadlocks in that case.  */
Packit 5e354d
#define NPTH_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP \
Packit 5e354d
  PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
Packit 5e354d
#define NPTH_RWLOCK_DEFAULT_NP PTHREAD_RWLOCK_DEFAULT_NP
Packit 5e354d
#define NPTH_RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER
Packit 5e354d
#define NPTH_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \
Packit 5e354d
  PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
Packit 5e354d
Packit 5e354d
typedef pthread_rwlock_t npth_rwlock_t;
Packit 5e354d
#define npth_rwlock_init pthread_rwlock_init
Packit 5e354d
#define npth_rwlock_destroy pthread_rwlock_destroy
Packit 5e354d
#define npth_rwlock_tryrdlock pthread_rwlock_tryrdlock
Packit 5e354d
Packit 5e354d
int npth_rwlock_rdlock (npth_rwlock_t *rwlock);
Packit 5e354d
Packit 5e354d
int npth_rwlock_timedrdlock (npth_rwlock_t *rwlock,
Packit 5e354d
			     const struct timespec *abstime);
Packit 5e354d
Packit 5e354d
#define npth_rwlock_trywrlock pthread_rwlock_trywrlock
Packit 5e354d
int npth_rwlock_wrlock (npth_rwlock_t *rwlock);
Packit 5e354d
int npth_rwlock_timedwrlock (npth_rwlock_t *rwlock,
Packit 5e354d
			     const struct timespec *abstime);
Packit 5e354d
#define npth_rwlock_unlock  pthread_rwlock_unlock
Packit 5e354d
Packit 5e354d
#endif /* !_NPTH_NO_RWLOCK */
Packit 5e354d
Packit 5e354d
Packit 5e354d
typedef pthread_cond_t npth_cond_t;
Packit 5e354d
#define NPTH_COND_INITIALIZER PTHREAD_COND_INITIALIZER
Packit 5e354d
/* For now, we don't support any cond attributes.  */
Packit 5e354d
#define npth_cond_init pthread_cond_init
Packit 5e354d
#define npth_cond_broadcast pthread_cond_broadcast
Packit 5e354d
#define npth_cond_signal pthread_cond_signal
Packit 5e354d
#define npth_cond_destroy pthread_cond_destroy
Packit 5e354d
int npth_cond_wait(npth_cond_t *cond, npth_mutex_t *mutex);
Packit 5e354d
int npth_cond_timedwait(npth_cond_t *cond, npth_mutex_t *mutex,
Packit 5e354d
			const struct timespec *abstime);
Packit 5e354d
Packit 5e354d
/* Not needed.  */
Packit 5e354d
Packit 5e354d
/* pth_barrier_t, pth_barrier_init, pth_barrier_reach */
Packit 5e354d
Packit 5e354d

Packit 5e354d
/* User-Space Context */
Packit 5e354d
Packit 5e354d
/* Can not be implemented.  */
Packit 5e354d
/* pth_uctx_create, pth_uctx_make, pth_uctx_switch, pth_uctx_destroy */
Packit 5e354d
Packit 5e354d

Packit 5e354d
/* Generalized POSIX Replacement API */
Packit 5e354d
Packit 5e354d
/* In general, we can not support these easily.  */
Packit 5e354d
/* pth_sigwait_ev, pth_accept_ev, pth_connect_ev, pth_select_ev,
Packit 5e354d
   pth_poll_ev, pth_read_ev, pth_readv_ev, pth_write_ev,
Packit 5e354d
   pth_writev_ev, pth_recv_ev, pth_recvfrom_ev, pth_send_ev,
Packit 5e354d
   pth_sendto_ev */
Packit 5e354d
Packit 5e354d

Packit 5e354d
/* Standard POSIX Replacement API */
Packit 5e354d
Packit 5e354d
/* We will provide a more specific way to handle signals.  */
Packit 5e354d
/* pth_sigmask, pth_sigwait */
Packit 5e354d
Packit 5e354d
/* Not needed.  */
Packit 5e354d
/* pth_nanosleep, pth_system, pth_readv, pth_writev, pth_poll,
Packit 5e354d
   pth_recv, pth_send, pth_recvfrom, pth_sendto */
Packit 5e354d
Packit 5e354d
int npth_usleep(unsigned int usec);
Packit 5e354d
unsigned int npth_sleep(unsigned int sec);
Packit 5e354d
Packit 5e354d
pid_t npth_waitpid(pid_t pid, int *status, int options);
Packit 5e354d
int npth_system(const char *cmd);
Packit 5e354d
#define npth_sigmask pthread_sigmask
Packit 5e354d
int npth_sigwait(const sigset_t *set, int *sig);
Packit 5e354d
Packit 5e354d
int npth_connect(int s, const struct sockaddr *addr, _npth_socklen_t addrlen);
Packit 5e354d
int npth_accept(int s, struct sockaddr *addr, _npth_socklen_t *addrlen);
Packit 5e354d
int npth_select(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds,
Packit 5e354d
		struct timeval *timeout);
Packit 5e354d
int npth_pselect(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds,
Packit 5e354d
		 const struct timespec *timeout, const sigset_t *sigmask);
Packit 5e354d
ssize_t npth_read(int fd, void *buf, size_t nbytes);
Packit 5e354d
ssize_t npth_write(int fd, const void *buf, size_t nbytes);
Packit 5e354d
int npth_recvmsg (int fd, struct msghdr *msg, int flags);
Packit 5e354d
int npth_sendmsg (int fd, const struct msghdr *msg, int flags);
Packit 5e354d
Packit 5e354d
/* For anything not covered here, you can enter/leave manually at your
Packit 5e354d
   own risk.  */
Packit 5e354d
void npth_unprotect (void);
Packit 5e354d
void npth_protect (void);
Packit 5e354d
Packit 5e354d
/* If you run into problems with the above calls, this function can be
Packit 5e354d
 * used to examine in which state nPth is.  */
Packit 5e354d
int npth_is_protected (void);
Packit 5e354d
Packit 5e354d

Packit 5e354d
/* Because the timed functions work on timespec, we provide a clock
Packit 5e354d
   interface for convenience and portability.  */
Packit 5e354d
int npth_clock_gettime (struct timespec *tp);
Packit 5e354d
Packit 5e354d
/* CMP may be ==, < or >.  Do not use <= or >=.  */
Packit 5e354d
#define npth_timercmp(t1, t2, cmp)					\
Packit 5e354d
  (((t1)->tv_sec == (t2)->tv_sec) ?					\
Packit 5e354d
   ((t1)->tv_nsec cmp (t2)->tv_nsec) :					\
Packit 5e354d
   ((t1)->tv_sec cmp (t2)->tv_sec))
Packit 5e354d
#define npth_timeradd(t1, t2, result)					\
Packit 5e354d
  do {									\
Packit 5e354d
    (result)->tv_sec = (t1)->tv_sec + (t2)->tv_sec;			\
Packit 5e354d
    (result)->tv_nsec = (t1)->tv_nsec + (t2)->tv_nsec;			\
Packit 5e354d
    if ((result)->tv_nsec >= 1000000000)				\
Packit 5e354d
      {									\
Packit 5e354d
	++(result)->tv_sec;						\
Packit 5e354d
	(result)->tv_nsec -= 1000000000;				\
Packit 5e354d
      }									\
Packit 5e354d
  } while (0)
Packit 5e354d
#define npth_timersub(t1, t2, result)					\
Packit 5e354d
  do {									\
Packit 5e354d
    (result)->tv_sec = (t1)->tv_sec - (t2)->tv_sec;			\
Packit 5e354d
    (result)->tv_nsec = (t1)->tv_nsec - (t2)->tv_nsec;			\
Packit 5e354d
    if ((result)->tv_nsec < 0) {					\
Packit 5e354d
      --(result)->tv_sec;						\
Packit 5e354d
      (result)->tv_nsec += 1000000000;					\
Packit 5e354d
    }									\
Packit 5e354d
  } while (0)
Packit 5e354d
Packit 5e354d
Packit 5e354d

Packit 5e354d
/* This is a support interface to make it easier to handle signals.
Packit 5e354d
 *
Packit 5e354d
 * The interfaces here support one (and only one) thread (here called
Packit 5e354d
 * "main thread") in the application to monitor several signals while
Packit 5e354d
 * selecting on filedescriptors.
Packit 5e354d
 *
Packit 5e354d
 * First, the main thread should call npth_sigev_init.  This
Packit 5e354d
 * initializes some global data structures used to record interesting
Packit 5e354d
 * and pending signals.
Packit 5e354d
 *
Packit 5e354d
 * Then, the main thread should call npth_sigev_add for every signal
Packit 5e354d
 * it is interested in observing, and finally npth_sigev_fini.  This
Packit 5e354d
 * will block the signal in the main threads sigmask.  Note that these
Packit 5e354d
 * signals should also be blocked in all other threads.  Since they
Packit 5e354d
 * are blocked in the main thread after calling npth_sigev_add, it is
Packit 5e354d
 * recommended to call npth_sigev_add in the main thread before
Packit 5e354d
 * creating any threads.
Packit 5e354d
 *
Packit 5e354d
 * The function npth_sigev_sigmask is a convenient function that
Packit 5e354d
 * returns the sigmask of the thread at time of npth_sigev_init, but
Packit 5e354d
 * with all registered signals unblocked.  It is recommended to do all
Packit 5e354d
 * other changes to the main thread's sigmask before calling
Packit 5e354d
 * npth_sigev_init, so that the return value of npth_sigev_sigmask can
Packit 5e354d
 * be used in the npth_pselect invocation.
Packit 5e354d
 *
Packit 5e354d
 * In any case, the main thread should invoke npth_pselect with a
Packit 5e354d
 * sigmask that has all signals that should be monitored unblocked.
Packit 5e354d
 *
Packit 5e354d
 * After npth_pselect returns, npth_sigev_get_pending can be called in
Packit 5e354d
 * a loop until it returns 0 to iterate over the list of pending
Packit 5e354d
 * signals.  Each time a signal is returned by that function, its
Packit 5e354d
 * status is reset to non-pending.
Packit 5e354d
 */
Packit 5e354d
Packit 5e354d
/* Start setting up signal event handling.  */
Packit 5e354d
void npth_sigev_init (void);
Packit 5e354d
Packit 5e354d
/* Add signal SIGNUM to the list of watched signals.  */
Packit 5e354d
void npth_sigev_add (int signum);
Packit 5e354d
Packit 5e354d
/* Finish the list of watched signals.  This starts to block them,
Packit 5e354d
   too.  */
Packit 5e354d
void npth_sigev_fini (void);
Packit 5e354d
Packit 5e354d
/* Get the sigmask as needed for pselect.  */
Packit 5e354d
sigset_t *npth_sigev_sigmask (void);
Packit 5e354d
Packit 5e354d
/* Return the next signal event that occured.  Returns if none are
Packit 5e354d
   left, 1 on success.  */
Packit 5e354d
int npth_sigev_get_pending (int *r_signum);
Packit 5e354d
Packit 5e354d
Packit 5e354d
#if 0 /* (Keep Emacsens' auto-indent happy.) */
Packit 5e354d
{
Packit 5e354d
#endif
Packit 5e354d
#ifdef __cplusplus
Packit 5e354d
}
Packit 5e354d
#endif
Packit 5e354d
#endif /*_NPTH_H*/
Packit 5e354d
/*
Packit 5e354d
Local Variables:
Packit 5e354d
buffer-read-only: t
Packit 5e354d
End:
Packit 5e354d
*/