Index: include/k5-thread.h
===================================================================
RCS file: /cvs/krbdev/krb5/src/include/k5-thread.h,v
retrieving revision 1.22.2.2
diff -p -u -r1.22.2.2 k5-thread.h
--- include/k5-thread.h	24 Jan 2005 20:46:41 -0000	1.22.2.2
+++ include/k5-thread.h	1 Jun 2005 03:09:28 -0000
@@ -372,14 +372,8 @@ typedef k5_os_nothread_mutex k5_os_mutex
 # ifdef HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP_IN_THREAD_LIB
 #  pragma weak pthread_mutexattr_setrobust_np
 # endif
-# if !defined HAVE_PTHREAD_ONCE
-#  define K5_PTHREADS_LOADED	(&pthread_once != 0)
-# elif !defined HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP \
-	&& defined HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP_IN_THREAD_LIB
-#  define K5_PTHREADS_LOADED	(&pthread_mutexattr_setrobust_np != 0)
-# else
-#  define K5_PTHREADS_LOADED	(1)
-# endif
+extern int krb5int_pthread_loaded(void);
+# define K5_PTHREADS_LOADED	(krb5int_pthread_loaded())
 #else
 /* no pragma weak support */
 # define K5_PTHREADS_LOADED	(1)
@@ -404,6 +398,8 @@ typedef k5_os_nothread_mutex k5_os_mutex
 #endif
 
 #if !defined(HAVE_PTHREAD_MUTEX_LOCK) && !defined(USE_PTHREAD_LOCK_ONLY_IF_LOADED)
+/* If we find a system with a broken stub for pthread_mutex_lock,
+   we may have to change this.  */
 # define USE_PTHREAD_LOCK_ONLY_IF_LOADED
 #endif
 
Index: util/support/libkrb5support.exports
===================================================================
RCS file: /cvs/krbdev/krb5/src/util/support/libkrb5support.exports,v
retrieving revision 1.3
diff -p -u -r1.3 libkrb5support.exports
--- util/support/libkrb5support.exports	25 Oct 2004 19:09:54 -0000	1.3
+++ util/support/libkrb5support.exports	1 Jun 2005 03:09:30 -0000
@@ -5,3 +5,4 @@ krb5int_setspecific
 krb5int_fac
 krb5int_lock_fac
 krb5int_unlock_fac
+krb5int_pthread_loaded
Index: util/support/threads.c
===================================================================
RCS file: /cvs/krbdev/krb5/src/util/support/threads.c,v
retrieving revision 1.11.4.3
diff -p -u -r1.11.4.3 threads.c
--- util/support/threads.c	23 Mar 2005 03:58:01 -0000	1.11.4.3
+++ util/support/threads.c	1 Jun 2005 03:09:30 -0000
@@ -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
