2008-06-27 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Cancellation): Document gpgme_cancel_async. gpgme/ 2008-06-27 Marcus Brinkmann <marcus@g10code.de> * context.h: Include "sema.h". (struct gpgme_context): New members lock and canceled. * gpgme.c (gpgme_new): Initialize lock. (gpgme_release): Destroy lock. (gpgme_cancel_async): New function. * op-support.c (_gpgme_op_reset): Reset the canceled flag. * wait-global.c (gpgme_wait): Check cancel flag before processing any I/O callbacks. * wait-private.c (_gpgme_wait_on_condition): Likewise. * wait-user.c (_gpgme_user_io_cb_handler): Likewise.
This commit is contained in:
parent
eccdb17c30
commit
695ec56ffb
@ -1,3 +1,7 @@
|
||||
2008-06-27 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* gpgme.texi (Cancellation): Document gpgme_cancel_async.
|
||||
|
||||
2008-06-25 Werner Koch <wk@g10code.com>
|
||||
|
||||
* gpgme.texi (Listing Keys): Updated example to the current API.
|
||||
|
@ -5488,13 +5488,15 @@ private:
|
||||
@cindex aborting operations
|
||||
@cindex cancelling operations
|
||||
|
||||
Sometimes you do not want to wait for an operation to finish. If you
|
||||
use external I/O callbacks, you can cancel a pending operation.
|
||||
However, you must ensure that no other thread is currently using the
|
||||
context in which the operation you want to cancel runs. This includes
|
||||
callback handlers. So your external event loop must either be halted
|
||||
or otherwise it must be guaranteed that no installed I/O callbacks are
|
||||
run for this context.
|
||||
Sometimes you do not want to wait for an operation to finish.
|
||||
@acronym{GPGME} provides two different functions to achieve that. The
|
||||
function @code{gpgme_cancel} takes effect immediately. When it
|
||||
returns, the operation is effectively canceled. However, it has some
|
||||
limitations and can not be used with synchronous operations. In
|
||||
contrast, the function @code{gpgme_cancel_async} can be used with any
|
||||
context and from any thread, but it is not guaranteed to take effect
|
||||
immediately. Instead, cancellation occurs at the next possible time
|
||||
(typically the next time I/O occurs in the target context).
|
||||
|
||||
@deftypefun gpgme_ctx_t gpgme_cancel (@w{gpgme_ctx_t @var{ctx}})
|
||||
The function @code{gpgme_cancel} attempts to cancel a pending
|
||||
@ -5517,6 +5519,18 @@ The function returns an error code if the cancellation failed (in this
|
||||
case the state of @var{ctx} is not modified).
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@deftypefun gpgme_ctx_t gpgme_cancel_async (@w{gpgme_ctx_t @var{ctx}})
|
||||
The function @code{gpgme_cancel} attempts to cancel a pending
|
||||
operation in the context @var{ctx}. This can be called by any thread
|
||||
at any time after starting an operation on the context, but will not
|
||||
take effect immediately. The actual cancellation happens at the next
|
||||
time GPGME processes I/O in that context.
|
||||
|
||||
The function returns an error code if the cancellation failed (in this
|
||||
case the state of @var{ctx} is not modified).
|
||||
@end deftypefun
|
||||
|
||||
@c **********************************************************
|
||||
@c ******************* Appendices *************************
|
||||
@c **********************************************************
|
||||
|
@ -1,3 +1,16 @@
|
||||
2008-06-27 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* context.h: Include "sema.h".
|
||||
(struct gpgme_context): New members lock and canceled.
|
||||
* gpgme.c (gpgme_new): Initialize lock.
|
||||
(gpgme_release): Destroy lock.
|
||||
(gpgme_cancel_async): New function.
|
||||
* op-support.c (_gpgme_op_reset): Reset the canceled flag.
|
||||
* wait-global.c (gpgme_wait): Check cancel flag before processing
|
||||
any I/O callbacks.
|
||||
* wait-private.c (_gpgme_wait_on_condition): Likewise.
|
||||
* wait-user.c (_gpgme_user_io_cb_handler): Likewise.
|
||||
|
||||
2008-06-26 Werner Koch <wk@g10code.com>
|
||||
|
||||
* w32-util.c (_gpgme_mkstemp): Replace sprint by stpcpy.
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "gpgme.h"
|
||||
#include "engine.h"
|
||||
#include "wait.h"
|
||||
#include "sema.h"
|
||||
|
||||
|
||||
/* Operations might require to remember arbitrary information and data
|
||||
@ -63,6 +64,11 @@ typedef struct ctx_op_data *ctx_op_data_t;
|
||||
be performed (sequentially). */
|
||||
struct gpgme_context
|
||||
{
|
||||
DECLARE_LOCK (lock);
|
||||
|
||||
/* True if the context was canceled asynchronously. */
|
||||
int canceled;
|
||||
|
||||
/* The engine info for this context. */
|
||||
gpgme_engine_info_t engine_info;
|
||||
|
||||
|
@ -54,6 +54,8 @@ gpgme_new (gpgme_ctx_t *r_ctx)
|
||||
if (!ctx)
|
||||
return TRACE_ERR (gpg_error_from_errno (errno));
|
||||
|
||||
INIT_LOCK (ctx->lock);
|
||||
|
||||
_gpgme_engine_info_copy (&ctx->engine_info);
|
||||
if (!ctx->engine_info)
|
||||
{
|
||||
@ -121,6 +123,22 @@ gpgme_cancel (gpgme_ctx_t ctx)
|
||||
return TRACE_ERR (0);
|
||||
}
|
||||
|
||||
|
||||
/* Cancel a pending operation asynchronously. */
|
||||
gpgme_error_t
|
||||
gpgme_cancel_async (gpgme_ctx_t ctx)
|
||||
{
|
||||
gpgme_error_t err;
|
||||
TRACE_BEG (DEBUG_CTX, "gpgme_cancel_async", ctx);
|
||||
|
||||
LOCK (ctx->lock);
|
||||
ctx->canceled = 1;
|
||||
UNLOCK (ctx->lock);
|
||||
|
||||
return TRACE_ERR (0);
|
||||
}
|
||||
|
||||
|
||||
/* Release all resources associated with the given context. */
|
||||
void
|
||||
gpgme_release (gpgme_ctx_t ctx)
|
||||
@ -139,6 +157,7 @@ gpgme_release (gpgme_ctx_t ctx)
|
||||
if (ctx->lc_messages)
|
||||
free (ctx->lc_messages);
|
||||
_gpgme_engine_info_release (ctx->engine_info);
|
||||
DESTROY_LOCK (ctx->lock);
|
||||
free (ctx);
|
||||
}
|
||||
|
||||
|
@ -1120,6 +1120,9 @@ unsigned long gpgme_key_sig_get_ulong_attr (gpgme_key_t key, int uid_idx,
|
||||
/* Cancel a pending asynchronous operation. */
|
||||
gpgme_error_t gpgme_cancel (gpgme_ctx_t ctx);
|
||||
|
||||
/* Cancel a pending operation asynchronously. */
|
||||
gpgme_error_t gpgme_cancel_async (gpgme_ctx_t ctx);
|
||||
|
||||
|
||||
struct _gpgme_invalid_key
|
||||
{
|
||||
|
@ -76,6 +76,9 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type)
|
||||
type &= 255;
|
||||
|
||||
_gpgme_release_result (ctx);
|
||||
LOCK (ctx->lock);
|
||||
ctx->canceled = 0;
|
||||
UNLOCK (ctx->lock);
|
||||
|
||||
if (ctx->engine && no_reset)
|
||||
reuse_engine = 1;
|
||||
|
@ -299,7 +299,7 @@ gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang)
|
||||
if (fdt.fds[i].fd != -1 && fdt.fds[i].signaled)
|
||||
{
|
||||
gpgme_ctx_t ictx;
|
||||
gpgme_error_t err;
|
||||
gpgme_error_t err = 0;
|
||||
struct wait_item_s *item;
|
||||
|
||||
assert (nr);
|
||||
@ -310,7 +310,13 @@ gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang)
|
||||
ictx = item->ctx;
|
||||
assert (ictx);
|
||||
|
||||
err = _gpgme_run_io_cb (&fdt.fds[i], 0);
|
||||
LOCK (ctx->lock);
|
||||
if (ctx->canceled)
|
||||
err = gpg_error (GPG_ERR_CANCELED);
|
||||
UNLOCK (ctx->lock);
|
||||
|
||||
if (!err)
|
||||
err = _gpgme_run_io_cb (&fdt.fds[i], 0);
|
||||
if (err)
|
||||
{
|
||||
/* An error occured. Close all fds in this context,
|
||||
|
@ -105,7 +105,13 @@ _gpgme_wait_on_condition (gpgme_ctx_t ctx, volatile int *cond)
|
||||
assert (nr);
|
||||
nr--;
|
||||
|
||||
err = _gpgme_run_io_cb (&ctx->fdt.fds[i], 0);
|
||||
LOCK (ctx->lock);
|
||||
if (ctx->canceled)
|
||||
err = gpg_error (GPG_ERR_CANCELED);
|
||||
UNLOCK (ctx->lock);
|
||||
|
||||
if (!err)
|
||||
err = _gpgme_run_io_cb (&ctx->fdt.fds[i], 0);
|
||||
if (err)
|
||||
{
|
||||
/* An error occured. Close all fds in this context,
|
||||
|
@ -39,7 +39,7 @@
|
||||
gpgme_error_t
|
||||
_gpgme_user_io_cb_handler (void *data, int fd)
|
||||
{
|
||||
gpgme_error_t err;
|
||||
gpgme_error_t err = 0;
|
||||
struct tag *tag = (struct tag *) data;
|
||||
gpgme_ctx_t ctx;
|
||||
|
||||
@ -47,7 +47,13 @@ _gpgme_user_io_cb_handler (void *data, int fd)
|
||||
ctx = tag->ctx;
|
||||
assert (ctx);
|
||||
|
||||
err = _gpgme_run_io_cb (&ctx->fdt.fds[tag->idx], 0);
|
||||
LOCK (ctx->lock);
|
||||
if (ctx->canceled)
|
||||
err = gpg_error (GPG_ERR_CANCELED);
|
||||
UNLOCK (ctx->lock);
|
||||
|
||||
if (! err)
|
||||
err = _gpgme_run_io_cb (&ctx->fdt.fds[tag->idx], 0);
|
||||
if (err)
|
||||
{
|
||||
unsigned int idx;
|
||||
|
Loading…
Reference in New Issue
Block a user