2002-06-28 Marcus Brinkmann <marcus@g10code.de>
authorMarcus Brinkmann <mb@g10code.com>
Fri, 28 Jun 2002 01:11:20 +0000 (01:11 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Fri, 28 Jun 2002 01:11:20 +0000 (01:11 +0000)
* ops.h (_gpgme_wait_on_condition): Remove HANG argument from
prototype and change return type to GpgmeError.
(_gpgme_wait_one): New prototype.
* wait.c (gpgme_wait): Replace with the meat from
_gpgme_wait_on_condition here, and remove the support for
conditions.
(_gpgme_wait_on_condition): Remove HANG argument from prototype
and change return type to GpgmeError.  Replace with meat from
_gpgme_wait_one and add support for conditions.
(_gpgme_wait_one): Just call _gpgme_wait_on_condition without
condition.
* keylist.c (gpgme_op_keylist_ext_start): Always use our own FD
table (eg use synchronous mode).
(gpgme_op_keylist_next): Remove HANG argument from
_gpgme_wait_on_condition.  Check its return value.
* trustlist.c (gpgme_op_trustlist_start): Always use our own FD
table (eg use synchronous mode).
(gpgme_op_trustlist_next): Remove HANG argument from
_gpgme_wait_on_condition.  Check its return value.

gpgme/ChangeLog
gpgme/keylist.c
gpgme/ops.h
gpgme/trustlist.c
gpgme/wait.c

index e49e8f9..56fd9c6 100644 (file)
@@ -1,3 +1,25 @@
+2002-06-28  Marcus Brinkmann  <marcus@g10code.de>
+
+       * ops.h (_gpgme_wait_on_condition): Remove HANG argument from
+       prototype and change return type to GpgmeError.
+       (_gpgme_wait_one): New prototype.
+       * wait.c (gpgme_wait): Replace with the meat from
+       _gpgme_wait_on_condition here, and remove the support for
+       conditions.
+       (_gpgme_wait_on_condition): Remove HANG argument from prototype
+       and change return type to GpgmeError.  Replace with meat from
+       _gpgme_wait_one and add support for conditions.
+       (_gpgme_wait_one): Just call _gpgme_wait_on_condition without
+       condition.
+       * keylist.c (gpgme_op_keylist_ext_start): Always use our own FD
+       table (eg use synchronous mode).
+       (gpgme_op_keylist_next): Remove HANG argument from
+       _gpgme_wait_on_condition.  Check its return value.
+       * trustlist.c (gpgme_op_trustlist_start): Always use our own FD
+       table (eg use synchronous mode).
+       (gpgme_op_trustlist_next): Remove HANG argument from
+       _gpgme_wait_on_condition.  Check its return value.
+       
 2002-06-27  Marcus Brinkmann  <marcus@g10code.de>
 
        * gpgme.h: Fix documentation of key attribute retrieval functions.
index 2adc3ac..032bac6 100644 (file)
@@ -563,7 +563,9 @@ gpgme_op_keylist_start (GpgmeCtx ctx, const char *pattern, int secret_only)
 {
   GpgmeError err = 0;
 
-  err = _gpgme_op_reset (ctx, 0);
+  /* Keylist operations are always "synchronous" in the sense that we
+     don't add ourself to the global FD table.  */
+  err = _gpgme_op_reset (ctx, 1);
   if (err)
     goto leave;
 
@@ -682,9 +684,21 @@ gpgme_op_keylist_next (GpgmeCtx ctx, GpgmeKey *r_key)
 
   if (!ctx->key_queue)
     {
-      _gpgme_wait_on_condition (ctx, 1, &ctx->key_cond);
-      if (ctx->error)
-       return ctx->error;
+      GpgmeError err = _gpgme_wait_on_condition (ctx, &ctx->key_cond);
+      if (err)
+       {
+         ctx->pending = 0;
+         return err;
+       }
+      if (!ctx->pending)
+       {
+         /* The operation finished.  Because not all keys might have
+            been returned to the caller yet, we just reset the
+            pending flag to 1.  This will cause us to call
+            _gpgme_wait_on_condition without any active file
+            descriptors, but that is a no-op, so it is safe.  */
+         ctx->pending = 1;
+       }
       if (!ctx->key_cond)
        {
          ctx->pending = 0;
index 28e0f54..56da5d3 100644 (file)
@@ -49,8 +49,8 @@ void _gpgme_set_op_info (GpgmeCtx c, GpgmeData info);
 void _gpgme_op_event_cb (void *data, GpgmeEventIO type, void *type_data);
 
 /*-- wait.c --*/
-GpgmeCtx _gpgme_wait_on_condition ( GpgmeCtx c,
-                                    int hang, volatile int *cond );
+GpgmeError _gpgme_wait_one (GpgmeCtx ctx);
+GpgmeError _gpgme_wait_on_condition (GpgmeCtx ctx, volatile int *cond);
 
 /*-- recipient.c --*/
 int _gpgme_recipients_all_valid ( const GpgmeRecipients rset );
index 7270e1c..3d10e51 100644 (file)
@@ -167,7 +167,9 @@ gpgme_op_trustlist_start (GpgmeCtx ctx, const char *pattern, int max_level)
   if (!pattern || !*pattern)
     return mk_error (Invalid_Value);
 
-  err = _gpgme_op_reset (ctx, 0);
+  /* Trustlist operations are always "synchronous" in the sense that
+     we don't add ourself to the global FD table.  */
+  err = _gpgme_op_reset (ctx, 1);
   if (err)
     goto leave;
 
@@ -209,11 +211,26 @@ gpgme_op_trustlist_next (GpgmeCtx ctx, GpgmeTrustItem *r_item)
 
   if (!ctx->trust_queue)
     {
-      _gpgme_wait_on_condition (ctx, 1, &ctx->key_cond);
-      if (ctx->error)
-       return ctx->error;
+      GpgmeError err = _gpgme_wait_on_condition (ctx, &ctx->key_cond);
+      if (err)
+       {
+         ctx->pending = 0;
+         return err;
+       }
+      if (!ctx->pending)
+       {
+         /* The operation finished.  Because not all keys might have
+            been returned to the caller yet, we just reset the
+            pending flag to 1.  This will cause us to call
+            _gpgme_wait_on_condition without any active file
+            descriptors, but that is a no-op, so it is safe.  */
+         ctx->pending = 1;
+       }
       if (!ctx->key_cond)
-       return mk_error (EOF);
+       {
+         ctx->pending = 0;
+         return mk_error (EOF);
+       }
       ctx->key_cond = 0; 
       assert (ctx->trust_queue);
     }
index 0e8141b..79f3ca7 100644 (file)
@@ -227,15 +227,62 @@ _gpgme_wait_event_cb (void *data, GpgmeEventIO type, void *type_data)
 GpgmeCtx 
 gpgme_wait (GpgmeCtx ctx, GpgmeError *status, int hang)
 {
-  ctx = _gpgme_wait_on_condition (ctx, hang, NULL);
+  DEBUG2 ("waiting... ctx=%p hang=%d", ctx, hang);
+  do
+    {
+      int i;
+
+      /* XXX We are ignoring all errors from select here.  */
+      do_select (&fdt_global);
+      
+      LOCK (ctx_done_list_lock);
+      /* A process that is done is eligible for election if it is the
+        requested context or if it was not yet reported.  */
+      for (i = 0; i < ctx_done_list_length; i++)
+       if (!ctx || ctx == ctx_done_list[i])
+         break;
+      if (i < ctx_done_list_length)
+       {
+         if (!ctx)
+           ctx = ctx_done_list[i];
+         hang = 0;
+         ctx->pending = 0;
+         if (--ctx_done_list_length)
+           memcpy (&ctx_done_list[i],
+                   &ctx_done_list[i + 1],
+                   (ctx_done_list_length - i) * sizeof (GpgmeCtx *));
+       }
+      UNLOCK (ctx_done_list_lock);
+
+      if (hang)
+       run_idle ();
+    }
+  while (hang && (!ctx || !ctx->cancel));
+
+  if (ctx && ctx->cancel)
+    {
+      /* FIXME: Paranoia?  */
+      ctx->cancel = 0;
+      ctx->pending = 0;
+      ctx->error = mk_error (Canceled);
+    }
+
   if (ctx && status)
     *status = ctx->error;
   return ctx;
 }
 
+
 GpgmeError
 _gpgme_wait_one (GpgmeCtx ctx)
 {
+  return _gpgme_wait_on_condition (ctx, NULL);
+}
+
+
+GpgmeError
+_gpgme_wait_on_condition (GpgmeCtx ctx, volatile int *cond)
+{
   GpgmeError err = 0;
   int hang = 1;
   DEBUG1 ("waiting... ctx=%p", ctx);
@@ -246,7 +293,9 @@ _gpgme_wait_one (GpgmeCtx ctx)
          err = mk_error (File_Error);
          hang = 0;
        }
-      else
+      else if (cond && *cond)
+       hang = 0;
+      else       
        {
          int any = 0;
          int i;
@@ -276,55 +325,6 @@ _gpgme_wait_one (GpgmeCtx ctx)
   return err ? err : ctx->error;
 }
 
-
-GpgmeCtx 
-_gpgme_wait_on_condition (GpgmeCtx ctx, int hang, volatile int *cond)
-{
-  DEBUG3 ("waiting... ctx=%p hang=%d cond=%p", ctx, hang, cond);
-  do
-    {
-      /* XXX We are ignoring all errors from select here.  */
-      do_select (&fdt_global);
-      
-      if (cond && *cond)
-       hang = 0;
-      else
-       {
-         int i;
-
-         LOCK (ctx_done_list_lock);
-         /* A process that is done is eligible for election if it is
-            the requested context or if it was not yet reported.  */
-         for (i = 0; i < ctx_done_list_length; i++)
-           if (!ctx || ctx == ctx_done_list[i])
-             break;
-         if (i < ctx_done_list_length)
-           {
-             if (!ctx)
-               ctx = ctx_done_list[i];
-             hang = 0;
-             ctx->pending = 0;
-             if (--ctx_done_list_length)
-               memcpy (&ctx_done_list[i],
-                       &ctx_done_list[i + 1],
-                       (ctx_done_list_length - i) * sizeof (GpgmeCtx *));
-           }
-         UNLOCK (ctx_done_list_lock);
-        }
-      if (hang)
-       run_idle ();
-    }
-  while (hang && (!ctx || !ctx->cancel));
-  if (ctx && ctx->cancel)
-    {
-      /* FIXME: Paranoia?  */
-      ctx->cancel = 0;
-      ctx->pending = 0;
-      ctx->error = mk_error (Canceled);
-    }
-  return ctx;
-}
-
 \f
 struct tag
 {