aboutsummaryrefslogtreecommitdiffstats
path: root/scd/scdaemon.c
diff options
context:
space:
mode:
authorMarcus Brinkmann <[email protected]>2012-01-03 21:12:37 +0000
committerMarcus Brinkmann <[email protected]>2012-01-25 13:07:08 +0000
commite917c07b2664bb01a5f7b5975723b90da0f396c9 (patch)
treee31e737fe07e96b596f8bbbaf16a1e122ac683ae /scd/scdaemon.c
parentRequire gitlog-to-changelog to be installed. (diff)
downloadgnupg-npth-3.tar.gz
gnupg-npth-3.zip
Port to npth.npth-3
* configure.ac: Don't check for PTH but for NPTH. (AH_BOTTOM): Remove PTH_SYSCALL_SOFT. (have_pth): Rename to ... (have_npth): ... this. (USE_GNU_NPTH): Rename to ... (USE_GNU_PTH): ... this. * m4/npth.m4: New file. * agent/Makefile.am, agent/cache.c, agent/call-pinentry.c, agent/call-scd.c, agent/findkey.c, agent/gpg-agent.c, agent/trustlist.c, common/Makefile.am, common/estream.c, common/exechelp-posix.c, common/exechelp-w32.c, common/exechelp-w32ce.c, common/http.c, common/init.c, common/sysutils.c, dirmngr/Makefile.am, dirmngr/crlfetch.c, dirmngr/dirmngr.c, dirmngr/dirmngr_ldap.c, dirmngr/ldap-wrapper-ce.c, dirmngr/ldap-wrapper.c, dirmngr/ldap.c, g13/Makefile.am, g13/call-gpg.c, g13/g13.c, g13/runner.c, scd/Makefile.am, scd/apdu.c, scd/app.c, scd/ccid-driver.c, scd/command.c, scd/scdaemon.c, tools/Makefile.am: Port to npth.
Diffstat (limited to 'scd/scdaemon.c')
-rw-r--r--scd/scdaemon.c230
1 files changed, 91 insertions, 139 deletions
diff --git a/scd/scdaemon.c b/scd/scdaemon.c
index e26beba13..e8073b7ee 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,24 @@ 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);
-#else
- sigs = 0;
- 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 ();
#endif
- time_ev = NULL;
FD_ZERO (&fdset);
nfd = 0;
@@ -1214,13 +1195,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 +1216,50 @@ 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);
+#ifndef HAVE_W32_SYSTEM
+ ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask());
+ saved_errno = errno;
+
+ while (npth_sigev_get_pending(&signo))
+ handle_signal (signo);
+#else
+ ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout, NULL, NULL);
+ saved_errno = errno;
+#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 (_("npth_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);
}