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 0a2509d..82f5fd6 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
 2005-06-02  Werner Koch  <wk@g10code.com>
 
        * passphrase.c (_gpgme_passphrase_status_handler): Take care of
index db422bf..d9f8727 100644 (file)
@@ -310,7 +310,7 @@ gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang)
              ictx = item->ctx;
              assert (ictx);
 
              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,
              if (err)
                {
                  /* An error occured.  Close all fds in this context,
index f883f20..73f11b7 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)
            {
        {
          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--;
              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,
              if (err)
                {
                  /* An error occured.  Close all fds in this context,
index 0f046f2..605401e 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;
   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);
 
   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;
   if (err)
     {
       unsigned int idx;
index 4d3cbf8..16a9f23 100644 (file)
@@ -167,3 +167,38 @@ _gpgme_remove_io_cb (void *data)
   fdt->fds[idx].for_write = 0;
   fdt->fds[idx].opaque = NULL;
 }
   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 cec4d8d..eafbb6f 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_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 */
 #endif /* WAIT_H */