If we find a platform with non-functional stubs and no weak
references, we may have to resort to some hack like dlsym on the
symbol tables of the current process. */
-extern int krb5int_pthread_loaded(void)
-#ifdef __GNUC__
-/* We should always get the same answer for the life of the process. */
- __attribute__((const))
-#endif
- ;
+
#if defined(HAVE_PRAGMA_WEAK_REF) && !defined(NO_WEAK_PTHREADS)
# pragma weak pthread_once
# pragma weak pthread_mutex_lock
# pragma weak pthread_mutex_init
# pragma weak pthread_self
# pragma weak pthread_equal
-# define K5_PTHREADS_LOADED (krb5int_pthread_loaded())
# define USE_PTHREAD_LOCK_ONLY_IF_LOADED
/* Can't rely on useful stubs -- see above regarding Solaris. */
k5_os_nothread_once_t n;
} k5_once_t;
# define K5_ONCE_INIT { PTHREAD_ONCE_INIT, K5_OS_NOTHREAD_ONCE_INIT }
-# define k5_once(O,F) (K5_PTHREADS_LOADED \
- ? pthread_once(&(O)->o,F) \
- : k5_os_nothread_once(&(O)->n,F))
+int k5_once(k5_once_t *once, void (*fn)(void));
#else
/* no pragma weak support */
-# define K5_PTHREADS_LOADED (1)
typedef pthread_once_t k5_once_t;
# define K5_ONCE_INIT PTHREAD_ONCE_INIT
#ifdef USE_PTHREAD_LOCK_ONLY_IF_LOADED
+# define USE_PTHREAD_LOADED_MUTEX_FUNCTIONS
# define k5_os_mutex_finish_init(M) (0)
-# define k5_os_mutex_init(M) \
- (K5_PTHREADS_LOADED ? pthread_mutex_init((M), 0) : 0)
-# define k5_os_mutex_destroy(M) \
- (K5_PTHREADS_LOADED ? pthread_mutex_destroy((M)) : 0)
-# define k5_os_mutex_lock(M) \
- (K5_PTHREADS_LOADED ? pthread_mutex_lock(M) : 0)
-# define k5_os_mutex_unlock(M) \
- (K5_PTHREADS_LOADED ? pthread_mutex_unlock(M) : 0)
+int k5_os_mutex_init(k5_os_mutex *m);
+int k5_os_mutex_destroy(k5_os_mutex *m);
+int k5_os_mutex_lock(k5_os_mutex *m);
+int k5_os_mutex_unlock(k5_os_mutex *m);
#else
#elif defined _WIN32
+# define k5_once_t k5_os_nothread_once_t
+
typedef struct {
HANDLE h;
int is_locked;
((M)->h = CreateMutex(NULL, FALSE, NULL)) ? 0 : GetLastError())
# define k5_os_mutex_destroy(M) \
(CloseHandle((M)->h) ? ((M)->h = 0, 0) : GetLastError())
+# define k5_os_mutex_lock k5_win_mutex_lock
-static inline int k5_os_mutex_lock(k5_os_mutex *m)
+static inline int k5_win_mutex_lock(k5_os_mutex *m)
{
DWORD res;
res = WaitForSingleObject(m->h, INFINITE);
MAKE_INIT_FUNCTION(krb5int_thread_support_init);
MAKE_FINI_FUNCTION(krb5int_thread_support_fini);
+#undef k5_once
+
#ifndef ENABLE_THREADS /* no thread support */
static void (*destructors[K5_KEY_MAX])(void *);
return 0;
}
+int
+k5_once(k5_once_t *once, void (*fn)(void))
+{
+ return k5_os_nothread_once(once, fn);
+}
+
#elif defined(_WIN32)
static DWORD tls_idx;
}
}
-/* Stub function not used on Windows. */
+/* Stub functions not used on Windows. */
int krb5int_pthread_loaded (void)
{
return 0;
}
+int
+k5_once(k5_once_t *once, void (*fn)(void))
+{
+ return 0;
+}
#else /* POSIX threads */
/* Must support register/delete/register sequence, e.g., if krb5 is
# pragma weak pthread_key_delete
# pragma weak pthread_create
# pragma weak pthread_join
+# define K5_PTHREADS_LOADED (krb5int_pthread_loaded())
static volatile int flag_pthread_loaded = -1;
static void loaded_test_aux(void)
{
of any system with non-functional stubs for those. */
return flag_pthread_loaded;
}
+
+int
+k5_once(k5_once_t *once, void (*fn)(void))
+{
+ if (krb5int_pthread_loaded())
+ return pthread_once(&once->o, fn);
+ else
+ return k5_os_nothread_once(&once->n, fn);
+}
+
static struct tsd_block tsd_if_single;
# define GET_NO_PTHREAD_TSD() (&tsd_if_single)
#else
+# define K5_PTHREADS_LOADED (1)
int krb5int_pthread_loaded (void)
{
return 1;
}
+
+int
+k5_once(k5_once_t *once, void (*fn)(void))
+{
+ return pthread_once(once, fn);
+}
# define GET_NO_PTHREAD_TSD() (abort(),(struct tsd_block *)0)
#endif
{
k5_mutex_unlock (m);
}
+
+#ifdef USE_PTHREAD_LOADED_MUTEX_FUNCTIONS
+
+int
+k5_os_mutex_init(k5_os_mutex *m)
+{
+ if (krb5int_pthread_loaded())
+ return pthread_mutex_init(m, 0);
+ else
+ return 0;
+}
+
+int
+k5_os_mutex_destroy(k5_os_mutex *m)
+{
+ if (krb5int_pthread_loaded())
+ return pthread_mutex_destroy(m);
+ else
+ return 0;
+}
+
+int
+k5_os_mutex_lock(k5_os_mutex *m)
+{
+ if (krb5int_pthread_loaded())
+ return pthread_mutex_lock(m);
+ else
+ return 0;
+}
+
+int
+k5_os_mutex_unlock(k5_os_mutex *m)
+{
+ if (krb5int_pthread_loaded())
+ return pthread_mutex_unlock(m);
+ else
+ return 0;
+}
+
+#else /* USE_PTHREAD_LOADED_MUTEX_FUNCTIONS */
+
+#undef k5_os_mutex_init
+#undef k5_os_mutex_destroy
+#undef k5_os_mutex_lock
+#undef k5_os_mutex_unlock
+
+/* Stub functions */
+int
+k5_os_mutex_init(k5_os_mutex *m)
+{
+ return 0;
+}
+int
+k5_os_mutex_destroy(k5_os_mutex *m)
+{
+ return 0;
+}
+int
+k5_os_mutex_lock(k5_os_mutex *m)
+{
+ return 0;
+}
+int
+k5_os_mutex_unlock(k5_os_mutex *m)
+{
+ return 0;
+}
+
+#endif /* USE_PTHREAD_LOADED_MUTEX_FUNCTIONS */