2005-06-02 Marcus Brinkmann <marcus@g10code.de>
authorMarcus Brinkmann <mb@g10code.com>
Thu, 2 Jun 2005 21:59:34 +0000 (21:59 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Thu, 2 Jun 2005 21:59:34 +0000 (21:59 +0000)
* wait.h (_gpgme_run_io_cb): New prototype.
* wait.c (_gpgme_run_io_cb): New function.
* wait-global.c (gpgme_wait): Call it.
* wait-user.c (_gpgme_user_io_cb_handler): Likewise.
* wait-private.c (_gpgme_wait_on_condition): Likewise.

gpgme/ChangeLog
gpgme/wait-global.c
gpgme/wait-private.c
gpgme/wait-user.c
gpgme/wait.c
gpgme/wait.h

index 0a2509dcba7f6c428bf7f394ef6ceff3f5fecb2f..82f5fd64e6c1a7590fd1a037989aba437b521370 100644 (file)
@@ -1,3 +1,11 @@
+2005-06-02  Marcus Brinkmann  <marcus@g10code.de>
+
+       * wait.h (_gpgme_run_io_cb): New prototype.
+       * wait.c (_gpgme_run_io_cb): New function.
+       * wait-global.c (gpgme_wait): Call it.
+       * wait-user.c (_gpgme_user_io_cb_handler): Likewise.
+       * wait-private.c (_gpgme_wait_on_condition): Likewise.
+
 2005-06-02  Werner Koch  <wk@g10code.com>
 
        * passphrase.c (_gpgme_passphrase_status_handler): Take care of
index db422bf22abd427dbc3eaac6831574e640a7e7a5..d9f8727202e5b7294e401d9ebc23586f573fdf8c 100644 (file)
@@ -310,7 +310,7 @@ gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang)
              ictx = item->ctx;
              assert (ictx);
 
-             err = item->handler (item->handler_value, fdt.fds[i].fd);
+             err = _gpgme_run_io_cb (&fdt.fds[i], 0);
              if (err)
                {
                  /* An error occured.  Close all fds in this context,
index f883f2064627bfd98447a04f810a52b6ac272377..73f11b760aa2f415355c5959fdc2d6f1d7cf9c2f 100644 (file)
@@ -101,15 +101,11 @@ _gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond)
        {
          if (ctx->fdt.fds[i].fd != -1 && ctx->fdt.fds[i].signaled)
            {
-             struct wait_item_s *item;
-             
              ctx->fdt.fds[i].signaled = 0;
              assert (nr);
              nr--;
-             
-             item = (struct wait_item_s *) ctx->fdt.fds[i].opaque;
 
-             err = item->handler (item->handler_value, ctx->fdt.fds[i].fd);
+             err = _gpgme_run_io_cb (&ctx->fdt.fds[i], 0);
              if (err)
                {
                  /* An error occured.  Close all fds in this context,
index 0f046f2eb7965846fbcd655ad5057c56a3f8b103..605401e936f0adf6b3b4f2054f45a429dfd1fd11 100644 (file)
@@ -42,15 +42,12 @@ _gpgme_user_io_cb_handler (void *data, int fd)
   gpgme_error_t err;
   struct tag *tag = (struct tag *) data;
   gpgme_ctx_t ctx;
-  struct wait_item_s *item;
 
   assert (data);
   ctx = tag->ctx;
   assert (ctx);
-  item = (struct wait_item_s *) ctx->fdt.fds[tag->idx].opaque;
-  assert (item);
 
-  err = (*item->handler) (item->handler_value, fd);
+  err = _gpgme_run_io_cb (&ctx->fdt.fds[tag->idx], 0);
   if (err)
     {
       unsigned int idx;
index 4d3cbf841171a47f8261f61c53d3f7016441ec82..16a9f23085c98f8fd93d199c13f038edb4227837 100644 (file)
@@ -167,3 +167,38 @@ _gpgme_remove_io_cb (void *data)
   fdt->fds[idx].for_write = 0;
   fdt->fds[idx].opaque = NULL;
 }
+
+\f
+/* This is slightly embarrassing.  The problem is that running an I/O
+   callback _may_ influence the status of other file descriptors.  Our
+   own event loops could compensate for that, but the external event
+   loops cannot.  FIXME: We may still want to optimize this a bit when
+   we are called from our own event loops.  So if CHECKED is 1, the
+   check is skipped.  */
+gpgme_error_t
+_gpgme_run_io_cb (struct io_select_fd_s *an_fds, int checked)
+{
+  struct wait_item_s *item;
+  item = (struct wait_item_s *) an_fds->opaque;
+  assert (item);
+
+  if (!checked)
+    {
+      int nr;
+      struct io_select_fd_s fds;
+
+      fds = *an_fds;
+      fds.signaled = 0;
+      /* Just give it a quick poll.  */
+      nr = _gpgme_io_select (&fds, 1, 1);
+      assert (nr <= 1);
+      if (nr < 0)
+       return errno;
+      else if (nr == 0)
+       /* The status changed in the meantime, there is nothing left
+          to do.  */
+       return 0;
+    }
+
+  return item->handler (item->handler_value, an_fds->fd);
+}
index cec4d8d1923a0693b49020b50aecbaa0d55c8258..eafbb6f6de5e04e4578a307db58c52accb482687 100644 (file)
@@ -77,4 +77,6 @@ void _gpgme_wait_user_event_cb (void *data, gpgme_event_io_t type,
 
 gpgme_error_t _gpgme_wait_one (gpgme_ctx_t ctx);
 
+gpgme_error_t _gpgme_run_io_cb (struct io_select_fd_s *an_fds, int checked);
+
 #endif /* WAIT_H */