diff options
| -rw-r--r-- | gpgme/ChangeLog | 22 | ||||
| -rw-r--r-- | gpgme/keylist.c | 22 | ||||
| -rw-r--r-- | gpgme/ops.h | 4 | ||||
| -rw-r--r-- | gpgme/trustlist.c | 27 | ||||
| -rw-r--r-- | 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  <[email protected]> + +	* 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  <[email protected]>  	* 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,15 +227,62 @@ _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;    DEBUG1 ("waiting... ctx=%p", ctx); @@ -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  {  | 
