From 3f2c25281f6084ebbcb939977cd038e76c9791e5 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Fri, 18 Jun 2004 22:49:55 +0000 Subject: [PATCH] * Makefile.in (BUILDTOP, LIBNAME, XTRA, OBJFILE): Define for Windows. (LIBOBJS): Define. ($(BUILDTOP)/include/krb5/autoconf.h): Disable rule on Windows. * threads.c (tls_idx, key_lock, destructors, destructors_set): New variables for Windows. (krb5int_thread_support_init, krb5int_thread_support_fini, k5_key_register, k5_getspecific, k5_setspecific, k5_key_delete, krb5int_thread_detach_hook): New functions for Windows. Some are just placeholders. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@16482 dc483132-0cff-0310-8789-dd5450dbe970 --- src/util/support/ChangeLog | 14 +++++ src/util/support/Makefile.in | 11 +++- src/util/support/threads.c | 103 ++++++++++++++++++++++++++++++++++- 3 files changed, 126 insertions(+), 2 deletions(-) diff --git a/src/util/support/ChangeLog b/src/util/support/ChangeLog index f4019c0a3..15d2eff1a 100644 --- a/src/util/support/ChangeLog +++ b/src/util/support/ChangeLog @@ -1,3 +1,17 @@ +2004-06-17 Ken Raeburn + + * Makefile.in (BUILDTOP, LIBNAME, XTRA, OBJFILE): Define for + Windows. + (LIBOBJS): Define. + ($(BUILDTOP)/include/krb5/autoconf.h): Disable rule on Windows. + + * threads.c (tls_idx, key_lock, destructors, destructors_set): New + variables for Windows. + (krb5int_thread_support_init, krb5int_thread_support_fini, + k5_key_register, k5_getspecific, k5_setspecific, k5_key_delete, + krb5int_thread_detach_hook): New functions for Windows. Some are + just placeholders. + 2004-06-14 Ken Raeburn * libkrb5support.exports: Drop krb5int_foreach_localaddr. diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in index 618c01f46..6ce7bdaba 100644 --- a/src/util/support/Makefile.in +++ b/src/util/support/Makefile.in @@ -4,6 +4,11 @@ mydir=util/support BUILDTOP=$(REL)..$(S).. RELDIR=../util/support +##DOS##BUILDTOP = ..\.. +##DOS##LIBNAME=$(OUTPRE)krb5support_32.lib +##DOS##XTRA= +##DOS##OBJFILE=$(OUTPRE)krb5support_32.lst + SED = sed KRB5_RUN_ENV= @KRB5_RUN_ENV@ @@ -20,6 +25,9 @@ LIBFINIFUNC=krb5int_thread_support_fini STLIBOBJS= \ threads.o +LIBOBJS= \ + $(OUTPRE)threads.$(OBJEXT) + STOBJLISTS=OBJS.ST INSTALLFILE = cp @@ -42,9 +50,10 @@ install-unix:: install-libs clean-unix:: clean-liblinks clean-libs clean-libobjs +##DOS##!if 0 $(BUILDTOP)/include/krb5/autoconf.h: $(SRCTOP)/include/krb5/autoconf.h.in (cd $(BUILDTOP)/include; $(MAKE) krb5/autoconf.h) - +##DOS##!endif # @lib_frag@ # @libobj_frag@ diff --git a/src/util/support/threads.c b/src/util/support/threads.c index 1b5d1723e..13a2e420f 100644 --- a/src/util/support/threads.c +++ b/src/util/support/threads.c @@ -36,12 +36,110 @@ MAKE_INIT_FUNCTION(krb5int_thread_support_init); MAKE_FINI_FUNCTION(krb5int_thread_support_fini); + #ifdef ENABLE_THREADS #ifdef _WIN32 -#error "need WIN32 thread support code written" +static DWORD tls_idx; +CRITICAL_SECTION key_lock; +static void (*destructors[K5_KEY_MAX])(void *); +static unsigned char destructors_set[K5_KEY_MAX]; + +int krb5int_thread_support_init (void) +{ + tls_idx = TlsAlloc(); + /* XXX This can raise an exception if memory is low! */ + InitializeCriticalSection(&key_lock); + return 0; +} + +void krb5int_thread_support_fini (void) +{ + if (! INITIALIZER_RAN (krb5int_thread_support_init)) + return; + /* ... free stuff ... */ + TlsFree(tls_idx); + DeleteCriticalSection(&key_lock); +} + +int k5_key_register (k5_key_t keynum, void (*destructor)(void *)) +{ + DWORD wait_result; + + assert(keynum >= 0 && keynum < K5_KEY_MAX); + /* XXX: This can raise EXCEPTION_POSSIBLE_DEADLOCK. */ + EnterCriticalSection(&key_lock); + assert(destructors_set[keynum] == 0); + destructors_set[keynum] = 1; + destructors[keynum] = destructor; + LeaveCriticalSection(&key_lock); + return 0; +} + +void *k5_getspecific (k5_key_t keynum) +{ + struct tsd_block *t; + + err = CALL_INIT_FUNCTION(krb5int_thread_support_init); + if (err) + return NULL; + + assert(keynum >= 0 && keynum < K5_KEY_MAX); + + t = TlsGetValue(tls_idx); + if (t == NULL) + return NULL; + return t->values[keynum]; +} + +int k5_setspecific (k5_key_t keynum, void *value) +{ + struct tsd_block *t; + + err = CALL_INIT_FUNCTION(krb5int_thread_support_init); + if (err) + return NULL; + + assert(keynum >= 0 && keynum < K5_KEY_MAX); + + t = TlsGetValue(tls_idx); + if (t == NULL) { + int i; + t = malloc(sizeof(*t)); + if (t == NULL) + return errno; + for (i = 0; i < K5_KEY_MAX; i++) + t->values[i] = 0; + /* add to global linked list */ + t->next = 0; + err = TlsSetValue(key, t); + if (err) { + free(t); + return err; + } + } + t->values[keynum] = value; + return 0; +} + +int k5_key_delete (k5_key_t keynum) +{ + assert(keynum >= 0 && keynum < K5_KEY_MAX); + /* XXX: This can raise EXCEPTION_POSSIBLE_DEADLOCK. */ + EnterCriticalSection(&key_lock); + abort(); + LeaveCriticalSection(&key_lock); + return 0; +} + +void krb5int_thread_detach_hook (void) +{ + /* XXX Memory leak here! + Need to destroy all TLS objects we know about for this thread. */ +} + #else /* POSIX */ @@ -79,6 +177,7 @@ int krb5int_thread_support_init(void) void krb5int_thread_support_fini(void) { + /* ... delete stuff ... */ if (INITIALIZER_RAN(krb5int_thread_support_init)) pthread_key_delete(key); } @@ -188,7 +287,9 @@ int k5_key_delete (k5_key_t keynum) #endif /* Win32 vs POSIX */ + #else +/* no thread support */ static void (*destructors[K5_KEY_MAX])(void *); static void *tsd_values[K5_KEY_MAX]; -- 2.26.2