diff options
author | Marcus Brinkmann <[email protected]> | 2002-05-09 03:38:12 +0000 |
---|---|---|
committer | Marcus Brinkmann <[email protected]> | 2002-05-09 03:38:12 +0000 |
commit | 4e0d4d7cf3e630fbde187c506799048a3f359fc1 (patch) | |
tree | ea81a03cf56216cd56be94605e474aff0f5de05c /doc | |
parent | revoce the previous commit, this was done erroneously (diff) | |
download | gpgme-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/ChangeLog | 5 | ||||
-rw-r--r-- | doc/gpgme.texi | 85 |
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 |