doc/
authorMarcus Brinkmann <mb@g10code.com>
Tue, 24 Feb 2004 23:08:48 +0000 (23:08 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Tue, 24 Feb 2004 23:08:48 +0000 (23:08 +0000)
2004-02-24  Marcus Brinkmann  <marcus@g10code.de>

* gpgme.texi (cancellation): New section.

gpgme/
2004-02-24  Marcus Brinkmann  <marcus@g10code.de>

* gpgme.c (gpgme_cancel): New function.
* engine-backend.h (struct engine_ops): New member cancel.
* engine.h (_gpgme_engine_cancel): New prototype.
* engine.c (_gpgme_engine_cancel): New function.
* engine-gpgsm.c: Add new member cancel.
(gpgsm_cancel): New function.
(gpgsm_release): Use it.
* rungpg.c: Add new member cancel.

NEWS
doc/ChangeLog
doc/gpgme.texi
gpgme/ChangeLog
gpgme/engine-backend.h
gpgme/engine-gpgsm.c
gpgme/engine.c
gpgme/engine.h
gpgme/gpgme.c
gpgme/gpgme.h
gpgme/rungpg.c

diff --git a/NEWS b/NEWS
index 5812dcf..ae00052 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -54,16 +54,19 @@ Noteworthy changes in version 0.4.5 (unreleased)
    needed.  Still, it is there if necessary.  If in doubt, contact us
    and we will give our advise for your specific situation.
 
- * A new key listing mode for validation of the key has been added.
-   See the manual.
+ * New key listing mode GPGME_KEYLIST_MODE_VALIDATE for validation of
+   the listed keys.
+
+ * New interface gpgme_cancel() that can be used to cancel
+   asynchronous operations.
 
  * Interface changes relative to the 0.4.4 release:
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 gpgme_data_seek_cb_t           CHANGED: off_t is now a largefile type.
 gpgme_data_seek                        CHANGED: off_t is now a largefile type.
 gpgme_data_new_from_filepart   CHANGED: off_t is now a largefile type.
-GPGME_KEYLIST_MODE_VALIDATE     NEW.
-
+GPGME_KEYLIST_MODE_VALIDATE     NEW
+gpgme_cancel                   NEW
 
 Noteworthy changes in version 0.4.4 (2004-01-12)
 ------------------------------------------------
index 809cc14..4bad3c3 100644 (file)
@@ -1,3 +1,7 @@
+2004-02-24  Marcus Brinkmann  <marcus@g10code.de>
+
+       * gpgme.texi (cancellation): New section.
+
 2004-02-17  Werner Koch  <wk@gnupg.org>
 
        * gpgme.texi (Key Listing Mode): Doc KEYLIST_MODE_VALIDATE.
index 3e5e898..4edf9ed 100644 (file)
@@ -201,6 +201,7 @@ Run Control
 
 * Waiting For Completion::        Waiting until an operation is completed.
 * Using External Event Loops::    Advanced control over what happens when.
+* Cancellation::                  How to end pending operations prematurely.
 
 Using External Event Loops
 
@@ -4315,6 +4316,7 @@ time.
 @menu
 * Waiting For Completion::        Waiting until an operation is completed.
 * Using External Event Loops::    Advanced control over what happens when.
+* Cancellation::                  How to end pending operations prematurely.
 @end menu
 
 
@@ -4898,6 +4900,43 @@ my_gpgme_register_io_callback (void *data, int fd, int dir, gpgme_io_cb_t fnc,
 @end example
 
 
+@node Cancellation
+@subsection Cancellation
+@cindex cryptographic operation, aborting
+@cindex cryptographic operation, cancelling
+@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.
+
+@deftypefun gpgme_ctx_t gpgme_cancel (@w{gpgme_ctx_t @var{ctx}})
+The function @code{gpgme_cancel} attempts to cancel a pending
+operation in the context @var{ctx}.  This only works if you use the
+global event loop or your own event loop.
+
+If you use the global event loop, you must not call @code{gpgme_wait}
+or @code{gpgme_wait} during cancellation.  After successful
+cancellation, you can call @code{gpgme_wait} (optionally waiting on
+@var{ctx}), and the context @var{ctx} will appear as if it had
+finished with the error code @code{GPG_ERR_CANCEL}.
+
+If you use your an external event loop, you must ensure that no I/O
+callbacks are invoked for this context (for example by halting the
+event loop).  On successful cancellation, all registered I/O callbacks
+for this context will be unregistered, and a @code{GPGME_EVENT_DONE}
+event with the error code @code{GPG_ERR_CANCEL} will be signaled.
+
+The function returns an error code if the cancellation failed (in this
+case the state of @var{ctx} is not modified).
+@end deftypefun
+
+
 @include gpl.texi
 
 
index 2a3488b..9000c17 100644 (file)
@@ -1,3 +1,14 @@
+2004-02-24  Marcus Brinkmann  <marcus@g10code.de>
+
+       * gpgme.c (gpgme_cancel): New function.
+       * engine-backend.h (struct engine_ops): New member cancel.
+       * engine.h (_gpgme_engine_cancel): New prototype.
+       * engine.c (_gpgme_engine_cancel): New function.
+       * engine-gpgsm.c: Add new member cancel.
+       (gpgsm_cancel): New function.
+       (gpgsm_release): Use it.
+       * rungpg.c: Add new member cancel.
+
 2004-02-17  Werner Koch  <wk@gnupg.org>
 
        * gpgme.h: Add GPGME_KEYLIST_MODE_VALIDATE. 
index 0632fb6..32fd242 100644 (file)
@@ -84,6 +84,8 @@ struct engine_ops
   
   void (*set_io_cbs) (void *engine, gpgme_io_cbs_t io_cbs);
   void (*io_event) (void *engine, gpgme_event_io_t type, void *type_data);
+
+  gpgme_error_t (*cancel) (void *engine);
 };
 
 
index 46c8090..9981255 100644 (file)
@@ -272,8 +272,8 @@ map_assuan_error (AssuanError err)
 }
 
 
-static void
-gpgsm_release (void *engine)
+static gpgme_error_t
+gpgsm_cancel (void *engine)
 {
   engine_gpgsm_t gpgsm = engine;
 
@@ -290,6 +290,18 @@ gpgsm_release (void *engine)
     _gpgme_io_close (gpgsm->message_cb.fd);
 
   assuan_disconnect (gpgsm->assuan_ctx);
+}
+
+
+static void
+gpgsm_release (void *engine)
+{
+  engine_gpgsm_t gpgsm = engine;
+
+  if (!gpgsm)
+    return;
+
+  gpgsm_cancel (engine);
 
   free (gpgsm->colon.attic.line);
   free (gpgsm);
@@ -1540,5 +1552,6 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
     NULL,              /* trustlist */
     gpgsm_verify,
     gpgsm_set_io_cbs,
-    gpgsm_io_event
+    gpgsm_io_event,
+    gpgsm_cancel
   };
index 4c52599..6128c2f 100644 (file)
@@ -484,3 +484,16 @@ _gpgme_engine_io_event (engine_t engine,
 
   (*engine->ops->io_event) (engine->engine, type, type_data);
 }
+
+
+gpgme_error_t
+_gpgme_engine_cancel (engine_t engine)
+{
+  if (!engine)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  if (!engine->ops->cancel)
+    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+  return (*engine->ops->cancel) (engine->engine);
+}
index d3a5403..42cec55 100644 (file)
@@ -110,4 +110,6 @@ void _gpgme_engine_set_io_cbs (engine_t engine,
 void _gpgme_engine_io_event (engine_t engine,
                             gpgme_event_io_t type, void *type_data);
 
+gpgme_error_t _gpgme_engine_cancel (engine_t engine);
+
 #endif /* ENGINE_H */
index 84862fe..de70767 100644 (file)
@@ -90,6 +90,22 @@ gpgme_new (gpgme_ctx_t *r_ctx)
 }
 
 
+/* Cancel a pending asynchronous operation.  */
+gpgme_error_t
+gpgme_cancel (gpgme_ctx_t ctx)
+{
+  gpgme_error_t err;
+
+  err = _gpgme_engine_cancel (ctx->engine);
+  if (err)
+    return err;
+
+  err = gpg_error (GPG_ERR_CANCELED);
+  _gpgme_engine_io_event (ctx->engine, GPGME_EVENT_DONE, &err);
+
+  return 0;
+}
+
 /* Release all resources associated with the given context.  */
 void
 gpgme_release (gpgme_ctx_t ctx)
index 4dd72ff..04615e6 100644 (file)
@@ -995,6 +995,10 @@ unsigned long gpgme_key_sig_get_ulong_attr (gpgme_key_t key, int uid_idx,
 \f
 /* Crypto Operations.  */
 
+/* Cancel a pending asynchronous operation.  */
+gpgme_error_t gpgme_cancel (gpgme_ctx_t ctx);
+
+\f
 struct _gpgme_invalid_key
 {
   struct _gpgme_invalid_key *next;
index 5a80f72..58c12f9 100644 (file)
@@ -1664,5 +1664,6 @@ struct engine_ops _gpgme_engine_ops_gpg =
     gpg_trustlist,
     gpg_verify,
     gpg_set_io_cbs,
-    gpg_io_event
+    gpg_io_event,
+    NULL
   };