/* npth.h - a lightweight implementation of pth over pthread. Copyright (C) 2011, 2015 g10 Code GmbH This file is part of NPTH. NPTH is free software; you can redistribute it and/or modify it under the terms of either - the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. or - the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. or both in parallel, as here. NPTH is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copies of the GNU General Public License and the GNU Lesser General Public License along with this program; if not, see . */ #ifndef _NPTH_H #define _NPTH_H #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #if 0 /* (Keep Emacsens' auto-indent happy.) */ } #endif #endif struct msghdr; /* At least with version 2 the mingw-w64 headers define timespec. For older compilers we keep our replacement. */ #if __MINGW64_VERSION_MAJOR < 2 struct timespec { long tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ }; #endif /*__MINGW64_VERSION_MAJOR < 2*/ #ifndef ETIMEDOUT #define ETIMEDOUT 10060 /* This is WSAETIMEDOUT. */ #endif #ifndef EOPNOTSUPP #define EOPNOTSUPP 10045 /* This is WSAEOPNOTSUPP. */ #endif int npth_init (void); typedef struct npth_attr_s *npth_attr_t; typedef unsigned long int npth_t; typedef struct npth_mutexattr_s *npth_mutexattr_t; typedef struct npth_mutex_s *npth_mutex_t; typedef struct npth_rwlockattr_s *npth_rwlockattr_t; typedef struct npth_rwlock_s *npth_rwlock_t; typedef struct npth_condattr_s *npth_condattr_t; typedef struct npth_cond_s *npth_cond_t; int npth_attr_init (npth_attr_t *attr); int npth_attr_destroy (npth_attr_t *attr); #define NPTH_CREATE_JOINABLE 0 #define NPTH_CREATE_DETACHED 1 int npth_attr_getdetachstate(npth_attr_t *attr, int *detachstate); int npth_attr_setdetachstate(npth_attr_t *attr, int detachstate); int npth_getname_np (npth_t target_thread, char *buf, size_t buflen); int npth_setname_np (npth_t target_thread, const char *name); int npth_create (npth_t *newthread, const npth_attr_t *attr, void *(*start_routine) (void *), void *arg); npth_t npth_self (void); int npth_join (npth_t th, void **thread_return); int npth_detach (npth_t th); void npth_exit (void *retval); typedef DWORD npth_key_t; int npth_key_create (npth_key_t *key, void (*destr_function) (void *)); int npth_key_delete (npth_key_t key); void *npth_getspecific (npth_key_t key); int npth_setspecific (npth_key_t key, const void *pointer); int npth_mutexattr_init (npth_mutexattr_t *attr); int npth_mutexattr_destroy (npth_mutexattr_t *attr); int npth_mutexattr_gettype (const npth_mutexattr_t *attr, int *kind); int npth_mutexattr_settype (npth_mutexattr_t *attr, int kind); #define NPTH_MUTEX_NORMAL 0 #define NPTH_MUTEX_RECURSIVE 1 #define NPTH_MUTEX_ERRORCHECK 2 #define NPTH_MUTEX_DEFAULT NPTH_MUTEX_NORMAL #define NPTH_MUTEX_INITIALIZER ((npth_mutex_t) -1) #define NPTH_RECURSIVE_MUTEX_INITIALIZER_NP ((npth_mutex_t) -2) #define NPTH_ERRORCHECK_MUTEX_INITIALIZER_NP ((npth_mutex_t) -3) int npth_mutex_init (npth_mutex_t *mutex, const npth_mutexattr_t *mutexattr); int npth_mutex_destroy (npth_mutex_t *mutex); int npth_mutex_trylock(npth_mutex_t *mutex); int npth_mutex_lock(npth_mutex_t *mutex); int npth_mutex_timedlock(npth_mutex_t *mutex, const struct timespec *abstime); int npth_mutex_unlock(npth_mutex_t *mutex); int npth_rwlockattr_init (npth_rwlockattr_t *attr); int npth_rwlockattr_destroy (npth_rwlockattr_t *attr); int npth_rwlockattr_gettype_np (const npth_rwlockattr_t *attr, int *kind); int npth_rwlockattr_settype_np (npth_rwlockattr_t *attr, int kind); #define NPTH_RWLOCK_PREFER_READER_NP 0 #define NPTH_RWLOCK_PREFER_WRITER_NP 1 #define NPTH_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP 2 #define NPTH_RWLOCK_DEFAULT_NP NPTH_RWLOCK_PREFER_READER_NP #define NPTH_RWLOCK_INITIALIZER ((npth_rwlock_t) -1) #define NPTH_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP ((npth_rwlock_t) -2) /* For now, we don't support any rwlock attributes. */ int npth_rwlock_init (npth_rwlock_t *rwlock, const npth_rwlockattr_t *attr); int npth_rwlock_destroy (npth_rwlock_t *rwlock); int npth_rwlock_tryrdlock (npth_rwlock_t *rwlock); int npth_rwlock_rdlock (npth_rwlock_t *rwlock); int npth_rwlock_timedrdlock (npth_rwlock_t *rwlock, const struct timespec *abstime); int npth_rwlock_trywrlock (npth_rwlock_t *rwlock); int npth_rwlock_wrlock (npth_rwlock_t *rwlock); int npth_rwlock_timedwrlock (npth_rwlock_t *rwlock, const struct timespec *abstime); int npth_rwlock_unlock (npth_rwlock_t *rwlock); #define NPTH_COND_INITIALIZER ((npth_cond_t) -1) /* For now, we don't support any cond attributes. */ int npth_cond_init (npth_cond_t *cond, const npth_condattr_t *cond_attr); int npth_cond_broadcast (npth_cond_t *cond); int npth_cond_signal (npth_cond_t *cond); int npth_cond_destroy (npth_cond_t *cond); int npth_cond_wait (npth_cond_t *cond, npth_mutex_t *mutex); int npth_cond_timedwait (npth_cond_t *cond, npth_mutex_t *mutex, const struct timespec *abstime); int npth_usleep(unsigned int usec); unsigned int npth_sleep(unsigned int sec); pid_t npth_waitpid(pid_t pid, int *status, int options); int npth_system(const char *cmd); #if 0 /* We do not support this on windows. */ int npth_sigmask(int how, const sigset_t *set, sigset_t *oldset); int npth_sigwait(const sigset_t *set, int *sig); #endif int npth_connect(int s, const struct sockaddr *addr, socklen_t addrlen); int npth_accept(int s, struct sockaddr *addr, socklen_t *addrlen); /* Only good for sockets! */ int npth_select(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout); #if 0 /* We do not support this on windows. */ int npth_pselect(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, const struct timespec *timeout, const sigset_t *sigmask); #endif /* Wait on the FDs (only good for sockets!) and the INVALID_HANDLE_VALUE terminated list of extra events. On return (even on error), the bits in EVENTS_SET will contain the extra events that occured (which means that there can only be up to 31 extra events). */ int npth_eselect(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, const struct timespec *timeout, HANDLE *events, unsigned int *events_set); ssize_t npth_read(int fd, void *buf, size_t nbytes); ssize_t npth_write(int fd, const void *buf, size_t nbytes); int npth_recvmsg (int fd, struct msghdr *msg, int flags); int npth_sendmsg (int fd, const struct msghdr *msg, int flags); void npth_unprotect (void); void npth_protect (void); int npth_clock_gettime(struct timespec *tp); /* CMP may be ==, < or >. Do not use <= or >=. */ #define npth_timercmp(t1, t2, cmp) \ (((t1)->tv_sec == (t2)->tv_sec) ? \ ((t1)->tv_nsec cmp (t2)->tv_nsec) : \ ((t1)->tv_sec cmp (t2)->tv_sec)) #define npth_timeradd(t1, t2, result) \ do { \ (result)->tv_sec = (t1)->tv_sec + (t2)->tv_sec; \ (result)->tv_nsec = (t1)->tv_nsec + (t2)->tv_nsec; \ if ((result)->tv_nsec >= 1000000000) \ { \ ++(result)->tv_sec; \ (result)->tv_nsec -= 1000000000; \ } \ } while (0) #define npth_timersub(t1, t2, result) \ do { \ (result)->tv_sec = (t1)->tv_sec - (t2)->tv_sec; \ (result)->tv_nsec = (t1)->tv_nsec - (t2)->tv_nsec; \ if ((result)->tv_nsec < 0) { \ --(result)->tv_sec; \ (result)->tv_nsec += 1000000000; \ } \ } while (0) #if 0 /* We do not support this on windows. */ void npth_sigev_init (void); void npth_sigev_add (int signum); void npth_sigev_fini (void); sigset_t *npth_sigev_sigmask (void); int npth_sigev_get_pending (int *r_signum); #endif #if 0 /* (Keep Emacsens' auto-indent happy.) */ { #endif #ifdef __cplusplus } #endif #endif /*_NPTH_H*/