From: Werner Koch Date: Fri, 28 Sep 2007 16:23:53 +0000 (+0000) Subject: Fixed the external event loop for glib. X-Git-Tag: gpgme-1.1.6~17 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=fea223a5ef1cc352fc60eb1f7ad53d7a1cf421c9;p=gpgme.git Fixed the external event loop for glib. Add a bit more tracing. --- diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index fc29731..fdcc02c 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,23 @@ +2007-09-28 Werner Koch + + * w32-glib-io.c (find_channel): Add a new primary flag. + (_gpgme_io_close): Close channel only if primary. + (_gpgme_io_dup): Put newfd into the table as shallow copy. + + * priv-io.h (struct io_select_fd_s): Remove member FROZEN. + * w32-io.c (_gpgme_io_select): Ditto. + * w32-glib-io.c (_gpgme_io_select): Ditto. + + * posix-io.c (_gpgme_io_select): Ditto. + * rungpg.c (read_status): Ditto. + * wait.c (fd_table_put): Ditto. + + * rungpg.c (gpg_io_event): Add tracing. + (start): Use gpg_io_event for sending the start event. + * engine-gpgsm.c (gpgsm_io_event): Add tracing. + (start): Use gpgsm_io_event for sending the start event. + * wait.c (_gpgme_add_io_cb, _gpgme_run_io_cb): Add tracing. + 2007-09-28 Marcus Brinkmann * kdpipeiodevice.moc, w32-qt-io.cpp, kdpipeiodevice.cpp: New diff --git a/gpgme/engine-gpgsm.c b/gpgme/engine-gpgsm.c index 8c55a01..245322c 100644 --- a/gpgme/engine-gpgsm.c +++ b/gpgme/engine-gpgsm.c @@ -96,6 +96,11 @@ struct engine_gpgsm typedef struct engine_gpgsm *engine_gpgsm_t; + +static void gpgsm_io_event (void *engine, + gpgme_event_io_t type, void *type_data); + + static char * gpgsm_get_version (const char *file_name) @@ -846,10 +851,10 @@ status_handler (void *opaque, int fd) gpgsm->colon.any = 0; err = gpgsm->colon.fnc (gpgsm->colon.fnc_value, NULL); } - _gpgme_io_close (gpgsm->status_cb.fd); TRACE2 (DEBUG_CTX, "gpgme:status_handler", gpgsm, "fd 0x%x: OK line - final status: %s", fd, err ? gpg_strerror (err) : "ok"); + _gpgme_io_close (gpgsm->status_cb.fd); return err; } else if (linelen > 2 @@ -963,15 +968,17 @@ add_io_cb (engine_gpgsm_t gpgsm, iocb_data_t *iocbd, gpgme_io_cb_t handler) { gpgme_error_t err; + TRACE_BEG2 (DEBUG_ENGINE, "engine-gpgsm:add_io_cb", gpgsm, + "fd %d, dir %d", iocbd->fd, iocbd->dir); err = (*gpgsm->io_cbs.add) (gpgsm->io_cbs.add_priv, iocbd->fd, iocbd->dir, handler, iocbd->data, &iocbd->tag); if (err) - return err; + return TRACE_ERR (err); if (!iocbd->dir) /* FIXME Kludge around poll() problem. */ err = _gpgme_io_set_nonblocking (iocbd->fd); - return err; + return TRACE_ERR (err); } @@ -1020,7 +1027,7 @@ start (engine_gpgsm_t gpgsm, const char *command) err = map_assuan_error (assuan_write_line (gpgsm->assuan_ctx, command)); if (!err) - (*gpgsm->io_cbs.event) (gpgsm->io_cbs.event_priv, GPGME_EVENT_START, NULL); + gpgsm_io_event (gpgsm, GPGME_EVENT_START, NULL); return err; } @@ -1713,6 +1720,9 @@ gpgsm_io_event (void *engine, gpgme_event_io_t type, void *type_data) { engine_gpgsm_t gpgsm = engine; + TRACE3 (DEBUG_ENGINE, "gpgme:gpgsm_io_event", gpgsm, + "event %p, type %d, type_data %p", + gpgsm->io_cbs.event, type, type_data); if (gpgsm->io_cbs.event) (*gpgsm->io_cbs.event) (gpgsm->io_cbs.event_priv, type, type_data); } diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h index c0bc8e3..57bb011 100644 --- a/gpgme/gpgme.h +++ b/gpgme/gpgme.h @@ -73,7 +73,7 @@ extern "C" { AM_PATH_GPGME macro) check that this header matches the installed library. Warning: Do not edit the next line. configure will do that for you! */ -#define GPGME_VERSION "1.1.6-svn1264" +#define GPGME_VERSION "1.1.6-svn1258" diff --git a/gpgme/posix-io.c b/gpgme/posix-io.c index 947b670..6b793f1 100644 --- a/gpgme/posix-io.c +++ b/gpgme/posix-io.c @@ -393,9 +393,7 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock) { if (fds[i].fd == -1) continue; - if (fds[i].frozen) - TRACE_ADD1 (dbg_help, "f0x%x ", fds[i].fd); - else if (fds[i].for_read) + if (fds[i].for_read) { assert (!FD_ISSET (fds[i].fd, &readfds)); FD_SET (fds[i].fd, &readfds); diff --git a/gpgme/priv-io.h b/gpgme/priv-io.h index 3099a49..a488acb 100644 --- a/gpgme/priv-io.h +++ b/gpgme/priv-io.h @@ -37,7 +37,6 @@ struct io_select_fd_s int for_read; int for_write; int signaled; - int frozen; void *opaque; }; diff --git a/gpgme/rungpg.c b/gpgme/rungpg.c index 6d918ef..8e1b73a 100644 --- a/gpgme/rungpg.c +++ b/gpgme/rungpg.c @@ -136,6 +136,9 @@ gpg_io_event (void *engine, gpgme_event_io_t type, void *type_data) { engine_gpg_t gpg = engine; + TRACE3 (DEBUG_ENGINE, "gpgme:gpg_io_event", gpg, + "event %p, type %d, type_data %p", + gpg->io_cbs.event, type, type_data); if (gpg->io_cbs.event) (*gpg->io_cbs.event) (gpg->io_cbs.event_priv, type, type_data); } @@ -1044,7 +1047,6 @@ read_status (engine_gpg_t gpg) gpg->fd_data_map[gpg->cmd.linked_idx].fd; fds.for_read = 1; fds.for_write = 0; - fds.frozen = 0; fds.opaque = NULL; do { @@ -1354,7 +1356,7 @@ start (engine_gpg_t gpg) } } - (*gpg->io_cbs.event) (gpg->io_cbs.event_priv, GPGME_EVENT_START, NULL); + gpg_io_event (gpg, GPGME_EVENT_START, NULL); /* fixme: check what data we can release here */ return 0; diff --git a/gpgme/w32-glib-io.c b/gpgme/w32-glib-io.c index 3bd162f..935050c 100644 --- a/gpgme/w32-glib-io.c +++ b/gpgme/w32-glib-io.c @@ -78,7 +78,11 @@ #define MAX_SLAFD 256 -GIOChannel *giochannel_table[MAX_SLAFD]; +static struct +{ + GIOChannel *chan; + int primary; /* Set if CHAN is the one we used to create the channel. */ +} giochannel_table[MAX_SLAFD]; static GIOChannel * @@ -87,14 +91,15 @@ find_channel (int fd, int create) if (fd < 0 || fd >= MAX_SLAFD) return NULL; - if (create && !giochannel_table[fd]) + if (create && !giochannel_table[fd].chan) { - giochannel_table[fd] = g_io_channel_win32_new_fd (fd); - g_io_channel_set_encoding (giochannel_table[fd], NULL, NULL); - g_io_channel_set_buffered (giochannel_table[fd], FALSE); + giochannel_table[fd].chan = g_io_channel_win32_new_fd (fd); + giochannel_table[fd].primary = 1; + g_io_channel_set_encoding (giochannel_table[fd].chan, NULL, NULL); + g_io_channel_set_buffered (giochannel_table[fd].chan, FALSE); } - return giochannel_table[fd]; + return giochannel_table[fd].chan; } @@ -279,7 +284,6 @@ _gpgme_io_pipe (int filedes[2], int inherit_idx) int _gpgme_io_close (int fd) { - GIOChannel *chan; TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_close", fd); if (fd < 0 || fd >= MAX_SLAFD) @@ -297,16 +301,19 @@ _gpgme_io_close (int fd) } /* Then do the close. */ - chan = giochannel_table[fd]; - if (chan) + if (giochannel_table[fd].chan) { - g_io_channel_shutdown (chan, 1, NULL); - g_io_channel_unref (chan); - giochannel_table[fd] = NULL; + if (giochannel_table[fd].primary) + { + g_io_channel_shutdown (giochannel_table[fd].chan, 1, NULL); + g_io_channel_unref (giochannel_table[fd].chan); + } + giochannel_table[fd].chan = NULL; } else _close (fd); + TRACE_SUC (); return 0; } @@ -621,14 +628,21 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock) any = 0; for (i = 0; i < nfds; i++) { + GIOChannel *chan = NULL; + if (fds[i].fd == -1) continue; - if (fds[i].frozen) - TRACE_ADD1 (dbg_help, "f0x%x ", fds[i].fd); + + if ((fds[i].for_read || fds[i].for_write) + && !(chan = find_channel (fds[i].fd, 0))) + { + TRACE_ADD1 (dbg_help, "[BAD0x%x ", fds[i].fd); + TRACE_END (dbg_help, "]"); + assert (!"see log file"); + } else if (fds[i].for_read ) { - GIOChannel *chan = find_channel (fds[i].fd, 0); - assert (chan); + assert(chan); g_io_channel_win32_make_pollfd (chan, G_IO_IN, pollfds + npollfds); pollfds_map[npollfds] = i; TRACE_ADD2 (dbg_help, "r0x%x<%d> ", fds[i].fd, pollfds[npollfds].fd); @@ -637,8 +651,7 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock) } else if (fds[i].for_write) { - GIOChannel *chan = find_channel (fds[i].fd, 0); - assert (chan); + assert(chan); g_io_channel_win32_make_pollfd (chan, G_IO_OUT, pollfds + npollfds); pollfds_map[npollfds] = i; TRACE_ADD2 (dbg_help, "w0x%x<%d> ", fds[i].fd, pollfds[npollfds].fd); @@ -711,5 +724,45 @@ leave: int _gpgme_io_dup (int fd) { - return _dup (fd); + int newfd; + GIOChannel *chan; + + TRACE_BEG1 (DEBUG_SYSIO, "_gpgme_io_dup", fd, "dup (%d)", fd); + + newfd =_dup (fd); + if (newfd == -1) + return TRACE_SYSRES (-1); + if (newfd < 0 || newfd >= MAX_SLAFD) + { + /* New fd won't fit into our table. */ + _close (newfd); + errno = EIO; + return TRACE_SYSRES (-1); + } + + chan = find_channel (fd, 0); + if (!chan) + { + /* No channel exists for the original fd, thus we create one for + our new fd. */ + if ( !find_channel (newfd, 1) ) + { + _close (newfd); + errno = EIO; + return TRACE_SYSRES (-1); + } + } + else + { + /* There is already a channel for the original one. Copy that + channel into a new table entry unless we already did so. */ + if ( !giochannel_table[newfd].chan) + { + giochannel_table[newfd].chan = chan; + giochannel_table[newfd].primary = 0; + } + assert (giochannel_table[newfd].chan == chan); + } + + return TRACE_SYSRES (newfd); } diff --git a/gpgme/w32-io.c b/gpgme/w32-io.c index 4af1b68..c4d2a1b 100644 --- a/gpgme/w32-io.c +++ b/gpgme/w32-io.c @@ -1192,9 +1192,7 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock) fds[i].signaled = 0; if (fds[i].for_read || fds[i].for_write) { - if (fds[i].frozen) - TRACE_ADD1 (dbg_help, "f0x%x ", fds[i].fd); - else if (fds[i].for_read) + if (fds[i].for_read) { struct reader_context_s *ctx = find_reader (fds[i].fd,1); diff --git a/gpgme/wait.c b/gpgme/wait.c index 67956d3..f5bc2d9 100644 --- a/gpgme/wait.c +++ b/gpgme/wait.c @@ -82,7 +82,6 @@ fd_table_put (fd_table_t fdt, int fd, int dir, void *opaque, int *idx) fdt->fds[i].fd = fd; fdt->fds[i].for_read = (dir == 1); fdt->fds[i].for_write = (dir == 0); - fdt->fds[i].frozen = 0; fdt->fds[i].signaled = 0; fdt->fds[i].opaque = opaque; *idx = i; @@ -136,6 +135,9 @@ _gpgme_add_io_cb (void *data, int fd, int dir, gpgme_io_cb_t fnc, return err; } + TRACE3 (DEBUG_CTX, "_gpgme_add_io_cb", ctx, + "fd %d, dir=%d -> tag=%p", fd, dir, tag); + *r_tag = tag; return 0; } @@ -189,6 +191,7 @@ _gpgme_run_io_cb (struct io_select_fd_s *an_fds, int checked) int nr; struct io_select_fd_s fds; + TRACE0 (DEBUG_CTX, "_gpgme_run_io_cb", item, "need to check"); fds = *an_fds; fds.signaled = 0; /* Just give it a quick poll. */ @@ -202,5 +205,7 @@ _gpgme_run_io_cb (struct io_select_fd_s *an_fds, int checked) return 0; } + TRACE2 (DEBUG_CTX, "_gpgme_run_io_cb", item, "handler (%p, %d)", + item->handler_value, an_fds->fd); return item->handler (item->handler_value, an_fds->fd); }