2003-04-01 02:30:57 +08:00
|
|
|
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
2007-02-07 22:56:24 +08:00
|
|
|
|
* Copyright by The HDF Group. *
|
2003-04-01 02:30:57 +08:00
|
|
|
|
* Copyright by the Board of Trustees of the University of Illinois. *
|
|
|
|
|
* All rights reserved. *
|
|
|
|
|
* *
|
|
|
|
|
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
|
|
|
|
* terms governing use, modification, and redistribution, is contained in *
|
|
|
|
|
* the files COPYING and Copyright.html. COPYING can be found at the root *
|
|
|
|
|
* of the source code distribution tree; Copyright.html can be found at the *
|
|
|
|
|
* root level of an installed copy of the electronic HDF5 document set and *
|
|
|
|
|
* is linked from the top-level documents page. It can also be found at *
|
2007-02-07 22:56:24 +08:00
|
|
|
|
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
|
|
|
|
|
* access to either file, you may request a copy from help@hdfgroup.org. *
|
2003-04-01 02:30:57 +08:00
|
|
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
2000-05-19 03:13:33 +08:00
|
|
|
|
|
|
|
|
|
/* private headers */
|
2011-09-07 00:50:32 +08:00
|
|
|
|
#include "H5private.h" /*library */
|
|
|
|
|
#include "H5Eprivate.h" /*error handling */
|
|
|
|
|
#include "H5MMprivate.h" /*memory management functions */
|
2000-05-19 03:13:33 +08:00
|
|
|
|
|
|
|
|
|
#ifdef H5_HAVE_THREADSAFE
|
|
|
|
|
|
2000-05-19 22:51:50 +08:00
|
|
|
|
/* Module specific data structures */
|
|
|
|
|
|
|
|
|
|
/* cancelability structure */
|
|
|
|
|
typedef struct H5TS_cancel_struct {
|
2000-05-20 06:02:24 +08:00
|
|
|
|
int previous_state;
|
|
|
|
|
unsigned int cancel_count;
|
2000-05-19 22:51:50 +08:00
|
|
|
|
} H5TS_cancel_t;
|
|
|
|
|
|
|
|
|
|
/* Global variable definitions */
|
2010-09-15 21:51:11 +08:00
|
|
|
|
#ifdef H5_HAVE_WIN_THREADS
|
2010-09-11 00:15:34 +08:00
|
|
|
|
H5TS_once_t H5TS_first_init_g;
|
2010-09-15 21:51:11 +08:00
|
|
|
|
#else /* H5_HAVE_WIN_THREADS */
|
|
|
|
|
H5TS_once_t H5TS_first_init_g = PTHREAD_ONCE_INIT;
|
|
|
|
|
#endif /* H5_HAVE_WIN_THREADS */
|
2010-09-11 00:15:34 +08:00
|
|
|
|
H5TS_key_t H5TS_errstk_key_g;
|
|
|
|
|
H5TS_key_t H5TS_funcstk_key_g;
|
|
|
|
|
H5TS_key_t H5TS_cancel_key_g;
|
2000-05-19 22:51:50 +08:00
|
|
|
|
|
2003-02-08 05:14:19 +08:00
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
* NAME
|
|
|
|
|
* H5TS_key_destructor
|
|
|
|
|
*
|
|
|
|
|
* USAGE
|
|
|
|
|
* H5TS_key_destructor()
|
2005-08-14 04:53:35 +08:00
|
|
|
|
*
|
2003-02-08 05:14:19 +08:00
|
|
|
|
* RETURNS
|
|
|
|
|
*
|
|
|
|
|
* DESCRIPTION
|
|
|
|
|
* Frees the memory for a key. Called by each thread as it exits.
|
|
|
|
|
* Currently all the thread-specific information for all keys are simple
|
|
|
|
|
* structures allocated with malloc, so we can free them all uniformly.
|
|
|
|
|
*
|
|
|
|
|
* PROGRAMMER: Quincey Koziol
|
|
|
|
|
* February 7, 2003
|
|
|
|
|
*
|
|
|
|
|
*--------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
H5TS_key_destructor(void *key_val)
|
|
|
|
|
{
|
2006-05-02 11:17:49 +08:00
|
|
|
|
/* Use HDfree here instead of H5MM_xfree(), to avoid calling the H5CS routines */
|
2015-09-14 11:58:59 +08:00
|
|
|
|
if(key_val != NULL)
|
2003-02-08 05:14:19 +08:00
|
|
|
|
HDfree(key_val);
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-15 21:51:11 +08:00
|
|
|
|
|
2014-04-05 04:51:30 +08:00
|
|
|
|
#ifndef H5_HAVE_WIN_THREADS
|
2010-09-15 21:51:11 +08:00
|
|
|
|
|
2000-05-19 03:13:33 +08:00
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
* NAME
|
2010-09-15 21:51:11 +08:00
|
|
|
|
* H5TS_pthread_first_thread_init
|
2000-05-20 06:02:24 +08:00
|
|
|
|
*
|
2000-05-19 03:13:33 +08:00
|
|
|
|
* USAGE
|
2010-09-15 21:51:11 +08:00
|
|
|
|
* H5TS_pthread_first_thread_init()
|
2005-08-14 04:53:35 +08:00
|
|
|
|
*
|
2000-05-19 03:13:33 +08:00
|
|
|
|
* RETURNS
|
|
|
|
|
*
|
|
|
|
|
* DESCRIPTION
|
2000-05-20 06:02:24 +08:00
|
|
|
|
* Initialization of global API lock, keys for per-thread error stacks and
|
|
|
|
|
* cancallability information. Called by the first thread that enters the
|
|
|
|
|
* library.
|
2000-05-19 03:13:33 +08:00
|
|
|
|
*
|
|
|
|
|
* PROGRAMMER: Chee Wai LEE
|
|
|
|
|
* May 2, 2000
|
|
|
|
|
*
|
|
|
|
|
*--------------------------------------------------------------------------
|
|
|
|
|
*/
|
2000-05-19 22:51:50 +08:00
|
|
|
|
void
|
2010-09-15 21:51:11 +08:00
|
|
|
|
H5TS_pthread_first_thread_init(void)
|
2000-05-19 22:51:50 +08:00
|
|
|
|
{
|
2015-09-14 11:58:59 +08:00
|
|
|
|
H5_g.H5_libinit_g = FALSE; /* Library hasn't been initialized */
|
|
|
|
|
H5_g.H5_libterm_g = FALSE; /* Library isn't being shutdown */
|
2010-09-15 21:51:11 +08:00
|
|
|
|
|
2011-09-07 00:50:32 +08:00
|
|
|
|
#ifdef H5_HAVE_WIN32_API
|
2011-09-02 01:27:27 +08:00
|
|
|
|
# ifdef PTW32_STATIC_LIB
|
|
|
|
|
pthread_win32_process_attach_np();
|
|
|
|
|
# endif
|
|
|
|
|
#endif
|
|
|
|
|
|
2000-05-20 06:02:24 +08:00
|
|
|
|
/* initialize global API mutex lock */
|
2000-05-19 22:51:50 +08:00
|
|
|
|
pthread_mutex_init(&H5_g.init_lock.atomic_lock, NULL);
|
|
|
|
|
pthread_cond_init(&H5_g.init_lock.cond_var, NULL);
|
|
|
|
|
H5_g.init_lock.lock_count = 0;
|
|
|
|
|
|
2003-08-09 02:58:50 +08:00
|
|
|
|
/* initialize key for thread-specific error stacks */
|
|
|
|
|
pthread_key_create(&H5TS_errstk_key_g, H5TS_key_destructor);
|
2004-12-29 22:26:20 +08:00
|
|
|
|
|
2003-02-08 05:14:19 +08:00
|
|
|
|
/* initialize key for thread-specific function stacks */
|
|
|
|
|
pthread_key_create(&H5TS_funcstk_key_g, H5TS_key_destructor);
|
2004-12-29 22:26:20 +08:00
|
|
|
|
|
2003-02-08 05:14:19 +08:00
|
|
|
|
/* initialize key for thread cancellability mechanism */
|
|
|
|
|
pthread_key_create(&H5TS_cancel_key_g, H5TS_key_destructor);
|
2000-05-19 03:13:33 +08:00
|
|
|
|
}
|
2010-09-15 21:51:11 +08:00
|
|
|
|
#endif /* H5_HAVE_WIN_THREADS */
|
2010-09-11 00:15:34 +08:00
|
|
|
|
|
2014-04-05 04:51:30 +08:00
|
|
|
|
|
2000-05-19 03:13:33 +08:00
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
* NAME
|
2000-05-19 22:51:50 +08:00
|
|
|
|
* H5TS_mutex_lock
|
2000-05-20 06:02:24 +08:00
|
|
|
|
*
|
2000-05-19 03:13:33 +08:00
|
|
|
|
* USAGE
|
2000-05-19 22:51:50 +08:00
|
|
|
|
* H5TS_mutex_lock(&mutex_var)
|
2005-08-14 04:53:35 +08:00
|
|
|
|
*
|
2000-05-19 03:13:33 +08:00
|
|
|
|
* RETURNS
|
2000-05-20 06:02:24 +08:00
|
|
|
|
* 0 on success and non-zero on error.
|
2000-05-19 03:13:33 +08:00
|
|
|
|
*
|
|
|
|
|
* DESCRIPTION
|
2000-05-20 06:02:24 +08:00
|
|
|
|
* Recursive lock semantics for HDF5 (locking) -
|
|
|
|
|
* Multiple acquisition of a lock by a thread is permitted with a
|
|
|
|
|
* corresponding unlock operation required.
|
2000-05-19 03:13:33 +08:00
|
|
|
|
*
|
|
|
|
|
* PROGRAMMER: Chee Wai LEE
|
|
|
|
|
* May 2, 2000
|
|
|
|
|
*
|
|
|
|
|
*--------------------------------------------------------------------------
|
|
|
|
|
*/
|
2000-05-20 06:02:24 +08:00
|
|
|
|
herr_t
|
2000-05-19 22:51:50 +08:00
|
|
|
|
H5TS_mutex_lock(H5TS_mutex_t *mutex)
|
|
|
|
|
{
|
2011-09-07 00:50:32 +08:00
|
|
|
|
#ifdef H5_HAVE_WIN_THREADS
|
2010-09-11 00:15:34 +08:00
|
|
|
|
EnterCriticalSection( &mutex->CriticalSection);
|
|
|
|
|
return 0;
|
|
|
|
|
#else /* H5_HAVE_WIN_THREADS */
|
|
|
|
|
herr_t ret_value = pthread_mutex_lock(&mutex->atomic_lock);
|
2000-05-20 06:02:24 +08:00
|
|
|
|
|
|
|
|
|
if (ret_value)
|
2003-08-09 02:58:50 +08:00
|
|
|
|
return ret_value;
|
2000-05-20 06:02:24 +08:00
|
|
|
|
|
2008-06-07 03:11:46 +08:00
|
|
|
|
if(mutex->lock_count && pthread_equal(HDpthread_self(), mutex->owner_thread)) {
|
2000-05-19 22:51:50 +08:00
|
|
|
|
/* already owned by self - increment count */
|
2000-05-20 06:02:24 +08:00
|
|
|
|
mutex->lock_count++;
|
2000-05-19 03:13:33 +08:00
|
|
|
|
} else {
|
2008-01-16 04:05:35 +08:00
|
|
|
|
/* if owned by other thread, wait for condition signal */
|
|
|
|
|
while(mutex->lock_count)
|
|
|
|
|
pthread_cond_wait(&mutex->cond_var, &mutex->atomic_lock);
|
2000-05-20 06:02:24 +08:00
|
|
|
|
|
2008-01-16 04:05:35 +08:00
|
|
|
|
/* After we've received the signal, take ownership of the mutex */
|
2008-06-07 03:11:46 +08:00
|
|
|
|
mutex->owner_thread = HDpthread_self();
|
2008-01-16 04:05:35 +08:00
|
|
|
|
mutex->lock_count = 1;
|
2000-05-19 03:13:33 +08:00
|
|
|
|
}
|
2000-05-20 06:02:24 +08:00
|
|
|
|
|
2010-09-11 00:15:34 +08:00
|
|
|
|
return pthread_mutex_unlock(&mutex->atomic_lock);
|
|
|
|
|
#endif /* H5_HAVE_WIN_THREADS */
|
2000-05-19 03:13:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
2014-04-05 04:51:30 +08:00
|
|
|
|
|
2000-05-19 03:13:33 +08:00
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
* NAME
|
2000-05-19 22:51:50 +08:00
|
|
|
|
* H5TS_mutex_unlock
|
2000-05-20 06:02:24 +08:00
|
|
|
|
*
|
2000-05-19 03:13:33 +08:00
|
|
|
|
* USAGE
|
2000-05-19 22:51:50 +08:00
|
|
|
|
* H5TS_mutex_unlock(&mutex_var)
|
2005-08-14 04:53:35 +08:00
|
|
|
|
*
|
2000-05-19 03:13:33 +08:00
|
|
|
|
* RETURNS
|
2000-05-20 06:02:24 +08:00
|
|
|
|
* 0 on success and non-zero on error.
|
2000-05-19 03:13:33 +08:00
|
|
|
|
*
|
|
|
|
|
* DESCRIPTION
|
2000-05-20 06:02:24 +08:00
|
|
|
|
* Recursive lock semantics for HDF5 (unlocking) -
|
|
|
|
|
* Multiple acquisition of a lock by a thread is permitted with a
|
|
|
|
|
* corresponding unlock operation required.
|
2000-05-19 03:13:33 +08:00
|
|
|
|
*
|
|
|
|
|
* PROGRAMMER: Chee Wai LEE
|
|
|
|
|
* May 2, 2000
|
|
|
|
|
*
|
|
|
|
|
*--------------------------------------------------------------------------
|
|
|
|
|
*/
|
2000-05-20 06:02:24 +08:00
|
|
|
|
herr_t
|
2000-05-19 22:51:50 +08:00
|
|
|
|
H5TS_mutex_unlock(H5TS_mutex_t *mutex)
|
|
|
|
|
{
|
2011-09-07 00:50:32 +08:00
|
|
|
|
#ifdef H5_HAVE_WIN_THREADS
|
2010-09-11 00:15:34 +08:00
|
|
|
|
/* Releases ownership of the specified critical section object. */
|
|
|
|
|
LeaveCriticalSection(&mutex->CriticalSection);
|
|
|
|
|
return 0;
|
|
|
|
|
#else /* H5_HAVE_WIN_THREADS */
|
|
|
|
|
herr_t ret_value = pthread_mutex_lock(&mutex->atomic_lock);
|
2000-05-20 06:02:24 +08:00
|
|
|
|
|
2008-01-16 04:05:35 +08:00
|
|
|
|
if(ret_value)
|
|
|
|
|
return ret_value;
|
2000-05-20 06:02:24 +08:00
|
|
|
|
|
2008-01-16 05:40:00 +08:00
|
|
|
|
mutex->lock_count--;
|
2000-05-20 06:02:24 +08:00
|
|
|
|
|
2008-01-16 04:05:35 +08:00
|
|
|
|
ret_value = pthread_mutex_unlock(&mutex->atomic_lock);
|
2000-05-20 06:02:24 +08:00
|
|
|
|
|
2008-01-16 05:40:00 +08:00
|
|
|
|
if(mutex->lock_count == 0) {
|
2008-01-16 04:05:35 +08:00
|
|
|
|
int err;
|
2000-05-20 06:02:24 +08:00
|
|
|
|
|
2008-01-16 04:05:35 +08:00
|
|
|
|
err = pthread_cond_signal(&mutex->cond_var);
|
|
|
|
|
if(err != 0)
|
|
|
|
|
ret_value = err;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
2010-09-11 00:15:34 +08:00
|
|
|
|
return ret_value;
|
|
|
|
|
#endif /* H5_HAVE_WIN_THREADS */
|
|
|
|
|
} /* H5TS_mutex_unlock */
|
2000-05-19 03:13:33 +08:00
|
|
|
|
|
2014-04-05 04:51:30 +08:00
|
|
|
|
|
2000-05-19 03:13:33 +08:00
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
* NAME
|
2000-05-19 22:51:50 +08:00
|
|
|
|
* H5TS_cancel_count_inc
|
2000-05-20 06:02:24 +08:00
|
|
|
|
*
|
2000-05-19 03:13:33 +08:00
|
|
|
|
* USAGE
|
2000-05-19 22:51:50 +08:00
|
|
|
|
* H5TS_cancel_count_inc()
|
2005-08-14 04:53:35 +08:00
|
|
|
|
*
|
2000-05-19 03:13:33 +08:00
|
|
|
|
* RETURNS
|
2000-05-20 06:02:24 +08:00
|
|
|
|
* 0 on success non-zero error code on error.
|
2000-05-19 03:13:33 +08:00
|
|
|
|
*
|
|
|
|
|
* DESCRIPTION
|
|
|
|
|
* Creates a cancelation counter for a thread if it is the first time
|
|
|
|
|
* the thread is entering the library.
|
|
|
|
|
*
|
|
|
|
|
* if counter value is zero, then set cancelability type of the thread
|
|
|
|
|
* to PTHREAD_CANCEL_DISABLE as thread is entering the library and store
|
|
|
|
|
* the previous cancelability type into cancelation counter.
|
|
|
|
|
* Increase the counter value by 1.
|
|
|
|
|
*
|
|
|
|
|
* PROGRAMMER: Chee Wai LEE
|
|
|
|
|
* May 2, 2000
|
|
|
|
|
*
|
|
|
|
|
*--------------------------------------------------------------------------
|
|
|
|
|
*/
|
2000-05-20 06:02:24 +08:00
|
|
|
|
herr_t
|
2000-05-19 22:51:50 +08:00
|
|
|
|
H5TS_cancel_count_inc(void)
|
2000-05-19 03:13:33 +08:00
|
|
|
|
{
|
2011-09-07 00:50:32 +08:00
|
|
|
|
#ifdef H5_HAVE_WIN_THREADS
|
2010-09-11 00:15:34 +08:00
|
|
|
|
/* unsupported; just return 0 */
|
|
|
|
|
return SUCCEED;
|
|
|
|
|
#else /* H5_HAVE_WIN_THREADS */
|
2000-05-19 22:51:50 +08:00
|
|
|
|
H5TS_cancel_t *cancel_counter;
|
2010-09-11 00:15:34 +08:00
|
|
|
|
herr_t ret_value = SUCCEED;
|
2000-05-19 22:51:50 +08:00
|
|
|
|
|
2010-09-15 21:51:11 +08:00
|
|
|
|
cancel_counter = (H5TS_cancel_t *)H5TS_get_thread_local_value(H5TS_cancel_key_g);
|
2000-05-20 06:02:24 +08:00
|
|
|
|
|
|
|
|
|
if (!cancel_counter) {
|
|
|
|
|
/*
|
2016-01-01 14:28:04 +08:00
|
|
|
|
* First time thread calls library - create new counter and associate
|
2016-04-30 14:10:38 +08:00
|
|
|
|
* with key.
|
|
|
|
|
*
|
|
|
|
|
* Don't use H5MM calls here since the destructor has to use HDfree in
|
|
|
|
|
* order to avoid codestack calls.
|
2000-05-19 22:51:50 +08:00
|
|
|
|
*/
|
2016-01-01 14:28:04 +08:00
|
|
|
|
cancel_counter = (H5TS_cancel_t *)HDcalloc(1, sizeof(H5TS_cancel_t));
|
2000-05-20 06:02:24 +08:00
|
|
|
|
|
2016-01-01 14:28:04 +08:00
|
|
|
|
if (!cancel_counter) {
|
|
|
|
|
H5E_push_stack(NULL, "H5TS_cancel_count_inc", __FILE__, __LINE__,
|
|
|
|
|
H5E_ERR_CLS_g, H5E_RESOURCE, H5E_NOSPACE, "memory allocation failed");
|
|
|
|
|
return FAIL;
|
|
|
|
|
}
|
2000-05-20 06:02:24 +08:00
|
|
|
|
|
2016-01-01 14:28:04 +08:00
|
|
|
|
ret_value = pthread_setspecific(H5TS_cancel_key_g, (void *)cancel_counter);
|
2000-05-19 22:51:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2000-05-20 06:02:24 +08:00
|
|
|
|
if (cancel_counter->cancel_count == 0)
|
2000-05-19 22:51:50 +08:00
|
|
|
|
/* thread entering library */
|
2000-05-20 06:02:24 +08:00
|
|
|
|
ret_value = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
|
2011-09-07 00:50:32 +08:00
|
|
|
|
&cancel_counter->previous_state);
|
2000-05-20 06:02:24 +08:00
|
|
|
|
|
|
|
|
|
++cancel_counter->cancel_count;
|
2010-09-11 00:15:34 +08:00
|
|
|
|
|
|
|
|
|
return ret_value;
|
|
|
|
|
#endif /* H5_HAVE_WIN_THREADS */
|
2000-05-19 03:13:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
2014-04-05 04:51:30 +08:00
|
|
|
|
|
2000-05-19 03:13:33 +08:00
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
* NAME
|
2000-05-19 22:51:50 +08:00
|
|
|
|
* H5TS_cancel_count_dec
|
2000-05-20 06:02:24 +08:00
|
|
|
|
*
|
2000-05-19 03:13:33 +08:00
|
|
|
|
* USAGE
|
2000-05-19 22:51:50 +08:00
|
|
|
|
* H5TS_cancel_count_dec()
|
2005-08-14 04:53:35 +08:00
|
|
|
|
*
|
2000-05-19 03:13:33 +08:00
|
|
|
|
* RETURNS
|
2000-05-20 06:02:24 +08:00
|
|
|
|
* 0 on success and a non-zero error code on error.
|
2000-05-19 03:13:33 +08:00
|
|
|
|
*
|
|
|
|
|
* DESCRIPTION
|
2000-05-20 06:02:24 +08:00
|
|
|
|
* If counter value is one, then set cancelability type of the thread
|
2000-05-19 03:13:33 +08:00
|
|
|
|
* to the previous cancelability type stored in the cancelation counter.
|
|
|
|
|
* (the thread is leaving the library).
|
|
|
|
|
*
|
|
|
|
|
* Decrement the counter value by 1.
|
|
|
|
|
*
|
|
|
|
|
* PROGRAMMER: Chee Wai LEE
|
|
|
|
|
* May 2, 2000
|
|
|
|
|
*
|
|
|
|
|
*--------------------------------------------------------------------------
|
|
|
|
|
*/
|
2000-05-20 06:02:24 +08:00
|
|
|
|
herr_t
|
2000-05-19 22:51:50 +08:00
|
|
|
|
H5TS_cancel_count_dec(void)
|
2000-05-19 03:13:33 +08:00
|
|
|
|
{
|
2011-09-07 00:50:32 +08:00
|
|
|
|
#ifdef H5_HAVE_WIN_THREADS
|
2010-09-11 00:15:34 +08:00
|
|
|
|
/* unsupported; will just return 0 */
|
|
|
|
|
return SUCCEED;
|
|
|
|
|
#else /* H5_HAVE_WIN_THREADS */
|
2010-09-15 21:51:11 +08:00
|
|
|
|
register H5TS_cancel_t *cancel_counter;
|
2010-09-11 00:15:34 +08:00
|
|
|
|
herr_t ret_value = SUCCEED;
|
2000-05-19 03:13:33 +08:00
|
|
|
|
|
2010-09-15 21:51:11 +08:00
|
|
|
|
cancel_counter = (H5TS_cancel_t *)H5TS_get_thread_local_value(H5TS_cancel_key_g);
|
2000-05-20 06:02:24 +08:00
|
|
|
|
|
|
|
|
|
if (cancel_counter->cancel_count == 1)
|
|
|
|
|
ret_value = pthread_setcancelstate(cancel_counter->previous_state, NULL);
|
|
|
|
|
|
2010-09-11 00:15:34 +08:00
|
|
|
|
--cancel_counter->cancel_count;
|
|
|
|
|
|
2000-05-20 06:02:24 +08:00
|
|
|
|
return ret_value;
|
2010-09-11 00:15:34 +08:00
|
|
|
|
#endif /* H5_HAVE_WIN_THREADS */
|
2000-05-19 03:13:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
2014-04-05 04:51:30 +08:00
|
|
|
|
|
|
|
|
|
#ifdef H5_HAVE_WIN_THREADS
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
* NAME
|
|
|
|
|
* H5TS_win32_process_enter
|
|
|
|
|
*
|
|
|
|
|
* RETURNS
|
|
|
|
|
* SUCCEED/FAIL
|
|
|
|
|
*
|
|
|
|
|
* DESCRIPTION
|
|
|
|
|
* Per-process setup on Windows when using Win32 threads.
|
|
|
|
|
*
|
|
|
|
|
*--------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
H5_DLL BOOL CALLBACK
|
|
|
|
|
H5TS_win32_process_enter(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *lpContex)
|
|
|
|
|
{
|
|
|
|
|
BOOL ret_value = TRUE;
|
|
|
|
|
|
|
|
|
|
/* Initialize the critical section (can't fail) */
|
|
|
|
|
InitializeCriticalSection(&H5_g.init_lock.CriticalSection);
|
|
|
|
|
|
|
|
|
|
/* Set up thread local storage */
|
|
|
|
|
if(TLS_OUT_OF_INDEXES == (H5TS_errstk_key_g = TlsAlloc()))
|
|
|
|
|
ret_value = FALSE;
|
|
|
|
|
|
|
|
|
|
#ifdef H5_HAVE_CODESTACK
|
|
|
|
|
if(TLS_OUT_OF_INDEXES == (H5TS_funcstk_key_g = TlsAlloc()))
|
|
|
|
|
ret_value = FALSE;
|
|
|
|
|
#endif /* H5_HAVE_CODESTACK */
|
|
|
|
|
|
|
|
|
|
return ret_value;
|
|
|
|
|
} /* H5TS_win32_process_enter() */
|
|
|
|
|
#endif /* H5_HAVE_WIN_THREADS */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef H5_HAVE_WIN_THREADS
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
* NAME
|
|
|
|
|
* H5TS_win32_thread_enter
|
|
|
|
|
*
|
|
|
|
|
* RETURNS
|
|
|
|
|
* SUCCEED/FAIL
|
|
|
|
|
*
|
|
|
|
|
* DESCRIPTION
|
|
|
|
|
* Per-thread setup on Windows when using Win32 threads.
|
|
|
|
|
*
|
|
|
|
|
*--------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
herr_t
|
|
|
|
|
H5TS_win32_thread_enter(void)
|
|
|
|
|
{
|
|
|
|
|
herr_t ret_value = SUCCEED;
|
|
|
|
|
|
|
|
|
|
/* Currently a placeholder function. TLS setup is performed
|
|
|
|
|
* elsewhere in the library.
|
|
|
|
|
*
|
|
|
|
|
* WARNING: Do NOT use C standard library functions here.
|
|
|
|
|
* CRT functions are not allowed in DllMain, which is where this code
|
|
|
|
|
* is used.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
return ret_value;
|
|
|
|
|
} /* H5TS_win32_thread_enter() */
|
|
|
|
|
#endif /* H5_HAVE_WIN_THREADS */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef H5_HAVE_WIN_THREADS
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
* NAME
|
|
|
|
|
* H5TS_win32_process_exit
|
|
|
|
|
*
|
|
|
|
|
* RETURNS
|
|
|
|
|
* SUCCEED/FAIL
|
|
|
|
|
*
|
|
|
|
|
* DESCRIPTION
|
|
|
|
|
* Per-process cleanup on Windows when using Win32 threads.
|
|
|
|
|
*
|
|
|
|
|
*--------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
H5TS_win32_process_exit(void)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/* Windows uses a different thread local storage mechanism which does
|
|
|
|
|
* not support auto-freeing like pthreads' keys.
|
|
|
|
|
*
|
|
|
|
|
* This function is currently registered via atexit() and is called
|
|
|
|
|
* AFTER H5_term_library().
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* Clean up critical section resources (can't fail) */
|
|
|
|
|
DeleteCriticalSection(&H5_g.init_lock.CriticalSection);
|
|
|
|
|
|
|
|
|
|
/* Clean up per-process thread local storage */
|
|
|
|
|
TlsFree(H5TS_errstk_key_g);
|
|
|
|
|
|
|
|
|
|
#ifdef H5_HAVE_CODESTACK
|
|
|
|
|
TlsFree(H5TS_funcstk_key_g);
|
|
|
|
|
#endif /* H5_HAVE_CODESTACK */
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
} /* H5TS_win32_process_exit() */
|
|
|
|
|
#endif /* H5_HAVE_WIN_THREADS */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef H5_HAVE_WIN_THREADS
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
* NAME
|
|
|
|
|
* H5TS_win32_thread_exit
|
|
|
|
|
*
|
|
|
|
|
* RETURNS
|
|
|
|
|
* SUCCEED/FAIL
|
|
|
|
|
*
|
|
|
|
|
* DESCRIPTION
|
|
|
|
|
* Per-thread cleanup on Windows when using Win32 threads.
|
|
|
|
|
*
|
|
|
|
|
*--------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
herr_t
|
|
|
|
|
H5TS_win32_thread_exit(void)
|
|
|
|
|
{
|
|
|
|
|
LPVOID lpvData;
|
|
|
|
|
herr_t ret_value = SUCCEED;
|
|
|
|
|
|
|
|
|
|
/* Windows uses a different thread local storage mechanism which does
|
|
|
|
|
* not support auto-freeing like pthreads' keys.
|
|
|
|
|
*
|
|
|
|
|
* WARNING: Do NOT use C standard library functions here.
|
|
|
|
|
* CRT functions are not allowed in DllMain, which is where this code
|
|
|
|
|
* is used.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* Clean up per-thread thread local storage */
|
|
|
|
|
lpvData = TlsGetValue(H5TS_errstk_key_g);
|
|
|
|
|
if(lpvData)
|
|
|
|
|
LocalFree((HLOCAL)lpvData);
|
|
|
|
|
|
|
|
|
|
#ifdef H5_HAVE_CODESTACK
|
|
|
|
|
lpvData = TlsGetValue(H5TS_funcstk_key_g);
|
|
|
|
|
if(lpvData)
|
|
|
|
|
LocalFree((HLOCAL)lpvData);
|
|
|
|
|
#endif /* H5_HAVE_CODESTACK */
|
|
|
|
|
|
|
|
|
|
return ret_value;
|
|
|
|
|
} /* H5TS_win32_thread_exit() */
|
|
|
|
|
#endif /* H5_HAVE_WIN_THREADS */
|
|
|
|
|
|
2010-09-11 00:15:34 +08:00
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
* NAME
|
|
|
|
|
* H5TS_create_thread
|
|
|
|
|
*
|
|
|
|
|
* RETURNS
|
|
|
|
|
* Thread identifier.
|
|
|
|
|
*
|
|
|
|
|
* DESCRIPTION
|
|
|
|
|
* Spawn off a new thread calling function 'func' with input 'udata'.
|
|
|
|
|
*
|
|
|
|
|
* PROGRAMMER: Mike McGreevy
|
|
|
|
|
* August 31, 2010
|
|
|
|
|
*
|
|
|
|
|
*--------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
H5TS_thread_t
|
2015-03-30 23:12:49 +08:00
|
|
|
|
H5TS_create_thread(void *(*func)(void *), H5TS_attr_t *attr, void *udata)
|
2010-09-11 00:15:34 +08:00
|
|
|
|
{
|
|
|
|
|
H5TS_thread_t ret_value;
|
|
|
|
|
|
2011-09-07 00:50:32 +08:00
|
|
|
|
#ifdef H5_HAVE_WIN_THREADS
|
2010-09-11 00:15:34 +08:00
|
|
|
|
|
2014-04-05 04:51:30 +08:00
|
|
|
|
/* When calling C runtime functions, you should use _beginthread or
|
2011-12-06 10:52:15 +08:00
|
|
|
|
* _beginthreadex instead of CreateThread. Threads created with
|
2014-04-05 04:51:30 +08:00
|
|
|
|
* CreateThread risk being killed in low-memory situations. Since we
|
|
|
|
|
* only create threads in our test code, this is unlikely to be an issue
|
|
|
|
|
* and we'll use the easier-to-deal-with CreateThread for now.
|
2011-12-06 10:52:15 +08:00
|
|
|
|
*
|
2014-04-05 04:51:30 +08:00
|
|
|
|
* NOTE: _beginthread() auto-recycles its handle when execution completes
|
|
|
|
|
* so you can't wait on it, making it unsuitable for the existing
|
|
|
|
|
* test code.
|
2011-12-06 10:52:15 +08:00
|
|
|
|
*/
|
2014-04-05 04:51:30 +08:00
|
|
|
|
ret_value = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, udata, 0, NULL);
|
2010-09-11 00:15:34 +08:00
|
|
|
|
|
|
|
|
|
#else /* H5_HAVE_WIN_THREADS */
|
|
|
|
|
|
2010-09-15 21:51:11 +08:00
|
|
|
|
pthread_create(&ret_value, attr, (void * (*)(void *))func, udata);
|
2010-09-11 00:15:34 +08:00
|
|
|
|
|
|
|
|
|
#endif /* H5_HAVE_WIN_THREADS */
|
|
|
|
|
|
|
|
|
|
return ret_value;
|
|
|
|
|
|
|
|
|
|
} /* H5TS_create_thread */
|
|
|
|
|
|
2011-09-07 00:50:32 +08:00
|
|
|
|
#endif /* H5_HAVE_THREADSAFE */
|