aboutsummaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorMarcus Brinkmann <[email protected]>2002-05-09 03:38:12 +0000
committerMarcus Brinkmann <[email protected]>2002-05-09 03:38:12 +0000
commit4e0d4d7cf3e630fbde187c506799048a3f359fc1 (patch)
treeea81a03cf56216cd56be94605e474aff0f5de05c /doc
parentrevoce the previous commit, this was done erroneously (diff)
downloadgpgme-4e0d4d7cf3e630fbde187c506799048a3f359fc1.tar.gz
gpgme-4e0d4d7cf3e630fbde187c506799048a3f359fc1.zip
doc/
2002-05-09 Marcus Brinkmann <[email protected]> * gpgme.texi (Overview): Replace note about thread-safeness. (Multi Threading): New section. gpgme/ 2002-05-08 Marcus Brinkmann <[email protected]> * w32-util.c: New static variable GET_PATH_LOCK. (_gpgme_get_gpg_path): Remove superfluous NULL initializer. Take lock while determining path. (_gpgme_get_gpgsm_path): Likewise. * version.c (do_subsystem_inits): Set DONE to 1 after initialization. (gpgme_get_engine_info): New variable ENGINE_INFO_LOCK. Take lock while determining engine info. * rungpg.c (_gpgme_gpg_get_version): New variable GPG_VERSION_LOCK. Take the lock while determining the program version. * posix-io.c: Include "sema.h". (_gpgme_io_spawn): New variable FIXED_SIGNALS_LOCK. Take the lock while fixing the signals. (_gpgme_io_select): Make READFDS and WRITEFDS non-static. * key.c: Include "sema.h". New globals KEY_CACHE_LOCK and KEY_REF_LOCK. (capabilities_to_string): Make STRINGS very const. (_gpgme_key_cache_add): Lock the key cache. (_gpgme_key_cache_get): Likewise. (gpgme_key_ref, gpgme_key_release): Lock the key_ref_lock. * import.c (append_xml_impinfo): Make IMPORTED_FIELDS and IMPORT_RES_FIELDS very const. Make FIELD and FIELD_NAME a litle const. * engine.c (_gpgme_engine_get_info): New variable ENGINE_INFO_LOCK. Take lock while determining engine info. * engine-gpgsm.c: Include "sema.h". (_gpgme_gpgsm_get_version): New variable GPGSM_VERSION_LOCK. Take lock while getting program version.
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