doc/
authorMarcus Brinkmann <mb@g10code.com>
Tue, 16 Jun 2009 14:43:38 +0000 (14:43 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Tue, 16 Jun 2009 14:43:38 +0000 (14:43 +0000)
2009-06-16  Marcus Brinkmann  <marcus@g10code.de>

* gpgme.texi (Result Management): New section.

src/
2009-06-16  Marcus Brinkmann  <marcus@g10code.de>

* gpgme.c (result_ref_lock): New global variable.
(gpgme_result_ref, gpgme_result_unref): use it.

NEWS
doc/ChangeLog
doc/gpgme.texi
src/ChangeLog
src/gpgme.c

diff --git a/NEWS b/NEWS
index 232ff537ba6351f7528dcfef45b6eadbf3a47956..2f6c4372d8bbdd493681a59b25d37e4de05b22a7 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-Noteworthy changes in version 1.2.0
+Noteworthy changes in version 1.2.0 (unreleased)
 ------------------------------------------------
 
  * New encryption flag GPGME_ENCRYPT_NO_ENCRYPT_TO to disable default
@@ -11,6 +11,16 @@ Noteworthy changes in version 1.2.0
  * New functions gpgme_io_read and gpgme_io_write for use with
    gpgme_passphrase_cb_t and gpgme_edit_cb_t functions.
 
+ * New functions gpgme_result_ref and gpgme_result_unref to detach
+   result structures from a context.
+
+ * New functions gpgme_op_export_keys_start and gpgme_op_export_keys
+   that allow to specify exported keys through gpgme_key_t objects
+   instead of patterns.
+
+ * New mode of operation gpgme_export_mode_t that allows exporting
+   external keys.
+
  * Interface changes relative to the 1.1.7 release:
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  GPGME_KEYLIST_MODE_EPHEMERAL   NEW.
index 5138a57fb34f7ddcbe624dc237961fa38d61ff6b..6bc623b42abd2ef3e5128333a8441f75de804148 100644 (file)
@@ -1,3 +1,7 @@
+2009-06-16  Marcus Brinkmann  <marcus@g10code.de>
+
+       * gpgme.texi (Result Management): New section.
+
 2009-06-16  Werner Koch  <wk@g10code.com>
 
        * gpgme.texi (Exporting Keys): Document gpgme_op_export_keys.
index a6f15d18958bcac948d35e59f58aef8eb6392b8a..8ecb449d344a4c9c40d02c55dadc3c5984dbcf25 100644 (file)
@@ -173,6 +173,7 @@ Contexts
 
 * Creating Contexts::             Creating new @acronym{GPGME} contexts.
 * Destroying Contexts::           Releasing @acronym{GPGME} contexts.
+* Result Management::             Managing the result of crypto operations.
 * Context Attributes::            Setting properties of a context.
 * Key Management::                Managing keys with @acronym{GPGME}.
 * Trust Item Management::         Managing trust items with @acronym{GPGME}.
@@ -1971,6 +1972,7 @@ cryptographic operations.
 @menu
 * Creating Contexts::             Creating new @acronym{GPGME} contexts.
 * Destroying Contexts::           Releasing @acronym{GPGME} contexts.
+* Result Management::             Managing the result of crypto operations.
 * Context Attributes::            Setting properties of a context.
 * Key Management::                Managing keys with @acronym{GPGME}.
 * Trust Item Management::         Managing trust items with @acronym{GPGME}.
@@ -2008,6 +2010,38 @@ The function @code{gpgme_release} destroys the context with the handle
 @end deftypefun
 
 
+@node Result Management
+@section Result Management
+@cindex context, result of operation
+
+The detailed result of an operation is returned in operation-specific
+structures such as @code{gpgme_decrypt_result_t}.  The corresponding
+retrieval functions such as @code{gpgme_op_decrypt_result} provide
+static access to the results after an operation completes.  The
+following interfaces make it possible to detach a result structure
+from its associated context and give it a lifetime beyond that of the
+current operation or context.
+
+@deftypefun void gpgme_result_ref (@w{void *@var{result}})
+The function @code{gpgme_result_ref} acquires an additional reference
+for the result @var{result}, which may be of any type
+@code{gpgme_*_result_t}.  As long as the user holds a reference, the
+result structure is guaranteed to be valid and unmodified.
+@end deftypefun
+
+@deftypefun void gpgme_result_unref (@w{void *@var{result}})
+The function @code{gpgme_result_unref} releases a reference for the
+result @var{result}.  If this was the last reference, the result
+structure will be destroyed and all resources associated to it will be
+released.
+@end deftypefun
+
+Note that a context may hold its own references to result structures,
+typically until the context is destroyed or the next operation is
+started.  In fact, these references are accessed through the
+@code{gpgme_op_*_result} functions.
+
+
 @node Context Attributes
 @section Context Attributes
 @cindex context, attributes
index dc1e11645126a947c29ac622838d2128f3a073a8..68619136fd5b237ace75e960b485f0c140da29b2 100644 (file)
@@ -1,3 +1,8 @@
+2009-06-16  Marcus Brinkmann  <marcus@g10code.de>
+
+       * gpgme.c (result_ref_lock): New global variable.
+       (gpgme_result_ref, gpgme_result_unref): use it.
+
 2009-06-16  Werner Koch  <wk@g10code.com>
 
        * gpgme.h.in (gpgme_op_export_keys_start, gpgme_op_export_keys): New.
index 2372a06ab63e2d7255da5cfd7cd829ce95c23246..73788e7e7f74771141154985c7c43c97acb1f0c5 100644 (file)
@@ -45,6 +45,10 @@ static char *def_lc_messages;
 \f
 gpgme_error_t _gpgme_selftest = GPG_ERR_NOT_OPERATIONAL;
 
+/* Protects all reference counters in result structures.  All other
+   accesses to a key are read only.  */
+DEFINE_STATIC_LOCK (result_ref_lock);
+
 \f
 /* Create a new context as an environment for GPGME crypto
    operations.  */
@@ -178,29 +182,39 @@ gpgme_release (gpgme_ctx_t ctx)
 void
 gpgme_result_ref (void *result)
 {
-  struct ctx_op_data *data = result - sizeof (struct ctx_op_data);
+  struct ctx_op_data *data;
 
   if (! result)
     return;
 
+  data = result - sizeof (struct ctx_op_data);
+
+  LOCK (result_ref_lock);
   data->references++;
+  UNLOCK (result_ref_lock);
 }
 
 
 void
 gpgme_result_unref (void *result)
 {
-  struct ctx_op_data *data = result - sizeof (struct ctx_op_data);
+  struct ctx_op_data *data;
 
   if (! result)
     return;
 
-  if (--data->references == 0)
+  data = result - sizeof (struct ctx_op_data);
+
+  LOCK (result_ref_lock);
+  if (--data->references)
     {
-      if (data->cleanup)
-       (*data->cleanup) (data->hook);
-      free (data);
+      UNLOCK (result_ref_lock);
+      return;
     }
+
+  if (data->cleanup)
+    (*data->cleanup) (data->hook);
+  free (data);
 }