summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2005-06-01 00:56:01 +0000
committerKen Raeburn <raeburn@mit.edu>2005-06-01 00:56:01 +0000
commitf249fb8ae3f7ee30805efdda0375868a5b636a3f (patch)
treeb380f64e2e5753acf88bb143626b0d986d4bbbe9 /src
parent9f2a7a71d53a08dafdf63616f4bab31749370393 (diff)
downloadkrb5-f249fb8ae3f7ee30805efdda0375868a5b636a3f.tar.gz
krb5-f249fb8ae3f7ee30805efdda0375868a5b636a3f.tar.xz
krb5-f249fb8ae3f7ee30805efdda0375868a5b636a3f.zip
Add run-time determination of whether thread support is available in the
support library. Check lots of weak references, and call pthread_once a couple of times, to distinguish a broken stub from the real thing. * threads.c [HAVE_PRAGMA_WEAK_REF]: Declare pthread_{g,s}etspecific, pthread_key_{create,delete}, pthread_{create,join} as weak references. (krb5int_pthread_loaded, loaded_test_aux) [HAVE_PRAGMA_WEAK_REF]: New functions. (flag_pthread_loaded, loaded_test_once) [HAVE_PRAGMA_WEAK_REF]: New variables. * libkrb5support.exports: Add krb5int_pthread_loaded. ticket: 3084 status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@17223 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r--src/util/support/ChangeLog11
-rw-r--r--src/util/support/libkrb5support.exports1
-rw-r--r--src/util/support/threads.c57
3 files changed, 68 insertions, 1 deletions
diff --git a/src/util/support/ChangeLog b/src/util/support/ChangeLog
index fa6147e92..eae47fc66 100644
--- a/src/util/support/ChangeLog
+++ b/src/util/support/ChangeLog
@@ -1,3 +1,14 @@
+2005-05-31 Ken Raeburn <raeburn@mit.edu>
+
+ * threads.c [HAVE_PRAGMA_WEAK_REF]: Declare
+ pthread_{g,s}etspecific, pthread_key_{create,delete},
+ pthread_{create,join} as weak references.
+ (krb5int_pthread_loaded, loaded_test_aux) [HAVE_PRAGMA_WEAK_REF]:
+ New functions.
+ (flag_pthread_loaded, loaded_test_once) [HAVE_PRAGMA_WEAK_REF]:
+ New variables.
+ * libkrb5support.exports: Add krb5int_pthread_loaded.
+
2005-05-17 Ken Raeburn <raeburn@mit.edu>
* fake-addrinfo.c (fai_add_hosts_by_name): Pass null pointer
diff --git a/src/util/support/libkrb5support.exports b/src/util/support/libkrb5support.exports
index 2464c02d4..9607ef822 100644
--- a/src/util/support/libkrb5support.exports
+++ b/src/util/support/libkrb5support.exports
@@ -10,3 +10,4 @@ krb5int_freeaddrinfo
krb5int_gai_strerror
krb5int_getnameinfo
krb5int_in6addr_any
+krb5int_pthread_loaded
diff --git a/src/util/support/threads.c b/src/util/support/threads.c
index e1e56e20d..d07b6ffff 100644
--- a/src/util/support/threads.c
+++ b/src/util/support/threads.c
@@ -1,7 +1,7 @@
/*
* util/support/threads.c
*
- * Copyright 2004 by the Massachusetts Institute of Technology.
+ * Copyright 2004,2005 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
@@ -106,6 +106,61 @@ struct tsd_block {
# pragma weak pthread_setspecific
# pragma weak pthread_key_create
# pragma weak pthread_key_delete
+# pragma weak pthread_create
+# pragma weak pthread_join
+static volatile int flag_pthread_loaded = -1;
+static void loaded_test_aux(void)
+{
+ if (flag_pthread_loaded == -1)
+ flag_pthread_loaded = 1;
+ else
+ /* Could we have been called twice? */
+ flag_pthread_loaded = 0;
+}
+static pthread_once_t loaded_test_once = PTHREAD_ONCE_INIT;
+int krb5int_pthread_loaded (void)
+{
+ int x = flag_pthread_loaded;
+ if (x != -1)
+ return x;
+ if (&pthread_getspecific == 0
+ || &pthread_setspecific == 0
+ || &pthread_key_create == 0
+ || &pthread_key_delete == 0
+ || &pthread_once == 0
+ || &pthread_mutex_lock == 0
+ || &pthread_mutex_unlock == 0
+ || &pthread_mutex_destroy == 0
+ || &pthread_mutex_init == 0
+ || &pthread_self == 0
+ || &pthread_equal == 0
+ /* This catches Solaris 9. May be redundant with the above
+ tests now. */
+# ifdef HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP_IN_THREAD_LIB
+ || &pthread_mutexattr_setrobust_np == 0
+# endif
+ /* Any program that's really multithreaded will have to be
+ able to create threads. */
+ || &pthread_create == 0
+ || &pthread_join == 0
+ /* Okay, all the interesting functions -- or stubs for them --
+ seem to be present. If we call pthread_once, does it
+ actually seem to cause the indicated function to get called
+ exactly one time? */
+ || pthread_once(&loaded_test_once, loaded_test_aux) != 0
+ || pthread_once(&loaded_test_once, loaded_test_aux) != 0
+ /* This catches cases where pthread_once does nothing, and
+ never causes the function to get called. That's a pretty
+ clear violation of the POSIX spec, but hey, it happens. */
+ || flag_pthread_loaded < 0) {
+ flag_pthread_loaded = 0;
+ return 0;
+ }
+ /* If we wanted to be super-paranoid, we could try testing whether
+ pthread_get/setspecific work, too. I don't know -- so far --
+ of any system with non-functional stubs for those. */
+ return flag_pthread_loaded;
+}
static struct tsd_block tsd_if_single;
# define GET_NO_PTHREAD_TSD() (&tsd_if_single)
#else