From b4473cfffd836c7f7e69069cec2b6feb2f10f1d3 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Sun, 14 Sep 2003 14:48:48 +0000 Subject: [PATCH] doc/ 2003-09-14 Marcus Brinkmann * gpgme.texi (Multi Threading): Correct documentation on memory synchronization requirement. tests/ 2003-09-14 Marcus Brinkmann * gpg/t-thread1.c (main): Call init_gpgme here. (initialize_gpgme): Function removed. --- doc/ChangeLog | 3 +++ doc/gpgme.texi | 56 +++++++++---------------------------------- tests/ChangeLog | 3 +++ tests/gpg/t-thread1.c | 18 ++------------ 4 files changed, 19 insertions(+), 61 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index 11cc544b..de523fea 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,8 @@ 2003-09-14 Marcus Brinkmann + * gpgme.texi (Multi Threading): Correct documentation on memory + synchronization requirement. + * gpgme.texi (Locale): New section. (Multi Threading): Set locale in example. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index eaa197c3..c76916e3 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -551,51 +551,17 @@ For example, if you use GNU Pth, the right name is @item The function @code{gpgme_check_version} must be called before any other function in the library, because it initializes the thread -support 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 -#include -#include -#include - -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 (NULL); - gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL)); - gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL)); - gpgme_init = 1; - @} - pthread_mutex_unlock (&gpgme_init_lock); -@} -@end example +support subsystem in @acronym{GPGME}. To achieve this in +multi-threaded programs, you must synchronize the memory with respect +to other threads that also want to use @acronym{GPGME}. For this, it +is sufficient to call @code{gpgme_check_version} before creating the +other threads using @acronym{GPGME}@footnote{At least this is true for +POSIX threads, as @code{pthread_create} is a function that +synchronizes memory with respects to other threads. There are many +functions which have this property, a complete list can be found in +POSIX, IEEE Std 1003.1-2003, Base Definitions, Issue 6, in the +definition of the term ``Memory Synchronization''. For other thread +packages other, more relaxed or more strict rules may apply.}. @item Any @code{gpgme_data_t} and @code{gpgme_ctx_t} object must only be diff --git a/tests/ChangeLog b/tests/ChangeLog index 4a42e19b..01256675 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,5 +1,8 @@ 2003-09-14 Marcus Brinkmann + * gpg/t-thread1.c (main): Call init_gpgme here. + (initialize_gpgme): Function removed. + * gpg/t-thread1.c: New file. * gpg/Makefile.am (TESTS): Add t-thread1.c. (t_thread1_LDADD): New variable. diff --git a/tests/gpg/t-thread1.c b/tests/gpg/t-thread1.c index 5b765a54..4c003b12 100644 --- a/tests/gpg/t-thread1.c +++ b/tests/gpg/t-thread1.c @@ -31,22 +31,6 @@ #define ROUNDS 20 - -void -initialize_gpgme (void) -{ - static int gpgme_init; - static pthread_mutex_t gpgme_init_lock = PTHREAD_MUTEX_INITIALIZER; - - pthread_mutex_lock (&gpgme_init_lock); - if (!gpgme_init) - { - init_gpgme (GPGME_PROTOCOL_OpenPGP); - gpgme_init = 1; - } - pthread_mutex_unlock (&gpgme_init_lock); -} - void * thread_one (void *name) @@ -156,6 +140,8 @@ main (int argc, char *argv[]) pthread_t tone; pthread_t ttwo; + init_gpgme (GPGME_PROTOCOL_OpenPGP); + pthread_create (&tone, NULL, thread_one, "A"); pthread_create (&ttwo, NULL, thread_two, "A");