diff options
author | Ken Raeburn <raeburn@mit.edu> | 2005-06-01 00:56:01 +0000 |
---|---|---|
committer | Ken Raeburn <raeburn@mit.edu> | 2005-06-01 00:56:01 +0000 |
commit | f249fb8ae3f7ee30805efdda0375868a5b636a3f (patch) | |
tree | b380f64e2e5753acf88bb143626b0d986d4bbbe9 /src | |
parent | 9f2a7a71d53a08dafdf63616f4bab31749370393 (diff) | |
download | krb5-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/ChangeLog | 11 | ||||
-rw-r--r-- | src/util/support/libkrb5support.exports | 1 | ||||
-rw-r--r-- | src/util/support/threads.c | 57 |
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 |