2003-09-14  Marcus Brinkmann  <marcus@g10code.de>

	* gpgme.texi (Multi Threading): Correct documentation on memory
	synchronization requirement.

tests/
2003-09-14  Marcus Brinkmann  <marcus@g10code.de>

	* gpg/t-thread1.c (main): Call init_gpgme here.
	(initialize_gpgme): Function removed.
This commit is contained in:
Marcus Brinkmann 2003-09-14 14:48:48 +00:00
parent 0a952a59b6
commit b4473cfffd
4 changed files with 19 additions and 61 deletions

View File

@ -1,5 +1,8 @@
2003-09-14 Marcus Brinkmann <marcus@g10code.de> 2003-09-14 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Multi Threading): Correct documentation on memory
synchronization requirement.
* gpgme.texi (Locale): New section. * gpgme.texi (Locale): New section.
(Multi Threading): Set locale in example. (Multi Threading): Set locale in example.

View File

@ -551,51 +551,17 @@ For example, if you use GNU Pth, the right name is
@item @item
The function @code{gpgme_check_version} must be called before any The function @code{gpgme_check_version} must be called before any
other function in the library, because it initializes the thread other function in the library, because it initializes the thread
support subsystem in @acronym{GPGME}. To achieve this in all support subsystem in @acronym{GPGME}. To achieve this in
generality, it is necessary to synchronize the call to this function multi-threaded programs, you must synchronize the memory with respect
with all other calls to functions in the library, using the to other threads that also want to use @acronym{GPGME}. For this, it
synchronization mechanisms available in your thread library. is sufficient to call @code{gpgme_check_version} before creating the
Otherwise, specific compiler or CPU memory cache optimizations could other threads using @acronym{GPGME}@footnote{At least this is true for
lead to the situation where a thread is started and uses POSIX threads, as @code{pthread_create} is a function that
@acronym{GPGME} before the effects of the initialization are visible synchronizes memory with respects to other threads. There are many
for this thread. It doesn't even suffice to call functions which have this property, a complete list can be found in
@code{gpgme_check_version} before creating this other POSIX, IEEE Std 1003.1-2003, Base Definitions, Issue 6, in the
thread@footnote{In SMP systems the new thread could be started on definition of the term ``Memory Synchronization''. For other thread
another CPU before the effects of the initialization are seen by that packages other, more relaxed or more strict rules may apply.}.
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 <stdlib.h>
#include <locale.h>
#include <pthread.h>
#include <gpgme.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 (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
@item @item
Any @code{gpgme_data_t} and @code{gpgme_ctx_t} object must only be Any @code{gpgme_data_t} and @code{gpgme_ctx_t} object must only be

View File

@ -1,5 +1,8 @@
2003-09-14 Marcus Brinkmann <marcus@g10code.de> 2003-09-14 Marcus Brinkmann <marcus@g10code.de>
* gpg/t-thread1.c (main): Call init_gpgme here.
(initialize_gpgme): Function removed.
* gpg/t-thread1.c: New file. * gpg/t-thread1.c: New file.
* gpg/Makefile.am (TESTS): Add t-thread1.c. * gpg/Makefile.am (TESTS): Add t-thread1.c.
(t_thread1_LDADD): New variable. (t_thread1_LDADD): New variable.

View File

@ -31,22 +31,6 @@
#define ROUNDS 20 #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 * void *
thread_one (void *name) thread_one (void *name)
@ -156,6 +140,8 @@ main (int argc, char *argv[])
pthread_t tone; pthread_t tone;
pthread_t ttwo; pthread_t ttwo;
init_gpgme (GPGME_PROTOCOL_OpenPGP);
pthread_create (&tone, NULL, thread_one, "A"); pthread_create (&tone, NULL, thread_one, "A");
pthread_create (&ttwo, NULL, thread_two, "A"); pthread_create (&ttwo, NULL, thread_two, "A");