* query.c (initialize_module_query):
authorWerner Koch <wk@gnupg.org>
Sun, 19 Dec 2004 17:44:20 +0000 (17:44 +0000)
committerWerner Koch <wk@gnupg.org>
Sun, 19 Dec 2004 17:44:20 +0000 (17:44 +0000)
* call-scd.c (initialize_module_call_scd): New.

* w32-pth.c (pth_init): Enable debugging depending on env var.
(pth_self): New.
(pth_mutex_release, pth_mutex_acquire): Implemented directly using
the W32 API.

agent/ChangeLog
agent/agent.h
agent/call-scd.c
agent/gpg-agent.c
agent/query.c
jnlib/ChangeLog
jnlib/w32-pth.c
jnlib/w32-pth.h
scd/scdaemon.c

index 52673e5..d3c4af3 100644 (file)
@@ -1,3 +1,9 @@
+2004-12-19  Werner Koch  <wk@g10code.com>
+
+       * query.c (initialize_module_query): 
+
+       * call-scd.c (initialize_module_call_scd): New.
+
 2004-12-18  Werner Koch  <wk@g10code.com>
 
        * gpg-agent.c (main):  Remove special Pth initialize.
index 7ff6925..e6c8e2a 100644 (file)
@@ -145,6 +145,7 @@ gpg_error_t agent_key_from_file (ctrl_t ctrl,
 int agent_key_available (const unsigned char *grip);
 
 /*-- query.c --*/
+void initialize_module_query (void);
 int agent_askpin (ctrl_t ctrl,
                   const char *desc_text, const char *inital_errtext,
                   struct pin_entry_info_s *pininfo);
@@ -212,6 +213,7 @@ int divert_generic_cmd (ctrl_t ctrl,
 
 
 /*-- call-scd.c --*/
+void initialize_module_call_scd (void);
 int agent_reset_scd (ctrl_t ctrl);
 int agent_card_learn (ctrl_t ctrl,
                       void (*kpinfo_cb)(void*, const char *),
index 8280407..90c625f 100644 (file)
@@ -52,7 +52,7 @@
 
 static ASSUAN_CONTEXT scd_ctx = NULL;
 #ifdef USE_GNU_PTH
-static pth_mutex_t scd_lock = PTH_MUTEX_INIT;
+static pth_mutex_t scd_lock;
 #endif
 /* We need to keep track of the connection currently using the SCD.
    For a pipe server this is all a NOP because the connection will
@@ -153,6 +153,23 @@ get_membuf (struct membuf *mb, size_t *len)
 
 
 \f
+/* This function must be called once to initialize this module.  This
+   has to be done before a second thread is spawned.  We can't do the
+   static initialization because Pth emulation code might not be able
+   to do a static init; in particualr, it is not possible for W32. */
+void
+initialize_module_call_scd (void)
+{
+#ifdef USE_GNU_PTH
+  static int initialized;
+
+  if (!initialized)
+    if (pth_mutex_init (&scd_lock))
+      initialized = 1;
+#endif /*USE_GNU_PTH*/
+}
+
+
 static int 
 unlock_scd (int rc)
 {
@@ -163,7 +180,7 @@ unlock_scd (int rc)
       if (!rc)
         rc = gpg_error (GPG_ERR_INTERNAL);
     }
-#endif
+#endif /*USE_GNU_PTH*/
   return rc;
 }
 
index ed12fed..65d5fd5 100644 (file)
@@ -627,6 +627,10 @@ main (int argc, char **argv )
       exit (1);
     }
 
+  initialize_module_query ();
+  initialize_module_call_scd ();
+  
+  /* Try to create missing directories. */
   create_directories ();
 
   if (debug_wait && pipe_server)
index b514f6f..4aafcbe 100644 (file)
@@ -51,7 +51,7 @@
 
 static ASSUAN_CONTEXT entry_ctx = NULL;
 #ifdef USE_GNU_PTH
-static pth_mutex_t entry_lock = PTH_MUTEX_INIT;
+static pth_mutex_t entry_lock;
 #endif
 
 /* data to be passed to our callbacks */
@@ -64,6 +64,25 @@ struct entry_parm_s {
 
 
 \f
+/* This function must be called once to initialize this module.  This
+   has to be done before a second thread is spawned.  We can't do the
+   static initialization because Pth emulation code might not be able
+   to do a static init; in particualr, it is not possible for W32. */
+void
+initialize_module_query (void)
+{
+#ifdef USE_GNU_PTH
+  static int initialized;
+
+  if (!initialized)
+    if (pth_mutex_init (&entry_lock))
+      initialized = 1;
+#endif /*USE_GNU_PTH*/
+}
+
+
+
+
 /* Unlock the pinentry so that another thread can start one and
    disconnect that pinentry - we do this after the unlock so that a
    stalled pinentry does not block other threads.  Fixme: We should
index e194cea..5a566ae 100644 (file)
@@ -1,6 +1,9 @@
 2004-12-19  Werner Koch  <wk@g10code.com>
 
        * w32-pth.c (pth_init): Enable debugging depending on env var.
+       (pth_self): New.
+       (pth_mutex_release, pth_mutex_acquire): Implemented directly using
+       the W32 API.
 
 2004-12-18  Werner Koch  <wk@g10code.com>
 
index 489b283..609a037 100644 (file)
@@ -68,7 +68,6 @@ static HANDLE pth_signo_ev;
 static CRITICAL_SECTION pth_shd;
 
 
-
 struct pth_event_s
 {
   struct pth_event_s * next;
@@ -306,8 +305,6 @@ pth_write (int fd, const void * buffer, size_t size)
           fprintf (stderr, "%s: pth_write(%d) failed in write: %s\n",
                    log_get_prefix (NULL), fd,
                    w32_strerror (strerr, sizeof strerr));
-          fprintf (stderr, "--> fd = %d, handle = %p, size = %lu\n",
-                   fd, (HANDLE)fd, size);
           n = -1;
         }
       else
@@ -444,107 +441,94 @@ pth_connect (int fd, struct sockaddr *name, int namelen)
 
 
 int
-pth_mutex_release (pth_mutex_t *hd)
+pth_mutex_release (pth_mutex_t *mutex)
 {
-  if (!hd)
-    return -1;
+  int rc;
+
   implicit_init ();
   enter_pth (__FUNCTION__);
-  if (hd->mx)
+
+  if (!ReleaseMutex (*mutex))
     {
-      CloseHandle (hd->mx);
-      hd->mx = NULL;
+      char strerr[256];
+
+      fprintf (stderr, "%s: pth_release_mutex %p failed: %s\n",
+               log_get_prefix (NULL), *mutex,
+               w32_strerror (strerr, sizeof strerr));
+      rc = FALSE;
     }
-  free (hd);
+  else
+    rc = TRUE;
+
   leave_pth (__FUNCTION__);
-  return 0;
+  return rc;
 }
 
 
 int
-pth_mutex_acquire (pth_mutex_t *hd, int tryonly, pth_event_t ev_extra)
+pth_mutex_acquire (pth_mutex_t *mutex, int tryonly, pth_event_t ev_extra)
 {
+  int code;
+  int rc;
+
   implicit_init ();
   enter_pth (__FUNCTION__);
 
-  if (!hd || !hd->mx)
-    {
-      leave_pth (__FUNCTION__);
-      return FALSE;
-    }
-    
-#if 0
-  /* still not locked, so simply acquire mutex? */
-  if (!(mutex->mx_state & PTH_MUTEX_LOCKED))
-    {
-      mutex->mx_state |= PTH_MUTEX_LOCKED;
-      mutex->mx_count = 1;
-      pth_ring_append(&(pth_current->mutexring), &(mutex->mx_node));
-      pth_debug1("pth_mutex_acquire: immediately locking mutex");
-      return 0;
-    }
-
-  /* already locked by caller? */
-  if (mutex->mx_count >= 1 && mutex->mx_owner == pth_current)
-    {
-      /* recursive lock */
-      mutex->mx_count++;
-      pth_debug1("pth_mutex_acquire: recursive locking");
-      return 0;
-    }
-
-  if (tryonly)
-    {
-      leave_pth (__FUNCTION__);
-      return -1;
-    }
-
-  for (;;)
+  /* FIXME: ev_extra is not yet supported.  */
+  
+  code = WaitForSingleObject (*mutex, INFINITE);
+  switch (code) 
     {
-      ev = pth_event(PTH_EVENT_MUTEX|PTH_MODE_STATIC, &ev_key, mutex);
-      if (ev_extra != NULL)
-        pth_event_concat (ev, ev_extra, NULL);
-      pth_wait (ev);
-      if (ev_extra != NULL)
+      case WAIT_FAILED:
         {
-          pth_event_isolate (ev);
-          if (do_pth_event_status(ev) == PTH_STATUS_PENDING)
-            {
-              leave_pth (__FUNCTION__);
-              return -1;
-            }
+          char strerr[256];
+          
+          fprintf (stderr, "%s: pth_mutex_acquire for %p failed: %s\n",
+                   log_get_prefix (NULL), *mutex,
+                   w32_strerror (strerr, sizeof strerr));
         }
-      if (!(mutex->mx_state & PTH_MUTEX_LOCKED))
+        rc = FALSE;
+        break;
+        
+      case WAIT_OBJECT_0:
+        rc = TRUE;
+        break;
+
+      default:
+        fprintf (stderr, "%s: WaitForSingleObject returned unexpected "
+                 "code %d for mutex %p\n",
+                 log_get_prefix (NULL), code, *mutex);
+        rc = FALSE;
         break;
     }
-#endif
 
-  hd->mx_state |= PTH_MUTEX_LOCKED;
   leave_pth (__FUNCTION__);
-  return TRUE;
+  return rc;
 }
 
 
+
 int
-pth_mutex_init (pth_mutex_t *hd)
+pth_mutex_init (pth_mutex_t *mutex)
 {
   SECURITY_ATTRIBUTES sa;
   
   implicit_init ();
   enter_pth (__FUNCTION__);
 
-  if (hd->mx)
-    {
-      ReleaseMutex (hd->mx);
-      CloseHandle (hd->mx);
-    }
   memset (&sa, 0, sizeof sa);
   sa.bInheritHandle = TRUE;
   sa.lpSecurityDescriptor = NULL;
   sa.nLength = sizeof sa;
-  hd->mx = CreateMutex (&sa, FALSE, NULL);
-  hd->mx_state = PTH_MUTEX_INITIALIZED;
-
+  *mutex = CreateMutex (&sa, FALSE, NULL);
+  if (!*mutex)
+   {
+      free (*mutex);
+      *mutex = NULL;
+      leave_pth (__FUNCTION__);
+      return FALSE;
+    }
+    
   leave_pth (__FUNCTION__);
   return TRUE;
 }
@@ -695,6 +679,12 @@ pth_spawn (pth_attr_t hd, void *(*func)(void *), void *arg)
 }
 
 
+pth_t 
+pth_self (void)
+{
+  return GetCurrentThread ();
+}
+
 int
 pth_join (pth_t hd, void **value)
 {
@@ -1271,9 +1261,6 @@ do_pth_wait (pth_event_t ev)
 
         case PTH_EVENT_MUTEX:
           fprintf (stderr, "pth_wait: add mutex event.\n");
-          hdidx[i++] = pos;
-          waitbuf[pos++] = tmp->u.mx->mx;
-          /* XXX: Use SetEvent(hd->ev) */
           break;
         }
     }
index bcd8265..5ef0ab2 100644 (file)
@@ -53,7 +53,9 @@ enum
 /* Mutex values. */
 #define PTH_MUTEX_INITIALIZED  (1<<0)
 #define PTH_MUTEX_LOCKED       (1<<1)
-#define PTH_MUTEX_INIT         {PTH_MUTEX_INITIALIZED}
+
+/* Note: We can't do static initialization, thus we don't define the
+   initializer PTH_MUTEX_INIT.  */
 
 
 #define PTH_KEY_INIT          (1<<0)
@@ -158,12 +160,7 @@ typedef void *pth_t;
 
 
 /* The Mutex object.  */
-struct pth_mutex_s 
-{
-  unsigned mx_state;
-  W32_PTH_HANDLE_INTERNAL mx; 
-};
-typedef struct pth_mutex_s pth_mutex_t;
+typedef W32_PTH_HANDLE_INTERNAL pth_mutex_t;
 
 
 /* The Event object.  */
@@ -214,6 +211,7 @@ int pth_attr_destroy (pth_attr_t hd);
 int pth_attr_set (pth_attr_t hd, int field, ...);
 
 pth_t pth_spawn (pth_attr_t hd, void *(*func)(void *), void *arg);
+pth_t pth_self (void);
 int pth_join (pth_t hd, void **value);
 int pth_abort (pth_t hd);
 void pth_exit (void *value);
index 901644e..49e392e 100644 (file)
@@ -351,12 +351,17 @@ main (int argc, char **argv )
      Note that this will also do the pth_init. */
 #ifndef HAVE_OPENSC
 #ifdef USE_GNU_PTH
+#ifdef HAVE_W32_SYSTEM
+  /* For W32 we need pth.  */
+  pth_init ();
+#else
   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
 #endif /*USE_GNU_PTH*/
 #endif /*!HAVE_OPENSC*/