From f249fb8ae3f7ee30805efdda0375868a5b636a3f Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Wed, 1 Jun 2005 00:56:01 +0000 Subject: [PATCH] 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 --- src/util/support/ChangeLog | 11 +++++ src/util/support/libkrb5support.exports | 1 + src/util/support/threads.c | 57 ++++++++++++++++++++++++- 3 files changed, 68 insertions(+), 1 deletion(-) 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 + + * 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 * 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 -- 2.26.2