diff --git a/configure.ac b/configure.ac index 23718d6..8090448 100644 --- a/configure.ac +++ b/configure.ac @@ -1,380 +1,390 @@ # configure.ac -*- Autoconf -*- # Copyright (C) 2011, 2012 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 the GNU Lesser General Public License as # published by the Free Software Foundation; either version 2.1 of the # License, or (at your option) any later version. # # 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 Lesser General # Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this program; if not, see . # Process this file with autoconf to produce a configure script. AC_PREREQ([2.67]) min_automake_version="1.14" # To build a release you need to create a tag with the version number # (git tag -s npth-n.m) and run "./autogen.sh --force". Please bump # the version number immediately after the release and do another # commit and push so that the git magic is able to work. # See below for the LT versions. m4_define([mym4_package],[npth]) m4_define([mym4_major], [1]) m4_define([mym4_minor], [7]) # To start a new development series, i.e a new major or minor number # you need to mark an arbitrary commit before the first beta release # with an annotated tag. For example a 2.1 branch starts off with # the tag "foo-2.1-base". This is used as the base for counting # beta numbers before the first release of a series. # Below is m4 magic to extract and compute the git revision number, # the decimalized short revision number, a beta version string and a # flag indicating a development version (mym4_isbeta). Note that the # m4 processing is done by autoconf and not during the configure run. m4_define([mym4_verslist], m4_split(m4_esyscmd([./autogen.sh --find-version] \ mym4_package mym4_major mym4_minor),[:])) m4_define([mym4_isbeta], m4_argn(2, mym4_verslist)) m4_define([mym4_version], m4_argn(4, mym4_verslist)) m4_define([mym4_revision], m4_argn(7, mym4_verslist)) m4_define([mym4_revision_dec], m4_argn(8, mym4_verslist)) m4_esyscmd([echo ]mym4_version[>VERSION]) AC_INIT([mym4_package],[mym4_version], [https://bugs.gnupg.org]) # LT Version numbers, remember to change them just *before* a release. # (Code changed: REVISION++) # (Interfaces added/removed/changed: CURRENT++, REVISION=0) # (Interfaces added: AGE++) # (Interfaces removed: AGE=0) # LIBNPTH_LT_CURRENT=1 LIBNPTH_LT_AGE=1 LIBNPTH_LT_REVISION=2 ################################################ AC_SUBST(LIBNPTH_LT_CURRENT) AC_SUBST(LIBNPTH_LT_AGE) AC_SUBST(LIBNPTH_LT_REVISION) VERSION_NUMBER=m4_esyscmd(printf "0x%02x%02x00" mym4_major mym4_minor) AC_SUBST(VERSION_NUMBER) # If the API is changed in an incompatible way: increment the next counter. NPTH_CONFIG_API_VERSION=1 ############################################## AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([serial-tests dist-bzip2 no-dist-gzip]) AM_MAINTAINER_MODE AC_CONFIG_SRCDIR([src/npth.c]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) AC_CANONICAL_HOST AM_SILENT_RULES # Enable GNU extensions on systems that have them. AC_GNU_SOURCE AH_VERBATIM([_REENTRANT], [#ifndef _REENTRANT # define _REENTRANT 1 #endif]) # Checks for programs. AC_PROG_CC run_tests="yes" AC_ARG_ENABLE(tests, AC_HELP_STRING([--disable-tests], [disable tests]), run_tests=$enableval) AM_CONDITIONAL(RUN_TESTS, test "$run_tests" = "yes") # Don't default to build static libs. LT_PREREQ([2.2.6]) LT_INIT([win32-dll disable-static]) LT_LANG([Windows Resource]) # For now we hardcode the use of version scripts. It would be better # to write a test for this or even implement this within libtool. have_ld_version_script=no case "${host}" in *-*-linux*) have_ld_version_script=yes ;; *-*-gnu*) have_ld_version_script=yes ;; *-apple-darwin*) AC_SEARCH_LIBS([dispatch_semaphore_create],[dispatch], [AC_DEFINE([HAVE_LIB_DISPATCH],1,[Defined if we have libdispatch])]) ;; *-*-aix*) have_fork_unsafe_semaphore=yes ;; *-*-dragonfly*|*-*-freebsd*|*-*-netbsd*|*-*-hpux*) LIBS="-lpthread $LIBS" AC_SEARCH_LIBS([sem_init],[rt]) ;; esac AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes") if test "$have_fork_unsafe_semaphore" = yes; then AC_DEFINE(HAVE_FORK_UNSAFE_SEMAPHORE, 1, [Defined if we have fork-unsafe semaphore]) fi # Set some default values config_libs="-lnpth $LIBS" have_w32_system=no have_w32ce_system=no have_w64_system=no # Define OS macros case "${host}" in x86_64-*mingw32*) have_w64_system=yes ;; *-mingw32ce*) have_w32ce_system=yes ;; esac case "${host}" in *-mingw32ce*|*-mingw32*) have_w32_system=yes ;; *) ;; esac if test "$have_w32_system" = yes; then AC_DEFINE(HAVE_W32_SYSTEM,1, [Defined if we run on any kind of W32 API based system]) fi AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes) if test "$have_w64_system" = yes; then AC_DEFINE(HAVE_W64_SYSTEM,1, [Defined if we run on a 64 bit W32 API based system]) fi AM_CONDITIONAL(HAVE_W64_SYSTEM, test "$have_w64_system" = yes) # # Generate values for the DLL version info # if test "$have_w32_system" = yes; then BUILD_ISODATE=`date --iso-8601` changequote(,)dnl BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'` changequote([,])dnl BUILD_FILEVERSION="${BUILD_FILEVERSION}git_revision_dec" fi AC_SUBST(BUILD_ISODATE) AC_SUBST(BUILD_FILEVERSION) AC_ARG_ENABLE([build-timestamp], AC_HELP_STRING([--enable-build-timestamp], [set an explicit build timestamp for reproducibility. (default is the current time in ISO-8601 format)]), [if test "$enableval" = "yes"; then BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date` else BUILD_TIMESTAMP="$enableval" fi], [BUILD_TIMESTAMP=""]) AC_SUBST(BUILD_TIMESTAMP) AC_DEFINE_UNQUOTED(BUILD_TIMESTAMP, "$BUILD_TIMESTAMP", [The time this package was configured for a build]) # # Checks for header files. # # fixme: For what do we need the sys/socket test? AC_CHECK_HEADERS([sys/socket.h sys/select.h unistd.h sys/time.h time.h \ signal.h]) INSERT_SYS_SELECT_H= if test x"$ac_cv_header_sys_select_h" = xyes; then INSERT_SYS_SELECT_H="include " fi AC_SUBST(INSERT_SYS_SELECT_H) if test x"$ac_cv_header_sys_time_h" = xyes; then INSERT_SYS_TIME_H="include " fi AC_SUBST(INSERT_SYS_TIME_H) if test x"$ac_cv_header_time_h" = xyes; then INSERT_TIME_H="include " fi AC_SUBST(INSERT_TIME_H) if test x"$ac_cv_header_signal_h" = xyes; then INSERT_SIGNAL_H="include " fi AC_SUBST(INSERT_SIGNAL_H) # Some systems lack socklen_t - provide a replacement. gl_TYPE_SOCKLEN_T case "${host}" in *-*-mingw32*) # socklen_t may or may not be defined depending on what headers # are included. To be safe we use int as this is the actual type. INSERT_SOCKLEN_T="define _npth_socklen_t int" ;; *) if test ".$gl_cv_socklen_t_equiv" = "."; then INSERT_SOCKLEN_T="define _npth_socklen_t socklen_t" else INSERT_SOCKLEN_T="define _npth_socklen_t ${gl_cv_socklen_t_equiv}" fi esac AC_SUBST(INSERT_SOCKLEN_T) # # Checks for typedefs, structures, and compiler characteristics. # AC_TYPE_PID_T AC_TYPE_SIZE_T AC_TYPE_SSIZE_T # # Checks for libraries and functions. # # We test for pthread_detach because glibc 2.22 includes # pthread_create but not pthread_detach. if test "$have_w32_system" = no; then AC_SEARCH_LIBS([pthread_detach],[pthread]) case "x$ac_cv_search_pthread_detach" in xno) have_pthread=no ;; xnone\ required) have_pthread=yes ;; *) have_pthread=yes config_libs="$config_libs $ac_cv_search_pthread_detach" ;; esac if test "$have_pthread" != no; then AC_DEFINE(HAVE_PTHREAD,1,[Define if we have pthread.]) AC_CHECK_TYPE([pthread_rwlock_t]) AC_CHECK_FUNCS([pthread_tryjoin_np pthread_setname_np pthread_getname_np]) AC_CHECK_FUNCS([pthread_mutex_timedlock]) AC_CHECK_FUNCS([pthread_rwlock_rdlock pthread_rwlock_wrlock]) AC_CHECK_FUNCS([pthread_rwlock_timedrdlock pthread_rwlock_timedwrlock]) AC_CHECK_FUNCS([pthread_rwlock_tryrdlock pthread_rwlock_trywrlock]) AC_CHECK_FUNCS([pthread_atfork]) fi fi INSERT_NO_RWLOCK="undef _NPTH_NO_RWLOCK" if test x"$ac_cv_type_pthread_rwlock_t" = xno; then INSERT_NO_RWLOCK="define _NPTH_NO_RWLOCK 1" fi AC_SUBST(INSERT_NO_RWLOCK) +case "${host}" in + *-*-linux*|*-*-gnu*) + INSERT_EXPOSE_RWLOCK_API="define _NPTH_EXPOSE_RWLOCK_API (defined(__USE_UNIX98) || defined(__USE_XOPEN2K))" + ;; + *) + INSERT_EXPOSE_RWLOCK_API="define _NPTH_EXPOSE_RWLOCK_API 1" + ;; +esac +AC_SUBST(INSERT_EXPOSE_RWLOCK_API) + AC_CHECK_FUNCS([select pselect gettimeofday]) npth_LIBSOCKET config_libs="$config_libs $LIBSOCKET" # Save and restore LIBS so e.g., -lrt, isn't added to it. Otherwise, *all* # programs in the package would end up linked with that potentially-shared # library, inducing unnecessary run-time overhead. LIB_CLOCK_GETTIME= AC_SUBST([LIB_CLOCK_GETTIME]) gl_saved_libs=$LIBS AC_SEARCH_LIBS([clock_gettime], [rt posix4], [if test "$ac_cv_search_clock_gettime" != "none required"; then LIB_CLOCK_GETTIME=$ac_cv_search_clock_gettime config_libs="$config_libs $LIB_CLOCK_GETTIME" fi AC_DEFINE([HAVE_CLOCK_GETTIME],1, [Define to 1 if you have the `clock_gettime' function.]) ]) LIBS=$gl_saved_libs # # Set NETLIBS # if test "$have_w32ce_system" = yes; then NETLIBS="-lws2 $NETLIBS" elif test "$have_w32_system" = yes; then NETLIBS="-lws2_32 $NETLIBS" fi AC_SUBST(NETLIBS) # # Substitutions to set generated files in a Emacs buffer to read-only. # AC_SUBST(emacs_local_vars_begin, [['Local][ ][Variables:']]) AC_SUBST(emacs_local_vars_read_only, ['buffer-read-only: t']) AC_SUBST(emacs_local_vars_end, ['End:']) # # Substitution used for npth-config # NPTH_CONFIG_LIBS="$config_libs" NPTH_CONFIG_CFLAGS="" NPTH_CONFIG_HOST="$host" AC_SUBST(NPTH_CONFIG_API_VERSION) AC_SUBST(NPTH_CONFIG_LIBS) AC_SUBST(NPTH_CONFIG_CFLAGS) AC_SUBST(NPTH_CONFIG_HOST) # # Last check. # die=no if test "$have_w32_system" = no; then if test "$have_pthread" = "no"; then die=yes AC_MSG_NOTICE([[ *** *** You need Pthread to build this program. *** Normally, this library comes with your system. On Windows, you can use: *** http://sourceware.org/pthreads-win32/ ***]]) fi fi if test "$die" = "yes"; then AC_MSG_ERROR([[ *** *** Required libraries not found. Please consult the above messages *** and install them before running configure again. ***]]) fi # # Write output # AC_CONFIG_FILES([Makefile npth.pc src/npth.h src/Makefile w32/Makefile tests/Makefile]) AC_CONFIG_FILES(npth-config, chmod +x npth-config) AC_OUTPUT echo " $PACKAGE_NAME v$PACKAGE_VERSION prepared for make Revision: mym4_revision (mym4_revision_dec) Platform: $host " diff --git a/src/npth.h.in b/src/npth.h.in index 1901ded..ea325c1 100644 --- a/src/npth.h.in +++ b/src/npth.h.in @@ -1,453 +1,456 @@ /* npth.h - a lightweight implementation of pth over pthread. * Configured for: @NPTH_CONFIG_HOST@. * Copyright (C) 2011, 2012, 2015, 2017 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 the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ /* Changes to GNU Pth: * * Return value and arguments follow strictly the pthread format: * * - Return the error number instead of setting errno, * * - have timedlock function instead of extra event argument, * * - have trylock function instead of extra event argument. Can't mix * timed and try. * * - No _new functions. Use _init functions instead. * * - Attributes are set by specific instead of generic getter/setter * functions. * * - Offers replacement functions for sendmsg and recvmsg. */ #ifndef _NPTH_H #define _NPTH_H #include #include #@INSERT_SYS_TIME_H@ #@INSERT_TIME_H@ #include #@INSERT_SOCKLEN_T@ #@INSERT_SYS_SELECT_H@ #@INSERT_SIGNAL_H@ #include #@INSERT_NO_RWLOCK@ #ifdef __ANDROID__ #include #if __ANDROID_API__ < 9 /* Android 8 and earlier are missing rwlocks. We punt to mutexes in that case. */ #define _NPTH_NO_RWLOCK 1 #endif #endif +#@INSERT_EXPOSE_RWLOCK_API@ #ifdef __cplusplus extern "C" { #if 0 /* (Keep Emacsens' auto-indent happy.) */ } #endif #endif /* Global Library Management */ #define npth_t pthread_t /* Initialize the library and convert current thread to main thread. Must be first npth function called in a process. Returns error number on error and 0 on success. */ int npth_init(void); /* Not needed. */ /* pth_kill, pth_ctrl, pth_version */ /* Thread Attribute Handling */ /* Can't do that. */ /* pth_attr_of */ #define npth_attr_t pthread_attr_t #define npth_attr_init pthread_attr_init #define npth_attr_destroy pthread_attr_destroy #define NPTH_CREATE_JOINABLE PTHREAD_CREATE_JOINABLE #define NPTH_CREATE_DETACHED PTHREAD_CREATE_DETACHED #define npth_attr_getdetachstate pthread_attr_getdetachstate #define npth_attr_setdetachstate pthread_attr_setdetachstate int npth_getname_np (npth_t target_thread, char *buf, size_t buflen); int npth_setname_np (npth_t target_thread, const char *name); /* Thread Control */ int npth_create(npth_t *thread, const npth_attr_t *attr, void *(*start_routine) (void *), void *arg); /* The Pth version of pth_once supports passing an argument, the pthread version does not. We would have to reimplement the whole feature with a global table. Not needed. */ /* pth_once */ #define npth_self pthread_self /* No can do! */ /* pth_suspend, pth_resume */ /* Yield is considered harmful and should never be used in high-level applications. Use a condition instead to wait for a specific event to happen, or, as a last resort, use npth_usleep to back off a hard busy wait. */ /* pth_yield */ /* Not needed. */ /* pth_nap */ /* pth_wait, pth_cancel, pth_abort, pth_raise */ int npth_join(npth_t thread, void **retval); #define npth_detach pthread_detach void npth_exit(void *retval); /* Utilities */ /* pth_fdmode, pth_time, pth_timeout, pth_sfiodisc */ /* Cancellation Management */ /* Not needed. */ /* pth_cancel_state. npth_cancel_point */ /* Event Handling */ /* No equivalent in pthread. */ /* pth_event, pth_event_typeof, pth_event_extract, pth_event_concat, pth_event_isolate, pth_event_walk, pth_event_status, pth_event_free */ /* Key-Based Storage */ #define npth_key_t pthread_key_t #define npth_key_create pthread_key_create #define npth_key_delete pthread_key_delete #define npth_setspecific pthread_setspecific #define npth_getspecific pthread_getspecific /* Message Port Communication */ /* No equivalent in pthread. */ /* pth_msgport_create, pth_msgport_destroy, pth_msgport_find, pth_msgport_pending, pth_msgport_put, pth_msgport_get, pth_msgport_reply. */ /* Thread Cleanups */ /* Not needed. */ /* pth_cleanup_push, pth_cleanup_pop */ /* Process Forking */ /* POSIX only supports a global atfork handler. So, to implement per-thread handlers like in Pth, we would need to keep the data in thread local storage. But, neither pthread_self nor pthread_getspecific are standardized as async-signal-safe (what a joke!), and __thread is an ELF extension. Still, using pthread_self and pthread_getspecific is probably portable enough to implement the atfork handlers, if required. pth_fork is only required because fork() is not pth aware. fork() is pthread aware though, and already only creates a single thread in the child process. */ /* pth_atfork_push, pth_atfork_pop, pth_fork */ /* Synchronization */ #define npth_mutexattr_t pthread_mutexattr_t #define npth_mutexattr_init pthread_mutexattr_init #define npth_mutexattr_destroy pthread_mutexattr_destroy #define npth_mutexattr_settype pthread_mutexattr_settype #define npth_mutexattr_gettype pthread_mutexattr_gettype #define NPTH_MUTEX_NORMAL PTHREAD_MUTEX_NORMAL #define NPTH_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE #define NPTH_MUTEX_ERRORCHECK PTHREAD_MUTEX_ERRORCHECK #define NPTH_MUTEX_DEFAULT PTHREAD_MUTEX_DEFAULT #define npth_mutex_t pthread_mutex_t #define NPTH_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER #define NPTH_RECURSIVE_MUTEX_INITIALIZER_NP \ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP #define NPTH_ERRORCHECK_MUTEX_INITIALIZER_NP \ PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP #define npth_mutex_init pthread_mutex_init #define npth_mutex_destroy pthread_mutex_destroy #define npth_mutex_trylock pthread_mutex_trylock int npth_mutex_lock(npth_mutex_t *mutex); int npth_mutex_timedlock(npth_mutex_t *mutex, const struct timespec *abstime); #define npth_mutex_unlock pthread_mutex_unlock +#if _NPTH_EXPOSE_RWLOCK_API #ifdef _NPTH_NO_RWLOCK typedef int npth_rwlockattr_t; #define npth_rwlockattr_init(attr) #define npth_rwlockattr_destroy(attr) #define npth_rwlockattr_gettype_np(attr,kind) #define npth_rwlockattr_settype_np(attr,kind) #define NPTH_RWLOCK_PREFER_READER_NP 0 #define NPTH_RWLOCK_PREFER_WRITER_NP 0 #define NPTH_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP 0 #define NPTH_RWLOCK_DEFAULT_NP 0 #define NPTH_RWLOCK_INITIALIZER NPTH_MUTEX_INITIALIZER #define NPTH_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP NPTH_MUTEX_INITIALIZER typedef npth_mutex_t npth_rwlock_t; #define npth_rwlock_init(rwlock,attr) npth_mutex_init(rwlock,0) #define npth_rwlock_destroy npth_mutex_destroy #define npth_rwlock_tryrdlock npth_mutex_trylock #define npth_rwlock_rdlock npth_mutex_lock #define npth_rwlock_trywrlock npth_mutex_trylock #define npth_rwlock_timedrdlock npth_mutex_timedlock #define npth_rwlock_wrlock npth_mutex_lock #define npth_rwlock_rdlock npth_mutex_lock #define npth_rwlock_timedwrlock npth_mutex_timedlock #define npth_rwlock_unlock npth_mutex_unlock #else /* _NPTH_NO_RWLOCK */ #define npth_rwlockattr_t pthread_rwlockattr_t #define npth_rwlockattr_init pthread_rwlockattr_init #define npth_rwlockattr_destroy pthread_rwlockattr_destroy #define npth_rwlockattr_gettype_np pthread_rwlockattr_gettype_np #define npth_rwlockattr_settype_np pthread_rwlockattr_settype_np #define NPTH_RWLOCK_PREFER_READER_NP PTHREAD_RWLOCK_PREFER_READER_NP /* Note: The prefer-writer setting is ineffective and the same as prefer-reader. This is because reader locks are specified to be recursive, but for efficiency reasons we do not keep track of which threads already hold a reader lock. For this reason, we can not prefer some reader locks over others, and thus a recursive reader lock could be stalled by a pending writer, leading to a dead lock. */ #define NPTH_RWLOCK_PREFER_WRITER_NP PTHREAD_RWLOCK_PREFER_WRITER_NP /* The non-recursive choise is a promise by the application that it does not lock the rwlock for reading recursively. In this setting, writers are preferred, but note that recursive reader locking is prone to deadlocks in that case. */ #define NPTH_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP \ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP #define NPTH_RWLOCK_DEFAULT_NP PTHREAD_RWLOCK_DEFAULT_NP #define NPTH_RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER #define NPTH_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \ PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP typedef pthread_rwlock_t npth_rwlock_t; #define npth_rwlock_init pthread_rwlock_init #define npth_rwlock_destroy pthread_rwlock_destroy #define npth_rwlock_tryrdlock pthread_rwlock_tryrdlock int npth_rwlock_rdlock (npth_rwlock_t *rwlock); int npth_rwlock_timedrdlock (npth_rwlock_t *rwlock, const struct timespec *abstime); #define npth_rwlock_trywrlock pthread_rwlock_trywrlock int npth_rwlock_wrlock (npth_rwlock_t *rwlock); int npth_rwlock_timedwrlock (npth_rwlock_t *rwlock, const struct timespec *abstime); #define npth_rwlock_unlock pthread_rwlock_unlock #endif /* !_NPTH_NO_RWLOCK */ +#endif typedef pthread_cond_t npth_cond_t; #define NPTH_COND_INITIALIZER PTHREAD_COND_INITIALIZER /* For now, we don't support any cond attributes. */ #define npth_cond_init pthread_cond_init #define npth_cond_broadcast pthread_cond_broadcast #define npth_cond_signal pthread_cond_signal #define npth_cond_destroy pthread_cond_destroy 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); /* Not needed. */ /* pth_barrier_t, pth_barrier_init, pth_barrier_reach */ /* User-Space Context */ /* Can not be implemented. */ /* pth_uctx_create, pth_uctx_make, pth_uctx_switch, pth_uctx_destroy */ /* Generalized POSIX Replacement API */ /* In general, we can not support these easily. */ /* pth_sigwait_ev, pth_accept_ev, pth_connect_ev, pth_select_ev, pth_poll_ev, pth_read_ev, pth_readv_ev, pth_write_ev, pth_writev_ev, pth_recv_ev, pth_recvfrom_ev, pth_send_ev, pth_sendto_ev */ /* Standard POSIX Replacement API */ /* We will provide a more specific way to handle signals. */ /* pth_sigmask, pth_sigwait */ /* Not needed. */ /* pth_nanosleep, pth_system, pth_readv, pth_writev, pth_poll, pth_recv, pth_send, pth_recvfrom, pth_sendto */ 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); #define npth_sigmask pthread_sigmask int npth_sigwait(const sigset_t *set, int *sig); int npth_connect(int s, const struct sockaddr *addr, _npth_socklen_t addrlen); int npth_accept(int s, struct sockaddr *addr, _npth_socklen_t *addrlen); int npth_select(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout); int npth_pselect(int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, const struct timespec *timeout, const sigset_t *sigmask); 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); /* For anything not covered here, you can enter/leave manually at your own risk. */ void npth_unprotect (void); void npth_protect (void); /* If you run into problems with the above calls, this function can be * used to examine in which state nPth is. */ int npth_is_protected (void); /* Because the timed functions work on timespec, we provide a clock interface for convenience and portability. */ 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) /* This is a support interface to make it easier to handle signals. * * The interfaces here support one (and only one) thread (here called * "main thread") in the application to monitor several signals while * selecting on filedescriptors. * * First, the main thread should call npth_sigev_init. This * initializes some global data structures used to record interesting * and pending signals. * * Then, the main thread should call npth_sigev_add for every signal * it is interested in observing, and finally npth_sigev_fini. This * will block the signal in the main threads sigmask. Note that these * signals should also be blocked in all other threads. Since they * are blocked in the main thread after calling npth_sigev_add, it is * recommended to call npth_sigev_add in the main thread before * creating any threads. * * The function npth_sigev_sigmask is a convenient function that * returns the sigmask of the thread at time of npth_sigev_init, but * with all registered signals unblocked. It is recommended to do all * other changes to the main thread's sigmask before calling * npth_sigev_init, so that the return value of npth_sigev_sigmask can * be used in the npth_pselect invocation. * * In any case, the main thread should invoke npth_pselect with a * sigmask that has all signals that should be monitored unblocked. * * After npth_pselect returns, npth_sigev_get_pending can be called in * a loop until it returns 0 to iterate over the list of pending * signals. Each time a signal is returned by that function, its * status is reset to non-pending. */ /* Start setting up signal event handling. */ void npth_sigev_init (void); /* Add signal SIGNUM to the list of watched signals. */ void npth_sigev_add (int signum); /* Finish the list of watched signals. This starts to block them, too. */ void npth_sigev_fini (void); /* Get the sigmask as needed for pselect. */ sigset_t *npth_sigev_sigmask (void); /* Return the next signal event that occured. Returns if none are left, 1 on success. */ int npth_sigev_get_pending (int *r_signum); #if 0 /* (Keep Emacsens' auto-indent happy.) */ { #endif #ifdef __cplusplus } #endif #endif /*_NPTH_H*/ /* @emacs_local_vars_begin@ @emacs_local_vars_read_only@ @emacs_local_vars_end@ */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 8092a3c..8dc681d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,38 +1,36 @@ # Makefile.am - Makefile for NPTH tests. # Copyright (C) 2011 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 the GNU Lesser General Public License as # published by the Free Software Foundation; either version 2.1 of the # License, or (at your option) any later version. # # 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 Lesser General # Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this program; if not, see . ## Process this file with automake to produce Makefile.in TESTS = t-mutex t-thread -# We explicitly require POSIX.1-2001 so that pthread_rwlock_t is -# available when build with c99. if HAVE_W32_SYSTEM AM_CPPFLAGS = -I$(top_srcdir)/w32 AM_LDFLAGS = LDADD = ../w32/libnpth.la $(LIB_CLOCK_GETTIME) else -AM_CPPFLAGS = -I../src -D_POSIX_C_SOURCE=200112L +AM_CPPFLAGS = -I../src AM_LDFLAGS = LDADD = ../src/libnpth.la $(LIBSOCKET) $(LIB_CLOCK_GETTIME) TESTS += t-fork endif noinst_HEADERS = t-support.h noinst_PROGRAMS = $(TESTS)