summaryrefslogtreecommitdiffstats
path: root/src/H5.c
diff options
context:
space:
mode:
authorDana Robinson <derobins@hdfgroup.org>2021-04-07 18:25:39 (GMT)
committerDana Robinson <derobins@hdfgroup.org>2021-04-07 18:25:39 (GMT)
commitdfc2a0993c076387d96f08e812e6eb9a84e4b778 (patch)
tree694520f115c6807d21b21096e89fc9e2b1742877 /src/H5.c
parentb7dc1ef6f4c9e8a3e1dd4ee18f2dafcd763c21c1 (diff)
downloadhdf5-dfc2a0993c076387d96f08e812e6eb9a84e4b778.zip
hdf5-dfc2a0993c076387d96f08e812e6eb9a84e4b778.tar.gz
hdf5-dfc2a0993c076387d96f08e812e6eb9a84e4b778.tar.bz2
Brings H5module.h from develop and fixes Autotools badness
Diffstat (limited to 'src/H5.c')
-rw-r--r--src/H5.c201
1 files changed, 172 insertions, 29 deletions
diff --git a/src/H5.c b/src/H5.c
index 0a572a7..06332fa 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -14,6 +14,7 @@
/****************/
/* Module Setup */
/****************/
+#include "H5module.h" /* This source code file is part of the H5 module */
/***********/
/* Headers */
@@ -43,18 +44,28 @@
/* Package Typedefs */
/********************/
+/* Node for list of 'atclose' routines to invoke at library shutdown */
+typedef struct H5_atclose_node_t {
+ H5_atclose_func_t func; /* Function to invoke */
+ void * ctx; /* Context to pass to function */
+ struct H5_atclose_node_t *next; /* Pointer to next node in list */
+} H5_atclose_node_t;
+
/********************/
/* Local Prototypes */
/********************/
-static void H5_debug_mask(const char *);
+static void H5__debug_mask(const char *);
#ifdef H5_HAVE_PARALLEL
-static int H5_mpi_delete_cb(MPI_Comm comm, int keyval, void *attr_val, int *flag);
+static int H5__mpi_delete_cb(MPI_Comm comm, int keyval, void *attr_val, int *flag);
#endif /*H5_HAVE_PARALLEL*/
/*********************/
/* Package Variables */
/*********************/
+/* Package initialization variable */
+hbool_t H5_PKG_INIT_VAR = FALSE;
+
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -84,6 +95,39 @@ H5_debug_t H5_debug_g; /* debugging info */
/* Local Variables */
/*******************/
+/* Linked list of registered 'atclose' functions to invoke at library shutdown */
+static H5_atclose_node_t *H5_atclose_head = NULL;
+
+/* Declare a free list to manage the H5_atclose_node_t struct */
+H5FL_DEFINE_STATIC(H5_atclose_node_t);
+
+/*--------------------------------------------------------------------------
+NAME
+ H5__init_package -- Initialize interface-specific information
+USAGE
+ herr_t H5__init_package()
+RETURNS
+ Non-negative on success/Negative on failure
+DESCRIPTION
+ Initializes any interface-specific data or routines.
+--------------------------------------------------------------------------*/
+herr_t
+H5__init_package(void)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Run the library initialization routine, if it hasn't already ran */
+ if (!H5_INIT_GLOBAL && !H5_TERM_GLOBAL) {
+ if (H5_init_library() < 0)
+ HGOTO_ERROR(H5E_LIB, H5E_CANTINIT, FAIL, "unable to initialize library")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5__init_package() */
+
/*--------------------------------------------------------------------------
* NAME
* H5_init_library -- Initialize library-global information
@@ -103,6 +147,11 @@ H5_init_library(void)
{
herr_t ret_value = SUCCEED;
+ /* Set the 'library initialized' flag as early as possible, to avoid
+ * possible re-entrancy.
+ */
+ H5_INIT_GLOBAL = TRUE;
+
FUNC_ENTER_NOAPI(FAIL)
#ifdef H5_HAVE_PARALLEL
@@ -132,7 +181,7 @@ H5_init_library(void)
int key_val;
if (MPI_SUCCESS != (mpi_code = MPI_Comm_create_keyval(
- MPI_COMM_NULL_COPY_FN, (MPI_Comm_delete_attr_function *)H5_mpi_delete_cb,
+ MPI_COMM_NULL_COPY_FN, (MPI_Comm_delete_attr_function *)H5__mpi_delete_cb,
&key_val, NULL)))
HMPI_GOTO_ERROR(FAIL, "MPI_Comm_create_keyval failed", mpi_code)
@@ -228,8 +277,8 @@ H5_init_library(void)
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize vol interface")
/* Debugging? */
- H5_debug_mask("-all");
- H5_debug_mask(HDgetenv("HDF5_DEBUG"));
+ H5__debug_mask("-all");
+ H5__debug_mask(HDgetenv("HDF5_DEBUG"));
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -273,6 +322,28 @@ H5_term_library(void)
/* Check if we should display error output */
(void)H5Eget_auto2(H5E_DEFAULT, &func, NULL);
+ /* Iterate over the list of 'atclose' callbacks that have been registered */
+ if (H5_atclose_head) {
+ H5_atclose_node_t *curr_atclose; /* Current 'atclose' node */
+
+ /* Iterate over all 'atclose' nodes, making callbacks */
+ curr_atclose = H5_atclose_head;
+ while (curr_atclose) {
+ H5_atclose_node_t *tmp_atclose; /* Temporary pointer to 'atclose' node */
+
+ /* Invoke callback, providing context */
+ (*curr_atclose->func)(curr_atclose->ctx);
+
+ /* Advance to next node and free this one */
+ tmp_atclose = curr_atclose;
+ curr_atclose = curr_atclose->next;
+ H5FL_FREE(H5_atclose_node_t, tmp_atclose);
+ } /* end while */
+
+ /* Reset list head, in case library is re-initialized */
+ H5_atclose_head = NULL;
+ } /* end if */
+
/*
* Terminate each interface. The termination functions return a positive
* value if they do something that might affect some other interface in a
@@ -564,12 +635,13 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5get_free_list_sizes(size_t *reg_size, size_t *arr_size, size_t *blk_size, size_t *fac_size)
+H5get_free_list_sizes(size_t *reg_size /*out*/, size_t *arr_size /*out*/, size_t *blk_size /*out*/,
+ size_t *fac_size /*out*/)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
- H5TRACE4("e", "*z*z*z*z", reg_size, arr_size, blk_size, fac_size);
+ H5TRACE4("e", "xxxx", reg_size, arr_size, blk_size, fac_size);
/* Call the free list function to actually get the sizes */
if (H5FL_get_free_list_sizes(reg_size, arr_size, blk_size, fac_size) < 0)
@@ -604,12 +676,12 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5get_alloc_stats(H5_alloc_stats_t *stats)
+H5get_alloc_stats(H5_alloc_stats_t *stats /*out*/)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
- H5TRACE1("e", "*Ha", stats);
+ H5TRACE1("e", "x", stats);
/* Call the internal allocation stat routine to get the values */
if (H5MM_get_alloc_stats(stats) < 0)
@@ -620,7 +692,7 @@ done:
} /* end H5get_alloc_stats() */
/*-------------------------------------------------------------------------
- * Function: H5_debug_mask
+ * Function: H5__debug_mask
*
* Purpose: Set runtime debugging flags according to the string S. The
* string should contain file numbers and package names
@@ -643,7 +715,7 @@ done:
*-------------------------------------------------------------------------
*/
static void
-H5_debug_mask(const char *s)
+H5__debug_mask(const char *s)
{
FILE * stream = stderr;
char pkg_name[32], *rest;
@@ -724,15 +796,12 @@ H5_debug_mask(const char *s)
s++;
} /* end if-else */
} /* end while */
-
- return;
-
-} /* end H5_debug_mask() */
+} /* end H5__debug_mask() */
#ifdef H5_HAVE_PARALLEL
/*-------------------------------------------------------------------------
- * Function: H5_mpi_delete_cb
+ * Function: H5__mpi_delete_cb
*
* Purpose: Callback attribute on MPI_COMM_SELF to terminate the HDF5
* library when the communicator is destroyed, i.e. on MPI_Finalize.
@@ -742,8 +811,8 @@ H5_debug_mask(const char *s)
*-------------------------------------------------------------------------
*/
static int
-H5_mpi_delete_cb(MPI_Comm H5_ATTR_UNUSED comm, int H5_ATTR_UNUSED keyval, void H5_ATTR_UNUSED *attr_val,
- int H5_ATTR_UNUSED *flag)
+H5__mpi_delete_cb(MPI_Comm H5_ATTR_UNUSED comm, int H5_ATTR_UNUSED keyval, void H5_ATTR_UNUSED *attr_val,
+ int H5_ATTR_UNUSED *flag)
{
H5_term_library();
return MPI_SUCCESS;
@@ -767,12 +836,12 @@ H5_mpi_delete_cb(MPI_Comm H5_ATTR_UNUSED comm, int H5_ATTR_UNUSED keyval, void H
*-------------------------------------------------------------------------
*/
herr_t
-H5get_libversion(unsigned *majnum, unsigned *minnum, unsigned *relnum)
+H5get_libversion(unsigned *majnum /*out*/, unsigned *minnum /*out*/, unsigned *relnum /*out*/)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
- H5TRACE3("e", "*Iu*Iu*Iu", majnum, minnum, relnum);
+ H5TRACE3("e", "xxx", majnum, minnum, relnum);
/* Set the version information */
if (majnum)
@@ -890,7 +959,7 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum)
HDstrncat(lib_str, "-", (size_t)1);
HDstrncat(lib_str, substr, (sizeof(lib_str) - HDstrlen(lib_str)) - 1);
} /* end if */
- if (HDstrcmp(lib_str, H5_lib_vers_info_g)) {
+ if (HDstrcmp(lib_str, H5_lib_vers_info_g) != 0) {
HDfputs("Warning! Library version information error.\n"
"The HDF5 library version information are not "
"consistent in its source code.\nThis is NOT a fatal error "
@@ -937,6 +1006,45 @@ done:
} /* end H5open() */
/*-------------------------------------------------------------------------
+ * Function: H5atclose
+ *
+ * Purpose: Register a callback for the library to invoke when it's
+ * closing. Callbacks are invoked in LIFO order.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5atclose(H5_atclose_func_t func, void *ctx)
+{
+ H5_atclose_node_t *new_atclose; /* New 'atclose' node */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "Hc*x", func, ctx);
+
+ /* Check arguments */
+ if (NULL == func)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL func pointer")
+
+ /* Allocate space for the 'atclose' node */
+ if (NULL == (new_atclose = H5FL_MALLOC(H5_atclose_node_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate 'atclose' node")
+
+ /* Set up 'atclose' node */
+ new_atclose->func = func;
+ new_atclose->ctx = ctx;
+
+ /* Connector to linked-list of 'atclose' nodes */
+ new_atclose->next = H5_atclose_head;
+ H5_atclose_head = new_atclose;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5atclose() */
+
+/*-------------------------------------------------------------------------
* Function: H5close
*
* Purpose: Terminate the library and release all resources.
@@ -1073,23 +1181,58 @@ H5free_memory(void *mem)
*-------------------------------------------------------------------------
*/
herr_t
-H5is_library_threadsafe(hbool_t *is_ts)
+H5is_library_threadsafe(hbool_t *is_ts /*out*/)
{
- FUNC_ENTER_API_NOINIT
- H5TRACE1("e", "*b", is_ts);
+ herr_t ret_value = SUCCEED; /* Return value */
- HDassert(is_ts);
+ FUNC_ENTER_API_NOINIT
+ H5TRACE1("e", "x", is_ts);
- /* At this time, it is impossible for this to fail. */
+ if (is_ts) {
#ifdef H5_HAVE_THREADSAFE
- *is_ts = TRUE;
+ *is_ts = TRUE;
#else /* H5_HAVE_THREADSAFE */
- *is_ts = FALSE;
+ *is_ts = FALSE;
#endif /* H5_HAVE_THREADSAFE */
+ }
+ else
+ ret_value = FAIL;
- FUNC_LEAVE_API_NOINIT(SUCCEED)
+ FUNC_LEAVE_API_NOINIT(ret_value)
} /* end H5is_library_threadsafe() */
+/*-------------------------------------------------------------------------
+ * Function: H5is_library_terminating
+ *
+ * Purpose: Checks to see if the library is shutting down.
+ *
+ * Note: Useful for plugins to detect when the library is terminating.
+ * For example, a VOL connector could check if a "file close"
+ * callback was the result of the library shutdown process, or
+ * an API action from the application.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5is_library_terminating(hbool_t *is_terminating /*out*/)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API_NOINIT
+ H5TRACE1("e", "x", is_terminating);
+
+ HDassert(is_terminating);
+
+ if (is_terminating)
+ *is_terminating = H5_TERM_GLOBAL;
+ else
+ ret_value = FAIL;
+
+ FUNC_LEAVE_API_NOINIT(ret_value)
+} /* end H5is_library_terminating() */
+
#if defined(H5_HAVE_THREADSAFE) && defined(H5_BUILT_AS_DYNAMIC_LIB) && defined(H5_HAVE_WIN32_API) && \
defined(H5_HAVE_WIN_THREADS)
/*-------------------------------------------------------------------------