aboutsummaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/ChangeLog5
-rw-r--r--doc/gpgme.texi85
2 files changed, 85 insertions, 5 deletions
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 19b141e5..a5c7c5e0 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,8 @@
+2002-05-09 Marcus Brinkmann <[email protected]>
+
+ * gpgme.texi (Overview): Replace note about thread-safeness.
+ (Multi Threading): New section.
+
2002-05-03 Werner Koch <[email protected]>
* gpgme.texi (Manipulating Data Buffers): Changed some data types
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index 0061274b..9606eedd 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -104,6 +104,7 @@ Preparation
* Header:: What header file you need to include.
* Building the Source:: Compiler options to be used.
* Library Version Check:: Getting and verifying the library version.
+* Multi Threading:: How GPGME can be used in an MT environment.
Protocols and Engines
@@ -278,11 +279,9 @@ including listing keys, querying their attributes, generating,
importing, exporting and deleting keys, and acquiring information
about the trust path.
-@cindex thread-safeness
-@cindex multi-threading
-@strong{Caution:} The @acronym{GPGME} library is not thread-safe. It
-will be to some extent in the future, but currently great care has to
-be taken if @acronym{GPGME} is used in a multi-threaded environment.
+With some precautions, @acronym{GPGME} can be used in a multi-threaded
+environment, although it is not completely thread safe and thus needs
+the support of the application.
@node Preparation
@@ -298,6 +297,7 @@ of the library are verified.
* Header:: What header file you need to include.
* Building the Source:: Compiler options to be used.
* Library Version Check:: Getting and verifying the library version.
+* Multi Threading:: How GPGME can be used in an MT environment.
@end menu
@@ -402,6 +402,81 @@ features are provided by the installed version of the library.
@end deftypefun
+@node Multi Threading
+@section Multi Threading
+@cindex thread-safeness
+@cindex multi-threading
+
+The @acronym{GPGME} library is not entirely thread-safe, but it can
+still be used in a multi-threaded environment if some care is taken.
+If the following requirements are met, there should be no race
+conditions to worry about:
+
+@itemize @bullet
+@item
+The function @code{gpgme_check_version} must be called before any
+other function in the library, because it initializes the locking
+subsystem in @acronym{GPGME}. To achieve this in all generality, it
+is necessary to synchronize the call to this function with all other
+calls to functions in the library, using the synchronization
+mechanisms available in your thread library. Otherwise, specific
+compiler or CPU memory cache optimizations could lead to the situation
+where a thread is started and uses @acronym{GPGME} before the effects
+of the initialization are visible for this thread. It doesn't even
+suffice to call @code{gpgme_check_version} before creating this other
+thread@footnote{In SMP systems the new thread could be started on
+another CPU before the effects of the initialization are seen by that
+CPU's memory cache. Not doing proper synchronization here leads to
+the same problems the double-checked locking idiom has. You might
+find that if you don't do proper synchronization, it still works in
+most configurations. Don't let this fool you. Someday it might lead
+to subtle bugs when someone tries it on a DEC Alpha or an SMP
+machine.}.
+
+For example, if you are using POSIX threads, each thread that wants to
+call functions in @acronym{GPGME} could call the following function
+before any function in the library:
+
+@example
+#include <pthread.h>
+
+void
+initialize_gpgme (void)
+{
+ static int gpgme_init;
+ static pthread_mutext_t gpgme_init_lock = PTHREAD_MUTEX_INITIALIZER;
+
+ pthread_mutex_lock (&gpgme_init_lock);
+ if (!gpgme_init)
+ {
+ gpgme_check_version ();
+ gpgme_init = 1;
+ }
+ pthread_mutex_unlock (&gpgme_init_lock);
+}
+@end example
+
+@item
+Any @code{GpgmeData}, @code{GpgmeCtx} and @code{GpgmeRecipients}
+object must only be accessed by one thread at a time. If multiple
+threads want to deal with the same object, the caller has to make sure
+that operations on this object are fully synchronized.
+
+@item
+Only one thread is allowed to call @code{gpgme_wait} at a time. If
+multiple threads call this function, the caller must make sure that
+all invocations are fully synchronized.
+
+@item
+Unfortunately, the last rule implies that all calls to one of the
+following functions have to be fully synchronized together with
+@code{gpgme_wait}, as they call @code{gpgme_wait} internally: All
+functions @code{gpgme_op_FOO} that have a corresponding
+@code{gpgme_op_FOO_start} function, @code{gpgme_op_keylist_next},
+@code{gpgme_op_trustlist_next}.
+@end itemize
+
+
@node Protocols and Engines
@chapter Protocols and Engines
@cindex protocol