+2002-06-28 Marcus Brinkmann <marcus@g10code.de>
+
+ * 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 <marcus@g10code.de>
* gpgme.h: Fix documentation of key attribute retrieval functions.
{
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;
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;
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 );
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;
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);
}
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;
err = mk_error (File_Error);
hang = 0;
}
- else
+ else if (cond && *cond)
+ hang = 0;
+ else
{
int any = 0;
int i;
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;
-}
-
\f
struct tag
{