From 90bc20edb598f4cb787b03d20a7ff6c2b9466ab0 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 6 Jun 2000 15:50:18 -0500 Subject: [svn-r2348] The way the pthread_t object was being initialized wasn't correct for all platforms. Also, it's not entirely certain that a value of 0 isn't a valid thread ID. So, I changed the pthread_t object to be a pointer to pthread_t with the appropriate memory management this entails. Part of the validity of this approach rests on the fact that one can assign a variable which is a structure to another variable of the same type and all fields within will be copied appropriately...See! C *does* do some things correctly :-). --- src/H5TS.c | 37 +++++++++++++++++++++++++------------ src/H5TSprivate.h | 2 +- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/H5TS.c b/src/H5TS.c index 7c29a95..dcf018f 100644 --- a/src/H5TS.c +++ b/src/H5TS.c @@ -37,9 +37,6 @@ pthread_key_t H5TS_errstk_key_g; pthread_key_t H5TS_cancel_key_g; hbool_t H5TS_allow_concurrent_g = FALSE; /* concurrent APIs override this */ -/* Local variable declarations */ -static pthread_t H5TS_null_g; /* Set to ``null'' with HDmemset for comparing*/ - /* Local function definitions */ #ifdef NOT_USED static void H5TS_mutex_init(H5TS_mutex_t *mutex); @@ -72,8 +69,7 @@ H5TS_first_thread_init(void) H5_g.H5_libinit_g = FALSE; /* set the two pthread_t objects to ``null'' */ - HDmemset(&H5_g.init_lock.owner_thread, 0, sizeof(pthread_t)); - HDmemset(&H5TS_null_g, 0, sizeof(pthread_t)); + H5_g.init_lock.owner_thread = NULL; /* initialize global API mutex lock */ pthread_mutex_init(&H5_g.init_lock.atomic_lock, NULL); @@ -115,7 +111,7 @@ H5TS_first_thread_init(void) static void H5TS_mutex_init(H5TS_mutex_t *mutex) { - HDmemset(&H5_g.init_lock.owner_thread, 0, sizeof(pthread_t)); + H5_g.init_lock.owner_thread = NULL; pthread_mutex_init(&mutex->atomic_lock, NULL); pthread_cond_init(&mutex->cond_var, NULL); mutex->lock_count = 0; @@ -157,20 +153,36 @@ H5TS_mutex_lock(H5TS_mutex_t *mutex) if (ret_value) return ret_value; - if (pthread_equal(pthread_self(), mutex->owner_thread)) { + if (mutex->owner_thread && pthread_equal(pthread_self(), *mutex->owner_thread)) { /* already owned by self - increment count */ mutex->lock_count++; - } else if (pthread_equal(mutex->owner_thread, H5TS_null_g)) { + } else if (!mutex->owner_thread) { /* no one else has locked it - set owner and grab lock */ - mutex->owner_thread = pthread_self(); + mutex->owner_thread = H5MM_malloc(sizeof(pthread_t)); + + if (!mutex->owner_thread) { + H5E_push(H5E_RESOURCE, H5E_NOSPACE, "H5TS_mutex_lock", + __FILE__, __LINE__, "memory allocation failed"); + return FAIL; + } + + *mutex->owner_thread = pthread_self(); mutex->lock_count = 1; } else { /* if already locked by someone else */ for (;;) { pthread_cond_wait(&mutex->cond_var, &mutex->atomic_lock); - if (pthread_equal(mutex->owner_thread, H5TS_null_g)) { - mutex->owner_thread = pthread_self(); + if (!mutex->owner_thread) { + mutex->owner_thread = H5MM_malloc(sizeof(pthread_t)); + + if (!mutex->owner_thread) { + H5E_push(H5E_RESOURCE, H5E_NOSPACE, "H5TS_mutex_lock", + __FILE__, __LINE__, "memory allocation failed"); + return FAIL; + } + + *mutex->owner_thread = pthread_self(); mutex->lock_count = 1; break; } @@ -219,7 +231,8 @@ H5TS_mutex_unlock(H5TS_mutex_t *mutex) mutex->lock_count--; if (mutex->lock_count == 0) { - HDmemset(&mutex->owner_thread, 0, sizeof(pthread_t)); + H5MM_xfree(mutex->owner_thread); + mutex->owner_thread = NULL; ret_value = pthread_cond_signal(&mutex->cond_var); if (ret_value) { diff --git a/src/H5TSprivate.h b/src/H5TSprivate.h index 525450c..2d88637 100644 --- a/src/H5TSprivate.h +++ b/src/H5TSprivate.h @@ -25,7 +25,7 @@ /* Library level data structures */ typedef struct H5TS_mutex_struct { - pthread_t owner_thread; /* current lock owner */ + pthread_t *owner_thread; /* current lock owner */ pthread_mutex_t atomic_lock; /* lock for atomicity of new mechanism */ pthread_cond_t cond_var; /* condition variable */ unsigned int lock_count; -- cgit v0.12