From 3ccd2790b329087073bac2e9bbc6fa9355825d42 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Fri, 28 Jun 2002 01:11:20 +0000 Subject: [PATCH] 2002-06-28 Marcus Brinkmann * 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 | 22 ++++++++++ gpgme/keylist.c | 22 ++++++++-- gpgme/ops.h | 4 +- gpgme/trustlist.c | 27 +++++++++--- gpgme/wait.c | 102 +++++++++++++++++++++++----------------------- 5 files changed, 115 insertions(+), 62 deletions(-) diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index e49e8f96..56fd9c69 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,25 @@ +2002-06-28 Marcus Brinkmann + + * 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 * gpgme.h: Fix documentation of key attribute retrieval functions. diff --git a/gpgme/keylist.c b/gpgme/keylist.c index 2adc3acb..032bac6c 100644 --- a/gpgme/keylist.c +++ b/gpgme/keylist.c @@ -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; diff --git a/gpgme/ops.h b/gpgme/ops.h index 28e0f54f..56da5d34 100644 --- a/gpgme/ops.h +++ b/gpgme/ops.h @@ -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 ); diff --git a/gpgme/trustlist.c b/gpgme/trustlist.c index 7270e1c1..3d10e511 100644 --- a/gpgme/trustlist.c +++ b/gpgme/trustlist.c @@ -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); } diff --git a/gpgme/wait.c b/gpgme/wait.c index 0e8141ba..79f3ca7d 100644 --- a/gpgme/wait.c +++ b/gpgme/wait.c @@ -227,14 +227,61 @@ _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; @@ -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; -} - struct tag {