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>
|
2008-06-25 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* gpgme.texi (Listing Keys): Updated example to the current API.
|
* gpgme.texi (Listing Keys): Updated example to the current API.
|
||||||
|
@ -5488,13 +5488,15 @@ private:
|
|||||||
@cindex aborting operations
|
@cindex aborting operations
|
||||||
@cindex cancelling operations
|
@cindex cancelling operations
|
||||||
|
|
||||||
Sometimes you do not want to wait for an operation to finish. If you
|
Sometimes you do not want to wait for an operation to finish.
|
||||||
use external I/O callbacks, you can cancel a pending operation.
|
@acronym{GPGME} provides two different functions to achieve that. The
|
||||||
However, you must ensure that no other thread is currently using the
|
function @code{gpgme_cancel} takes effect immediately. When it
|
||||||
context in which the operation you want to cancel runs. This includes
|
returns, the operation is effectively canceled. However, it has some
|
||||||
callback handlers. So your external event loop must either be halted
|
limitations and can not be used with synchronous operations. In
|
||||||
or otherwise it must be guaranteed that no installed I/O callbacks are
|
contrast, the function @code{gpgme_cancel_async} can be used with any
|
||||||
run for this context.
|
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}})
|
@deftypefun gpgme_ctx_t gpgme_cancel (@w{gpgme_ctx_t @var{ctx}})
|
||||||
The function @code{gpgme_cancel} attempts to cancel a pending
|
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).
|
case the state of @var{ctx} is not modified).
|
||||||
@end deftypefun
|
@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 **********************************************************
|
||||||
@c ******************* Appendices *************************
|
@c ******************* Appendices *************************
|
||||||
@c **********************************************************
|
@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>
|
2008-06-26 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* w32-util.c (_gpgme_mkstemp): Replace sprint by stpcpy.
|
* w32-util.c (_gpgme_mkstemp): Replace sprint by stpcpy.
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "gpgme.h"
|
#include "gpgme.h"
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
#include "wait.h"
|
#include "wait.h"
|
||||||
|
#include "sema.h"
|
||||||
|
|
||||||
|
|
||||||
/* Operations might require to remember arbitrary information and data
|
/* 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). */
|
be performed (sequentially). */
|
||||||
struct gpgme_context
|
struct gpgme_context
|
||||||
{
|
{
|
||||||
|
DECLARE_LOCK (lock);
|
||||||
|
|
||||||
|
/* True if the context was canceled asynchronously. */
|
||||||
|
int canceled;
|
||||||
|
|
||||||
/* The engine info for this context. */
|
/* The engine info for this context. */
|
||||||
gpgme_engine_info_t engine_info;
|
gpgme_engine_info_t engine_info;
|
||||||
|
|
||||||
|
@ -54,6 +54,8 @@ gpgme_new (gpgme_ctx_t *r_ctx)
|
|||||||
if (!ctx)
|
if (!ctx)
|
||||||
return TRACE_ERR (gpg_error_from_errno (errno));
|
return TRACE_ERR (gpg_error_from_errno (errno));
|
||||||
|
|
||||||
|
INIT_LOCK (ctx->lock);
|
||||||
|
|
||||||
_gpgme_engine_info_copy (&ctx->engine_info);
|
_gpgme_engine_info_copy (&ctx->engine_info);
|
||||||
if (!ctx->engine_info)
|
if (!ctx->engine_info)
|
||||||
{
|
{
|
||||||
@ -121,6 +123,22 @@ gpgme_cancel (gpgme_ctx_t ctx)
|
|||||||
return TRACE_ERR (0);
|
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. */
|
/* Release all resources associated with the given context. */
|
||||||
void
|
void
|
||||||
gpgme_release (gpgme_ctx_t ctx)
|
gpgme_release (gpgme_ctx_t ctx)
|
||||||
@ -139,6 +157,7 @@ gpgme_release (gpgme_ctx_t ctx)
|
|||||||
if (ctx->lc_messages)
|
if (ctx->lc_messages)
|
||||||
free (ctx->lc_messages);
|
free (ctx->lc_messages);
|
||||||
_gpgme_engine_info_release (ctx->engine_info);
|
_gpgme_engine_info_release (ctx->engine_info);
|
||||||
|
DESTROY_LOCK (ctx->lock);
|
||||||
free (ctx);
|
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. */
|
/* Cancel a pending asynchronous operation. */
|
||||||
gpgme_error_t gpgme_cancel (gpgme_ctx_t ctx);
|
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
|
struct _gpgme_invalid_key
|
||||||
{
|
{
|
||||||
|
@ -76,6 +76,9 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type)
|
|||||||
type &= 255;
|
type &= 255;
|
||||||
|
|
||||||
_gpgme_release_result (ctx);
|
_gpgme_release_result (ctx);
|
||||||
|
LOCK (ctx->lock);
|
||||||
|
ctx->canceled = 0;
|
||||||
|
UNLOCK (ctx->lock);
|
||||||
|
|
||||||
if (ctx->engine && no_reset)
|
if (ctx->engine && no_reset)
|
||||||
reuse_engine = 1;
|
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)
|
if (fdt.fds[i].fd != -1 && fdt.fds[i].signaled)
|
||||||
{
|
{
|
||||||
gpgme_ctx_t ictx;
|
gpgme_ctx_t ictx;
|
||||||
gpgme_error_t err;
|
gpgme_error_t err = 0;
|
||||||
struct wait_item_s *item;
|
struct wait_item_s *item;
|
||||||
|
|
||||||
assert (nr);
|
assert (nr);
|
||||||
@ -310,7 +310,13 @@ gpgme_wait (gpgme_ctx_t ctx, gpgme_error_t *status, int hang)
|
|||||||
ictx = item->ctx;
|
ictx = item->ctx;
|
||||||
assert (ictx);
|
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)
|
if (err)
|
||||||
{
|
{
|
||||||
/* An error occured. Close all fds in this context,
|
/* 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);
|
assert (nr);
|
||||||
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)
|
if (err)
|
||||||
{
|
{
|
||||||
/* An error occured. Close all fds in this context,
|
/* An error occured. Close all fds in this context,
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
gpgme_error_t
|
gpgme_error_t
|
||||||
_gpgme_user_io_cb_handler (void *data, int fd)
|
_gpgme_user_io_cb_handler (void *data, int fd)
|
||||||
{
|
{
|
||||||
gpgme_error_t err;
|
gpgme_error_t err = 0;
|
||||||
struct tag *tag = (struct tag *) data;
|
struct tag *tag = (struct tag *) data;
|
||||||
gpgme_ctx_t ctx;
|
gpgme_ctx_t ctx;
|
||||||
|
|
||||||
@ -47,7 +47,13 @@ _gpgme_user_io_cb_handler (void *data, int fd)
|
|||||||
ctx = tag->ctx;
|
ctx = tag->ctx;
|
||||||
assert (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)
|
if (err)
|
||||||
{
|
{
|
||||||
unsigned int idx;
|
unsigned int idx;
|
||||||
|
Loading…
Reference in New Issue
Block a user