|
Packit |
5e354d |
/* npth.h - a lightweight implementation of pth over native threads
|
|
Packit |
5e354d |
* Copyright (C) 2011, 2015 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 |
#ifndef _NPTH_H
|
|
Packit |
5e354d |
#define _NPTH_H
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
#include <sys/types.h>
|
|
Packit |
5e354d |
#include <time.h>
|
|
Packit |
5e354d |
#include <errno.h>
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
#include <winsock2.h>
|
|
Packit |
5e354d |
#include <ws2tcpip.h>
|
|
Packit |
5e354d |
#include <windows.h>
|
|
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 |
struct msghdr;
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
/* The mingw-w64 headers define timespec. For older compilers we keep
|
|
Packit |
5e354d |
our replacement. */
|
|
Packit |
5e354d |
#ifndef __MINGW64_VERSION_MAJOR
|
|
Packit |
5e354d |
struct timespec {
|
|
Packit |
5e354d |
long tv_sec; /* seconds */
|
|
Packit |
5e354d |
long tv_nsec; /* nanoseconds */
|
|
Packit |
5e354d |
};
|
|
Packit |
5e354d |
#endif /*__MINGW64_VERSION_MAJOR */
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
#ifndef ETIMEDOUT
|
|
Packit |
5e354d |
#define ETIMEDOUT 10060 /* This is WSAETIMEDOUT. */
|
|
Packit |
5e354d |
#endif
|
|
Packit |
5e354d |
#ifndef EOPNOTSUPP
|
|
Packit |
5e354d |
#define EOPNOTSUPP 10045 /* This is WSAEOPNOTSUPP. */
|
|
Packit |
5e354d |
#endif
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
int npth_init (void);
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
typedef struct npth_attr_s *npth_attr_t;
|
|
Packit |
5e354d |
typedef unsigned long int npth_t;
|
|
Packit |
5e354d |
typedef struct npth_mutexattr_s *npth_mutexattr_t;
|
|
Packit |
5e354d |
typedef struct npth_mutex_s *npth_mutex_t;
|
|
Packit |
5e354d |
typedef struct npth_rwlockattr_s *npth_rwlockattr_t;
|
|
Packit |
5e354d |
typedef struct npth_rwlock_s *npth_rwlock_t;
|
|
Packit |
5e354d |
typedef struct npth_condattr_s *npth_condattr_t;
|
|
Packit |
5e354d |
typedef struct npth_cond_s *npth_cond_t;
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
int npth_attr_init (npth_attr_t *attr);
|
|
Packit |
5e354d |
int npth_attr_destroy (npth_attr_t *attr);
|
|
Packit |
5e354d |
#define NPTH_CREATE_JOINABLE 0
|
|
Packit |
5e354d |
#define NPTH_CREATE_DETACHED 1
|
|
Packit |
5e354d |
int npth_attr_getdetachstate(npth_attr_t *attr, int *detachstate);
|
|
Packit |
5e354d |
int npth_attr_setdetachstate(npth_attr_t *attr, int detachstate);
|
|
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 |
int npth_create (npth_t *newthread, const npth_attr_t *attr,
|
|
Packit |
5e354d |
void *(*start_routine) (void *), void *arg);
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
npth_t npth_self (void);
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
int npth_join (npth_t th, void **thread_return);
|
|
Packit |
5e354d |
int npth_detach (npth_t th);
|
|
Packit |
5e354d |
void npth_exit (void *retval);
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
typedef DWORD npth_key_t;
|
|
Packit |
5e354d |
int npth_key_create (npth_key_t *key,
|
|
Packit |
5e354d |
void (*destr_function) (void *));
|
|
Packit |
5e354d |
int npth_key_delete (npth_key_t key);
|
|
Packit |
5e354d |
void *npth_getspecific (npth_key_t key);
|
|
Packit |
5e354d |
int npth_setspecific (npth_key_t key, const void *pointer);
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
int npth_mutexattr_init (npth_mutexattr_t *attr);
|
|
Packit |
5e354d |
int npth_mutexattr_destroy (npth_mutexattr_t *attr);
|
|
Packit |
5e354d |
int npth_mutexattr_gettype (const npth_mutexattr_t *attr,
|
|
Packit |
5e354d |
int *kind);
|
|
Packit |
5e354d |
int npth_mutexattr_settype (npth_mutexattr_t *attr, int kind);
|
|
Packit |
5e354d |
#define NPTH_MUTEX_NORMAL 0
|
|
Packit |
5e354d |
#define NPTH_MUTEX_RECURSIVE 1
|
|
Packit |
5e354d |
#define NPTH_MUTEX_ERRORCHECK 2
|
|
Packit |
5e354d |
#define NPTH_MUTEX_DEFAULT NPTH_MUTEX_NORMAL
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
#define NPTH_MUTEX_INITIALIZER ((npth_mutex_t) -1)
|
|
Packit |
5e354d |
#define NPTH_RECURSIVE_MUTEX_INITIALIZER_NP ((npth_mutex_t) -2)
|
|
Packit |
5e354d |
#define NPTH_ERRORCHECK_MUTEX_INITIALIZER_NP ((npth_mutex_t) -3)
|
|
Packit |
5e354d |
int npth_mutex_init (npth_mutex_t *mutex, const npth_mutexattr_t *mutexattr);
|
|
Packit |
5e354d |
int npth_mutex_destroy (npth_mutex_t *mutex);
|
|
Packit |
5e354d |
int npth_mutex_trylock(npth_mutex_t *mutex);
|
|
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 |
int npth_mutex_unlock(npth_mutex_t *mutex);
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
int npth_rwlockattr_init (npth_rwlockattr_t *attr);
|
|
Packit |
5e354d |
int npth_rwlockattr_destroy (npth_rwlockattr_t *attr);
|
|
Packit |
5e354d |
int npth_rwlockattr_gettype_np (const npth_rwlockattr_t *attr,
|
|
Packit |
5e354d |
int *kind);
|
|
Packit |
5e354d |
int npth_rwlockattr_settype_np (npth_rwlockattr_t *attr, int kind);
|
|
Packit |
5e354d |
#define NPTH_RWLOCK_PREFER_READER_NP 0
|
|
Packit |
5e354d |
#define NPTH_RWLOCK_PREFER_WRITER_NP 1
|
|
Packit |
5e354d |
#define NPTH_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP 2
|
|
Packit |
5e354d |
#define NPTH_RWLOCK_DEFAULT_NP NPTH_RWLOCK_PREFER_READER_NP
|
|
Packit |
5e354d |
#define NPTH_RWLOCK_INITIALIZER ((npth_rwlock_t) -1)
|
|
Packit |
5e354d |
#define NPTH_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP ((npth_rwlock_t) -2)
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
/* For now, we don't support any rwlock attributes. */
|
|
Packit |
5e354d |
int npth_rwlock_init (npth_rwlock_t *rwlock,
|
|
Packit |
5e354d |
const npth_rwlockattr_t *attr);
|
|
Packit |
5e354d |
int npth_rwlock_destroy (npth_rwlock_t *rwlock);
|
|
Packit |
5e354d |
int npth_rwlock_tryrdlock (npth_rwlock_t *rwlock);
|
|
Packit |
5e354d |
int npth_rwlock_rdlock (npth_rwlock_t *rwlock);
|
|
Packit |
5e354d |
int npth_rwlock_timedrdlock (npth_rwlock_t *rwlock,
|
|
Packit |
5e354d |
const struct timespec *abstime);
|
|
Packit |
5e354d |
int npth_rwlock_trywrlock (npth_rwlock_t *rwlock);
|
|
Packit |
5e354d |
|
|
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 |
int npth_rwlock_unlock (npth_rwlock_t *rwlock);
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
#define NPTH_COND_INITIALIZER ((npth_cond_t) -1)
|
|
Packit |
5e354d |
/* For now, we don't support any cond attributes. */
|
|
Packit |
5e354d |
int npth_cond_init (npth_cond_t *cond,
|
|
Packit |
5e354d |
const npth_condattr_t *cond_attr);
|
|
Packit |
5e354d |
int npth_cond_broadcast (npth_cond_t *cond);
|
|
Packit |
5e354d |
int npth_cond_signal (npth_cond_t *cond);
|
|
Packit |
5e354d |
int npth_cond_destroy (npth_cond_t *cond);
|
|
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 |
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 |
|
|
Packit |
5e354d |
#if 0
|
|
Packit |
5e354d |
/* We do not support this on windows. */
|
|
Packit |
5e354d |
int npth_sigmask(int how, const sigset_t *set, sigset_t *oldset);
|
|
Packit |
5e354d |
int npth_sigwait(const sigset_t *set, int *sig);
|
|
Packit |
5e354d |
#endif
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
int npth_connect(int s, const struct sockaddr *addr, socklen_t addrlen);
|
|
Packit |
5e354d |
int npth_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
|
|
Packit |
5e354d |
/* Only good for sockets! */
|
|
Packit |
5e354d |
int npth_select(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds,
|
|
Packit |
5e354d |
struct timeval *timeout);
|
|
Packit |
5e354d |
#if 0
|
|
Packit |
5e354d |
/* We do not support this on windows. */
|
|
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 |
#endif
|
|
Packit |
5e354d |
/* Wait on the FDs (only good for sockets!) and the
|
|
Packit |
5e354d |
INVALID_HANDLE_VALUE terminated list of extra events. On return
|
|
Packit |
5e354d |
(even on error), the bits in EVENTS_SET will contain the extra
|
|
Packit |
5e354d |
events that occured (which means that there can only be up to 31
|
|
Packit |
5e354d |
extra events). */
|
|
Packit |
5e354d |
int npth_eselect(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds,
|
|
Packit |
5e354d |
const struct timespec *timeout,
|
|
Packit |
5e354d |
HANDLE *events, unsigned int *events_set);
|
|
Packit |
5e354d |
|
|
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 |
void npth_unprotect (void);
|
|
Packit |
5e354d |
void npth_protect (void);
|
|
Packit |
5e354d |
|
|
Packit |
5e354d |
/* Return true when we hold the sceptre. This is used to debug
|
|
Packit |
5e354d |
* problems with npth_unprotect and npth_protect. */
|
|
Packit |
5e354d |
int npth_is_protected (void);
|
|
Packit |
5e354d |
|
|
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 |
#if 0
|
|
Packit |
5e354d |
/* We do not support this on windows. */
|
|
Packit |
5e354d |
void npth_sigev_init (void);
|
|
Packit |
5e354d |
void npth_sigev_add (int signum);
|
|
Packit |
5e354d |
void npth_sigev_fini (void);
|
|
Packit |
5e354d |
sigset_t *npth_sigev_sigmask (void);
|
|
Packit |
5e354d |
int npth_sigev_get_pending (int *r_signum);
|
|
Packit |
5e354d |
#endif
|
|
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*/
|