diff options
Diffstat (limited to '')
-rw-r--r-- | scd/Makefile.am | 6 | ||||
-rw-r--r-- | scd/apdu.c | 73 | ||||
-rw-r--r-- | scd/app.c | 49 | ||||
-rw-r--r-- | scd/ccid-driver.c | 8 | ||||
-rw-r--r-- | scd/command.c | 40 | ||||
-rw-r--r-- | scd/scdaemon.c | 224 |
6 files changed, 180 insertions, 220 deletions
diff --git a/scd/Makefile.am b/scd/Makefile.am index b42e53dff..09aea0e84 100644 --- a/scd/Makefile.am +++ b/scd/Makefile.am @@ -29,7 +29,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common include $(top_srcdir)/am/cmacros.am AM_CFLAGS = $(LIBGCRYPT_CFLAGS) \ - $(KSBA_CFLAGS) $(LIBASSUAN_CFLAGS) $(PTH_CFLAGS) + $(KSBA_CFLAGS) $(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS) card_apps = app-openpgp.c app-nks.c app-dinsig.c app-p15.c app-geldkarte.c @@ -45,7 +45,7 @@ scdaemon_SOURCES = \ scdaemon_LDADD = $(libcommonpth) ../gl/libgnu.a \ - $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(PTH_LIBS) \ + $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \ $(LIBUSB_LIBS) $(GPG_ERROR_LIBS) \ $(LIBINTL) $(DL_LIBS) $(NETLIBS) $(LIBICONV) @@ -63,7 +63,7 @@ scdaemon_LDADD = $(libcommonpth) ../gl/libgnu.a \ #sc_copykeys_LDADD = \ # ../jnlib/libjnlib.a ../common/libcommon.a \ # ../common/libsimple-pwquery.a \ -# $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(PTH_LIBS) \ +# $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \ # $(LIBUSB_LIBS) \ # -lgpg-error @LIBINTL@ @DL_LIBS@ # diff --git a/scd/apdu.c b/scd/apdu.c index 70c28cd30..064f0d636 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -19,7 +19,7 @@ */ /* NOTE: This module is also used by other software, thus the use of - the macro USE_GNU_PTH is mandatory. For GnuPG this macro is + the macro USE_NPTH is mandatory. For GnuPG this macro is guaranteed to be defined true. */ #include <config.h> @@ -29,10 +29,10 @@ #include <string.h> #include <assert.h> #include <signal.h> -#ifdef USE_GNU_PTH +#ifdef USE_NPTH # include <unistd.h> # include <fcntl.h> -# include <pth.h> +# include <npth.h> #endif @@ -67,7 +67,7 @@ /* Due to conflicting use of threading libraries we usually can't link against libpcsclite. Instead we use a wrapper program. */ -#ifdef USE_GNU_PTH +#ifdef USE_NPTH #if !defined(HAVE_W32_SYSTEM) && !defined(__CYGWIN__) #define NEED_PCSC_WRAPPER 1 #endif @@ -144,9 +144,9 @@ struct reader_table_s { not yet been read; i.e. the card is not ready for use. */ unsigned int change_counter; -#ifdef USE_GNU_PTH +#ifdef USE_NPTH int lock_initialized; - pth_mutex_t lock; + npth_mutex_t lock; #endif }; typedef struct reader_table_s *reader_table_t; @@ -352,6 +352,7 @@ static int new_reader_slot (void) { int i, reader = -1; + int err; for (i=0; i < MAX_READER; i++) { @@ -363,17 +364,18 @@ new_reader_slot (void) log_error ("new_reader_slot: out of slots\n"); return -1; } -#ifdef USE_GNU_PTH +#ifdef USE_NPTH if (!reader_table[reader].lock_initialized) { - if (!pth_mutex_init (&reader_table[reader].lock)) + err = npth_mutex_init (&reader_table[reader].lock, NULL); + if (err) { - log_error ("error initializing mutex: %s\n", strerror (errno)); + log_error ("error initializing mutex: %s\n", strerror (err)); return -1; } reader_table[reader].lock_initialized = 1; } -#endif /*USE_GNU_PTH*/ +#endif /*USE_NPTH*/ reader_table[reader].connect_card = NULL; reader_table[reader].disconnect_card = NULL; reader_table[reader].close_reader = NULL; @@ -698,8 +700,8 @@ writen (int fd, const void *buf, size_t nbytes) while (nleft > 0) { -#ifdef USE_GNU_PTH - nwritten = pth_write (fd, buf, nleft); +#ifdef USE_NPTH + nwritten = npth_write (fd, buf, nleft); #else nwritten = write (fd, buf, nleft); #endif @@ -724,11 +726,11 @@ readn (int fd, void *buf, size_t buflen, size_t *nread) while (nleft > 0) { -#ifdef USE_GNU_PTH +#ifdef USE_NPTH # ifdef HAVE_W32_SYSTEM -# error Cannot use pth_read here because it expects a system HANDLE. +# error Cannot use npth_read here because it expects a system HANDLE. # endif - n = pth_read (fd, buf, nleft); + n = npth_read (fd, buf, nleft); #else n = read (fd, buf, nleft); #endif @@ -1874,8 +1876,8 @@ open_pcsc_reader_wrapped (const char *portstr) slotp->pcsc.rsp_fd = rp[0]; /* Wait for the intermediate child to terminate. */ -#ifdef USE_GNU_PTH -#define WAIT pth_waitpid +#ifdef USE_NPTH +#define WAIT npth_waitpid #else #define WAIT waitpid #endif @@ -2117,6 +2119,8 @@ pcsc_keypad_verify (int slot, int class, int ins, int p0, int p1, pin_verify, len, result, &resultlen); xfree (pin_verify); if (sw || resultlen < 2) + return sw? sw : SW_HOST_INCOMPLETE_CARD_RESPONSE; + sw = (result[resultlen-2] << 8) | result[resultlen-1]; { log_error ("control_pcsc failed: %d\n", sw); return sw? sw: SW_HOST_INCOMPLETE_CARD_RESPONSE; @@ -2749,38 +2753,47 @@ open_rapdu_reader (int portno, static int lock_slot (int slot) { -#ifdef USE_GNU_PTH - if (!pth_mutex_acquire (&reader_table[slot].lock, 0, NULL)) +#ifdef USE_NPTH + int err; + + err = npth_mutex_lock (&reader_table[slot].lock); + if (err) { - log_error ("failed to acquire apdu lock: %s\n", strerror (errno)); + log_error ("failed to acquire apdu lock: %s\n", strerror (err)); return SW_HOST_LOCKING_FAILED; } -#endif /*USE_GNU_PTH*/ +#endif /*USE_NPTH*/ return 0; } static int trylock_slot (int slot) { -#ifdef USE_GNU_PTH - if (!pth_mutex_acquire (&reader_table[slot].lock, TRUE, NULL)) +#ifdef USE_NPTH + int err; + + err = npth_mutex_trylock (&reader_table[slot].lock); + if (err == EBUSY) + return SW_HOST_BUSY; + else if (err) { - if (errno == EBUSY) - return SW_HOST_BUSY; - log_error ("failed to acquire apdu lock: %s\n", strerror (errno)); + log_error ("failed to acquire apdu lock: %s\n", strerror (err)); return SW_HOST_LOCKING_FAILED; } -#endif /*USE_GNU_PTH*/ +#endif /*USE_NPTH*/ return 0; } static void unlock_slot (int slot) { -#ifdef USE_GNU_PTH - if (!pth_mutex_release (&reader_table[slot].lock)) +#ifdef USE_NPTH + int err; + + err = npth_mutex_unlock (&reader_table[slot].lock); + if (err) log_error ("failed to release apdu lock: %s\n", strerror (errno)); -#endif /*USE_GNU_PTH*/ +#endif /*USE_NPTH*/ } @@ -22,7 +22,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <pth.h> +#include <npth.h> #include "scdaemon.h" #include "app-common.h" @@ -37,7 +37,7 @@ static struct { int initialized; - pth_mutex_t lock; + npth_mutex_t lock; app_t app; /* Application context in use or NULL. */ app_t last_app; /* Last application object used as this slot or NULL. */ } lock_table[10]; @@ -72,30 +72,30 @@ print_progress_line (void *opaque, const char *what, int pc, int cur, int tot) static gpg_error_t lock_reader (int slot, ctrl_t ctrl) { - gpg_error_t err; + int res; if (slot < 0 || slot >= DIM (lock_table)) return gpg_error (slot<0? GPG_ERR_INV_VALUE : GPG_ERR_RESOURCE_LIMIT); if (!lock_table[slot].initialized) { - if (!pth_mutex_init (&lock_table[slot].lock)) + res = npth_mutex_init (&lock_table[slot].lock, NULL); + if (res) { - err = gpg_error_from_syserror (); - log_error ("error initializing mutex: %s\n", strerror (errno)); - return err; + log_error ("error initializing mutex: %s\n", strerror (res)); + return gpg_error_from_errno (res); } lock_table[slot].initialized = 1; lock_table[slot].app = NULL; lock_table[slot].last_app = NULL; } - if (!pth_mutex_acquire (&lock_table[slot].lock, 0, NULL)) + res = npth_mutex_lock (&lock_table[slot].lock); + if (res) { - err = gpg_error_from_syserror (); log_error ("failed to acquire APP lock for slot %d: %s\n", - slot, strerror (errno)); - return err; + slot, strerror (res)); + return gpg_error_from_errno (res); } apdu_set_progress_cb (slot, print_progress_line, ctrl); @@ -107,32 +107,18 @@ lock_reader (int slot, ctrl_t ctrl) static void unlock_reader (int slot) { + int res; + if (slot < 0 || slot >= DIM (lock_table) || !lock_table[slot].initialized) log_bug ("unlock_reader called for invalid slot %d\n", slot); apdu_set_progress_cb (slot, NULL, NULL); - if (!pth_mutex_release (&lock_table[slot].lock)) + res = npth_mutex_unlock (&lock_table[slot].lock); + if (res) log_error ("failed to release APP lock for slot %d: %s\n", - slot, strerror (errno)); -} - - -static void -dump_mutex_state (pth_mutex_t *m) -{ -#ifdef _W32_PTH_H - (void)m; - log_printf ("unknown under W32"); -#else - if (!(m->mx_state & PTH_MUTEX_INITIALIZED)) - log_printf ("not_initialized"); - else if (!(m->mx_state & PTH_MUTEX_LOCKED)) - log_printf ("not_locked"); - else - log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count); -#endif + slot, strerror (res)); } @@ -146,8 +132,7 @@ app_dump_state (void) for (slot=0; slot < DIM (lock_table); slot++) if (lock_table[slot].initialized) { - log_info ("app_dump_state: slot=%d lock=", slot); - dump_mutex_state (&lock_table[slot].lock); + log_info ("app_dump_state: slot=%d", slot); if (lock_table[slot].app) { log_printf (" app=%p", lock_table[slot].app); diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 8e2af6541..8b2ee8f24 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -85,9 +85,9 @@ #include <sys/stat.h> #include <fcntl.h> #include <time.h> -#ifdef HAVE_PTH -# include <pth.h> -#endif /*HAVE_PTH*/ +#ifdef HAVE_NPTH +# include <npth.h> +#endif /*HAVE_NPTH*/ #include <usb.h> @@ -328,7 +328,7 @@ set_msg_len (unsigned char *msg, unsigned int length) static void my_sleep (int seconds) { -#ifdef HAVE_PTH +#ifdef HAVE_NPTH /* With Pth we also call the standard sleep(0) so that the process may give up its timeslot. */ if (!seconds) diff --git a/scd/command.c b/scd/command.c index 88f8ec2c9..4c3646c99 100644 --- a/scd/command.c +++ b/scd/command.c @@ -26,8 +26,8 @@ #include <ctype.h> #include <unistd.h> #include <signal.h> -#ifdef USE_GNU_PTH -# include <pth.h> +#ifdef USE_NPTH +# include <npth.h> #endif #include "scdaemon.h" @@ -156,7 +156,7 @@ static struct server_local_s *locked_session; /* While doing a reset we need to make sure that the ticker does not call scd_update_reader_status_file while we are using it. */ -static pth_mutex_t status_file_update_lock; +static npth_mutex_t status_file_update_lock; /*-- Local prototypes --*/ @@ -173,10 +173,12 @@ void initialize_module_command (void) { static int initialized; + int err; if (!initialized) { - if (pth_mutex_init (&status_file_update_lock)) + err = npth_mutex_init (&status_file_update_lock, NULL); + if (!err) initialized = 1; } } @@ -304,6 +306,7 @@ do_reset (ctrl_t ctrl, int send_reset) { int vrdr = ctrl->server_local->vreader_idx; int slot; + int err; if (!(vrdr == -1 || (vrdr >= 0 && vrdr < DIM(vreader_table)))) BUG (); @@ -360,7 +363,8 @@ do_reset (ctrl_t ctrl, int send_reset) try to update the file. Calling update_reader_status_file is required to get hold of the new status of the card in the vreader table. */ - if (!pth_mutex_acquire (&status_file_update_lock, 0, NULL)) + err = npth_mutex_lock (&status_file_update_lock); + if (err) { log_error ("failed to acquire status_file_update lock\n"); ctrl->server_local->vreader_idx = -1; @@ -368,8 +372,10 @@ do_reset (ctrl_t ctrl, int send_reset) } update_reader_status_file (0); /* Update slot status table. */ update_card_removed (vrdr, 0); /* Clear card_removed flag. */ - if (!pth_mutex_release (&status_file_update_lock)) - log_error ("failed to release status_file_update lock\n"); + err = npth_mutex_unlock (&status_file_update_lock); + if (err) + log_error ("failed to release status_file_update lock: %s\n", + strerror (err)); /* Do this last, so that the update_card_removed above does its job. */ ctrl->server_local->vreader_idx = -1; @@ -1597,18 +1603,18 @@ cmd_lock (assuan_context_t ctx, char *line) else locked_session = ctrl->server_local; -#ifdef USE_GNU_PTH +#ifdef USE_NPTH if (rc && has_option (line, "--wait")) { rc = 0; - pth_sleep (1); /* Better implement an event mechanism. However, - for card operations this should be - sufficient. */ + npth_sleep (1); /* Better implement an event mechanism. However, + for card operations this should be + sufficient. */ /* FIXME: Need to check that the connection is still alive. This can be done by issuing status messages. */ goto retry; } -#endif /*USE_GNU_PTH*/ +#endif /*USE_NPTH*/ if (rc) log_error ("cmd_lock failed: %s\n", gpg_strerror (rc)); @@ -2395,9 +2401,13 @@ update_reader_status_file (int set_card_removed_flag) void scd_update_reader_status_file (void) { - if (!pth_mutex_acquire (&status_file_update_lock, 1, NULL)) + int err; + err = npth_mutex_lock (&status_file_update_lock); + if (err) return; /* locked - give up. */ update_reader_status_file (1); - if (!pth_mutex_release (&status_file_update_lock)) - log_error ("failed to release status_file_update lock\n"); + err = npth_mutex_unlock (&status_file_update_lock); + if (err) + log_error ("failed to release status_file_update lock: %s\n", + strerror (err)); } diff --git a/scd/scdaemon.c b/scd/scdaemon.c index e26beba13..ad5f691bb 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -35,7 +35,7 @@ #endif /*HAVE_W32_SYSTEM*/ #include <unistd.h> #include <signal.h> -#include <pth.h> +#include <npth.h> #define JNLIB_NEED_LOG_LOGV #define JNLIB_NEED_AFLOCAL @@ -169,7 +169,7 @@ static ARGPARSE_OPTS opts[] = { easy way to block on card status changes it is the best we can do. For PC/SC we could in theory use an extra thread to wait for status changes but that requires a native thread because there is no way - to make the underlying PC/SC card change function block using a Pth + to make the underlying PC/SC card change function block using a Npth mechanism. Given that a native thread could only be used under W32 we don't do that at all. */ #define TIMERTICK_INTERVAL_SEC (0) @@ -206,20 +206,9 @@ static void *start_connection_thread (void *arg); static void handle_connections (int listen_fd); /* Pth wrapper function definitions. */ -ASSUAN_SYSTEM_PTH_IMPL; +ASSUAN_SYSTEM_NPTH_IMPL; -#if defined(GCRY_THREAD_OPTION_VERSION) && (GCRY_THREAD_OPTION_VERSION == 0) -#define USE_GCRY_THREAD_CBS 1 -#endif - -#ifdef USE_GCRY_THREAD_CBS -GCRY_THREAD_OPTION_PTH_IMPL; - -static int fixed_gcry_pth_init (void) -{ - return pth_self ()? 0 : (pth_init () == FALSE) ? errno : 0; -} -#endif +static int active_connections; static char * @@ -280,16 +269,16 @@ my_strusage (int level) static int tid_log_callback (unsigned long *rvalue) { -#ifdef PTH_HAVE_PTH_THREAD_ID - *rvalue = pth_thread_id (); -#else - *rvalue = (unsigned long)pth_self (); -#endif - return 2; /* Use use hex representation. */ -} - + int len = sizeof (*rvalue); + npth_t thread; + thread = npth_self (); + if (sizeof (thread) < len) + len = sizeof (thread); + memcpy (rvalue, &thread, len); + return 2; /* Use use hex representation. */ +} /* Setup the debugging. With a LEVEL of NULL only the active debug @@ -382,9 +371,6 @@ main (int argc, char **argv ) { ARGPARSE_ARGS pargs; int orig_argc; -#ifdef USE_GCRY_THREAD_CBS - gpg_error_t err; -#endif char **orig_argv; FILE *configfp = NULL; char *configname = NULL; @@ -406,6 +392,8 @@ main (int argc, char **argv ) int allow_coredump = 0; int standard_socket = 0; struct assuan_malloc_hooks malloc_hooks; + int res; + npth_t pipecon_handler; set_strusage (my_strusage); gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); @@ -418,18 +406,7 @@ main (int argc, char **argv ) i18n_init (); init_common_subsystems (&argc, &argv); - - /* Libgcrypt requires us to register the threading model first. - Note that this will also do the pth_init. */ -#ifdef USE_GCRY_THREAD_CBS - gcry_threads_pth.init = fixed_gcry_pth_init; - err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth); - if (err) - { - log_fatal ("can't register GNU Pth with Libgcrypt: %s\n", - gpg_strerror (err)); - } -#endif + npth_init (); /* Check that the libraries are suitable. Do it here because the option parsing may need services of the library */ @@ -446,7 +423,7 @@ main (int argc, char **argv ) malloc_hooks.free = gcry_free; assuan_set_malloc_hooks (&malloc_hooks); assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); - assuan_set_system_hooks (ASSUAN_SYSTEM_PTH); + assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH); assuan_sock_init (); setup_libassuan_logging (&opt.debug); @@ -712,7 +689,7 @@ main (int argc, char **argv ) { /* This is the simple pipe based server */ ctrl_t ctrl; - pth_attr_t tattr; + npth_attr_t tattr; int fd = -1; #ifndef HAVE_W32_SYSTEM @@ -751,10 +728,14 @@ main (int argc, char **argv ) socket_name, &socket_nonce)); } - tattr = pth_attr_new(); - pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0); - pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 512*1024); - pth_attr_set (tattr, PTH_ATTR_NAME, "pipe-connection"); + res = npth_attr_init (&tattr); + if (res) + { + log_error ("error allocating thread attributes: %s\n", + strerror (res)); + scd_exit (2); + } + npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED); ctrl = xtrycalloc (1, sizeof *ctrl); if ( !ctrl ) @@ -764,13 +745,16 @@ main (int argc, char **argv ) scd_exit (2); } ctrl->thread_startup.fd = GNUPG_INVALID_FD; - if ( !pth_spawn (tattr, start_connection_thread, ctrl) ) + res = npth_create (&pipecon_handler, &tattr, start_connection_thread, ctrl); + if (res) { log_error ("error spawning pipe connection handler: %s\n", - strerror (errno) ); + strerror (res) ); xfree (ctrl); scd_exit (2); } + npth_setname_np (pipecon_handler, "pipe-connection"); + npth_attr_destroy (&tattr); /* We run handle_connection to wait for the shutdown signal and to run the ticker stuff. */ @@ -981,8 +965,8 @@ handle_signal (int signo) if (!shutdown_pending) log_info ("SIGTERM received - shutting down ...\n"); else - log_info ("SIGTERM received - still %ld running threads\n", - pth_ctrl( PTH_CTRL_GETTHREADS )); + log_info ("SIGTERM received - still %i running threads\n", + active_connections); shutdown_pending++; if (shutdown_pending > 2) { @@ -1176,9 +1160,7 @@ start_connection_thread (void *arg) static void handle_connections (int listen_fd) { - pth_attr_t tattr; - pth_event_t ev, time_ev; - sigset_t sigs; + npth_attr_t tattr; int signo; struct sockaddr_un paddr; socklen_t plen; @@ -1186,25 +1168,27 @@ handle_connections (int listen_fd) int ret; int fd; int nfd; + struct timespec abstime; + struct timespec curtime; + struct timespec timeout; + int saved_errno; - tattr = pth_attr_new(); - pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0); - pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 512*1024); - -#ifndef HAVE_W32_SYSTEM /* fixme */ - sigemptyset (&sigs ); - sigaddset (&sigs, SIGHUP); - sigaddset (&sigs, SIGUSR1); - sigaddset (&sigs, SIGUSR2); - sigaddset (&sigs, SIGINT); - sigaddset (&sigs, SIGTERM); - pth_sigmask (SIG_UNBLOCK, &sigs, NULL); - ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); + ret = npth_attr_init(&tattr); + /* FIXME: Check error. */ + npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED); + +#ifndef HAVE_W32_SYSTEM + npth_sigev_init (); + npth_sigev_add (SIGHUP); + npth_sigev_add (SIGUSR1); + npth_sigev_add (SIGUSR2); + npth_sigev_add (SIGINT); + npth_sigev_add (SIGTERM); + npth_sigev_fini (); #else sigs = 0; ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); #endif - time_ev = NULL; FD_ZERO (&fdset); nfd = 0; @@ -1214,13 +1198,17 @@ handle_connections (int listen_fd) nfd = listen_fd; } + npth_clock_gettime (&curtime); + timeout.tv_sec = TIMERTICK_INTERVAL_SEC; + timeout.tv_nsec = TIMERTICK_INTERVAL_USEC * 1000; + npth_timeradd (&curtime, &timeout, &abstime); + /* We only require abstime here. The others will be reused. */ + for (;;) { - sigset_t oldsigs; - if (shutdown_pending) { - if (pth_ctrl (PTH_CTRL_GETTHREADS) == 1) + if (active_connections == 0) break; /* ready */ /* Do not accept anymore connections but wait for existing @@ -1231,80 +1219,47 @@ handle_connections (int listen_fd) listen_fd = -1; } - /* Create a timeout event if needed. Round it up to the next - microsecond interval to help with power saving. */ - if (!time_ev) - { - pth_time_t nexttick = pth_timeout (TIMERTICK_INTERVAL_SEC, - TIMERTICK_INTERVAL_USEC/2); - if ((nexttick.tv_usec % (TIMERTICK_INTERVAL_USEC/2)) > 10) - { - nexttick.tv_usec = ((nexttick.tv_usec - /(TIMERTICK_INTERVAL_USEC/2)) - + 1) * (TIMERTICK_INTERVAL_USEC/2); - if (nexttick.tv_usec >= 1000000) - { - nexttick.tv_sec++; - nexttick.tv_usec = 0; - } - } - time_ev = pth_event (PTH_EVENT_TIME, nexttick); - } + npth_clock_gettime (&curtime); + if (!(npth_timercmp (&curtime, &abstime, <))) + { + /* Timeout. */ + handle_tick (); + timeout.tv_sec = TIMERTICK_INTERVAL_SEC; + timeout.tv_nsec = TIMERTICK_INTERVAL_USEC * 1000; + npth_timeradd (&curtime, &timeout, &abstime); + } + npth_timersub (&abstime, &curtime, &timeout); /* POSIX says that fd_set should be implemented as a structure, thus a simple assignment is fine to copy the entire set. */ read_fdset = fdset; - if (time_ev) - pth_event_concat (ev, time_ev, NULL); - ret = pth_select_ev (nfd+1, &read_fdset, NULL, NULL, NULL, ev); - if (time_ev) - pth_event_isolate (time_ev); + ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask()); + saved_errno = errno; + +#ifndef HAVE_W32_SYSTEM + while (npth_sigev_get_pending(&signo)) + handle_signal (signo); +#endif - if (ret == -1) + if (ret == -1 && saved_errno != EINTR) { - if (pth_event_occurred (ev) - || (time_ev && pth_event_occurred (time_ev))) - { - if (pth_event_occurred (ev)) - handle_signal (signo); - if (time_ev && pth_event_occurred (time_ev)) - { - pth_event_free (time_ev, PTH_FREE_ALL); - time_ev = NULL; - handle_tick (); - } - continue; - } - log_error (_("pth_select failed: %s - waiting 1s\n"), - strerror (errno)); - pth_sleep (1); + log_error (_("pth_pselect failed: %s - waiting 1s\n"), + strerror (saved_errno)); + npth_sleep (1); continue; } - if (pth_event_occurred (ev)) - { - handle_signal (signo); - } - - if (time_ev && pth_event_occurred (time_ev)) - { - pth_event_free (time_ev, PTH_FREE_ALL); - time_ev = NULL; - handle_tick (); - } - - /* We now might create new threads and because we don't want any - signals - we are handling here - to be delivered to a new - thread. Thus we need to block those signals. */ - pth_sigmask (SIG_BLOCK, &sigs, &oldsigs); + if (ret <= 0) + /* Timeout. Will be handled when calculating the next timeout. */ + continue; if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset)) { ctrl_t ctrl; plen = sizeof paddr; - fd = pth_accept (listen_fd, (struct sockaddr *)&paddr, &plen); + fd = npth_accept (listen_fd, (struct sockaddr *)&paddr, &plen); if (fd == -1) { log_error ("accept failed: %s\n", strerror (errno)); @@ -1318,30 +1273,27 @@ handle_connections (int listen_fd) else { char threadname[50]; + npth_t thread; snprintf (threadname, sizeof threadname-1, "conn fd=%d", fd); threadname[sizeof threadname -1] = 0; - pth_attr_set (tattr, PTH_ATTR_NAME, threadname); ctrl->thread_startup.fd = INT2FD (fd); - if (!pth_spawn (tattr, start_connection_thread, ctrl)) + ret = npth_create (&thread, &tattr, start_connection_thread, ctrl); + if (ret) { log_error ("error spawning connection handler: %s\n", - strerror (errno) ); + strerror (ret)); xfree (ctrl); close (fd); } + else + npth_setname_np (thread, threadname); } fd = -1; } - - /* Restore the signal mask. */ - pth_sigmask (SIG_SETMASK, &oldsigs, NULL); - } - pth_event_free (ev, PTH_FREE_ALL); - if (time_ev) - pth_event_free (time_ev, PTH_FREE_ALL); cleanup (); log_info (_("%s %s stopped\n"), strusage(11), strusage(13)); + npth_attr_destroy (&tattr); } |