|
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 |
*/
|