2005-06-02 Marcus Brinkmann <marcus@g10code.de>
authorMarcus Brinkmann <mb@g10code.com>
Thu, 2 Jun 2005 22:05:32 +0000 (22:05 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Thu, 2 Jun 2005 22:05:32 +0000 (22:05 +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 8a348c4605d5e371eff3342c5c62036ca7c00e8e..d949da7481a8b2607cd8426124fc1385ba9d3786 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>
 
        * gpgme.h: Add GPGME_STATUS_NEED_PASSPHRASE_PIN.
index f3a5b430ff5e35a0cb0bca68048d8abdc5f026d7..7895d8b4f541521a9d250bf59fc69c3e1db651ed 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 166b7132e60fa4626e7c4cbf464519d4a95f82fd..d884c9416efeeebc9ba43c7401b1b5de3b7462e5 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 3800b4f48de75f7acec2c859cfc60552a66b7592..ad3c9d33228d6a2d71746d12342dc464ce299654 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 f3cc8f68701e1d57984e6713cdb5ee5b51926178..c78704587b88904116f54b6590ccd3f94eb310d6 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 */