* threads.c (key_lock): Change to a k5_mutex_t.
authorKen Raeburn <raeburn@mit.edu>
Mon, 21 Jun 2004 20:58:34 +0000 (20:58 +0000)
committerKen Raeburn <raeburn@mit.edu>
Mon, 21 Jun 2004 20:58:34 +0000 (20:58 +0000)
(k5_key_register): Use k5_ lock routines.
(pthread_getspecific, pthread_setspecific, pthread_key_create,
pthread_key_delete) [HAVE_PRAGMA_WEAK_REF]: Declare weak.
(tsd_if_single) [HAVE_PRAGMA_WEAK_REF]: New variable.
(krb5int_thread_support_init): Do pthread key creation only if pthread code is
loaded.
(krb5int_thread_support_fini): Do pthread key deletion only if pthread code is
loaded.
(k5_key_register, k5_getspecific, k5_setspecific): Use tsd_if_single when
pthread code is not loaded.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@16502 dc483132-0cff-0310-8789-dd5450dbe970

src/util/support/ChangeLog
src/util/support/threads.c

index 15d2eff1a70dfa1cadf99f0148ac0c2cecee4fcb..b8ef14bcb1d1bf7301508222167eb2b8ae195cd0 100644 (file)
@@ -1,3 +1,17 @@
+2004-06-21  Ken Raeburn  <raeburn@mit.edu>
+
+       * threads.c (key_lock): Change to a k5_mutex_t.
+       (k5_key_register): Use k5_ lock routines.
+       (pthread_getspecific, pthread_setspecific, pthread_key_create,
+       pthread_key_delete) [HAVE_PRAGMA_WEAK_REF]: Declare weak.
+       (tsd_if_single) [HAVE_PRAGMA_WEAK_REF]: New variable.
+       (krb5int_thread_support_init): Do pthread key creation only if
+       pthread code is loaded.
+       (krb5int_thread_support_fini): Do pthread key deletion only if
+       pthread code is loaded.
+       (k5_key_register, k5_getspecific, k5_setspecific): Use
+       tsd_if_single when pthread code is not loaded.
+
 2004-06-17  Ken Raeburn  <raeburn@mit.edu>
 
        * Makefile.in (BUILDTOP, LIBNAME, XTRA, OBJFILE): Define for
index 13a2e420f54f0cc3892bb7177306ba1c1d4861fe..60c0bad8cddf75d607ef32f615bc397420171a80 100644 (file)
@@ -148,7 +148,7 @@ void krb5int_thread_detach_hook (void)
    loaded so this support code stays in the process, and gssapi is
    loaded, unloaded, and loaded again.  */
 
-static pthread_mutex_t key_lock = PTHREAD_MUTEX_INITIALIZER;
+static k5_mutex_t key_lock = K5_MUTEX_PARTIAL_INITIALIZER;
 static void (*destructors[K5_KEY_MAX])(void *);
 static unsigned char destructors_set[K5_KEY_MAX];
 
@@ -167,19 +167,37 @@ struct tsd_block {
     void *values[K5_KEY_MAX];
 };
 
+#ifdef HAVE_PRAGMA_WEAK_REF
+# pragma weak pthread_getspecific
+# pragma weak pthread_setspecific
+# pragma weak pthread_key_create
+# pragma weak pthread_key_delete
+static struct tsd_block tsd_if_single;
+#endif
+
 static pthread_key_t key;
 static void thread_termination(void *);
 
 int krb5int_thread_support_init(void)
 {
-    return pthread_key_create(&key, thread_termination);
+    int err;
+    err = k5_mutex_finish_init(&key_lock);
+    if (err)
+       return err;
+    if (K5_PTHREADS_LOADED)
+       return pthread_key_create(&key, thread_termination);
+    else
+       return 0;
 }
 
 void krb5int_thread_support_fini(void)
 {
-    /* ... delete stuff ... */
-    if (INITIALIZER_RAN(krb5int_thread_support_init))
+    if (! INITIALIZER_RAN(krb5int_thread_support_init))
+       return;
+    if (K5_PTHREADS_LOADED)
        pthread_key_delete(key);
+    /* ... delete stuff ... */
+    k5_mutex_destroy(&key_lock);
 }
 
 static void thread_termination (void *tptr)
@@ -215,14 +233,17 @@ int k5_key_register (k5_key_t keynum, void (*destructor)(void *))
 {
     int err;
 
-    err = pthread_mutex_lock(&key_lock);
+    err = CALL_INIT_FUNCTION(krb5int_thread_support_init);
+    if (err)
+       return err;
+    err = k5_mutex_lock(&key_lock);
     if (err)
        return err;
     assert(keynum >= 0 && keynum < K5_KEY_MAX);
     assert(destructors_set[keynum] == 0);
     destructors_set[keynum] = 1;
     destructors[keynum] = destructor;
-    err = pthread_mutex_unlock(&key_lock);
+    err = k5_mutex_unlock(&key_lock);
     if (err)
        return err;
     return 0;
@@ -240,7 +261,15 @@ void *k5_getspecific (k5_key_t keynum)
     assert(keynum >= 0 && keynum < K5_KEY_MAX);
     assert(destructors_set[keynum] != 0);
 
-    t = pthread_getspecific(key);
+    if (K5_PTHREADS_LOADED)
+       t = pthread_getspecific(key);
+    else {
+#ifdef HAVE_PRAGMA_WEAK_REF
+       t = &tsd_if_single;
+#else
+       abort();
+#endif
+    }
     if (t == NULL)
        return NULL;
 
@@ -259,21 +288,29 @@ int k5_setspecific (k5_key_t keynum, void *value)
     assert(keynum >= 0 && keynum < K5_KEY_MAX);
     assert(destructors_set[keynum] != 0);
 
-    t = pthread_getspecific(key);
-    if (t == NULL) {
-       int i;
-       t = malloc(sizeof(*t));
-       if (t == NULL)
-           return errno;
-       for (i = 0; i < K5_KEY_MAX; i++)
-           t->values[i] = 0;
-       /* add to global linked list */
-       t->next = 0;
-       err = pthread_setspecific(key, t);
-       if (err) {
-           free(t);
-           return err;
+    if (K5_PTHREADS_LOADED) {
+       t = pthread_getspecific(key);
+       if (t == NULL) {
+           int i;
+           t = malloc(sizeof(*t));
+           if (t == NULL)
+               return errno;
+           for (i = 0; i < K5_KEY_MAX; i++)
+               t->values[i] = 0;
+           /* add to global linked list */
+           t->next = 0;
+           err = pthread_setspecific(key, t);
+           if (err) {
+               free(t);
+               return err;
+           }
        }
+    } else {
+#ifdef HAVE_PRAGMA_WEAK_REF
+       t = &tsd_if_single;
+#else
+       abort();
+#endif
     }
 
     t->values[keynum] = value;