From 2c58357b8f8d9f4dffad5859816c9ed8c0a8216b Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 24 Oct 2024 08:28:40 -0500 Subject: [PATCH] Refactor H5FD and package initialization (#4934) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Reverts PR#1024, which (unnecessarily) switched from deferred package initialization to centralized initialization of all packages and introduced H5FDperform_init() to wrap an internal routine to initialize VFD plugins. - Went back to deferred package initialization (primarily), to eliminate unnecessary resource use. (Performance has been verified to be the same either way) - Switched VFD plugins to use “#define (H5OPEN, )” pattern, with registration of internal VFD plugins at library initialization time. Eliminates calling API routine (H5FDperform_init) from within the library, which was deadlocking threadsafe concurrency. And also eliminates exposing internal library routines in a public header file. - Removed copy-and-paste replicas of the H5OPEN macro and put a (better) single definition in H5public.h - Separated API and internal routine calls in stdio and multi VFD plugins into separate source files, so that the library doesn’t invoke API routines internally (also a deadlock problem for threadsafe concurrency). Also needed a “private” header for these plugins. - Separated registering/unregistering a VFD plugin from initializing /finalizing the plugin, instead of blurring those ideas together. Defers the VFD plugin init to when it’s actually used, which reduces resource usage, especially for the MPI-based plugins like the subfiling, etc. - Refactored the copy-and-pasted check for locking into a central location in the H5FD.c code. - Fixed a bunch of compiler warnings, especially ones that trigger CI failures with -Werror --- .github/workflows/netcdf.yml | 3 +- release_docs/RELEASE.txt | 30 +- src/CMakeLists.txt | 4 +- src/H5.c | 391 +++++++++--------- src/H5AC.c | 32 +- src/H5ACmodule.h | 5 +- src/H5ACproxy_entry.c | 3 +- src/H5Aint.c | 80 +++- src/H5Amodule.h | 5 +- src/H5B.c | 3 + src/H5B2.c | 3 + src/H5B2module.h | 5 +- src/H5Bmodule.h | 5 +- src/H5C.c | 3 + src/H5CX.c | 94 +++-- src/H5CXmodule.h | 5 +- src/H5CXprivate.h | 2 - src/H5Cmodule.h | 5 +- src/H5D.c | 3 + src/H5Dchunk.c | 29 +- src/H5Dint.c | 110 +++-- src/H5Dmodule.h | 5 +- src/H5Dmpio.c | 19 +- src/H5Dvirtual.c | 3 +- src/H5E.c | 3 + src/H5EA.c | 3 + src/H5EAmodule.h | 5 +- src/H5ESint.c | 27 +- src/H5ESmodule.h | 5 +- src/H5ESprivate.h | 5 +- src/H5Eint.c | 138 ++++--- src/H5Emodule.h | 5 +- src/H5Epublic.h | 8 - src/H5FA.c | 3 + src/H5FAmodule.h | 5 +- src/H5FD.c | 159 ++++++- src/H5FDcore.c | 65 ++- src/H5FDcore.h | 11 +- src/H5FDdevelop.h | 1 - src/H5FDdirect.c | 69 ++-- src/H5FDdirect.h | 11 +- src/H5FDfamily.c | 48 +-- src/H5FDfamily.h | 11 +- src/H5FDhdfs.c | 116 ++++-- src/H5FDhdfs.h | 18 +- src/H5FDint.c | 3 +- src/H5FDlog.c | 65 ++- src/H5FDlog.h | 10 +- src/H5FDmirror.c | 56 ++- src/H5FDmirror.h | 11 +- src/H5FDmodule.h | 5 +- src/H5FDmpi.c | 43 +- src/H5FDmpio.c | 206 ++++++--- src/H5FDmpio.h | 19 +- src/H5FDmulti.c | 339 ++++++--------- src/H5FDmulti.h | 11 +- src/H5FDmulti_int.c | 83 ++++ ...{H5FDdrvr_module.h => H5FDmulti_private.h} | 40 +- src/H5FDonion.c | 55 ++- src/H5FDonion.h | 11 +- src/H5FDonion_header.c | 6 +- src/H5FDonion_history.c | 6 +- src/H5FDonion_index.c | 6 +- src/H5FDonion_priv.h | 4 + src/H5FDperform.c | 57 --- src/H5FDpkg.h | 49 +++ src/H5FDprivate.h | 2 +- src/H5FDros3.c | 104 +++-- src/H5FDros3.h | 59 +-- src/H5FDsec2.c | 65 ++- src/H5FDsec2.h | 11 +- src/H5FDsplitter.c | 50 ++- src/H5FDsplitter.h | 11 +- src/H5FDstdio.c | 170 ++++---- src/H5FDstdio.h | 11 +- src/H5FDstdio_int.c | 83 ++++ src/H5FDstdio_private.h | 45 ++ src/H5FDsubfiling/H5FDioc.c | 232 +++++++---- src/H5FDsubfiling/H5FDioc.h | 15 +- src/H5FDsubfiling/H5FDioc_int.c | 33 +- src/H5FDsubfiling/H5FDioc_priv.h | 12 +- src/H5FDsubfiling/H5FDioc_threads.c | 7 +- src/H5FDsubfiling/H5FDsubfile_int.c | 7 +- src/H5FDsubfiling/H5FDsubfiling.c | 272 ++++++------ src/H5FDsubfiling/H5FDsubfiling.h | 15 +- src/H5FDsubfiling/H5FDsubfiling_priv.h | 11 +- src/H5FDsubfiling/H5subfiling_common.c | 14 +- src/H5FDsubfiling/H5subfiling_common.h | 13 +- src/H5FDwindows.c | 13 +- src/H5FDwindows.h | 13 +- src/H5FL.c | 24 +- src/H5FLmodule.h | 5 +- src/H5FS.c | 3 + src/H5FSint.c | 22 + src/H5FSmodule.h | 5 +- src/H5FSprivate.h | 3 + src/H5Fcwfs.c | 6 +- src/H5Fint.c | 54 ++- src/H5Fmodule.h | 5 +- src/H5Fmpi.c | 6 +- src/H5Fpublic.h | 56 +-- src/H5Fquery.c | 2 +- src/H5Gint.c | 72 +++- src/H5Gmodule.h | 5 +- src/H5Gname.c | 33 +- src/H5HF.c | 3 + src/H5HFmodule.h | 5 +- src/H5HFsection.c | 69 ++-- src/H5HG.c | 3 + src/H5HGmodule.h | 5 +- src/H5HL.c | 3 + src/H5HLmodule.h | 5 +- src/H5HLpkg.h | 9 - src/H5Iint.c | 41 +- src/H5Imodule.h | 5 +- src/H5Lint.c | 44 +- src/H5Lmodule.h | 5 +- src/H5M.c | 63 ++- src/H5MF.c | 59 +-- src/H5MFmodule.h | 5 +- src/H5Mmodule.h | 5 +- src/H5Oint.c | 39 +- src/H5Omodule.h | 5 +- src/H5P.c | 5 +- src/H5PB.c | 3 + src/H5PBmodule.h | 5 +- src/H5PLint.c | 43 +- src/H5PLmodule.h | 5 +- src/H5PLprivate.h | 1 - src/H5Pint.c | 294 +++++++------ src/H5Pmodule.h | 5 +- src/H5Ppublic.h | 8 - src/H5RS.c | 3 + src/H5RSmodule.h | 5 +- src/H5Rint.c | 30 +- src/H5Rmodule.h | 5 +- src/H5Rprivate.h | 2 - src/H5S.c | 82 +++- src/H5SL.c | 74 ++-- src/H5SLmodule.h | 5 +- src/H5SLprivate.h | 1 - src/H5SM.c | 3 + src/H5SMmodule.h | 5 +- src/H5Shyper.c | 17 +- src/H5Smodule.h | 5 +- src/H5T.c | 370 ++++++++++------- src/H5TSint.c | 3 + src/H5TSmodule.h | 5 +- src/H5TSwin.c | 2 +- src/H5Tfields.c | 2 +- src/H5Tmodule.h | 5 +- src/H5Topaque.c | 2 +- src/H5Tpublic.h | 8 - src/H5VLint.c | 148 ++++--- src/H5VLmodule.h | 5 +- src/H5VLnative.h | 8 - src/H5VLpassthru.h | 8 - src/H5Z.c | 141 ++++--- src/H5Zmodule.h | 5 +- src/H5module.h | 5 +- src/H5private.h | 114 ++--- src/H5public.h | 33 ++ src/Makefile.am | 5 +- 163 files changed, 3577 insertions(+), 2488 deletions(-) create mode 100644 src/H5FDmulti_int.c rename src/{H5FDdrvr_module.h => H5FDmulti_private.h} (53%) delete mode 100644 src/H5FDperform.c create mode 100644 src/H5FDstdio_int.c create mode 100644 src/H5FDstdio_private.h diff --git a/.github/workflows/netcdf.yml b/.github/workflows/netcdf.yml index febc7b6fd8f..ab92a1e68ec 100644 --- a/.github/workflows/netcdf.yml +++ b/.github/workflows/netcdf.yml @@ -77,7 +77,8 @@ jobs: run: | cd netcdf-c autoreconf -if - CFLAGS=${CFLAGS} LDFLAGS=${LDFLAGS} LD_LIBRARY_PATH=${LD_LIBRARY_PATH} ./configure --enable-hdf5 --enable-dap --disable-dap-remote-tests --enable-external-server-tests + # NOTE: --disable-byterange should be removed when the HTTP VFD has been updated + CFLAGS=${CFLAGS} LDFLAGS=${LDFLAGS} LD_LIBRARY_PATH=${LD_LIBRARY_PATH} ./configure --enable-hdf5 --enable-dap --disable-dap-remote-tests --disable-byterange --enable-external-server-tests cat config.log cat libnetcdf.settings CFLAGS=${CFLAGS} LDFLAGS=${LDFLAGS} LD_LIBRARY_PATH=${LD_LIBRARY_PATH} make -j diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 19e8e59c1fc..6a01a10a586 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -47,6 +47,18 @@ New Features Configuration: ------------- + - Added a configuration option for internal threading/concurrency support: + + CMake: HDF5_ENABLE_THREADS (ON/OFF) (Default: ON) + Autotools: --enable-threads (yes/no) (Default: yes) + + This option enables support for threading and concurrency algorithms + within the HDF5 library. It is required for, but separate from, the + 'threadsafe' configure option, which makes the HDF5 API safe to call from + multiple threads. It is possible to enable the 'threads' option and + disable the 'threadsafe' option, but not vice versa. The 'threads' option + must be on to enable the subfiling VFD. + - Added support for native zlib-ng compression. Changed the zlib-ng CMake logic to prefer the native zlib-ng library. Added @@ -54,7 +66,7 @@ New Features header file with the same #ifdef. - Renamed remaining HDF5 library CMake options except for CMake BUILD* variables - + DEFAULT_API_VERSION to HDF5_DEFAULT_API_VERSION DISABLE_PDB_FILES to HDF5_DISABLE_PDB_FILES ONLY_SHARED_LIBS to HDF5_ONLY_SHARED_LIBS @@ -62,6 +74,7 @@ New Features TEST_SHELL_SCRIPTS to HDF5_TEST_SHELL_SCRIPTS All other HDF5 library CMake options are prefixed with HDF5_ + - bin/cmakehdf5 has been removed This was an unsupported build script that made building HDF5 via CMake @@ -104,21 +117,14 @@ New Features We have updated the build files to set the C standard to C11, though some platforms use gnu11 to get some GNU things to work. - - Added configuration option for internal threading/concurrency support: - - CMake: HDF5_ENABLE_THREADS (ON/OFF) (Default: ON) - Autotools: --enable-threads (yes/no) (Default: yes) - - This option enables support for threading and concurrency algorithms - within the HDF5 library. It is required for, but separate from, the - 'threadsafe' configure option, which makes the HDF5 API safe to call from - multiple threads. It is possible to enable the 'threads' option and - disable the 'threadsafe' option, but not vice versa. The 'threads' option - must be on to enable the subfiling VFD. Library: -------- + - Removed H5FDperform_init API routine. Virtual File Driver (VFD) + developers who wish to provide an ID for their driver should create + a routine specific to their individual implementation. + - H5Pset_external() now uses HDoff_t, which is always a 64-bit type The H5Pset_external() call took an off_t parameter in HDF5 1.14.x and diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3db8991df8c..d2cafa37df2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -236,17 +236,18 @@ set (H5FD_SOURCES ${HDF5_SRC_DIR}/H5FDmpi.c ${HDF5_SRC_DIR}/H5FDmpio.c ${HDF5_SRC_DIR}/H5FDmulti.c + ${HDF5_SRC_DIR}/H5FDmulti_int.c ${HDF5_SRC_DIR}/H5FDonion.c ${HDF5_SRC_DIR}/H5FDonion_header.c ${HDF5_SRC_DIR}/H5FDonion_history.c ${HDF5_SRC_DIR}/H5FDonion_index.c - ${HDF5_SRC_DIR}/H5FDperform.c ${HDF5_SRC_DIR}/H5FDros3.c ${HDF5_SRC_DIR}/H5FDs3comms.c ${HDF5_SRC_DIR}/H5FDsec2.c ${HDF5_SRC_DIR}/H5FDspace.c ${HDF5_SRC_DIR}/H5FDsplitter.c ${HDF5_SRC_DIR}/H5FDstdio.c + ${HDF5_SRC_DIR}/H5FDstdio_int.c ${HDF5_SRC_DIR}/H5FDtest.c ${HDF5_SRC_DIR}/H5FDwindows.c ) @@ -754,7 +755,6 @@ set (H5_MODULE_HEADERS ${HDF5_SRC_DIR}/H5ESmodule.h ${HDF5_SRC_DIR}/H5Fmodule.h ${HDF5_SRC_DIR}/H5FAmodule.h - ${HDF5_SRC_DIR}/H5FDdrvr_module.h ${HDF5_SRC_DIR}/H5FDmodule.h ${HDF5_SRC_DIR}/H5FLmodule.h ${HDF5_SRC_DIR}/H5FSmodule.h diff --git a/src/H5.c b/src/H5.c index f591e84eb76..8fcc8eeb2b8 100644 --- a/src/H5.c +++ b/src/H5.c @@ -32,8 +32,6 @@ #include "H5SLprivate.h" /* Skip lists */ #include "H5Tprivate.h" /* Datatypes */ -#include "H5FDsec2.h" /* for H5FD_sec2_init() */ - /****************/ /* Local Macros */ /****************/ @@ -60,11 +58,15 @@ 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); #endif /*H5_HAVE_PARALLEL*/ +static herr_t H5_check_version(unsigned majnum, unsigned minnum, unsigned relnum); /*********************/ /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /*****************************/ /* Library Private Variables */ /*****************************/ @@ -91,30 +93,31 @@ 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); -/*------------------------------------------------------------------------- - * Function: H5_default_vfd_init - * - * Purpose: Initialize the default VFD. - * - * Return: Success: non-negative - * Failure: negative - *------------------------------------------------------------------------- - */ -static herr_t -H5_default_vfd_init(void) +/*-------------------------------------------------------------------------- +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; + 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"); - FUNC_ENTER_NOAPI(FAIL) - /* Load the hid_t for the default VFD for the side effect - * it has of initializing the default VFD. - */ - if (H5FD_sec2_init() == H5I_INVALID_HID) { - HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to load default VFD ID"); - } done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5__init_package() */ /*-------------------------------------------------------------------------- * NAME @@ -133,7 +136,6 @@ H5_default_vfd_init(void) herr_t H5_init_library(void) { - size_t i; herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(FAIL) @@ -142,6 +144,10 @@ H5_init_library(void) if (H5_INIT_GLOBAL || H5_TERM_GLOBAL) HGOTO_DONE(SUCCEED); + /* Check library version */ + /* (Will abort() on failure) */ + H5_check_version(H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE); + /* Set the 'library initialized' flag as early as possible, to avoid * possible re-entrancy. */ @@ -224,50 +230,53 @@ H5_init_library(void) } /* end if */ /* - * Initialize interfaces that might not be able to initialize themselves - * soon enough. The file & dataset interfaces must be initialized because - * calling H5P_create() might require the file/dataset property classes to be - * initialized. The property interface must be initialized before the file - * & dataset interfaces though, in order to provide them with the proper - * property classes. - * The link interface needs to be initialized so that link property lists - * have their properties registered. + * Initialize interfaces that use macros of the form "(H5OPEN )", so + * that the variable returned through the macros has been initialized. + * Also initialize some interfaces that might not be able to initialize + * themselves soon enough. + * + * Interfaces returning variables through a macro: H5E, H5FD, H5O, H5P, H5T + * + * The link interface needs to be initialized so that the external link + * class is registered. + * * The FS module needs to be initialized as a result of the fix for HDFFV-10160: * It might not be initialized during normal file open. * When the application does not close the file, routines in the module might * be called via H5_term_library() when shutting down the file. + * * The dataspace interface needs to be initialized so that future IDs for * dataspaces work. + * + * The VFD & VOL interfaces need to be initialized before the H5P interface + * so that the default VFD and default VOL connector are ready for the + * default FAPL. + * */ - { - /* clang-format off */ - struct { - herr_t (*func)(void); - const char *descr; - } initializer[] = { - {H5E_init, "error"} - , {H5VL_init_phase1, "VOL"} - , {H5SL_init, "skip lists"} - , {H5FD_init, "VFD"} - , {H5_default_vfd_init, "default VFD"} - , {H5P_init_phase1, "property list"} - , {H5AC_init, "metadata caching"} - , {H5L_init, "link"} - , {H5S_init, "dataspace"} - , {H5PL_init, "plugins"} - /* Finish initializing interfaces that depend on the interfaces above */ - , {H5P_init_phase2, "property list"} - , {H5VL_init_phase2, "VOL"} - }; - - for (i = 0; i < NELMTS(initializer); i++) { - if (initializer[i].func() < 0) { - HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, - "unable to initialize %s interface", initializer[i].descr); - } - } - /* clang-format on */ - } + if (H5E_init() < 0) + HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize error interface"); + if (H5FD_init() < 0) + HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize VFL interface"); + if (H5VL_init_phase1() < 0) + HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize vol interface"); + if (H5P_init_phase1() < 0) + HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize property list interface"); + if (H5L_init() < 0) + HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize link interface"); + if (H5O_init() < 0) + HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize object interface"); + if (H5FS_init() < 0) + HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize FS interface"); + if (H5S_init() < 0) + HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize dataspace interface"); + if (H5T_init() < 0) + HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize datatype interface"); + + /* Finish initializing interfaces that depend on the interfaces above */ + if (H5P_init_phase2() < 0) + HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize property list interface"); + if (H5VL_init_phase2() < 0) + HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize vol interface"); /* Debugging? */ H5__debug_mask("-all"); @@ -291,11 +300,9 @@ H5_init_library(void) void H5_term_library(void) { - int pending, ntries = 0; - char loop[1024], *next = loop; - size_t i; - size_t nleft = sizeof(loop); - int nprinted; + int pending, ntries = 0, n; + size_t at = 0; + char loop[1024]; H5E_auto2_t func; /* Acquire the API lock */ @@ -337,147 +344,114 @@ H5_term_library(void) H5_atclose_head = NULL; } /* end if */ - /* clang-format off */ - /* * Terminate each interface. The termination functions return a positive * value if they do something that might affect some other interface in a * way that would necessitate some cleanup work in the other interface. */ +#define DOWN(F) \ + (((n = H5##F##_term_package()) && (at + 8) < sizeof loop) \ + ? (sprintf(loop + at, "%s%s", (at ? "," : ""), #F), at += strlen(loop + at), n) \ + : ((n > 0 && (at + 5) < sizeof loop) ? (sprintf(loop + at, "..."), at += strlen(loop + at), n) \ + : n)) - { -#define TERMINATOR(module, wait) { \ - .func = H5##module##_term_package \ - , .name = #module \ - , .completed = false \ - , .await_prior = wait \ - } + do { + pending = 0; - /* - * Termination is ordered by the `terminator` table so the "higher" level - * packages are shut down before "lower" level packages that they - * rely on: + /* Try to organize these so the "higher" level components get shut + * down before "lower" level components that they might rely on. -QAK */ - struct { - int (*func)(void); /* function to terminate the module; returns 0 - * on success, >0 if termination was not - * completed and we should try to terminate - * some dependent modules, first. - */ - const char *name; /* name of the module */ - bool completed; /* true iff this terminator was already - * completed - */ - const bool await_prior; /* true iff all prior terminators in the - * list must complete before this - * terminator is attempted - */ - } terminator[] = { - /* Close the event sets first, so that all asynchronous operations - * complete before anything else attempts to shut down. - */ - TERMINATOR(ES, false) - /* Do not attempt to close down package L until after event sets - * have finished closing down. - */ - , TERMINATOR(L, true) + + /* Close the event sets first, so that all asynchronous operations + * complete before anything else attempts to shut down. + */ + pending += DOWN(ES); + + /* Close down the user-facing interfaces, after the event sets */ + if (pending == 0) { + /* Close the interfaces dependent on others */ + pending += DOWN(L); + /* Close the "top" of various interfaces (IDs, etc) but don't shut * down the whole interface yet, so that the object header messages * get serialized correctly for entries in the metadata cache and the * symbol table entry in the superblock gets serialized correctly, etc. * all of which is performed in the 'F' shutdown. - * - * The tops of packages A, D, G, M, S, T do not need to wait for L - * or previous packages to finish closing down. */ - , TERMINATOR(A_top, false) - , TERMINATOR(D_top, false) - , TERMINATOR(G_top, false) - , TERMINATOR(M_top, false) - , TERMINATOR(S_top, false) - , TERMINATOR(T_top, false) - /* Don't shut down the file code until objects in files are shut down */ - , TERMINATOR(F, true) - /* Don't shut down the property list code until all objects that might - * use property lists are shut down - */ - , TERMINATOR(P, true) - /* Wait to shut down the "bottom" of various interfaces until the - * files are closed, so pieces of the file can be serialized - * correctly. - * - * Shut down the "bottom" of the attribute, dataset, group, - * reference, dataspace, and datatype interfaces, fully closing + pending += DOWN(A_top); + pending += DOWN(D_top); + pending += DOWN(G_top); + pending += DOWN(M_top); + pending += DOWN(S_top); + pending += DOWN(T_top); + } /* end if */ + + /* Don't shut down the file code until objects in files are shut down */ + if (pending == 0) + pending += DOWN(F); + + /* Don't shut down the property list code until all objects that might + * use property lists are shut down */ + if (pending == 0) + pending += DOWN(P); + + /* Wait to shut down the "bottom" of various interfaces until the + * files are closed, so pieces of the file can be serialized + * correctly. + */ + if (pending == 0) { + /* Shut down the "bottom" of the attribute, dataset, group, + * dataspace, and datatype interfaces, fully closing * out the interfaces now. */ - , TERMINATOR(A, true) - , TERMINATOR(D, false) - , TERMINATOR(G, false) - , TERMINATOR(M, false) - , TERMINATOR(S, false) - , TERMINATOR(T, false) - /* Wait to shut down low-level packages like AC until after - * the preceding high-level packages have shut down. This prevents - * low-level objects from closing "out from underneath" their - * reliant high-level objects. - */ - , TERMINATOR(AC, true) - /* Shut down the "pluggable" interfaces, before the plugin framework */ - , TERMINATOR(Z, false) - , TERMINATOR(FD, false) - , TERMINATOR(VL, false) - /* Don't shut down the plugin code until all "pluggable" interfaces - * (Z, FD, PL) are shut down - */ - , TERMINATOR(PL, true) - /* Shut down the following packages in strictly the order given - * by the table. - */ - , TERMINATOR(E, true) - , TERMINATOR(I, true) - , TERMINATOR(SL, true) - , TERMINATOR(FL, true) - , TERMINATOR(CX, true) - }; - - do { - pending = 0; - for (i = 0; i < NELMTS(terminator); i++) { - if (terminator[i].completed) - continue; - if (pending != 0 && terminator[i].await_prior) - break; - if (terminator[i].func() == 0) { - terminator[i].completed = true; - continue; - } - - /* log a package when its terminator needs to be retried */ - pending++; - nprinted = snprintf(next, nleft, "%s%s", - (next != loop) ? "," : "", terminator[i].name); - if (nprinted < 0) - continue; - if ((size_t)nprinted >= nleft) - nprinted = snprintf(next, nleft, "..."); - if (nprinted < 0 || (size_t)nprinted >= nleft) - continue; - nleft -= (size_t)nprinted; - next += nprinted; - } - } while (pending && ntries++ < 100); + pending += DOWN(A); + pending += DOWN(D); + pending += DOWN(G); + pending += DOWN(M); + pending += DOWN(S); + pending += DOWN(T); + } /* end if */ - /* clang-format on */ + /* Don't shut down "low-level" components until "high-level" components + * have successfully shut down. This prevents property lists and IDs + * from being closed "out from underneath" of the high-level objects + * that depend on them. -QAK + */ + if (pending == 0) { + pending += DOWN(AC); + /* Shut down the "pluggable" interfaces, before the plugin framework */ + pending += DOWN(Z); + pending += DOWN(FD); + pending += DOWN(VL); + /* Don't shut down the plugin code until all "pluggable" interfaces (Z, FD, PL) are shut down */ + if (pending == 0) + pending += DOWN(PL); + /* Don't shut down the error code until other APIs which use it are shut down */ + if (pending == 0) + pending += DOWN(E); + /* Don't shut down the ID code until other APIs which use them are shut down */ + if (pending == 0) + pending += DOWN(I); + /* Don't shut down the skip list code until everything that uses it is down */ + if (pending == 0) + pending += DOWN(SL); + /* Don't shut down the free list code until everything that uses it is down */ + if (pending == 0) + pending += DOWN(FL); + /* Don't shut down the API context code until _everything_ else is down */ + if (pending == 0) + pending += DOWN(CX); + } /* end if */ + } while (pending && ntries++ < 100); - if (pending) { - /* Only display the error message if the user is interested in them. */ - if (func) { - fprintf(stderr, "HDF5: infinite loop closing library\n"); - fprintf(stderr, " %s\n", loop); + if (pending) { + /* Only display the error message if the user is interested in them. */ + if (func) { + fprintf(stderr, "HDF5: infinite loop closing library\n"); + fprintf(stderr, " %s\n", loop); #ifndef NDEBUG - abort(); + abort(); #endif - } } } @@ -531,14 +505,14 @@ H5dont_atexit(void) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API_NOINIT_NOERR_NOFS + FUNC_ENTER_API_NOINIT_NOERR if (H5_dont_atexit_g) ret_value = FAIL; else H5_dont_atexit_g = true; - FUNC_LEAVE_API_NOFS(ret_value) + FUNC_LEAVE_API_NOERR(ret_value) } /* end H5dont_atexit() */ /*------------------------------------------------------------------------- @@ -816,13 +790,10 @@ H5get_libversion(unsigned *majnum /*out*/, unsigned *minnum /*out*/, unsigned *r } /* end H5get_libversion() */ /*------------------------------------------------------------------------- - * Function: H5check_version + * Function: H5__check_version * - * Purpose: Verifies that the arguments match the version numbers - * compiled into the library. This function is intended to be - * called from user to verify that the versions of header files - * compiled into the application match the version of the hdf5 - * library. + * Purpose: Internal routine which Verifies that the arguments match the + * version numbers compiled into the library. * * Within major.minor.release version, the expectation * is that all release versions are compatible, exceptions to @@ -852,18 +823,18 @@ H5get_libversion(unsigned *majnum /*out*/, unsigned *minnum /*out*/, unsigned *r "You should recompile the application or check your shared library related\n" \ "settings such as 'LD_LIBRARY_PATH'.\n" -herr_t -H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) +static herr_t +H5_check_version(unsigned majnum, unsigned minnum, unsigned relnum) { char lib_str[256]; char substr[] = H5_VERS_SUBRELEASE; - static int checked = 0; /* If we've already checked the version info */ - static unsigned int disable_version_check = 0; /* Set if the version check should be disabled */ + static bool checked = false; /* If we've already checked the version info */ + static unsigned int disable_version_check = 0; /* Set if the version check should be disabled */ static const char *version_mismatch_warning = VERSION_MISMATCH_WARNING; static const char *release_mismatch_warning = RELEASE_MISMATCH_WARNING; herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API_NOINIT_NOERR_NOFS + FUNC_ENTER_NOAPI_NOINIT_NOERR /* Don't check again, if we already have */ if (checked) @@ -960,7 +931,7 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) } /* end if (H5_VERS_RELEASE != relnum) */ /* Indicate that the version check has been performed */ - checked = 1; + checked = true; if (!disable_version_check) { /* @@ -988,7 +959,21 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) } done: - FUNC_LEAVE_API_NOFS(ret_value) + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5__check_version() */ + +herr_t +H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API_NOINIT_NOERR + + /* Call internal routine */ + /* (Will abort() on failure) */ + H5_check_version(majnum, minnum, relnum); + + FUNC_LEAVE_API_NOERR(ret_value) } /* end H5check_version() */ /*------------------------------------------------------------------------- @@ -1071,11 +1056,11 @@ H5close(void) * whole library just to release it all right away. It is safe to call * this function for an uninitialized library. */ - FUNC_ENTER_API_NOINIT_NOERR_NOFS + FUNC_ENTER_API_NOINIT_NOERR H5_term_library(); - FUNC_LEAVE_API_NOFS(SUCCEED) + FUNC_LEAVE_API_NOERR(SUCCEED) } /* end H5close() */ /*------------------------------------------------------------------------- diff --git a/src/H5AC.c b/src/H5AC.c index 8ad885e8af3..9aef2957663 100644 --- a/src/H5AC.c +++ b/src/H5AC.c @@ -67,6 +67,9 @@ static herr_t H5AC__verify_tag(const H5AC_class_t *type); /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /*****************************/ /* Library Private Variables */ /*****************************/ @@ -134,7 +137,26 @@ H5AC_init(void) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5AC_init() */ + +/*------------------------------------------------------------------------- + * Function: H5AC__init_package + * + * Purpose: Initialize interface-specific information + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC__init_package(void) +{ + FUNC_ENTER_PACKAGE_NOERR #ifdef H5_HAVE_PARALLEL /* check whether to enable strict collective function calling @@ -151,8 +173,8 @@ H5AC_init(void) } #endif /* H5_HAVE_PARALLEL */ - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5AC_init() */ + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5AC__init_package() */ /*------------------------------------------------------------------------- * Function: H5AC_term_package @@ -170,6 +192,10 @@ H5AC_term_package(void) { FUNC_ENTER_NOAPI_NOINIT_NOERR + if (H5_PKG_INIT_VAR) + /* Reset interface initialization flag */ + H5_PKG_INIT_VAR = false; + FUNC_LEAVE_NOAPI(0) } /* end H5AC_term_package() */ diff --git a/src/H5ACmodule.h b/src/H5ACmodule.h index 94cf94bd334..1b9b88e0d24 100644 --- a/src/H5ACmodule.h +++ b/src/H5ACmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5AC_MODULE -#define H5_MY_PKG H5AC -#define H5_MY_PKG_ERR H5E_CACHE +#define H5_MY_PKG H5AC +#define H5_MY_PKG_ERR H5E_CACHE +#define H5_MY_PKG_INIT YES #endif /* H5ACmodule_H */ diff --git a/src/H5ACproxy_entry.c b/src/H5ACproxy_entry.c index c8142cca4f3..109c1b42cb4 100644 --- a/src/H5ACproxy_entry.c +++ b/src/H5ACproxy_entry.c @@ -399,7 +399,7 @@ H5AC_proxy_entry_dest(H5AC_proxy_entry_t *pentry) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Sanity checks */ assert(pentry); @@ -411,6 +411,7 @@ H5AC_proxy_entry_dest(H5AC_proxy_entry_t *pentry) /* Free the proxy entry object */ pentry = H5FL_FREE(H5AC_proxy_entry_t, pentry); +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5AC_proxy_entry_dest() */ diff --git a/src/H5Aint.c b/src/H5Aint.c index fdeb9643510..d0e0bcff9af 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -88,6 +88,9 @@ static herr_t H5A__iterate_common(hid_t loc_id, H5_index_t idx_type, H5_iter_ord /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* Format version bounds for attribute */ const unsigned H5O_attr_ver_bounds[] = { H5O_ATTR_VERSION_1, /* H5F_LIBVER_EARLIEST */ @@ -128,6 +131,9 @@ static const H5I_class_t H5I_ATTR_CLS[1] = {{ (H5I_free_t)H5A__close_cb /* Callback routine for closing objects of this class */ }}; +/* Flag indicating "top" of interface has been initialized */ +static hbool_t H5A_top_package_initialize_s = false; + /*------------------------------------------------------------------------- * Function: H5A_init * @@ -144,6 +150,30 @@ H5A_init(void) herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_init() */ + +/*-------------------------------------------------------------------------- +NAME + H5A__init_package -- Initialize interface-specific information +USAGE + herr_t H5A__init_package() + +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. + +--------------------------------------------------------------------------*/ +herr_t +H5A__init_package(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE /* * Create attribute ID type. @@ -151,9 +181,12 @@ H5A_init(void) if (H5I_register_type(H5I_ATTR_CLS) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to initialize interface"); + /* Mark "top" of interface as initialized, too */ + H5A_top_package_initialize_s = true; + done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_init() */ +} /* end H5A__init_package() */ /*-------------------------------------------------------------------------- NAME @@ -179,10 +212,16 @@ H5A_top_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - if (H5I_nmembers(H5I_ATTR) > 0) { - (void)H5I_clear_type(H5I_ATTR, false, false); - n++; /*H5I*/ - } /* end if */ + if (H5A_top_package_initialize_s) { + if (H5I_nmembers(H5I_ATTR) > 0) { + (void)H5I_clear_type(H5I_ATTR, false, false); + n++; /*H5I*/ + } /* end if */ + + /* Mark closed */ + if (0 == n) + H5A_top_package_initialize_s = false; + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* H5A_top_term_package() */ @@ -213,11 +252,18 @@ H5A_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - /* Sanity checks */ - assert(0 == H5I_nmembers(H5I_ATTR)); + if (H5_PKG_INIT_VAR) { + /* Sanity checks */ + assert(0 == H5I_nmembers(H5I_ATTR)); + assert(false == H5A_top_package_initialize_s); + + /* Destroy the attribute object id group */ + n += (H5I_dec_type_ref(H5I_ATTR) > 0); - /* Destroy the attribute object id group */ - n += (H5I_dec_type_ref(H5I_ATTR) > 0); + /* Mark closed */ + if (0 == n) + H5_PKG_INIT_VAR = false; + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* H5A_term_package() */ @@ -1095,9 +1141,7 @@ H5A__get_create_plist(H5A_t *attr) herr_t H5A__get_info(const H5A_t *attr, H5A_info_t *ainfo) { - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_PACKAGE_NOERR /* Check args */ assert(attr); @@ -1115,7 +1159,7 @@ H5A__get_info(const H5A_t *attr, H5A_info_t *ainfo) ainfo->corder = attr->shared->crt_idx; } /* end else */ - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5A__get_info() */ /*------------------------------------------------------------------------- @@ -1319,13 +1363,14 @@ H5A_oloc(H5A_t *attr) { H5O_loc_t *ret_value = NULL; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(NULL) assert(attr); /* Set return value */ ret_value = &(attr->oloc); +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5A_oloc() */ @@ -1346,13 +1391,14 @@ H5A_nameof(H5A_t *attr) { H5G_name_t *ret_value = NULL; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(NULL) assert(attr); /* Set return value */ ret_value = &(attr->path); +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5A_nameof() */ @@ -1371,13 +1417,14 @@ H5A_type(const H5A_t *attr) { H5T_t *ret_value = NULL; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(NULL) assert(attr); /* Set return value */ ret_value = attr->shared->dt; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5A_type() */ @@ -1435,6 +1482,7 @@ H5A__exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name, * into table. * * Return: Non-negative on success/Negative on failure + * *------------------------------------------------------------------------- */ static herr_t diff --git a/src/H5Amodule.h b/src/H5Amodule.h index 77d1b338761..7e0e2bb76e7 100644 --- a/src/H5Amodule.h +++ b/src/H5Amodule.h @@ -22,8 +22,9 @@ * reporting macros. */ #define H5A_MODULE -#define H5_MY_PKG H5A -#define H5_MY_PKG_ERR H5E_ATTR +#define H5_MY_PKG H5A +#define H5_MY_PKG_ERR H5E_ATTR +#define H5_MY_PKG_INIT YES /** \page H5A_UG HDF5 Attributes * diff --git a/src/H5B.c b/src/H5B.c index 9c081a91fe0..9969e08b0c9 100644 --- a/src/H5B.c +++ b/src/H5B.c @@ -153,6 +153,9 @@ static H5B_t *H5B__copy(const H5B_t *old_bt); /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* Declare a free list to manage the haddr_t sequence information */ H5FL_SEQ_DEFINE(haddr_t); diff --git a/src/H5B2.c b/src/H5B2.c index 1bdfd5decda..82e58243f75 100644 --- a/src/H5B2.c +++ b/src/H5B2.c @@ -59,6 +59,9 @@ /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* v2 B-tree client ID to class mapping */ /* Remember to add client ID to H5B2_subid_t in H5B2private.h when adding a new diff --git a/src/H5B2module.h b/src/H5B2module.h index 2807ac6ea2e..d29a54d3f04 100644 --- a/src/H5B2module.h +++ b/src/H5B2module.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5B2_MODULE -#define H5_MY_PKG H5B2 -#define H5_MY_PKG_ERR H5E_BTREE +#define H5_MY_PKG H5B2 +#define H5_MY_PKG_ERR H5E_BTREE +#define H5_MY_PKG_INIT NO #endif /* H5B2module_H */ diff --git a/src/H5Bmodule.h b/src/H5Bmodule.h index 04aafdb0532..ed7c14b6b96 100644 --- a/src/H5Bmodule.h +++ b/src/H5Bmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5B_MODULE -#define H5_MY_PKG H5B -#define H5_MY_PKG_ERR H5E_BTREE +#define H5_MY_PKG H5B +#define H5_MY_PKG_ERR H5E_BTREE +#define H5_MY_PKG_INIT NO #endif /* H5Bmodule_H */ diff --git a/src/H5C.c b/src/H5C.c index 156251e592f..66de1c5e3a5 100644 --- a/src/H5C.c +++ b/src/H5C.c @@ -84,6 +84,9 @@ /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* Declare a free list to manage the tag info struct */ H5FL_DEFINE(H5C_tag_info_t); diff --git a/src/H5CX.c b/src/H5CX.c index 92a8d2cb88b..c2a25e8d7a2 100644 --- a/src/H5CX.c +++ b/src/H5CX.c @@ -449,6 +449,9 @@ static H5CX_node_t *H5CX__pop_common(bool update_dxpl_props); /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /*******************/ /* Local Variables */ /*******************/ @@ -481,17 +484,18 @@ H5FL_DEFINE_STATIC(H5CX_node_t); /* Declare a static free list to manage H5CX_state_t structs */ H5FL_DEFINE_STATIC(H5CX_state_t); -/*------------------------------------------------------------------------- - * Function: H5CX_init - * - * Purpose: Initialize the interface from some other layer. - * - * Return: Success: non-negative - * Failure: negative - *------------------------------------------------------------------------- - */ +/*-------------------------------------------------------------------------- +NAME + H5CX__init_package -- Initialize interface-specific information +USAGE + herr_t H5CX__init_package() +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. +--------------------------------------------------------------------------*/ herr_t -H5CX_init(void) +H5CX__init_package(void) { H5P_genplist_t *dx_plist; /* Data transfer property list */ H5P_genplist_t *lc_plist; /* Link creation property list */ @@ -501,7 +505,7 @@ H5CX_init(void) H5P_genplist_t *fa_plist; /* File access property list */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Reset the "default DXPL cache" information */ memset(&H5CX_def_dxpl_cache, 0, sizeof(H5CX_dxpl_cache_t)); @@ -685,9 +689,10 @@ H5CX_init(void) if (H5P_get(fa_plist, H5F_ACS_LIBVER_HIGH_BOUND_NAME, &H5CX_def_fapl_cache.high_bound) < 0) HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve dataset minimize flag"); + done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5CX__init_package() */ /*------------------------------------------------------------------------- * Function: H5CX_term_package @@ -705,20 +710,24 @@ H5CX_term_package(void) { FUNC_ENTER_NOAPI_NOINIT_NOERR - H5CX_node_t *cnode; /* Context node */ + if (H5_PKG_INIT_VAR) { + H5CX_node_t *cnode; /* Context node */ - /* Pop the top context node from the stack */ - /* (Can't check for errors, as rest of library is shut down) */ - cnode = H5CX__pop_common(false); + /* Pop the top context node from the stack */ + /* (Can't check for errors, as rest of library is shut down) */ + cnode = H5CX__pop_common(false); - /* Free the context node */ - /* (Allocated with malloc() in H5CX_push_special() ) */ - free(cnode); + /* Free the context node */ + /* (Allocated with malloc() in H5CX_push_special() ) */ + free(cnode); #ifndef H5_HAVE_THREADSAFE - H5CX_head_g = NULL; + H5CX_head_g = NULL; #endif /* H5_HAVE_THREADSAFE */ + H5_PKG_INIT_VAR = false; + } /* end if */ + FUNC_LEAVE_NOAPI(0) } /* end H5CX_term_package() */ @@ -734,14 +743,18 @@ H5CX_term_package(void) bool H5CX_pushed(void) { - H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + bool is_pushed = false; /* Flag to indicate context is pushed */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI_NOINIT_NOERR head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ assert(head); - FUNC_LEAVE_NOAPI(*head != NULL); + /* Set return value */ + is_pushed = (*head != NULL); + + FUNC_LEAVE_NOAPI(is_pushed) } /*------------------------------------------------------------------------- @@ -1196,7 +1209,7 @@ H5CX_set_libver_bounds(H5F_t *f) H5CX_node_t **head = NULL; /* Pointer to head of API context list */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ @@ -1210,6 +1223,7 @@ H5CX_set_libver_bounds(H5F_t *f) (*head)->ctx.low_bound_valid = true; (*head)->ctx.high_bound_valid = true; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5CX_set_libver_bounds() */ @@ -1458,7 +1472,7 @@ H5CX_set_vol_wrap_ctx(void *vol_wrap_ctx) H5CX_node_t **head = NULL; /* Pointer to head of API context list */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ @@ -1470,6 +1484,7 @@ H5CX_set_vol_wrap_ctx(void *vol_wrap_ctx) /* Mark the value as valid */ (*head)->ctx.vol_wrap_ctx_valid = true; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5CX_set_vol_wrap_ctx() */ @@ -1488,7 +1503,7 @@ H5CX_set_vol_connector_prop(const H5VL_connector_prop_t *vol_connector_prop) H5CX_node_t **head = NULL; /* Pointer to head of API context list */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ @@ -1500,6 +1515,7 @@ H5CX_set_vol_connector_prop(const H5VL_connector_prop_t *vol_connector_prop) /* Mark the value as valid */ (*head)->ctx.vol_connector_prop_valid = true; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5CX_set_vol_connector_prop() */ @@ -1613,7 +1629,7 @@ H5CX_get_vol_connector_prop(H5VL_connector_prop_t *vol_connector_prop) H5CX_node_t **head = NULL; /* Pointer to head of API context list */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ assert(vol_connector_prop); @@ -1627,6 +1643,7 @@ H5CX_get_vol_connector_prop(H5VL_connector_prop_t *vol_connector_prop) else memset(vol_connector_prop, 0, sizeof(H5VL_connector_prop_t)); +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5CX_get_vol_connector_prop() */ @@ -1729,7 +1746,7 @@ H5CX_get_mpi_coll_datatypes(MPI_Datatype *btype, MPI_Datatype *ftype) H5CX_node_t **head = NULL; /* Pointer to head of API context list */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ assert(btype); @@ -1741,6 +1758,7 @@ H5CX_get_mpi_coll_datatypes(MPI_Datatype *btype, MPI_Datatype *ftype) *btype = (*head)->ctx.btype; *ftype = (*head)->ctx.ftype; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5CX_get_mpi_coll_datatypes() */ @@ -2948,11 +2966,10 @@ H5CX_set_coll_metadata_read(bool cmdr) herr_t H5CX_set_mpi_coll_datatypes(MPI_Datatype btype, MPI_Datatype ftype) { - H5CX_node_t **head = NULL; /* Pointer to head of API context list */ - - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ @@ -2962,6 +2979,7 @@ H5CX_set_mpi_coll_datatypes(MPI_Datatype btype, MPI_Datatype ftype) (*head)->ctx.btype = btype; (*head)->ctx.ftype = ftype; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5CX_set_mpi_coll_datatypes() */ @@ -2980,7 +2998,7 @@ H5CX_set_io_xfer_mode(H5FD_mpio_xfer_t io_xfer_mode) H5CX_node_t **head = NULL; /* Pointer to head of API context list */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ @@ -2992,6 +3010,7 @@ H5CX_set_io_xfer_mode(H5FD_mpio_xfer_t io_xfer_mode) /* Mark the value as valid */ (*head)->ctx.io_xfer_mode_valid = true; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5CX_set_io_xfer_mode() */ @@ -3010,7 +3029,7 @@ H5CX_set_mpio_coll_opt(H5FD_mpio_collective_opt_t mpio_coll_opt) H5CX_node_t **head = NULL; /* Pointer to head of API context list */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ @@ -3022,6 +3041,7 @@ H5CX_set_mpio_coll_opt(H5FD_mpio_collective_opt_t mpio_coll_opt) /* Mark the value as valid */ (*head)->ctx.mpio_coll_opt_valid = true; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5CX_set_mpio_coll_opt() */ @@ -3092,7 +3112,7 @@ H5CX_set_vlen_alloc_info(H5MM_allocate_t alloc_func, void *alloc_info, H5MM_free H5CX_node_t **head = NULL; /* Pointer to head of API context list */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ @@ -3107,6 +3127,7 @@ H5CX_set_vlen_alloc_info(H5MM_allocate_t alloc_func, void *alloc_info, H5MM_free /* Mark the value as valid */ (*head)->ctx.vl_alloc_info_valid = true; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5CX_set_vlen_alloc_info() */ @@ -3125,7 +3146,7 @@ H5CX_set_nlinks(size_t nlinks) H5CX_node_t **head = NULL; /* Pointer to head of API context list */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ @@ -3137,6 +3158,7 @@ H5CX_set_nlinks(size_t nlinks) /* Mark the value as valid */ (*head)->ctx.nlinks_valid = true; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5CX_set_nlinks() */ diff --git a/src/H5CXmodule.h b/src/H5CXmodule.h index 7306966a5c0..722eb765c99 100644 --- a/src/H5CXmodule.h +++ b/src/H5CXmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5CX_MODULE -#define H5_MY_PKG H5CX -#define H5_MY_PKG_ERR H5E_CONTEXT +#define H5_MY_PKG H5CX +#define H5_MY_PKG_ERR H5E_CONTEXT +#define H5_MY_PKG_INIT YES #endif /* H5CXmodule_H */ diff --git a/src/H5CXprivate.h b/src/H5CXprivate.h index a2066f235a4..71935de75a4 100644 --- a/src/H5CXprivate.h +++ b/src/H5CXprivate.h @@ -159,8 +159,6 @@ H5_DLL herr_t H5CX_set_vlen_alloc_info(H5MM_allocate_t alloc_func, void *alloc_i /* "Setter" routines for LAPL properties cached in API context */ H5_DLL herr_t H5CX_set_nlinks(size_t nlinks); -H5_DLL herr_t H5CX_init(void); - /* "Setter" routines for cached DXPL properties that must be returned to application */ H5_DLL void H5CX_set_no_selection_io_cause(uint32_t no_selection_io_cause); diff --git a/src/H5Cmodule.h b/src/H5Cmodule.h index 80a3583a3a9..03a55b7a5fe 100644 --- a/src/H5Cmodule.h +++ b/src/H5Cmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5C_MODULE -#define H5_MY_PKG H5C -#define H5_MY_PKG_ERR H5E_CACHE +#define H5_MY_PKG H5C +#define H5_MY_PKG_ERR H5E_CACHE +#define H5_MY_PKG_INIT NO #endif /* H5Cmodule_H */ diff --git a/src/H5D.c b/src/H5D.c index 80540fe6a58..492f80793cc 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -63,6 +63,9 @@ static herr_t H5D__set_extent_api_common(hid_t dset_id, const hsize_t size[], vo /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /*****************************/ /* Library Private Variables */ /*****************************/ diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 10843a6997f..8b83d1d3cda 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -43,21 +43,21 @@ /***********/ /* Headers */ /***********/ -#include "H5private.h" /* Generic Functions */ +#include "H5private.h" /* Generic Functions */ #ifdef H5_HAVE_PARALLEL -#include "H5ACprivate.h" /* Metadata cache */ +#include "H5ACprivate.h" /* Metadata cache */ #endif /* H5_HAVE_PARALLEL */ -#include "H5CXprivate.h" /* API Contexts */ -#include "H5Dpkg.h" /* Dataset functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5Fprivate.h" /* File functions */ -#include "H5FLprivate.h" /* Free Lists */ -#include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5MFprivate.h" /* File memory management */ -#include "H5PBprivate.h" /* Page Buffer */ +#include "H5CXprivate.h" /* API Contexts */ +#include "H5Dpkg.h" /* Dataset functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* File functions */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5MFprivate.h" /* File memory management */ +#include "H5PBprivate.h" /* Page Buffer */ #include "H5SLprivate.h" /* Skip Lists */ -#include "H5VMprivate.h" /* Vector and array functions */ +#include "H5VMprivate.h" /* Vector and array functions */ /****************/ /* Local Macros */ @@ -5728,13 +5728,16 @@ H5D__chunk_cmp_coll_fill_info(const void *_entry1, const void *_entry2) { const struct chunk_coll_fill_info *entry1; const struct chunk_coll_fill_info *entry2; + int ret_value = 0; FUNC_ENTER_PACKAGE_NOERR entry1 = (const struct chunk_coll_fill_info *)_entry1; entry2 = (const struct chunk_coll_fill_info *)_entry2; - FUNC_LEAVE_NOAPI(H5_addr_cmp(entry1->addr, entry2->addr)) + ret_value = H5_addr_cmp(entry1->addr, entry2->addr); + + FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__chunk_cmp_coll_fill_info() */ #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5Dint.c b/src/H5Dint.c index bede70a57d4..f956d8761fd 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -140,6 +140,9 @@ static const H5I_class_t H5I_DATASET_CLS[1] = {{ (H5I_free_t)H5D__close_cb /* Callback routine for closing objects of this class */ }}; +/* Flag indicating "top" of interface has been initialized */ +static bool H5D_top_package_initialize_s = false; + /* Prefixes of VDS and external file from the environment variables * HDF5_EXTFILE_PREFIX and HDF5_VDS_PREFIX */ static const char *H5D_prefix_ext_env = NULL; @@ -157,11 +160,38 @@ static const char *H5D_prefix_vds_env = NULL; */ herr_t H5D_init(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_init() */ + +/*-------------------------------------------------------------------------- +NAME + H5D__init_package -- Initialize interface-specific information +USAGE + herr_t H5D__init_package() + +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. +NOTES + Care must be taken when using the H5P functions, since they can cause + a deadlock in the library when the library is attempting to terminate -QAK + +--------------------------------------------------------------------------*/ +herr_t +H5D__init_package(void) { H5P_genplist_t *def_dcpl; /* Default Dataset Creation Property list */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Initialize the ID group for the dataset IDs */ if (H5I_register_type(H5I_DATASET_CLS) < 0) @@ -191,13 +221,16 @@ H5D_init(void) if (H5P_get(def_dcpl, H5O_CRT_PIPELINE_NAME, &H5D_def_dset.dcpl_cache.pline) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve pipeline filter"); + /* Mark "top" of interface as initialized, too */ + H5D_top_package_initialize_s = true; + /* Retrieve the prefixes of VDS and external file from the environment variable */ H5D_prefix_vds_env = getenv("HDF5_VDS_PREFIX"); H5D_prefix_ext_env = getenv("HDF5_EXTFILE_PREFIX"); done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D_init() */ +} /* end H5D__init_package() */ /*------------------------------------------------------------------------- * Function: H5D_top_term_package @@ -216,32 +249,38 @@ H5D_top_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - if (H5I_nmembers(H5I_DATASET) > 0) { - /* The dataset API uses the "force" flag set to true because it - * is using the "file objects" (H5FO) API functions to track open - * objects in the file. Using the H5FO code means that dataset - * IDs can have reference counts >1, when an existing dataset is - * opened more than once. However, the H5I code does not attempt - * to close objects with reference counts>1 unless the "force" flag - * is set to true. - * - * At some point (probably after the group and datatypes use the - * the H5FO code), the H5FO code might need to be switched around - * to storing pointers to the objects being tracked (H5D_t, H5G_t, - * etc) and reference count those itself instead of relying on the - * reference counting in the H5I layer. Then, the "force" flag can - * be put back to false. - * - * Setting the "force" flag to true for all the interfaces won't - * work because the "file driver" (H5FD) APIs use the H5I reference - * counting to avoid closing a file driver out from underneath an - * open file... - * - * QAK - 5/13/03 - */ - (void)H5I_clear_type(H5I_DATASET, true, false); - n++; /*H5I*/ - } + if (H5D_top_package_initialize_s) { + if (H5I_nmembers(H5I_DATASET) > 0) { + /* The dataset API uses the "force" flag set to true because it + * is using the "file objects" (H5FO) API functions to track open + * objects in the file. Using the H5FO code means that dataset + * IDs can have reference counts >1, when an existing dataset is + * opened more than once. However, the H5I code does not attempt + * to close objects with reference counts>1 unless the "force" flag + * is set to true. + * + * At some point (probably after the group and datatypes use the + * the H5FO code), the H5FO code might need to be switched around + * to storing pointers to the objects being tracked (H5D_t, H5G_t, + * etc) and reference count those itself instead of relying on the + * reference counting in the H5I layer. Then, the "force" flag can + * be put back to false. + * + * Setting the "force" flag to true for all the interfaces won't + * work because the "file driver" (H5FD) APIs use the H5I reference + * counting to avoid closing a file driver out from underneath an + * open file... + * + * QAK - 5/13/03 + */ + (void)H5I_clear_type(H5I_DATASET, true, false); + n++; /*H5I*/ + } /* end if */ + + /* Mark closed */ + if (0 == n) + H5D_top_package_initialize_s = false; + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5D_top_term_package() */ @@ -266,11 +305,18 @@ H5D_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - /* Sanity checks */ - assert(0 == H5I_nmembers(H5I_DATASET)); + if (H5_PKG_INIT_VAR) { + /* Sanity checks */ + assert(0 == H5I_nmembers(H5I_DATASET)); + assert(false == H5D_top_package_initialize_s); + + /* Destroy the dataset object id group */ + n += (H5I_dec_type_ref(H5I_DATASET) > 0); - /* Destroy the dataset object id group */ - n += (H5I_dec_type_ref(H5I_DATASET) > 0); + /* Mark closed */ + if (0 == n) + H5_PKG_INIT_VAR = false; + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5D_term_package() */ diff --git a/src/H5Dmodule.h b/src/H5Dmodule.h index ad10a94e41d..9b021105ed3 100644 --- a/src/H5Dmodule.h +++ b/src/H5Dmodule.h @@ -22,8 +22,9 @@ * reporting macros. */ #define H5D_MODULE -#define H5_MY_PKG H5D -#define H5_MY_PKG_ERR H5E_DATASET +#define H5_MY_PKG H5D +#define H5_MY_PKG_ERR H5E_DATASET +#define H5_MY_PKG_INIT YES /** \page H5D_UG HDF5 Datasets * diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c index e6e2444ffd7..c19f0ab4b68 100644 --- a/src/H5Dmpio.c +++ b/src/H5Dmpio.c @@ -2716,13 +2716,16 @@ H5D__cmp_piece_addr(const void *piece_info1, const void *piece_info2) { haddr_t addr1; haddr_t addr2; + int ret_value = 0; FUNC_ENTER_PACKAGE_NOERR addr1 = (*((const H5D_piece_info_t *const *)piece_info1))->faddr; addr2 = (*((const H5D_piece_info_t *const *)piece_info2))->faddr; - FUNC_LEAVE_NOAPI(H5_addr_cmp(addr1, addr2)) + ret_value = H5_addr_cmp(addr1, addr2); + + FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__cmp_chunk_addr() */ /*------------------------------------------------------------------------- @@ -2744,9 +2747,9 @@ H5D__cmp_filtered_collective_io_info_entry(const void *filtered_collective_io_in { const H5D_filtered_collective_chunk_info_t *entry1; const H5D_filtered_collective_chunk_info_t *entry2; - haddr_t addr1 = HADDR_UNDEF; - haddr_t addr2 = HADDR_UNDEF; - int ret_value; + haddr_t addr1 = HADDR_UNDEF; + haddr_t addr2 = HADDR_UNDEF; + int ret_value = 0; FUNC_ENTER_PACKAGE_NOERR @@ -2803,7 +2806,7 @@ H5D__cmp_chunk_redistribute_info(const void *_entry1, const void *_entry2) const H5D_chunk_redistribute_info_t *entry2; haddr_t oloc_addr1; haddr_t oloc_addr2; - int ret_value; + int ret_value = 0; FUNC_ENTER_PACKAGE_NOERR @@ -2863,9 +2866,9 @@ H5D__cmp_chunk_redistribute_info_orig_owner(const void *_entry1, const void *_en { const H5D_chunk_redistribute_info_t *entry1; const H5D_chunk_redistribute_info_t *entry2; - int owner1 = -1; - int owner2 = -1; - int ret_value; + int owner1 = -1; + int owner2 = -1; + int ret_value = 0; FUNC_ENTER_PACKAGE_NOERR diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c index 59c3a3f2e25..bdb093ed07b 100644 --- a/src/H5Dvirtual.c +++ b/src/H5Dvirtual.c @@ -1264,7 +1264,7 @@ H5D_virtual_free_parsed_name(H5O_storage_virtual_name_seg_t *name_seg) H5O_storage_virtual_name_seg_t *next_seg; herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Walk name segments, freeing them */ while (name_seg) { @@ -1274,6 +1274,7 @@ H5D_virtual_free_parsed_name(H5O_storage_virtual_name_seg_t *name_seg) name_seg = next_seg; } /* end while */ +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_virtual_free_parsed_name() */ diff --git a/src/H5E.c b/src/H5E.c index 2c2776eddd4..b1063f7b861 100644 --- a/src/H5E.c +++ b/src/H5E.c @@ -73,6 +73,9 @@ /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* Declare extern the free list to manage the H5E_stack_t struct */ H5FL_EXTERN(H5E_stack_t); diff --git a/src/H5EA.c b/src/H5EA.c index b0a3c2ab574..09258449a4c 100644 --- a/src/H5EA.c +++ b/src/H5EA.c @@ -72,6 +72,9 @@ static H5EA_t *H5EA__new(H5F_t *f, haddr_t ea_addr, bool from_open, void *ctx_ud /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* Extensible array client ID to class mapping */ /* Remember to add client ID to H5EA_cls_id_t in H5EAprivate.h when adding a new diff --git a/src/H5EAmodule.h b/src/H5EAmodule.h index 102149be954..3c8b4c0006a 100644 --- a/src/H5EAmodule.h +++ b/src/H5EAmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5EA_MODULE -#define H5_MY_PKG H5EA -#define H5_MY_PKG_ERR H5E_EARRAY +#define H5_MY_PKG H5EA +#define H5_MY_PKG_ERR H5E_EARRAY +#define H5_MY_PKG_INIT NO #endif /* H5EAmodule_H */ diff --git a/src/H5ESint.c b/src/H5ESint.c index 9542bb636a1..6a72d911440 100644 --- a/src/H5ESint.c +++ b/src/H5ESint.c @@ -103,6 +103,9 @@ static int H5ES__close_failed_cb(H5ES_event_t *ev, void *_ctx); /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /*****************************/ /* Library Private Variables */ /*****************************/ @@ -123,20 +126,22 @@ static const H5I_class_t H5I_EVENTSET_CLS[1] = {{ H5FL_DEFINE_STATIC(H5ES_t); /*------------------------------------------------------------------------- - * Function: H5ES_init + * Function: H5ES__init_package + * + * Purpose: Initializes any interface-specific data or routines. + * + * Return: Non-negative on success / Negative on failure * * Purpose: Initialize the interface from some other layer. * - * Return: Success: non-negative - * Failure: negative *------------------------------------------------------------------------- */ herr_t -H5ES_init(void) +H5ES__init_package(void) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Initialize the ID group for the event set IDs */ if (H5I_register_type(H5I_EVENTSET_CLS) < 0) @@ -144,7 +149,7 @@ H5ES_init(void) done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5ES__init_package() */ /*------------------------------------------------------------------------- * Function: H5ES_term_package @@ -164,8 +169,14 @@ H5ES_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - /* Destroy the event set ID group */ - n += (H5I_dec_type_ref(H5I_EVENTSET) > 0); + if (H5_PKG_INIT_VAR) { + /* Destroy the event set ID group */ + n += (H5I_dec_type_ref(H5I_EVENTSET) > 0); + + /* Mark closed */ + if (0 == n) + H5_PKG_INIT_VAR = false; + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5ES_term_package() */ diff --git a/src/H5ESmodule.h b/src/H5ESmodule.h index 77408e14e20..5d05e2f82ce 100644 --- a/src/H5ESmodule.h +++ b/src/H5ESmodule.h @@ -22,8 +22,9 @@ * reporting macros. */ #define H5ES_MODULE -#define H5_MY_PKG H5ES -#define H5_MY_PKG_ERR H5E_EVENTSET +#define H5_MY_PKG H5ES +#define H5_MY_PKG_ERR H5E_EVENTSET +#define H5_MY_PKG_INIT YES /** \page H5ES_UG HDF5 Event Set * @todo Under Construction diff --git a/src/H5ESprivate.h b/src/H5ESprivate.h index 3b397b7289b..1899cdc24c0 100644 --- a/src/H5ESprivate.h +++ b/src/H5ESprivate.h @@ -47,8 +47,7 @@ typedef struct H5ES_t H5ES_t; /***************************************/ /* Library-private Function Prototypes */ /***************************************/ -herr_t H5ES_insert(hid_t es_id, H5VL_connector_t *connector, void *token, const char *caller, - const char *caller_args, ...); -H5_DLL herr_t H5ES_init(void); +herr_t H5ES_insert(hid_t es_id, H5VL_connector_t *connector, void *token, const char *caller, + const char *caller_args, ...); #endif /* H5ESprivate_H */ diff --git a/src/H5Eint.c b/src/H5Eint.c index fa1be37925a..8227e7cd421 100644 --- a/src/H5Eint.c +++ b/src/H5Eint.c @@ -228,6 +228,30 @@ H5E_init(void) herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5E_init() */ + +/*-------------------------------------------------------------------------- + * Function: H5E__init_package + * + * Purpose: Initialize interface-specific information + * + * Return: SUCCEED/FAIL + * + * Programmer: Raymond Lu + * Friday, July 11, 2003 + * + *-------------------------------------------------------------------------- + */ +herr_t +H5E__init_package(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE /* Initialize the ID group for the error class IDs */ if (H5I_register_type(H5I_ERRCLS_CLS) < 0) @@ -254,7 +278,7 @@ H5E_init(void) done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5E__init_package() */ /*------------------------------------------------------------------------- * Function: H5E_term_package @@ -275,61 +299,66 @@ H5E_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - int64_t ncls, nmsg, nstk; - - /* Check if there are any open error stacks, classes or messages */ - ncls = H5I_nmembers(H5I_ERROR_CLASS); - nmsg = H5I_nmembers(H5I_ERROR_MSG); - nstk = H5I_nmembers(H5I_ERROR_STACK); - - if ((ncls + nmsg + nstk) > 0) { - /* Clear the default error stack. Note that - * the following H5I_clear_type calls do not - * force the clears and will not be able to - * clear any error message IDs that are still - * in use by the default error stack unless we - * clear that stack manually. - * - * Error message IDs will typically still be - * in use by the default error stack when the - * application does H5E_BEGIN/END_TRY cleanup - * at the very end. - */ - H5E_clear_stack(); - - /* Clear any outstanding error stacks */ - if (nstk > 0) - (void)H5I_clear_type(H5I_ERROR_STACK, false, false); - - /* Clear all the error classes */ - if (ncls > 0) { - (void)H5I_clear_type(H5I_ERROR_CLASS, false, false); - - /* Reset the HDF5 error class, if its been closed */ - if (H5I_nmembers(H5I_ERROR_CLASS) == 0) - H5E_ERR_CLS_g = H5I_INVALID_HID; - } /* end if */ + if (H5_PKG_INIT_VAR) { + int64_t ncls, nmsg, nstk; + + /* Check if there are any open error stacks, classes or messages */ + ncls = H5I_nmembers(H5I_ERROR_CLASS); + nmsg = H5I_nmembers(H5I_ERROR_MSG); + nstk = H5I_nmembers(H5I_ERROR_STACK); + + if ((ncls + nmsg + nstk) > 0) { + /* Clear the default error stack. Note that + * the following H5I_clear_type calls do not + * force the clears and will not be able to + * clear any error message IDs that are still + * in use by the default error stack unless we + * clear that stack manually. + * + * Error message IDs will typically still be + * in use by the default error stack when the + * application does H5E_BEGIN/END_TRY cleanup + * at the very end. + */ + H5E_clear_stack(); + + /* Clear any outstanding error stacks */ + if (nstk > 0) + (void)H5I_clear_type(H5I_ERROR_STACK, false, false); + + /* Clear all the error classes */ + if (ncls > 0) { + (void)H5I_clear_type(H5I_ERROR_CLASS, false, false); + + /* Reset the HDF5 error class, if its been closed */ + if (H5I_nmembers(H5I_ERROR_CLASS) == 0) + H5E_ERR_CLS_g = H5I_INVALID_HID; + } /* end if */ - /* Clear all the error messages */ - if (nmsg > 0) { - (void)H5I_clear_type(H5I_ERROR_MSG, false, false); + /* Clear all the error messages */ + if (nmsg > 0) { + (void)H5I_clear_type(H5I_ERROR_MSG, false, false); - /* Reset the HDF5 error messages, if they've been closed */ - if (H5I_nmembers(H5I_ERROR_MSG) == 0) { + /* Reset the HDF5 error messages, if they've been closed */ + if (H5I_nmembers(H5I_ERROR_MSG) == 0) { /* Include the automatically generated error code termination */ #include "H5Eterm.h" - } /* end if */ - } /* end if */ - - n++; /*H5I*/ - } /* end if */ - else { - /* Destroy the error class, message, and stack id groups */ - n += (H5I_dec_type_ref(H5I_ERROR_STACK) > 0); - n += (H5I_dec_type_ref(H5I_ERROR_CLASS) > 0); - n += (H5I_dec_type_ref(H5I_ERROR_MSG) > 0); + } /* end if */ + } /* end if */ - } /* end else */ + n++; /*H5I*/ + } /* end if */ + else { + /* Destroy the error class, message, and stack id groups */ + n += (H5I_dec_type_ref(H5I_ERROR_STACK) > 0); + n += (H5I_dec_type_ref(H5I_ERROR_CLASS) > 0); + n += (H5I_dec_type_ref(H5I_ERROR_MSG) > 0); + + /* Mark closed */ + if (0 == n) + H5_PKG_INIT_VAR = false; + } /* end else */ + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5E_term_package() */ @@ -1787,7 +1816,7 @@ H5E_dump_api_stack(void) H5E_stack_t *estack = H5E__get_my_stack(); herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) assert(estack); @@ -1805,6 +1834,7 @@ H5E_dump_api_stack(void) } /* end else */ #endif /* H5_NO_DEPRECATED_SYMBOLS */ +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5E_dump_api_stack() */ @@ -1836,7 +1866,7 @@ H5E_pause_stack(void) { H5E_stack_t *estack = H5E__get_my_stack(); - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI_NOINIT_NOERR assert(estack); @@ -1874,7 +1904,7 @@ H5E_resume_stack(void) { H5E_stack_t *estack = H5E__get_my_stack(); - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI_NOINIT_NOERR assert(estack); assert(estack->paused); diff --git a/src/H5Emodule.h b/src/H5Emodule.h index 027e94309d0..7243655cc03 100644 --- a/src/H5Emodule.h +++ b/src/H5Emodule.h @@ -22,8 +22,9 @@ * reporting macros. */ #define H5E_MODULE -#define H5_MY_PKG H5E -#define H5_MY_PKG_ERR H5E_ERROR +#define H5_MY_PKG H5E +#define H5_MY_PKG_ERR H5E_ERROR +#define H5_MY_PKG_INIT YES /** \page H5E_UG HDF5 Error Handling * diff --git a/src/H5Epublic.h b/src/H5Epublic.h index 4e41f166176..328cd4d2d84 100644 --- a/src/H5Epublic.h +++ b/src/H5Epublic.h @@ -49,14 +49,6 @@ typedef struct H5E_error2_t { /**< Optional supplied description */ } H5E_error2_t; -/* When this header is included from a private header, don't make calls to H5open() */ -#undef H5OPEN -#ifndef H5private_H -#define H5OPEN H5open(), -#else /* H5private_H */ -#define H5OPEN -#endif /* H5private_H */ - /* HDF5 error class */ /* Extern "C" block needed to compile C++ filter plugins with some compilers */ #ifdef __cplusplus diff --git a/src/H5FA.c b/src/H5FA.c index 42830178cca..b170e8ffb15 100644 --- a/src/H5FA.c +++ b/src/H5FA.c @@ -61,6 +61,9 @@ static H5FA_t *H5FA__new(H5F_t *f, haddr_t fa_addr, bool from_open, void *ctx_ud /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* Fixed array client ID to class mapping */ /* Remember to add client ID to H5FA_cls_id_t in H5FAprivate.h when adding a new diff --git a/src/H5FAmodule.h b/src/H5FAmodule.h index d76384f55cc..3fe56c012b2 100644 --- a/src/H5FAmodule.h +++ b/src/H5FAmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5FA_MODULE -#define H5_MY_PKG H5FA -#define H5_MY_PKG_ERR H5E_FARRAY +#define H5_MY_PKG H5FA +#define H5_MY_PKG_ERR H5E_FARRAY +#define H5_MY_PKG_INIT NO #endif /* H5FAmodule_H */ diff --git a/src/H5FD.c b/src/H5FD.c index 82daa37cee1..567eb2c809f 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -59,6 +59,12 @@ static herr_t H5FD__query(const H5FD_t *f, unsigned long *flags /*out*/); /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + +/* Whether to ignore file locks when disabled (env var value) */ +htri_t H5FD_ignore_disabled_file_locks_p = FAIL; + /*****************************/ /* Library Private Variables */ /*****************************/ @@ -92,10 +98,11 @@ static const H5I_class_t H5I_VFL_CLS[1] = {{ /*------------------------------------------------------------------------- * Function: H5FD_init * - * Purpose: Initialize the interface from some other layer. + * Purpose: Initialize the interface from some other package. + * + * Return: Success: non-negative + * Failure: negative * - * Return: Success: non-negative - * Failure: negative *------------------------------------------------------------------------- */ herr_t @@ -104,6 +111,28 @@ H5FD_init(void) herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD_init() */ + +/*------------------------------------------------------------------------- + * Function: H5FD__init_package + * + * Purpose: Initialize the virtual file layer. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD__init_package(void) +{ + char *lock_env_var = NULL; /* Environment variable pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE if (H5I_register_type(H5I_VFL_CLS) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize interface"); @@ -111,9 +140,64 @@ H5FD_init(void) /* Reset the file serial numbers */ H5FD_file_serial_no_g = 0; + /* Check the use disabled file locks environment variable */ + lock_env_var = getenv(HDF5_USE_FILE_LOCKING); + if (lock_env_var && !strcmp(lock_env_var, "BEST_EFFORT")) + H5FD_ignore_disabled_file_locks_p = true; /* Override: Ignore disabled locks */ + else if (lock_env_var && (!strcmp(lock_env_var, "TRUE") || !strcmp(lock_env_var, "1"))) + H5FD_ignore_disabled_file_locks_p = false; /* Override: Don't ignore disabled locks */ + else + H5FD_ignore_disabled_file_locks_p = FAIL; /* Environment variable not set, or not set correctly */ + + /* Initialize all internal VFD drivers, so their driver IDs are set up */ + if (H5FD__core_register() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register core VFD"); +#ifdef H5_HAVE_DIRECT + if (H5FD__direct_register() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register direct VFD"); +#endif + if (H5FD__family_register() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register family VFD"); +#ifdef H5_HAVE_LIBHDFS + if (H5FD__hdfs_register() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register hdfs VFD"); +#endif +#ifdef H5_HAVE_IOC_VFD + if (H5FD__ioc_register() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register ioc VFD"); +#endif + if (H5FD__log_register() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register log VFD"); +#ifdef H5_HAVE_MIRROR_VFD + if (H5FD__mirror_register() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register mirror VFD"); +#endif +#ifdef H5_HAVE_PARALLEL + if (H5FD__mpio_register() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register mpio VFD"); +#endif + if (H5FD__multi_register() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register multi VFD"); + if (H5FD__onion_register() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register onion VFD"); +#ifdef H5_HAVE_ROS3_VFD + if (H5FD__ros3_register() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register ros3 VFD"); +#endif + if (H5FD__sec2_register() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register sec2 VFD"); + if (H5FD__splitter_register() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register splitter VFD"); + if (H5FD__stdio_register() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register stdio VFD"); +#ifdef H5_HAVE_SUBFILING_VFD + if (H5FD__subfiling_register() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register subfiling VFD"); +#endif + done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD__init_package() */ /*------------------------------------------------------------------------- * Function: H5FD_term_package @@ -137,14 +221,52 @@ H5FD_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - if (H5I_nmembers(H5I_VFL) > 0) { - (void)H5I_clear_type(H5I_VFL, false, false); - n++; /*H5I*/ - } /* end if */ - else { - /* Destroy the VFL driver ID group */ - n += (H5I_dec_type_ref(H5I_VFL) > 0); - } /* end else */ + if (H5_PKG_INIT_VAR) { + if (H5I_nmembers(H5I_VFL) > 0) { + (void)H5I_clear_type(H5I_VFL, false, false); + + /* Reset all internal VFD driver IDs */ + H5FD__core_unregister(); +#ifdef H5_HAVE_DIRECT + H5FD__direct_unregister(); +#endif + H5FD__family_unregister(); +#ifdef H5_HAVE_LIBHDFS + H5FD__hdfs_unregister(); +#endif +#ifdef H5_HAVE_IOC_VFD + H5FD__ioc_unregister(); +#endif + H5FD__log_unregister(); +#ifdef H5_HAVE_MIRROR_VFD + H5FD__mirror_unregister(); +#endif +#ifdef H5_HAVE_PARALLEL + H5FD__mpio_unregister(); +#endif + H5FD__multi_unregister(); + H5FD__onion_unregister(); +#ifdef H5_HAVE_ROS3_VFD + H5FD__ros3_unregister(); +#endif + H5FD__sec2_unregister(); + H5FD__splitter_unregister(); + H5FD__stdio_unregister(); +#ifdef H5_HAVE_SUBFILING_VFD + H5FD__subfiling_unregister(); +#endif + + n++; /*H5I*/ + } /* end if */ + else { + /* Destroy the VFL driver ID group */ + n += (H5I_dec_type_ref(H5I_VFL) > 0); + + /* Mark closed */ + if (0 == n) + H5_PKG_INIT_VAR = false; + } /* end else */ + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5FD_term_package() */ @@ -154,7 +276,7 @@ H5FD_term_package(void) * * Purpose: Frees a file driver class struct and returns an indication of * success. This function is used as the free callback for the - * virtual file layer object identifiers (cf H5FD_init). + * virtual file layer object identifiers (cf H5FD__init_package). * * Return: SUCCEED/FAIL * @@ -441,7 +563,7 @@ H5FD_sb_size(H5FD_t *file) { hsize_t ret_value = 0; - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(0) /* Sanity checks */ assert(file); @@ -451,6 +573,7 @@ H5FD_sb_size(H5FD_t *file) if (file->cls->sb_size) ret_value = (file->cls->sb_size)(file); +done: FUNC_LEAVE_NOAPI(ret_value) } @@ -578,7 +701,7 @@ H5FD_fapl_get(H5FD_t *file) { void *ret_value = NULL; - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(NULL) /* Sanity checks */ assert(file); @@ -588,6 +711,7 @@ H5FD_fapl_get(H5FD_t *file) if (file->cls->fapl_get) ret_value = (file->cls->fapl_get)(file); +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_fapl_get() */ @@ -945,7 +1069,7 @@ H5FD_cmp(const H5FD_t *f1, const H5FD_t *f2) { int ret_value = -1; /* Return value */ - FUNC_ENTER_NOAPI_NOERR /* return value is arbitrary */ + FUNC_ENTER_NOAPI(-1) /* return value is arbitrary */ if ((!f1 || !f1->cls) && (!f2 || !f2->cls)) HGOTO_DONE(0); @@ -1299,7 +1423,7 @@ H5FD_get_maxaddr(const H5FD_t *file) { haddr_t ret_value = HADDR_UNDEF; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(HADDR_UNDEF) /* Sanity checks */ assert(file); @@ -1307,6 +1431,7 @@ H5FD_get_maxaddr(const H5FD_t *file) /* Set return value */ ret_value = file->maxaddr; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_get_maxaddr() */ diff --git a/src/H5FDcore.c b/src/H5FDcore.c index 86dda9763d2..b1aeef9032d 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -16,13 +16,13 @@ * access to small, temporary hdf5 files. */ -#include "H5FDdrvr_module.h" /* This source code file is part of the H5FD driver module */ +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ #include "H5FDcore.h" /* Core file driver */ +#include "H5FDpkg.h" /* File drivers */ #include "H5FLprivate.h" /* Free lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ @@ -30,10 +30,7 @@ #include "H5SLprivate.h" /* Skip lists */ /* The driver identification number, initialized at runtime */ -static hid_t H5FD_CORE_g = 0; - -/* Whether to ignore file locks when disabled (env var value) */ -static htri_t ignore_disabled_file_locks_s = FAIL; +hid_t H5FD_CORE_id_g = H5I_INVALID_HID; /* The skip list node type. Represents a region in the file. */ typedef struct H5FD_core_region_t { @@ -126,7 +123,6 @@ typedef struct H5FD_core_fapl_t { static herr_t H5FD__core_add_dirty_region(H5FD_core_t *file, haddr_t start, haddr_t end); static herr_t H5FD__core_destroy_dirty_list(H5FD_core_t *file); static herr_t H5FD__core_write_to_bstore(H5FD_core_t *file, haddr_t addr, size_t size); -static herr_t H5FD__core_term(void); static void *H5FD__core_fapl_get(H5FD_t *_file); static H5FD_t *H5FD__core_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr); static herr_t H5FD__core_close(H5FD_t *_file); @@ -153,7 +149,7 @@ static const H5FD_class_t H5FD_core_g = { "core", /* name */ MAXADDR, /* maxaddr */ H5F_CLOSE_WEAK, /* fc_degree */ - H5FD__core_term, /* terminate */ + NULL, /* terminate */ NULL, /* sb_size */ NULL, /* sb_encode */ NULL, /* sb_decode */ @@ -443,61 +439,48 @@ H5FD__core_get_default_config(void) } /* end H5FD__core_get_default_config() */ /*------------------------------------------------------------------------- - * Function: H5FD_core_init + * Function: H5FD__core_register * - * Purpose: Initialize this driver by registering the driver with the - * library. + * Purpose: Register the driver with the library. * - * Return: Success: The driver ID for the core driver - * Failure: H5I_INVALID_HID + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ -hid_t -H5FD_core_init(void) +herr_t +H5FD__core_register(void) { - char *lock_env_var = NULL; /* Environment variable pointer */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ - - FUNC_ENTER_NOAPI_NOERR - - /* Check the use disabled file locks environment variable */ - lock_env_var = getenv(HDF5_USE_FILE_LOCKING); - if (lock_env_var && !strcmp(lock_env_var, "BEST_EFFORT")) - ignore_disabled_file_locks_s = true; /* Override: Ignore disabled locks */ - else if (lock_env_var && (!strcmp(lock_env_var, "TRUE") || !strcmp(lock_env_var, "1"))) - ignore_disabled_file_locks_s = false; /* Override: Don't ignore disabled locks */ - else - ignore_disabled_file_locks_s = FAIL; /* Environment variable not set, or not set correctly */ + herr_t ret_value = SUCCEED; /* Return value */ - if (H5I_VFL != H5I_get_type(H5FD_CORE_g)) - H5FD_CORE_g = H5FD_register(&H5FD_core_g, sizeof(H5FD_class_t), false); + FUNC_ENTER_PACKAGE - /* Set return value */ - ret_value = H5FD_CORE_g; + if (H5I_VFL != H5I_get_type(H5FD_CORE_id_g)) + if ((H5FD_CORE_id_g = H5FD_register(&H5FD_core_g, sizeof(H5FD_class_t), false)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register core driver"); +done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FD_core_init() */ +} /* end H5FD__core_register() */ /*--------------------------------------------------------------------------- - * Function: H5FD__core_term + * Function: H5FD__core_unregister * - * Purpose: Shut down the VFD + * Purpose: Reset library driver info. * * Returns: SUCCEED (Can't fail) * *--------------------------------------------------------------------------- */ -static herr_t -H5FD__core_term(void) +herr_t +H5FD__core_unregister(void) { FUNC_ENTER_PACKAGE_NOERR /* Reset VFL ID */ - H5FD_CORE_g = 0; + H5FD_CORE_id_g = H5I_INVALID_HID; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5FD__core_term() */ +} /* end H5FD__core_unregister() */ /*------------------------------------------------------------------------- * Function: H5Pset_core_write_tracking @@ -798,9 +781,9 @@ H5FD__core_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr file->fi_callbacks = file_image_info.callbacks; /* Check the file locking flags in the fapl */ - if (ignore_disabled_file_locks_s != FAIL) + if (H5FD_ignore_disabled_file_locks_p != FAIL) /* The environment variable was set, so use that preferentially */ - file->ignore_disabled_file_locks = ignore_disabled_file_locks_s; + file->ignore_disabled_file_locks = H5FD_ignore_disabled_file_locks_p; else { /* Use the value in the property list */ if (H5P_get(plist, H5F_ACS_IGNORE_DISABLED_FILE_LOCKS_NAME, &file->ignore_disabled_file_locks) < 0) diff --git a/src/H5FDcore.h b/src/H5FDcore.h index 7b21ca32865..97aa138761f 100644 --- a/src/H5FDcore.h +++ b/src/H5FDcore.h @@ -16,8 +16,11 @@ #ifndef H5FDcore_H #define H5FDcore_H -/** Initializer for the core VFD */ -#define H5FD_CORE (H5FDperform_init(H5FD_core_init)) +/* Public header files */ +#include "H5FDpublic.h" /* File drivers */ + +/** ID for the core VFD */ +#define H5FD_CORE (H5OPEN H5FD_CORE_id_g) /** Identifier for the core VFD */ #define H5FD_CORE_VALUE H5_VFD_CORE @@ -28,9 +31,9 @@ extern "C" { /** @private * - * \brief Private initializer for the core VFD + * \brief ID for the core VFD */ -H5_DLL hid_t H5FD_core_init(void); +H5_DLLVAR hid_t H5FD_CORE_id_g; /** * \ingroup FAPL diff --git a/src/H5FDdevelop.h b/src/H5FDdevelop.h index 88e8113a2a0..f6915ef3c73 100644 --- a/src/H5FDdevelop.h +++ b/src/H5FDdevelop.h @@ -359,7 +359,6 @@ typedef hid_t (*H5FD_init_t)(void); extern "C" { #endif -H5_DLL hid_t H5FDperform_init(H5FD_init_t op); H5_DLL hid_t H5FDregister(const H5FD_class_t *cls); H5_DLL htri_t H5FDis_driver_registered_by_name(const char *driver_name); H5_DLL htri_t H5FDis_driver_registered_by_value(H5FD_class_value_t driver_value); diff --git a/src/H5FDdirect.c b/src/H5FDdirect.c index eea9fd11bc9..147013f7c95 100644 --- a/src/H5FDdirect.c +++ b/src/H5FDdirect.c @@ -16,13 +16,13 @@ * buffer. The main system support this feature is Linux. */ -#include "H5FDdrvr_module.h" /* This source code file is part of the H5FD driver module */ +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ #include "H5FDdirect.h" /* Direct file driver */ +#include "H5FDpkg.h" /* File drivers */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ @@ -31,10 +31,7 @@ #ifdef H5_HAVE_DIRECT /* The driver identification number, initialized at runtime */ -static hid_t H5FD_DIRECT_g = 0; - -/* Whether to ignore file locks when disabled (env var value) */ -static htri_t ignore_disabled_file_locks_s = FAIL; +hid_t H5FD_DIRECT_id_g = H5I_INVALID_HID; /* File operations */ #define OP_UNKNOWN 0 @@ -115,7 +112,6 @@ typedef struct H5FD_direct_t { (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || HADDR_UNDEF == (A) + (Z) || (HDoff_t)((A) + (Z)) < (HDoff_t)(A)) /* Prototypes */ -static herr_t H5FD__direct_term(void); static herr_t H5FD__direct_populate_config(size_t boundary, size_t block_size, size_t cbuf_size, H5FD_direct_fapl_t *fa_out); static void *H5FD__direct_fapl_get(H5FD_t *file); @@ -143,7 +139,7 @@ static const H5FD_class_t H5FD_direct_g = { "direct", /* name */ MAXADDR, /* maxaddr */ H5F_CLOSE_WEAK, /* fc_degree */ - H5FD__direct_term, /* terminate */ + NULL, /* terminate */ NULL, /* sb_size */ NULL, /* sb_encode */ NULL, /* sb_decode */ @@ -184,65 +180,48 @@ static const H5FD_class_t H5FD_direct_g = { H5FL_DEFINE_STATIC(H5FD_direct_t); /*------------------------------------------------------------------------- - * Function: H5FD_direct_init + * Function: H5FD__direct_register * - * Purpose: Initialize this driver by registering the driver with the - * library. + * Purpose: Register the driver with the library. * - * Return: Success: The driver ID for the direct driver - * Failure: H5I_INVALID_HID + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ -hid_t -H5FD_direct_init(void) +herr_t +H5FD__direct_register(void) { - char *lock_env_var = NULL; /* Environment variable pointer */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ - - FUNC_ENTER_NOAPI(H5I_INVALID_HID) - - /* Check the use disabled file locks environment variable */ - lock_env_var = getenv(HDF5_USE_FILE_LOCKING); - if (lock_env_var && !strcmp(lock_env_var, "BEST_EFFORT")) - ignore_disabled_file_locks_s = true; /* Override: Ignore disabled locks */ - else if (lock_env_var && (!strcmp(lock_env_var, "TRUE") || !strcmp(lock_env_var, "1"))) - ignore_disabled_file_locks_s = false; /* Override: Don't ignore disabled locks */ - else - ignore_disabled_file_locks_s = FAIL; /* Environment variable not set, or not set correctly */ + herr_t ret_value = SUCCEED; /* Return value */ - if (H5I_VFL != H5I_get_type(H5FD_DIRECT_g)) { - H5FD_DIRECT_g = H5FD_register(&H5FD_direct_g, sizeof(H5FD_class_t), false); - if (H5I_INVALID_HID == H5FD_DIRECT_g) - HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register direct"); - } + FUNC_ENTER_PACKAGE - /* Set return value */ - ret_value = H5FD_DIRECT_g; + if (H5I_VFL != H5I_get_type(H5FD_DIRECT_id_g)) + if ((H5FD_DIRECT_id_g = H5FD_register(&H5FD_direct_g, sizeof(H5FD_class_t), false)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register direct driver"); done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FD_direct_init() */ +} /* end H5FD__direct_register() */ /*--------------------------------------------------------------------------- - * Function: H5FD__direct_term + * Function: H5FD__direct_unregister * - * Purpose: Shut down the VFD + * Purpose: Reset library driver info. * * Returns: Non-negative on success or negative on failure * *--------------------------------------------------------------------------- */ -static herr_t -H5FD__direct_term(void) +herr_t +H5FD__direct_unregister(void) { FUNC_ENTER_PACKAGE_NOERR /* Reset VFL ID */ - H5FD_DIRECT_g = 0; + H5FD_DIRECT_id_g = H5I_INVALID_HID; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5FD__direct_term() */ +} /* end H5FD__direct_unregister() */ /*------------------------------------------------------------------------- * Function: H5Pset_fapl_direct @@ -437,7 +416,7 @@ H5FD__direct_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad int fd = (-1); H5FD_direct_t *file = NULL; const H5FD_direct_fapl_t *fa; - H5FD_direct_fapl_t default_fa; + H5FD_direct_fapl_t default_fa = {0}; #ifdef H5_HAVE_WIN32_API HFILE filehandle; struct _BY_HANDLE_FILE_INFORMATION fileinfo; @@ -511,9 +490,9 @@ H5FD__direct_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad file->fa.cbsize = fa->cbsize; /* Check the file locking flags in the fapl */ - if (ignore_disabled_file_locks_s != FAIL) + if (H5FD_ignore_disabled_file_locks_p != FAIL) /* The environment variable was set, so use that preferentially */ - file->ignore_disabled_file_locks = ignore_disabled_file_locks_s; + file->ignore_disabled_file_locks = H5FD_ignore_disabled_file_locks_p; else { /* Use the value in the property list */ if (H5P_get(plist, H5F_ACS_IGNORE_DISABLED_FILE_LOCKS_NAME, &file->ignore_disabled_file_locks) < 0) diff --git a/src/H5FDdirect.h b/src/H5FDdirect.h index ac5bf3ec99e..6ceca0e9c17 100644 --- a/src/H5FDdirect.h +++ b/src/H5FDdirect.h @@ -16,10 +16,13 @@ #ifndef H5FDdirect_H #define H5FDdirect_H +/* Public header files */ +#include "H5FDpublic.h" /* File drivers */ + #ifdef H5_HAVE_DIRECT -/** Initializer for the direct VFD */ -#define H5FD_DIRECT (H5FDperform_init(H5FD_direct_init)) +/** ID for the direct VFD */ +#define H5FD_DIRECT (H5OPEN H5FD_DIRECT_id_g) /** Identifier for the direct VFD */ #define H5FD_DIRECT_VALUE H5_VFD_DIRECT @@ -50,9 +53,9 @@ extern "C" { /** @private * - * \brief Private initializer for the direct VFD + * \brief ID for the direct VFD */ -H5_DLL hid_t H5FD_direct_init(void); +H5_DLLVAR hid_t H5FD_DIRECT_id_g; /** * \ingroup FAPL diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c index 1a70f9875fc..e186c06017e 100644 --- a/src/H5FDfamily.c +++ b/src/H5FDfamily.c @@ -28,13 +28,13 @@ * */ -#include "H5FDdrvr_module.h" /* This source code file is part of the H5FD driver module */ +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ #include "H5FDfamily.h" /* Family file driver */ +#include "H5FDpkg.h" /* File drivers */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ @@ -46,7 +46,7 @@ #define H5FD_FAM_DEF_MEM_SIZE ((hsize_t)(100 * H5_MB)) /* The driver identification number, initialized at runtime */ -static hid_t H5FD_FAMILY_g = 0; +hid_t H5FD_FAMILY_id_g = H5I_INVALID_HID; /* The description of a file belonging to this driver. */ typedef struct H5FD_family_t { @@ -80,7 +80,6 @@ static herr_t H5FD__family_get_default_config(H5FD_family_fapl_t *fa_out); static char *H5FD__family_get_default_printf_filename(const char *old_filename); /* Callback prototypes */ -static herr_t H5FD__family_term(void); static void *H5FD__family_fapl_get(H5FD_t *_file); static void *H5FD__family_fapl_copy(const void *_old_fa); static herr_t H5FD__family_fapl_free(void *_fa); @@ -112,7 +111,7 @@ static const H5FD_class_t H5FD_family_g = { "family", /* name */ HADDR_MAX, /* maxaddr */ H5F_CLOSE_WEAK, /* fc_degree */ - H5FD__family_term, /* terminate */ + NULL, /* terminate */ H5FD__family_sb_size, /* sb_size */ H5FD__family_sb_encode, /* sb_encode */ H5FD__family_sb_decode, /* sb_decode */ @@ -267,51 +266,48 @@ H5FD__family_get_default_printf_filename(const char *old_filename) } /* end H5FD__family_get_default_printf_filename() */ /*------------------------------------------------------------------------- - * Function: H5FD_family_init + * Function: H5FD__family_register * - * Purpose: Initialize this driver by registering the driver with the - * library. + * Purpose: Register the driver with the library. * - * Return: Success: The driver ID for the family driver - * Failure: H5I_INVALID_HID + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ -hid_t -H5FD_family_init(void) +herr_t +H5FD__family_register(void) { - hid_t ret_value = H5I_INVALID_HID; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR - - if (H5I_VFL != H5I_get_type(H5FD_FAMILY_g)) - H5FD_FAMILY_g = H5FD_register(&H5FD_family_g, sizeof(H5FD_class_t), false); + FUNC_ENTER_PACKAGE - /* Set return value */ - ret_value = H5FD_FAMILY_g; + if (H5I_VFL != H5I_get_type(H5FD_FAMILY_id_g)) + if ((H5FD_FAMILY_id_g = H5FD_register(&H5FD_family_g, sizeof(H5FD_class_t), false)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register family driver"); +done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5FD_family_init() */ +} /* H5FD__family_register() */ /*--------------------------------------------------------------------------- - * Function: H5FD__family_term + * Function: H5FD__family_unregister * - * Purpose: Shut down the VFD + * Purpose: Reset library driver info. * * Returns: Non-negative on success or negative on failure * *--------------------------------------------------------------------------- */ -static herr_t -H5FD__family_term(void) +herr_t +H5FD__family_unregister(void) { FUNC_ENTER_PACKAGE_NOERR /* Reset VFL ID */ - H5FD_FAMILY_g = 0; + H5FD_FAMILY_id_g = H5I_INVALID_HID; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5FD__family_term() */ +} /* end H5FD__family_unregister() */ /*------------------------------------------------------------------------- * Function: H5Pset_fapl_family diff --git a/src/H5FDfamily.h b/src/H5FDfamily.h index b2aac30c74b..3f032f8aae1 100644 --- a/src/H5FDfamily.h +++ b/src/H5FDfamily.h @@ -16,8 +16,11 @@ #ifndef H5FDfamily_H #define H5FDfamily_H -/** Initializer for the family VFD */ -#define H5FD_FAMILY (H5FDperform_init(H5FD_family_init)) +/* Public header files */ +#include "H5FDpublic.h" /* File drivers */ + +/** ID for the family VFD */ +#define H5FD_FAMILY (H5OPEN H5FD_FAMILY_id_g) /** Identifier for the family VFD */ #define H5FD_FAMILY_VALUE H5_VFD_FAMILY @@ -28,9 +31,9 @@ extern "C" { /** @private * - * \brief Private initializer for the family VFD + * \brief ID for the family VFD */ -H5_DLL hid_t H5FD_family_init(void); +H5_DLLVAR hid_t H5FD_FAMILY_id_g; /** * \ingroup FAPL diff --git a/src/H5FDhdfs.c b/src/H5FDhdfs.c index c28972a4a1c..e217948137b 100644 --- a/src/H5FDhdfs.c +++ b/src/H5FDhdfs.c @@ -15,21 +15,19 @@ * File System (HDFS). */ +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ + +#include "H5private.h" /* Generic Functions */ + #ifdef H5_HAVE_LIBHDFS -/* This source code file is part of the H5FD driver module */ -#include "H5FDdrvr_module.h" -#endif -#include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ -#include "H5FDprivate.h" /* File drivers */ #include "H5FDhdfs.h" /* hdfs file driver */ +#include "H5FDpkg.h" /* File drivers */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ -#ifdef H5_HAVE_LIBHDFS - /* HDFS routines */ #include "hdfs.h" @@ -40,7 +38,12 @@ #define HDFS_STATS 0 /* The driver identification number, initialized at runtime */ -static hid_t H5FD_HDFS_g = 0; +hid_t H5FD_HDFS_id_g = H5I_INVALID_HID; + +/* Flag to indicate whether global driver resources & settings have been + * initialized. + */ +static bool H5FD_hdfs_init_s = false; #if HDFS_STATS @@ -241,7 +244,6 @@ typedef struct H5FD_hdfs_t { #define ADDR_OVERFLOW(A) (HADDR_UNDEF == (A) || ((A) & ~(haddr_t)MAXADDR)) /* Prototypes */ -static herr_t H5FD__hdfs_term(void); static void *H5FD__hdfs_fapl_get(H5FD_t *_file); static void *H5FD__hdfs_fapl_copy(const void *_old_fa); static herr_t H5FD__hdfs_fapl_free(void *_fa); @@ -267,7 +269,7 @@ static const H5FD_class_t H5FD_hdfs_g = { "hdfs", /* name */ MAXADDR, /* maxaddr */ H5F_CLOSE_WEAK, /* fc_degree */ - H5FD__hdfs_term, /* terminate */ + NULL, /* terminate */ NULL, /* sb_size */ NULL, /* sb_encode */ NULL, /* sb_decode */ @@ -308,61 +310,44 @@ static const H5FD_class_t H5FD_hdfs_g = { H5FL_DEFINE_STATIC(H5FD_hdfs_t); /*------------------------------------------------------------------------- - * Function: H5FD_hdfs_init + * Function: H5FD__hdfs_register * - * Purpose: Initialize this driver by registering the driver with the - * library. + * Purpose: Register the driver with the library. * - * Return: Success: The driver ID for the hdfs driver. - * Failure: Negative + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ -hid_t -H5FD_hdfs_init(void) +herr_t +H5FD__hdfs_register(void) { - hid_t ret_value = H5I_INVALID_HID; -#if HDFS_STATS - unsigned int bin_i; -#endif + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5I_INVALID_HID) + FUNC_ENTER_PACKAGE #if HDFS_DEBUG fprintf(stdout, "called %s.\n", __func__); #endif - if (H5I_VFL != H5I_get_type(H5FD_HDFS_g)) - H5FD_HDFS_g = H5FD_register(&H5FD_hdfs_g, sizeof(H5FD_class_t), false); - -#if HDFS_STATS - /* pre-compute statsbin boundaries - */ - for (bin_i = 0; bin_i < HDFS_STATS_BIN_COUNT; bin_i++) { - unsigned long long value = 0; - - HDFS_STATS_POW(bin_i, &value) - hdfs_stats_boundaries[bin_i] = value; - } -#endif - - ret_value = H5FD_HDFS_g; + if (H5I_VFL != H5I_get_type(H5FD_HDFS_id_g)) + if ((H5FD_HDFS_id_g = H5FD_register(&H5FD_hdfs_g, sizeof(H5FD_class_t), false)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register hdfs driver"); done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FD_hdfs_init() */ +} /* end H5FD__hdfs_register() */ /*--------------------------------------------------------------------------- - * Function: H5FD__hdfs_term + * Function: H5FD__hdfs_unregister * - * Purpose: Shut down the VFD + * Purpose: Reset library driver info. * * Returns: SUCCEED (Can't fail) * *--------------------------------------------------------------------------- */ -static herr_t -H5FD__hdfs_term(void) +herr_t +H5FD__hdfs_unregister(void) { FUNC_ENTER_PACKAGE_NOERR @@ -371,10 +356,48 @@ H5FD__hdfs_term(void) #endif /* Reset VFL ID */ - H5FD_HDFS_g = 0; + H5FD_HDFS_id_g = H5I_INVALID_HID; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5FD__hdfs_term() */ +} /* end H5FD__hdfs_unregister() */ + +/*------------------------------------------------------------------------- + * Function: H5FD__hdfs_init + * + * Purpose: Singleton to initialize global driver settings & resources. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__hdfs_init(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + +#if HDFS_DEBUG + fprintf(stdout, "called %s.\n", __func__); +#endif + +#if HDFS_STATS + /* pre-compute statsbin boundaries + */ + for (unsigned bin_i = 0; bin_i < HDFS_STATS_BIN_COUNT; bin_i++) { + unsigned long long value = 0; + + HDFS_STATS_POW(bin_i, &value) + hdfs_stats_boundaries[bin_i] = value; + } +#endif + + /* Indicate that driver is set up */ + H5FD_hdfs_init_s = true; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__hdfs_init() */ /*-------------------------------------------------------------------------- * Function: H5FD__hdfs_handle_open @@ -401,6 +424,11 @@ H5FD__hdfs_handle_open(const char *path, const char *namenode_name, const int32_ fprintf(stdout, "called %s.\n", __func__); #endif + /* Initialize driver, if it's not yet */ + if (!H5FD_hdfs_init_s) + if (H5FD__hdfs_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "can't initialize driver"); + if (path == NULL || path[0] == '\0') HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "path cannot be null"); if (namenode_name == NULL) diff --git a/src/H5FDhdfs.h b/src/H5FDhdfs.h index 22fbbc50d17..cc667ac1d81 100644 --- a/src/H5FDhdfs.h +++ b/src/H5FDhdfs.h @@ -18,10 +18,13 @@ #ifndef H5FDhdfs_H #define H5FDhdfs_H +/* Public header files */ +#include "H5FDpublic.h" /* File drivers */ + #ifdef H5_HAVE_LIBHDFS -/** Initializer for the hdfs VFD */ -#define H5FD_HDFS (H5FDperform_init(H5FD_hdfs_init)) +/** ID for the HDFS VFD */ +#define H5FD_HDFS (H5OPEN H5FD_HDFS_id_g) /** Identifier for the hdfs VFD */ #define H5FD_HDFS_VALUE H5_VFD_HDFS @@ -37,9 +40,6 @@ #endif /* H5_HAVE_LIBHDFS */ #ifdef H5_HAVE_LIBHDFS -#ifdef __cplusplus -extern "C" { -#endif /** * The version number of the H5FD_hdfs_fapl_t configuration @@ -93,11 +93,15 @@ typedef struct H5FD_hdfs_fapl_t { int32_t stream_buffer_size; } H5FD_hdfs_fapl_t; +#ifdef __cplusplus +extern "C" { +#endif + /** @private * - * \brief Private initializer for the hdfs VFD + * \brief ID for the HDFS VFD */ -H5_DLL hid_t H5FD_hdfs_init(void); +H5_DLLVAR hid_t H5FD_HDFS_id_g; /** * \ingroup FAPL diff --git a/src/H5FDint.c b/src/H5FDint.c index 12049ca87cc..4456ae485fa 100644 --- a/src/H5FDint.c +++ b/src/H5FDint.c @@ -3044,7 +3044,7 @@ H5FD_check_plugin_load(const H5FD_class_t *cls, const H5PL_key_t *key, bool *suc { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Sanity checks */ assert(cls); @@ -3066,6 +3066,7 @@ H5FD_check_plugin_load(const H5FD_class_t *cls, const H5PL_key_t *key, bool *suc *success = true; } +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_check_plugin_load() */ diff --git a/src/H5FDlog.c b/src/H5FDlog.c index 726a8f6e105..13e64ef939c 100644 --- a/src/H5FDlog.c +++ b/src/H5FDlog.c @@ -20,23 +20,20 @@ * With custom modifications... */ -#include "H5FDdrvr_module.h" /* This source code file is part of the H5FD driver module */ +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ #include "H5FDlog.h" /* Logging file driver */ +#include "H5FDpkg.h" /* File drivers */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ /* The driver identification number, initialized at runtime */ -static hid_t H5FD_LOG_g = 0; - -/* Whether to ignore file locks when disabled (env var value) */ -static htri_t ignore_disabled_file_locks_s = FAIL; +hid_t H5FD_LOG_id_g = H5I_INVALID_HID; /* Driver-specific file access properties */ typedef struct H5FD_log_fapl_t { @@ -154,7 +151,6 @@ typedef struct H5FD_log_t { (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || HADDR_UNDEF == (A) + (Z) || (HDoff_t)((A) + (Z)) < (HDoff_t)(A)) /* Prototypes */ -static herr_t H5FD__log_term(void); static void *H5FD__log_fapl_get(H5FD_t *file); static void *H5FD__log_fapl_copy(const void *_old_fa); static herr_t H5FD__log_fapl_free(void *_fa); @@ -183,7 +179,7 @@ static const H5FD_class_t H5FD_log_g = { "log", /* name */ MAXADDR, /* maxaddr */ H5F_CLOSE_WEAK, /* fc_degree */ - H5FD__log_term, /* terminate */ + NULL, /* terminate */ NULL, /* sb_size */ NULL, /* sb_encode */ NULL, /* sb_decode */ @@ -227,61 +223,48 @@ static const H5FD_log_fapl_t H5FD_log_default_config_g = {NULL, H5FD_LOG_LOC_IO H5FL_DEFINE_STATIC(H5FD_log_t); /*------------------------------------------------------------------------- - * Function: H5FD_log_init + * Function: H5FD__log_register * - * Purpose: Initialize this driver by registering the driver with the - * library. + * Purpose: Register the driver with the library. * - * Return: Success: The driver ID for the log driver - * Failure: H5I_INVALID_HID + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ -hid_t -H5FD_log_init(void) +herr_t +H5FD__log_register(void) { - char *lock_env_var = NULL; /* Environment variable pointer */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ - - FUNC_ENTER_NOAPI_NOERR - - /* Check the use disabled file locks environment variable */ - lock_env_var = getenv(HDF5_USE_FILE_LOCKING); - if (lock_env_var && !strcmp(lock_env_var, "BEST_EFFORT")) - ignore_disabled_file_locks_s = true; /* Override: Ignore disabled locks */ - else if (lock_env_var && (!strcmp(lock_env_var, "TRUE") || !strcmp(lock_env_var, "1"))) - ignore_disabled_file_locks_s = false; /* Override: Don't ignore disabled locks */ - else - ignore_disabled_file_locks_s = FAIL; /* Environment variable not set, or not set correctly */ + herr_t ret_value = SUCCEED; /* Return value */ - if (H5I_VFL != H5I_get_type(H5FD_LOG_g)) - H5FD_LOG_g = H5FD_register(&H5FD_log_g, sizeof(H5FD_class_t), false); + FUNC_ENTER_PACKAGE - /* Set return value */ - ret_value = H5FD_LOG_g; + if (H5I_VFL != H5I_get_type(H5FD_LOG_id_g)) + if ((H5FD_LOG_id_g = H5FD_register(&H5FD_log_g, sizeof(H5FD_class_t), false)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register log driver"); +done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FD_log_init() */ +} /* end H5FD__log_register() */ /*--------------------------------------------------------------------------- - * Function: H5FD__log_term + * Function: H5FD__log_unregister * - * Purpose: Shut down the VFD + * Purpose: Reset library driver info. * * Returns: SUCCEED (Can't fail) * *--------------------------------------------------------------------------- */ -static herr_t -H5FD__log_term(void) +herr_t +H5FD__log_unregister(void) { FUNC_ENTER_PACKAGE_NOERR /* Reset VFL ID */ - H5FD_LOG_g = 0; + H5FD_LOG_id_g = H5I_INVALID_HID; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5FD__log_term() */ +} /* end H5FD__log_unregister() */ /*------------------------------------------------------------------------- * Function: H5Pset_fapl_log @@ -599,9 +582,9 @@ H5FD__log_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) } /* Check the file locking flags in the fapl */ - if (ignore_disabled_file_locks_s != FAIL) + if (H5FD_ignore_disabled_file_locks_p != FAIL) /* The environment variable was set, so use that preferentially */ - file->ignore_disabled_file_locks = ignore_disabled_file_locks_s; + file->ignore_disabled_file_locks = H5FD_ignore_disabled_file_locks_p; else { /* Use the value in the property list */ if (H5P_get(plist, H5F_ACS_IGNORE_DISABLED_FILE_LOCKS_NAME, &file->ignore_disabled_file_locks) < 0) diff --git a/src/H5FDlog.h b/src/H5FDlog.h index e957157a5a5..871845cf189 100644 --- a/src/H5FDlog.h +++ b/src/H5FDlog.h @@ -17,7 +17,11 @@ #define H5FDlog_H /** Initializer for the log VFD */ -#define H5FD_LOG (H5FDperform_init(H5FD_log_init)) +/* Public header files */ +#include "H5FDpublic.h" /* File drivers */ + +/** ID for the log VFD */ +#define H5FD_LOG (H5OPEN H5FD_LOG_id_g) /** Identifier for the log VFD */ #define H5FD_LOG_VALUE H5_VFD_LOG @@ -67,9 +71,9 @@ extern "C" { /** @private * - * \brief Private initializer for the log VFD + * \brief ID for the log VFD */ -H5_DLL hid_t H5FD_log_init(void); +H5_DLLVAR hid_t H5FD_LOG_id_g; /** * \ingroup FAPL diff --git a/src/H5FDmirror.c b/src/H5FDmirror.c index c0fc9d07817..5e4ccd7cc9b 100644 --- a/src/H5FDmirror.c +++ b/src/H5FDmirror.c @@ -15,24 +15,24 @@ * a remote host. */ +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ + #include "H5private.h" /* Generic Functions */ #ifdef H5_HAVE_MIRROR_VFD -#include "H5FDdrvr_module.h" /* This source code file is part of the H5FD driver module */ - #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ #include "H5FDmirror.h" /* "Mirror" definitions */ #include "H5FDmirror_priv.h" /* Private header for the mirror VFD */ +#include "H5FDpkg.h" /* File drivers */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ /* The driver identification number, initialized at runtime */ -static hid_t H5FD_MIRROR_g = 0; +hid_t H5FD_MIRROR_id_g = H5I_INVALID_HID; /* Virtual file structure for a Mirror Driver */ typedef struct H5FD_mirror_t { @@ -139,7 +139,6 @@ typedef struct H5FD_mirror_t { #endif /* MIRROR_DEBUG_OP_CALLS */ /* Prototypes */ -static herr_t H5FD__mirror_term(void); static void *H5FD__mirror_fapl_get(H5FD_t *_file); static void *H5FD__mirror_fapl_copy(const void *_old_fa); static herr_t H5FD__mirror_fapl_free(void *_fa); @@ -165,7 +164,7 @@ static const H5FD_class_t H5FD_mirror_g = { "mirror", /* name */ MAXADDR, /* maxaddr */ H5F_CLOSE_WEAK, /* fc_degree */ - H5FD__mirror_term, /* terminate */ + NULL, /* terminate */ NULL, /* sb_size */ NULL, /* sb_encode */ NULL, /* sb_decode */ @@ -212,55 +211,52 @@ H5FL_DEFINE_STATIC(H5FD_mirror_t); H5FL_DEFINE_STATIC(H5FD_mirror_xmit_open_t); /* ------------------------------------------------------------------------- - * Function: H5FD_mirror_init + * Function: H5FD__mirror_register * - * Purpose: Initialize this driver by registering the driver with the - * library. + * Purpose: Register the driver with the library. + * + * Return: SUCCEED/FAIL * - * Return: Success: The driver ID for the mirror driver. - * Failure: Negative * ------------------------------------------------------------------------- */ -hid_t -H5FD_mirror_init(void) +herr_t +H5FD__mirror_register(void) { - hid_t ret_value = H5I_INVALID_HID; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5I_INVALID_HID) + FUNC_ENTER_PACKAGE LOG_OP_CALL(__func__); - if (H5I_VFL != H5I_get_type(H5FD_MIRROR_g)) { - H5FD_MIRROR_g = H5FD_register(&H5FD_mirror_g, sizeof(H5FD_class_t), false); - if (H5I_INVALID_HID == H5FD_MIRROR_g) - HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register mirror"); - } - ret_value = H5FD_MIRROR_g; + if (H5I_VFL != H5I_get_type(H5FD_MIRROR_id_g)) + if ((H5FD_MIRROR_id_g = H5FD_register(&H5FD_mirror_g, sizeof(H5FD_class_t), false)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register mirror driver"); done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FD_mirror_init() */ +} /* end H5FD__mirror_register() */ /* --------------------------------------------------------------------------- - * Function: H5FD__mirror_term + * Function: H5FD__mirror_unregister * - * Purpose: Shut down the VFD + * Purpose: Reset library driver info. * * Returns: SUCCEED (Can't fail) + * * --------------------------------------------------------------------------- */ -static herr_t -H5FD__mirror_term(void) +herr_t +H5FD__mirror_unregister(void) { FUNC_ENTER_PACKAGE_NOERR - /* Reset VFL ID */ - H5FD_MIRROR_g = 0; - LOG_OP_CALL(__func__); + /* Reset VFL ID */ + H5FD_MIRROR_id_g = H5I_INVALID_HID; + FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5FD__mirror_term() */ +} /* end H5FD__mirror_unregister() */ /* --------------------------------------------------------------------------- * Function: H5FD__mirror_xmit_decode_uint16 diff --git a/src/H5FDmirror.h b/src/H5FDmirror.h index d64d6d778b7..3758dc083fa 100644 --- a/src/H5FDmirror.h +++ b/src/H5FDmirror.h @@ -17,10 +17,13 @@ #ifndef H5FDmirror_H #define H5FDmirror_H +/* Public header files */ +#include "H5FDpublic.h" /* File drivers */ + #ifdef H5_HAVE_MIRROR_VFD -/** Initializer for the mirror VFD */ -#define H5FD_MIRROR (H5FDperform_init(H5FD_mirror_init)) +/** ID for the mirror VFD */ +#define H5FD_MIRROR (H5OPEN H5FD_MIRROR_id_g) /** Identifier for the mirror VFD */ #define H5FD_MIRROR_VALUE H5_VFD_MIRROR @@ -75,9 +78,9 @@ extern "C" { /** @private * - * \brief Private initializer for the mirror VFD + * \brief ID for the mirror VFD */ -H5_DLL hid_t H5FD_mirror_init(void); +H5_DLLVAR hid_t H5FD_MIRROR_id_g; /** * \ingroup FAPL diff --git a/src/H5FDmodule.h b/src/H5FDmodule.h index ed399a4cb12..d692b8fef0d 100644 --- a/src/H5FDmodule.h +++ b/src/H5FDmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5FD_MODULE -#define H5_MY_PKG H5FD -#define H5_MY_PKG_ERR H5E_VFL +#define H5_MY_PKG H5FD +#define H5_MY_PKG_ERR H5E_VFL +#define H5_MY_PKG_INIT YES #endif /* H5FDmodule_H */ diff --git a/src/H5FDmpi.c b/src/H5FDmpi.c index 761cdf026ae..e5cbc2458c3 100644 --- a/src/H5FDmpi.c +++ b/src/H5FDmpi.c @@ -14,13 +14,16 @@ * Purpose: Common routines for all MPI-based VFL drivers. */ -#include "H5private.h" /* Generic Functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5FDprivate.h" /* File drivers */ -#include "H5FDmpi.h" /* Common MPI file driver */ +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ + +#include "H5private.h" /* Generic Functions */ #ifdef H5_HAVE_PARALLEL +#include "H5Eprivate.h" /* Error handling */ +#include "H5FDmpi.h" /* Common MPI file driver */ +#include "H5FDpkg.h" /* File drivers */ + /*------------------------------------------------------------------------- * Function: H5FD_mpi_get_rank * @@ -36,10 +39,10 @@ int H5FD_mpi_get_rank(H5FD_t *file) { const H5FD_class_t *cls; - uint64_t flags = H5FD_CTL_FAIL_IF_UNKNOWN_FLAG | H5FD_CTL_ROUTE_TO_TERMINAL_VFD_FLAG; - int rank = -1; - void *rank_ptr = (void *)(&rank); - int ret_value; + uint64_t flags = H5FD_CTL_FAIL_IF_UNKNOWN_FLAG | H5FD_CTL_ROUTE_TO_TERMINAL_VFD_FLAG; + int rank = -1; + void *rank_ptr = (void *)(&rank); + int ret_value = -1; FUNC_ENTER_NOAPI(FAIL) @@ -75,10 +78,10 @@ int H5FD_mpi_get_size(H5FD_t *file) { const H5FD_class_t *cls; - uint64_t flags = H5FD_CTL_FAIL_IF_UNKNOWN_FLAG | H5FD_CTL_ROUTE_TO_TERMINAL_VFD_FLAG; - int size = 0; - void *size_ptr = (void *)(&size); - int ret_value; + uint64_t flags = H5FD_CTL_FAIL_IF_UNKNOWN_FLAG | H5FD_CTL_ROUTE_TO_TERMINAL_VFD_FLAG; + int size = 0; + void *size_ptr = (void *)(&size); + int ret_value = 0; FUNC_ENTER_NOAPI(FAIL) @@ -114,10 +117,10 @@ MPI_Comm H5FD_mpi_get_comm(H5FD_t *file) { const H5FD_class_t *cls; - uint64_t flags = H5FD_CTL_FAIL_IF_UNKNOWN_FLAG | H5FD_CTL_ROUTE_TO_TERMINAL_VFD_FLAG; - MPI_Comm comm = MPI_COMM_NULL; - void *comm_ptr = (void *)(&comm); - MPI_Comm ret_value; + uint64_t flags = H5FD_CTL_FAIL_IF_UNKNOWN_FLAG | H5FD_CTL_ROUTE_TO_TERMINAL_VFD_FLAG; + MPI_Comm comm = MPI_COMM_NULL; + void *comm_ptr = (void *)(&comm); + MPI_Comm ret_value = MPI_COMM_NULL; FUNC_ENTER_NOAPI(MPI_COMM_NULL) @@ -153,10 +156,10 @@ MPI_Info H5FD_mpi_get_info(H5FD_t *file) { const H5FD_class_t *cls; - uint64_t flags = H5FD_CTL_FAIL_IF_UNKNOWN_FLAG | H5FD_CTL_ROUTE_TO_TERMINAL_VFD_FLAG; - MPI_Info info = MPI_INFO_NULL; - void *info_ptr = (void *)(&info); - MPI_Info ret_value; + uint64_t flags = H5FD_CTL_FAIL_IF_UNKNOWN_FLAG | H5FD_CTL_ROUTE_TO_TERMINAL_VFD_FLAG; + MPI_Info info = MPI_INFO_NULL; + void *info_ptr = (void *)(&info); + MPI_Info ret_value = MPI_INFO_NULL; FUNC_ENTER_NOAPI(MPI_INFO_NULL) diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 2d950f236cf..2d811ac68cc 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -14,34 +14,40 @@ * Purpose: This is the MPI I/O driver. */ -#include "H5FDdrvr_module.h" /* This source code file is part of the H5FD driver module */ +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ + +#include "H5private.h" /* Generic Functions */ + +#ifdef H5_HAVE_PARALLEL -#include "H5private.h" /* Generic Functions */ #include "H5CXprivate.h" /* API Contexts */ #include "H5Dprivate.h" /* Dataset functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ #include "H5FDmpi.h" /* MPI-based file drivers */ +#include "H5FDpkg.h" /* File drivers */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ -#ifdef H5_HAVE_PARALLEL - /* * The driver identification number, initialized at runtime if H5_HAVE_PARALLEL * is defined. This allows applications to still have the H5FD_MPIO * "constants" in their source code. */ -static hid_t H5FD_MPIO_g = 0; +hid_t H5FD_MPIO_id_g = H5I_INVALID_HID; + +/* Flag to indicate whether global driver resources & settings have been + * initialized. + */ +static bool H5FD_mpio_init_s = false; /* Whether to allow collective I/O operations */ /* (Can be changed by setting "HDF5_MPI_OPT_TYPES" environment variable to '0' or '1') */ bool H5FD_mpi_opt_types_g = true; /* Whether the driver initialized MPI on its own */ -static bool H5FD_mpi_self_initialized = false; +static bool H5FD_mpi_self_initialized_s = false; /* * The view is set to this value @@ -256,79 +262,110 @@ H5FD__mem_t_to_str(H5FD_mem_t mem_type) #endif /* H5FDmpio_DEBUG */ /*------------------------------------------------------------------------- - * Function: H5FD_mpio_init + * Function: H5FD__mpio_register * - * Purpose: Initialize this driver by registering the driver with the - * library. + * Purpose: Register the driver with the library. * - * Return: Success: The driver ID for the mpio driver - * Failure: H5I_INVALID_HID + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ -hid_t -H5FD_mpio_init(void) +herr_t +H5FD__mpio_register(void) { - static int H5FD_mpio_Debug_inited = 0; - char *env = NULL; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5I_INVALID_HID) + FUNC_ENTER_PACKAGE /* Register the MPI-IO VFD, if it isn't already */ - if (H5I_VFL != H5I_get_type(H5FD_MPIO_g)) { - H5FD_MPIO_g = H5FD_register((const H5FD_class_t *)&H5FD_mpio_g, sizeof(H5FD_class_t), false); - - /* Check if MPI driver has been loaded dynamically */ - env = getenv(HDF5_DRIVER); - if (env && !strcmp(env, "mpio")) { - int mpi_initialized = 0; - - /* Initialize MPI if not already initialized */ - if (MPI_SUCCESS != MPI_Initialized(&mpi_initialized)) - HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, H5I_INVALID_HID, "can't check if MPI is initialized"); - if (!mpi_initialized) { - if (MPI_SUCCESS != MPI_Init(NULL, NULL)) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, "can't initialize MPI"); - H5FD_mpi_self_initialized = true; - } + if (H5I_VFL != H5I_get_type(H5FD_MPIO_id_g)) + if ((H5FD_MPIO_id_g = H5FD_register(&H5FD_mpio_g, sizeof(H5FD_class_t), false)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register mpio driver"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__mpio_register() */ + +/*--------------------------------------------------------------------------- + * Function: H5FD__mpio_unregister + * + * Purpose: Reset library driver info. + * + * Returns: SUCCEED (Can't fail) + * + *--------------------------------------------------------------------------- + */ +herr_t +H5FD__mpio_unregister(void) +{ + FUNC_ENTER_PACKAGE_NOERR + + /* Reset VFL ID */ + H5FD_MPIO_id_g = H5I_INVALID_HID; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5FD__mpio_unregister() */ + +/*------------------------------------------------------------------------- + * Function: H5FD__mpio_init + * + * Purpose: Singleton to initialize global driver settings & resources. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__mpio_init(void) +{ + char *env = NULL; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Check if MPI driver has been loaded dynamically */ + env = getenv(HDF5_DRIVER); + if (env && !strcmp(env, "mpio")) { + int mpi_initialized = 0; + + /* Initialize MPI if not already initialized */ + if (MPI_SUCCESS != MPI_Initialized(&mpi_initialized)) + HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, FAIL, "can't check if MPI is initialized"); + if (!mpi_initialized) { + if (MPI_SUCCESS != MPI_Init(NULL, NULL)) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize MPI"); + H5FD_mpi_self_initialized_s = true; } } - if (!H5FD_mpio_Debug_inited) { - const char *s; /* String for environment variables */ - - /* Allow MPI buf-and-file-type optimizations? */ - s = getenv("HDF5_MPI_OPT_TYPES"); - if (s && isdigit(*s)) - H5FD_mpi_opt_types_g = (0 == strtol(s, NULL, 0)) ? false : true; + /* Allow MPI buf-and-file-type optimizations? */ + env = getenv("HDF5_MPI_OPT_TYPES"); + if (env && isdigit(*env)) + H5FD_mpi_opt_types_g = (0 == strtol(env, NULL, 0)) ? false : true; #ifdef H5FDmpio_DEBUG - /* Clear the flag buffer */ - memset(H5FD_mpio_debug_flags_s, 0, sizeof(H5FD_mpio_debug_flags_s)); + /* Clear the flag buffer */ + memset(H5FD_mpio_debug_flags_s, 0, sizeof(H5FD_mpio_debug_flags_s)); - /* Retrieve MPI-IO debugging environment variable */ - s = getenv("H5FD_mpio_Debug"); - if (s) - H5FD__mpio_parse_debug_str(s); + /* Retrieve MPI-IO debugging environment variable */ + env = getenv("H5FD_mpio_Debug"); + if (env) + H5FD__mpio_parse_debug_str(env); #endif /* H5FDmpio_DEBUG */ - H5FD_mpio_Debug_inited++; - } /* end if */ - - /* Set return value */ - ret_value = H5FD_MPIO_g; + /* Indicate that driver is set up */ + H5FD_mpio_init_s = true; done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FD_mpio_init() */ +} /* end H5FD__mpio_init() */ /*--------------------------------------------------------------------------- * Function: H5FD__mpio_term * * Purpose: Shut down the VFD * - * Returns: Non-negative on success or negative on failure + * Returns: SUCCEED (Can't fail) * *--------------------------------------------------------------------------- */ @@ -338,19 +375,16 @@ H5FD__mpio_term(void) FUNC_ENTER_PACKAGE_NOERR /* Terminate MPI if the driver initialized it */ - if (H5FD_mpi_self_initialized) { + if (H5FD_mpi_self_initialized_s) { int mpi_finalized = 0; MPI_Finalized(&mpi_finalized); if (!mpi_finalized) MPI_Finalize(); - H5FD_mpi_self_initialized = false; + H5FD_mpi_self_initialized_s = false; } - /* Reset VFL ID */ - H5FD_MPIO_g = 0; - FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5FD__mpio_term() */ @@ -398,6 +432,11 @@ H5Pset_fapl_mpio(hid_t fapl_id, MPI_Comm comm, MPI_Info info) if (MPI_COMM_NULL == comm) HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "MPI_COMM_NULL is not a valid communicator"); + /* Initialize driver, if it's not yet */ + if (!H5FD_mpio_init_s) + if (H5FD__mpio_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize driver"); + /* Set the MPI communicator and info object */ if (H5P_set(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI communicator"); @@ -451,6 +490,11 @@ H5Pget_fapl_mpio(hid_t fapl_id, MPI_Comm *comm /*out*/, MPI_Info *info /*out*/) if (H5FD_MPIO != H5P_peek_driver(plist)) HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "VFL driver is not MPI-I/O"); + /* Initialize driver, if it's not yet */ + if (!H5FD_mpio_init_s) + if (H5FD__mpio_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize driver"); + /* Get the MPI communicator and info object */ if (comm) if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, comm) < 0) @@ -510,6 +554,11 @@ H5Pset_dxpl_mpio(hid_t dxpl_id, H5FD_mpio_xfer_t xfer_mode) if (H5FD_MPIO_INDEPENDENT != xfer_mode && H5FD_MPIO_COLLECTIVE != xfer_mode) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "incorrect xfer_mode"); + /* Initialize driver, if it's not yet */ + if (!H5FD_mpio_init_s) + if (H5FD__mpio_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize driver"); + /* Set the transfer mode */ if (H5P_set(plist, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value"); @@ -543,6 +592,11 @@ H5Pget_dxpl_mpio(hid_t dxpl_id, H5FD_mpio_xfer_t *xfer_mode /*out*/) if (NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER))) HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl"); + /* Initialize driver, if it's not yet */ + if (!H5FD_mpio_init_s) + if (H5FD__mpio_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize driver"); + /* Get the transfer mode */ if (xfer_mode) if (H5P_get(plist, H5D_XFER_IO_XFER_MODE_NAME, xfer_mode) < 0) @@ -582,6 +636,11 @@ H5Pset_dxpl_mpio_collective_opt(hid_t dxpl_id, H5FD_mpio_collective_opt_t opt_mo if (NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER))) HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl"); + /* Initialize driver, if it's not yet */ + if (!H5FD_mpio_init_s) + if (H5FD__mpio_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize driver"); + /* Set the transfer mode */ if (H5P_set(plist, H5D_XFER_MPIO_COLLECTIVE_OPT_NAME, &opt_mode) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value"); @@ -620,6 +679,11 @@ H5Pset_dxpl_mpio_chunk_opt(hid_t dxpl_id, H5FD_mpio_chunk_opt_t opt_mode) if (NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER))) HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl"); + /* Initialize driver, if it's not yet */ + if (!H5FD_mpio_init_s) + if (H5FD__mpio_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize driver"); + /* Set the transfer mode */ if (H5P_set(plist, H5D_XFER_MPIO_CHUNK_OPT_HARD_NAME, &opt_mode) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value"); @@ -656,6 +720,11 @@ H5Pset_dxpl_mpio_chunk_opt_num(hid_t dxpl_id, unsigned num_chunk_per_proc) if (NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER))) HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl"); + /* Initialize driver, if it's not yet */ + if (!H5FD_mpio_init_s) + if (H5FD__mpio_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize driver"); + /* Set the transfer mode */ if (H5P_set(plist, H5D_XFER_MPIO_CHUNK_OPT_NUM_NAME, &num_chunk_per_proc) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value"); @@ -695,6 +764,11 @@ H5Pset_dxpl_mpio_chunk_opt_ratio(hid_t dxpl_id, unsigned percent_num_proc_per_ch if (NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER))) HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dxpl"); + /* Initialize driver, if it's not yet */ + if (!H5FD_mpio_init_s) + if (H5FD__mpio_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize driver"); + /* Set the transfer mode */ if (H5P_set(plist, H5D_XFER_MPIO_CHUNK_OPT_RATIO_NAME, &percent_num_proc_per_chunk) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value"); @@ -824,11 +898,16 @@ H5FD__mpio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t H5_ATTR FUNC_ENTER_PACKAGE + /* Initialize driver, if it's not yet */ + if (!H5FD_mpio_init_s) + if (H5FD__mpio_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "can't initialize driver"); + /* Get a pointer to the fapl */ if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list"); - if (H5FD_mpi_self_initialized) { + if (H5FD_mpi_self_initialized_s) { comm = MPI_COMM_WORLD; } else { @@ -3738,11 +3817,16 @@ H5FD__mpio_delete(const char *filename, hid_t fapl_id) assert(filename); + /* Initialize driver, if it's not yet */ + if (!H5FD_mpio_init_s) + if (H5FD__mpio_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize driver"); + if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); assert(H5FD_MPIO == H5P_peek_driver(plist)); - if (H5FD_mpi_self_initialized) { + if (H5FD_mpi_self_initialized_s) { comm = MPI_COMM_WORLD; } else { diff --git a/src/H5FDmpio.h b/src/H5FDmpio.h index 453b58221a3..1ae96ab517c 100644 --- a/src/H5FDmpio.h +++ b/src/H5FDmpio.h @@ -16,10 +16,13 @@ #ifndef H5FDmpio_H #define H5FDmpio_H +/* Public header files */ +#include "H5FDpublic.h" /* File drivers */ + #ifdef H5_HAVE_PARALLEL -/** Initializer for the mpio VFD */ -#define H5FD_MPIO (H5FDperform_init(H5FD_mpio_init)) +/** ID for the mpio VFD */ +#define H5FD_MPIO (H5OPEN H5FD_MPIO_id_g) #else @@ -35,19 +38,19 @@ #define H5FDmpio_DEBUG #endif -/* Global var whose value comes from environment variable */ -/* (Defined in H5FDmpio.c) */ -H5_DLLVAR hbool_t H5FD_mpi_opt_types_g; - #ifdef __cplusplus extern "C" { #endif +/* Global var whose value comes from environment variable */ +/* (Defined in H5FDmpio.c) */ +H5_DLLVAR hbool_t H5FD_mpi_opt_types_g; + /** @private * - * \brief Private initializer for the mpio VFD + * \brief ID for the mpio VFD */ -H5_DLL hid_t H5FD_mpio_init(void); +H5_DLLVAR hid_t H5FD_MPIO_id_g; /** * \ingroup FAPL diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c index 82c36a2df78..72d7fd4c455 100644 --- a/src/H5FDmulti.c +++ b/src/H5FDmulti.c @@ -72,9 +72,6 @@ #define H5FD_MULT_MAX_FILE_NAME_LEN 1024 -/* The driver identification number, initialized at runtime */ -static hid_t H5FD_MULTI_g = 0; - /* Driver-specific file access properties */ typedef struct H5FD_multi_fapl_t { H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; /*memory usage map */ @@ -119,7 +116,6 @@ static int compute_next(H5FD_multi_t *file); static int open_members(H5FD_multi_t *file); /* Callback prototypes */ -static herr_t H5FD_multi_term(void); static hsize_t H5FD_multi_sb_size(H5FD_t *file); static herr_t H5FD_multi_sb_encode(H5FD_t *file, char *name /*out*/, unsigned char *buf /*out*/); static herr_t H5FD_multi_sb_decode(H5FD_t *file, const char *name, const unsigned char *buf); @@ -150,13 +146,13 @@ static herr_t H5FD_multi_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, c void **output); /* The class struct */ -static const H5FD_class_t H5FD_multi_g = { +const H5FD_class_t H5FD_multi_g = { H5FD_CLASS_VERSION, /* struct version */ H5_VFD_MULTI, /* value */ "multi", /* name */ HADDR_MAX, /* maxaddr */ H5F_CLOSE_WEAK, /* fc_degree */ - H5FD_multi_term, /* terminate */ + NULL, /* terminate */ H5FD_multi_sb_size, /* sb_size */ H5FD_multi_sb_encode, /* sb_encode */ H5FD_multi_sb_decode, /* sb_decode */ @@ -193,47 +189,6 @@ static const H5FD_class_t H5FD_multi_g = { H5FD_FLMAP_DEFAULT /* fl_map */ }; -/*------------------------------------------------------------------------- - * Function: H5FD_multi_init - * - * Purpose: Initialize this driver by registering the driver with the - * library. - * - * Return: Success: The driver ID for the multi driver - * Failure: H5I_INVALID_HID - * - *------------------------------------------------------------------------- - */ -hid_t -H5FD_multi_init(void) -{ - /* Clear the error stack */ - H5Eclear2(H5E_DEFAULT); - - if (H5I_VFL != H5Iget_type(H5FD_MULTI_g)) - H5FD_MULTI_g = H5FDregister(&H5FD_multi_g); - - return H5FD_MULTI_g; -} /* end H5FD_multi_init() */ - -/*--------------------------------------------------------------------------- - * Function: H5FD_multi_term - * - * Purpose: Shut down the VFD - * - * Returns: Non-negative on success or negative on failure - * - *--------------------------------------------------------------------------- - */ -static herr_t -H5FD_multi_term(void) -{ - /* Reset VFL ID */ - H5FD_MULTI_g = 0; - - return 0; -} /* end H5FD_multi_term() */ - /*------------------------------------------------------------------------- * Function: H5Pset_fapl_split * @@ -251,15 +206,14 @@ herr_t H5Pset_fapl_split(hid_t fapl, const char *meta_ext, hid_t meta_plist_id, const char *raw_ext, hid_t raw_plist_id) { - H5FD_multi_fapl_t fa; - static const char *func = "H5Pset_fapl_split"; /* Function Name for error reporting */ + H5FD_multi_fapl_t fa; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); if (H5FD_split_populate_config(meta_ext, meta_plist_id, raw_ext, raw_plist_id, true, &fa) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET, "can't setup split driver configuration", - -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET, + "can't setup split driver configuration", -1); return H5Pset_driver(fapl, H5FD_MULTI, &fa); } @@ -341,17 +295,16 @@ herr_t H5Pset_fapl_multi(hid_t fapl_id, const H5FD_mem_t *memb_map, const hid_t *memb_fapl, const char *const *memb_name, const haddr_t *memb_addr, hbool_t relax) { - H5FD_multi_fapl_t fa; - static const char *func = "H5FDset_fapl_multi"; /* Function Name for error reporting */ + H5FD_multi_fapl_t fa; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); /* Check arguments and supply default values */ if (H5I_GENPROP_LST != H5Iget_type(fapl_id) || true != H5Pisa_class(fapl_id, H5P_FILE_ACCESS)) - H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADVALUE, "not an access list", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_PLIST, H5E_BADVALUE, "not an access list", -1); if (H5FD_multi_populate_config(memb_map, memb_fapl, memb_name, memb_addr, relax, &fa) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET, "can't setup driver configuration", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET, "can't setup driver configuration", -1); return H5Pset_driver(fapl_id, H5FD_MULTI, &fa); } @@ -376,15 +329,14 @@ H5Pget_fapl_multi(hid_t fapl_id, H5FD_mem_t *memb_map /*out*/, hid_t *memb_fapl const H5FD_multi_fapl_t *fa; H5FD_multi_fapl_t default_fa; H5FD_mem_t mt; - static const char *func = "H5FDget_fapl_multi"; /* Function Name for error reporting */ /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); if (H5I_GENPROP_LST != H5Iget_type(fapl_id) || true != H5Pisa_class(fapl_id, H5P_FILE_ACCESS)) - H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADTYPE, "not an access list", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_PLIST, H5E_BADTYPE, "not an access list", -1); if (H5FD_MULTI != H5Pget_driver(fapl_id)) - H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADVALUE, "incorrect VFL driver", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_PLIST, H5E_BADVALUE, "incorrect VFL driver", -1); H5E_BEGIN_TRY { fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id); @@ -392,8 +344,8 @@ H5Pget_fapl_multi(hid_t fapl_id, H5FD_mem_t *memb_map /*out*/, hid_t *memb_fapl H5E_END_TRY if (!fa || (H5P_FILE_ACCESS_DEFAULT == fapl_id)) { if (H5FD_multi_populate_config(NULL, NULL, NULL, NULL, true, &default_fa) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_CANTSET, "can't setup default driver configuration", - -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_VFL, H5E_CANTSET, + "can't setup default driver configuration", -1); fa = &default_fa; } @@ -438,7 +390,6 @@ static herr_t H5FD_split_populate_config(const char *meta_ext, hid_t meta_plist_id, const char *raw_ext, hid_t raw_plist_id, bool relax, H5FD_multi_fapl_t *fa_out) { - static const char *func = "H5FD_split_populate_config"; /* Function Name for error reporting */ static char meta_name_g[H5FD_MULT_MAX_FILE_NAME_LEN]; /* Static scratch buffer to store metadata member name */ static char @@ -510,18 +461,20 @@ H5FD_split_populate_config(const char *meta_ext, hid_t meta_plist_id, const char /* Map usage type */ H5FD_mem_t mmt = _memb_map[mt]; if (mmt < 0 || mmt >= H5FD_MEM_NTYPES) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADRANGE, "file resource type out of range", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADRANGE, "file resource type out of range", + -1); /* * All members of MEMB_FAPL must be either defaults or actual file * access property lists. */ if (H5P_DEFAULT != _memb_fapl[mmt] && true != H5Pisa_class(_memb_fapl[mmt], H5P_FILE_ACCESS)) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type incorrect", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type incorrect", + -1); /* All names must be defined */ if (!_memb_name[mmt] || !_memb_name[mmt][0]) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type not set", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type not set", -1); } END_MEMBERS @@ -541,7 +494,7 @@ H5FD_split_populate_config(const char *meta_ext, hid_t meta_plist_id, const char if (fa_out->memb_fapl[mt] == H5P_DEFAULT) { fa_out->memb_fapl[mt] = H5Pcreate(H5P_FILE_ACCESS); if (H5Pset_fapl_sec2(fa_out->memb_fapl[mt]) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET, + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET, "can't set sec2 driver on member FAPL", -1); } } @@ -564,7 +517,6 @@ static herr_t H5FD_multi_populate_config(const H5FD_mem_t *memb_map, const hid_t *memb_fapl, const char *const *memb_name, const haddr_t *memb_addr, bool relax, H5FD_multi_fapl_t *fa_out) { - static const char *func = "H5FD_multi_populate_config"; /* Function Name for error reporting */ static const char *letters = "Xsbrglo"; static char _memb_name_g[H5FD_MEM_NTYPES][16]; /* Static scratch buffer to store member names */ H5FD_mem_t mt, mmt; @@ -585,7 +537,7 @@ H5FD_multi_populate_config(const H5FD_mem_t *memb_map, const hid_t *memb_fapl, c for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) { _memb_fapl[mt] = H5Pcreate(H5P_FILE_ACCESS); if (H5Pset_fapl_sec2(_memb_fapl[mt]) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET, + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET, "can't set sec2 driver on member FAPL", -1); } memb_fapl = _memb_fapl; @@ -608,7 +560,8 @@ H5FD_multi_populate_config(const H5FD_mem_t *memb_map, const hid_t *memb_fapl, c /* Map usage type */ mmt = memb_map[mt]; if (mmt < 0 || mmt >= H5FD_MEM_NTYPES) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADRANGE, "file resource type out of range", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADRANGE, "file resource type out of range", + -1); if (H5FD_MEM_DEFAULT == mmt) mmt = mt; @@ -617,11 +570,12 @@ H5FD_multi_populate_config(const H5FD_mem_t *memb_map, const hid_t *memb_fapl, c * access property lists. */ if (H5P_DEFAULT != memb_fapl[mmt] && true != H5Pisa_class(memb_fapl[mmt], H5P_FILE_ACCESS)) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type incorrect", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type incorrect", + -1); /* All names must be defined */ if (!memb_name[mmt] || !memb_name[mmt][0]) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type not set", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "file resource type not set", -1); } /* @@ -640,7 +594,7 @@ H5FD_multi_populate_config(const H5FD_mem_t *memb_map, const hid_t *memb_fapl, c if (fa_out->memb_fapl[mt] == H5P_DEFAULT) { fa_out->memb_fapl[mt] = H5Pcreate(H5P_FILE_ACCESS); if (H5Pset_fapl_sec2(fa_out->memb_fapl[mt]) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET, + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET, "can't set sec2 driver on member FAPL", -1); } } @@ -712,13 +666,12 @@ H5FD_multi_sb_size(H5FD_t *_file) static herr_t H5FD_multi_sb_encode(H5FD_t *_file, char *name /*out*/, unsigned char *buf /*out*/) { - H5FD_multi_t *file = (H5FD_multi_t *)_file; - haddr_t memb_eoa; - unsigned char *p; - size_t nseen; - size_t i; - H5FD_mem_t m; - static const char *func = "H5FD_multi_sb_encode"; /* Function Name for error reporting */ + H5FD_multi_t *file = (H5FD_multi_t *)_file; + haddr_t memb_eoa; + unsigned char *p; + size_t nseen; + size_t i; + H5FD_mem_t m; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -754,7 +707,8 @@ H5FD_multi_sb_encode(H5FD_t *_file, char *name /*out*/, unsigned char *buf /*out } END_MEMBERS if (H5Tconvert(H5T_NATIVE_HADDR, H5T_STD_U64LE, nseen * 2, buf + 8, NULL, H5P_DEFAULT) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_DATATYPE, H5E_CANTCONVERT, "can't convert superblock info", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_DATATYPE, H5E_CANTCONVERT, "can't convert superblock info", + -1); /* Encode all name templates */ p = buf + 8 + nseen * 2 * 8; @@ -790,25 +744,24 @@ H5FD_multi_sb_encode(H5FD_t *_file, char *name /*out*/, unsigned char *buf /*out static herr_t H5FD_multi_sb_decode(H5FD_t *_file, const char *name, const unsigned char *buf) { - H5FD_multi_t *file = (H5FD_multi_t *)_file; - char x[2 * H5FD_MEM_NTYPES * 8]; - H5FD_mem_t map[H5FD_MEM_NTYPES]; - int i; - size_t nseen = 0; - bool map_changed = false; - bool in_use[H5FD_MEM_NTYPES]; - const char *memb_name[H5FD_MEM_NTYPES]; - haddr_t memb_addr[H5FD_MEM_NTYPES]; - haddr_t memb_eoa[H5FD_MEM_NTYPES]; - haddr_t *ap; - static const char *func = "H5FD_multi_sb_decode"; /* Function Name for error reporting */ + H5FD_multi_t *file = (H5FD_multi_t *)_file; + char x[2 * H5FD_MEM_NTYPES * 8]; + H5FD_mem_t map[H5FD_MEM_NTYPES]; + int i; + size_t nseen = 0; + bool map_changed = false; + bool in_use[H5FD_MEM_NTYPES]; + const char *memb_name[H5FD_MEM_NTYPES]; + haddr_t memb_addr[H5FD_MEM_NTYPES]; + haddr_t memb_eoa[H5FD_MEM_NTYPES]; + haddr_t *ap; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); /* Make sure the name/version number is correct */ if (strcmp(name, "NCSAmult") != 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_BADVALUE, "invalid multi superblock", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_FILE, H5E_BADVALUE, "invalid multi superblock", -1); /* Set default values */ ALL_MEMBERS (mt) { @@ -840,7 +793,8 @@ H5FD_multi_sb_decode(H5FD_t *_file, const char *name, const unsigned char *buf) memcpy(x, buf, (nseen * 2 * 8)); buf += nseen * 2 * 8; if (H5Tconvert(H5T_STD_U64LE, H5T_NATIVE_HADDR, nseen * 2, x, NULL, H5P_DEFAULT) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_DATATYPE, H5E_CANTCONVERT, "can't convert superblock info", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_DATATYPE, H5E_CANTCONVERT, "can't convert superblock info", + -1); ap = (haddr_t *)((void *)x); /* Extra (void *) cast to quiet "cast to create alignment" warning - 2019/07/05, QAK */ UNIQUE_MEMBERS (map, mt) { @@ -897,17 +851,17 @@ H5FD_multi_sb_decode(H5FD_t *_file, const char *name, const unsigned char *buf) } END_MEMBERS if (compute_next(file) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "compute_next() failed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "compute_next() failed", -1); /* Open all necessary files */ if (open_members(file) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "open_members() failed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "open_members() failed", -1); /* Set the EOA marker for all open files */ UNIQUE_MEMBERS (file->fa.memb_map, mt) { if (file->memb[mt]) if (H5FDset_eoa(file->memb[mt], mt, memb_eoa[mt]) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET, "set_eoa() failed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET, "set_eoa() failed", -1); /* Save the individual EOAs in one place for later comparison (in H5FD_multi_set_eoa) */ @@ -960,7 +914,6 @@ H5FD_multi_fapl_copy(const void *_old_fa) const H5FD_multi_fapl_t *old_fa = (const H5FD_multi_fapl_t *)_old_fa; H5FD_multi_fapl_t *new_fa = (H5FD_multi_fapl_t *)calloc(1, sizeof(H5FD_multi_fapl_t)); int nerrors = 0; - static const char *func = "H5FD_multi_fapl_copy"; /* Function Name for error reporting */ assert(new_fa); @@ -995,7 +948,7 @@ H5FD_multi_fapl_copy(const void *_old_fa) } END_MEMBERS free(new_fa); - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "can't release object on error", NULL); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "can't release object on error", NULL); } return new_fa; } @@ -1014,8 +967,7 @@ H5FD_multi_fapl_copy(const void *_old_fa) static herr_t H5FD_multi_fapl_free(void *_fa) { - H5FD_multi_fapl_t *fa = (H5FD_multi_fapl_t *)_fa; - static const char *func = "H5FD_multi_fapl_free"; /* Function Name for error reporting */ + H5FD_multi_fapl_t *fa = (H5FD_multi_fapl_t *)_fa; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -1023,7 +975,8 @@ H5FD_multi_fapl_free(void *_fa) ALL_MEMBERS (mt) { if (fa->memb_fapl[mt] >= 0) if (H5Idec_ref(fa->memb_fapl[mt]) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTCLOSEOBJ, "can't close property list", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_FILE, H5E_CANTCLOSEOBJ, "can't close property list", + -1); if (fa->memb_name[mt]) free(fa->memb_name[mt]); } @@ -1053,16 +1006,15 @@ H5FD_multi_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr hid_t close_fapl = -1; const H5FD_multi_fapl_t *fa; H5FD_mem_t m; - static const char *func = "H5FD_multi_open"; /* Function Name for error reporting */ /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); /* Check arguments */ if (!name || !*name) - H5Epush_ret(func, H5E_ERR_CLS, H5E_ARGS, H5E_BADVALUE, "invalid file name", NULL); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_ARGS, H5E_BADVALUE, "invalid file name", NULL); if (0 == maxaddr || HADDR_UNDEF == maxaddr) - H5Epush_ret(func, H5E_ERR_CLS, H5E_ARGS, H5E_BADRANGE, "bogus maxaddr", NULL); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_ARGS, H5E_BADRANGE, "bogus maxaddr", NULL); /* * Initialize the file from the file access properties, using default @@ -1071,7 +1023,7 @@ H5FD_multi_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr * in H5FD_multi_t. */ if (NULL == (file = (H5FD_multi_t *)calloc((size_t)1, sizeof(H5FD_multi_t)))) - H5Epush_ret(func, H5E_ERR_CLS, H5E_RESOURCE, H5E_NOSPACE, "memory allocation failed", NULL); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_RESOURCE, H5E_NOSPACE, "memory allocation failed", NULL); H5E_BEGIN_TRY { fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id); @@ -1083,11 +1035,11 @@ H5FD_multi_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr close_fapl = fapl_id = H5Pcreate(H5P_FILE_ACCESS); if (env && !strcmp(env, "split")) { if (H5Pset_fapl_split(fapl_id, NULL, H5P_DEFAULT, NULL, H5P_DEFAULT) < 0) - H5Epush_goto(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTSET, "can't set property value", error); + H5Epush_goto(__func__, H5E_ERR_CLS, H5E_FILE, H5E_CANTSET, "can't set property value", error); } else { if (H5Pset_fapl_multi(fapl_id, NULL, NULL, NULL, NULL, true) < 0) - H5Epush_goto(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTSET, "can't set property value", error); + H5Epush_goto(__func__, H5E_ERR_CLS, H5E_FILE, H5E_CANTSET, "can't set property value", error); } fa = (const H5FD_multi_fapl_t *)H5Pget_driver_info(fapl_id); @@ -1110,13 +1062,14 @@ H5FD_multi_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr file->name = my_strdup(name); if (close_fapl >= 0) if (H5Pclose(close_fapl) < 0) - H5Epush_goto(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTCLOSEOBJ, "can't close property list", error); + H5Epush_goto(__func__, H5E_ERR_CLS, H5E_FILE, H5E_CANTCLOSEOBJ, "can't close property list", + error); /* Compute derived properties and open member files */ if (compute_next(file) < 0) - H5Epush_goto(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "compute_next() failed", error); + H5Epush_goto(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "compute_next() failed", error); if (open_members(file) < 0) - H5Epush_goto(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "open_members() failed", error); + H5Epush_goto(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "open_members() failed", error); /* We must have opened at least the superblock file */ if (H5FD_MEM_DEFAULT == (m = file->fa.memb_map[H5FD_MEM_SUPER])) @@ -1161,9 +1114,8 @@ H5FD_multi_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr static herr_t H5FD_multi_close(H5FD_t *_file) { - H5FD_multi_t *file = (H5FD_multi_t *)_file; - int nerrors = 0; - static const char *func = "H5FD_multi_close"; /* Function Name for error reporting */ + H5FD_multi_t *file = (H5FD_multi_t *)_file; + int nerrors = 0; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -1181,7 +1133,7 @@ H5FD_multi_close(H5FD_t *_file) } END_MEMBERS if (nerrors) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "error closing member files", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "error closing member files", -1); /* Clean up other stuff */ ALL_MEMBERS (mt) { @@ -1311,7 +1263,6 @@ H5FD_multi_get_eoa(const H5FD_t *_file, H5FD_mem_t type) { const H5FD_multi_t *file = (const H5FD_multi_t *)_file; haddr_t eoa = 0; - static const char *func = "H5FD_multi_get_eoa"; /* Function Name for error reporting */ /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -1335,8 +1286,8 @@ H5FD_multi_get_eoa(const H5FD_t *_file, H5FD_mem_t type) H5E_END_TRY if (HADDR_UNDEF == memb_eoa) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "member file has unknown eoa", - HADDR_UNDEF); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, + "member file has unknown eoa", HADDR_UNDEF); if (memb_eoa > 0) memb_eoa += file->fa.memb_addr[mt]; } @@ -1349,7 +1300,7 @@ H5FD_multi_get_eoa(const H5FD_t *_file, H5FD_mem_t type) assert(HADDR_UNDEF != memb_eoa); } else { - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "bad eoa", HADDR_UNDEF); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "bad eoa", HADDR_UNDEF); } if (memb_eoa > eoa) @@ -1371,7 +1322,7 @@ H5FD_multi_get_eoa(const H5FD_t *_file, H5FD_mem_t type) H5E_END_TRY if (HADDR_UNDEF == eoa) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "member file has unknown eoa", + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "member file has unknown eoa", HADDR_UNDEF); if (eoa > 0) eoa += file->fa.memb_addr[mmt]; @@ -1385,7 +1336,7 @@ H5FD_multi_get_eoa(const H5FD_t *_file, H5FD_mem_t type) assert(HADDR_UNDEF != eoa); } else { - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "bad eoa", HADDR_UNDEF); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "bad eoa", HADDR_UNDEF); } } @@ -1409,10 +1360,9 @@ H5FD_multi_get_eoa(const H5FD_t *_file, H5FD_mem_t type) static herr_t H5FD_multi_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t eoa) { - H5FD_multi_t *file = (H5FD_multi_t *)_file; - H5FD_mem_t mmt; - herr_t status; - static const char *func = "H5FD_multi_set_eoa"; /* Function Name for error reporting */ + H5FD_multi_t *file = (H5FD_multi_t *)_file; + H5FD_mem_t mmt; + herr_t status; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -1448,7 +1398,7 @@ H5FD_multi_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t eoa) } H5E_END_TRY if (status < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_BADVALUE, "member H5FDset_eoa failed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_FILE, H5E_BADVALUE, "member H5FDset_eoa failed", -1); return 0; } /* end H5FD_multi_set_eoa() */ @@ -1472,7 +1422,6 @@ H5FD_multi_get_eof(const H5FD_t *_file, H5FD_mem_t type) { const H5FD_multi_t *file = (const H5FD_multi_t *)_file; haddr_t eof = 0; - static const char *func = "H5FD_multi_get_eof"; /* Function Name for error reporting */ /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -1490,8 +1439,8 @@ H5FD_multi_get_eof(const H5FD_t *_file, H5FD_mem_t type) H5E_END_TRY if (HADDR_UNDEF == tmp_eof) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "member file has unknown eof", - HADDR_UNDEF); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, + "member file has unknown eof", HADDR_UNDEF); if (tmp_eof > 0) tmp_eof += file->fa.memb_addr[mt]; } @@ -1504,7 +1453,7 @@ H5FD_multi_get_eof(const H5FD_t *_file, H5FD_mem_t type) assert(HADDR_UNDEF != tmp_eof); } else { - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "bad eof", HADDR_UNDEF); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "bad eof", HADDR_UNDEF); } if (tmp_eof > eof) eof = tmp_eof; @@ -1526,7 +1475,7 @@ H5FD_multi_get_eof(const H5FD_t *_file, H5FD_mem_t type) H5E_END_TRY if (HADDR_UNDEF == eof) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "member file has unknown eof", + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "member file has unknown eof", HADDR_UNDEF); if (eof > 0) eof += file->fa.memb_addr[mmt]; @@ -1540,7 +1489,7 @@ H5FD_multi_get_eof(const H5FD_t *_file, H5FD_mem_t type) assert(HADDR_UNDEF != eof); } else { - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "bad eof", HADDR_UNDEF); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "bad eof", HADDR_UNDEF); } } return eof; @@ -1558,16 +1507,15 @@ H5FD_multi_get_eof(const H5FD_t *_file, H5FD_mem_t type) static herr_t H5FD_multi_get_handle(H5FD_t *_file, hid_t fapl, void **file_handle) { - H5FD_multi_t *file = (H5FD_multi_t *)_file; - H5FD_mem_t type, mmt; - static const char *func = "H5FD_multi_get_handle"; /* Function Name for error reporting */ + H5FD_multi_t *file = (H5FD_multi_t *)_file; + H5FD_mem_t type, mmt; /* Get data type for multi driver */ if (H5Pget_multi_type(fapl, &type) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "can't get data type for multi driver", + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "can't get data type for multi driver", -1); if (type < H5FD_MEM_DEFAULT || type >= H5FD_MEM_NTYPES) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "data type is out of range", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "data type is out of range", -1); mmt = file->fa.memb_map[type]; if (H5FD_MEM_DEFAULT == mmt) mmt = type; @@ -1589,10 +1537,9 @@ H5FD_multi_get_handle(H5FD_t *_file, hid_t fapl, void **file_handle) static haddr_t H5FD_multi_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) { - H5FD_multi_t *file = (H5FD_multi_t *)_file; - H5FD_mem_t mmt; - haddr_t addr; - static const char *func = "H5FD_multi_alloc"; /* Function Name for error reporting */ + H5FD_multi_t *file = (H5FD_multi_t *)_file; + H5FD_mem_t mmt; + haddr_t addr; mmt = file->fa.memb_map[type]; if (H5FD_MEM_DEFAULT == mmt) @@ -1608,23 +1555,10 @@ H5FD_multi_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size) } if (HADDR_UNDEF == (addr = H5FDalloc(file->memb[mmt], mmt, dxpl_id, size))) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "member file can't alloc", HADDR_UNDEF); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "member file can't alloc", + HADDR_UNDEF); addr += file->fa.memb_addr[mmt]; - /*#ifdef TMP - if ( addr + size > file->eoa ) { - - if ( H5FD_multi_set_eoa(_file, addr + size) < 0 ) { - - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, \ - "can't set eoa", HADDR_UNDEF); - } - } - #else - if ( addr + size > file->eoa ) - file->eoa = addr + size; - #endif */ - return addr; } @@ -1758,42 +1692,9 @@ H5FD_multi_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, si static herr_t H5FD_multi_flush(H5FD_t *_file, hid_t dxpl_id, bool closing) { - H5FD_multi_t *file = (H5FD_multi_t *)_file; - H5FD_mem_t mt; - int nerrors = 0; - static const char *func = "H5FD_multi_flush"; /* Function Name for error reporting */ - -#if 0 - H5FD_mem_t mmt; - - /* Debugging stuff... */ - fprintf(stderr, "multifile access information:\n"); - - /* print the map */ - fprintf(stderr, " map="); - for (mt=1; mtmemb_map[mt]; - if (H5FD_MEM_DEFAULT==mmt) mmt = mt; - fprintf(stderr, "%s%d", 1==mt?"":",", (int)mmt); - } - fprintf(stderr, "\n"); - - /* print info about each file */ - fprintf(stderr, " File Starting Allocated Next Member\n"); - fprintf(stderr, " Number Address Size Address Name\n"); - fprintf(stderr, " ------ -------------------- -------------------- -------------------- ------------------------------\n"); - - for (mt=1; mtmemb_addr[mt]) { - haddr_t eoa = H5FDget_eoa(file->memb[mt], mt); - fprintf(stderr, " %6d %20llu %20llu %20llu %s\n", - (int)mt, (unsigned long long)(file->memb_addr[mt]), - (unsigned long long)eoa, - (unsigned long long)(file->memb_next[mt]), - file->memb_name[mt]); - } - } -#endif + H5FD_multi_t *file = (H5FD_multi_t *)_file; + H5FD_mem_t mt; + int nerrors = 0; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -1810,7 +1711,7 @@ H5FD_multi_flush(H5FD_t *_file, hid_t dxpl_id, bool closing) } } if (nerrors) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "error flushing member files", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "error flushing member files", -1); return 0; } @@ -1828,10 +1729,9 @@ H5FD_multi_flush(H5FD_t *_file, hid_t dxpl_id, bool closing) static herr_t H5FD_multi_truncate(H5FD_t *_file, hid_t dxpl_id, bool closing) { - H5FD_multi_t *file = (H5FD_multi_t *)_file; - H5FD_mem_t mt; - int nerrors = 0; - static const char *func = "H5FD_multi_truncate"; /* Function Name for error reporting */ + H5FD_multi_t *file = (H5FD_multi_t *)_file; + H5FD_mem_t mt; + int nerrors = 0; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -1848,7 +1748,7 @@ H5FD_multi_truncate(H5FD_t *_file, hid_t dxpl_id, bool closing) } } if (nerrors) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "error truncating member files", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "error truncating member files", -1); return 0; } /* end H5FD_multi_truncate() */ @@ -1869,10 +1769,9 @@ H5FD_multi_truncate(H5FD_t *_file, hid_t dxpl_id, bool closing) static herr_t H5FD_multi_lock(H5FD_t *_file, bool rw) { - H5FD_multi_t *file = (H5FD_multi_t *)_file; - int nerrors = 0; - H5FD_mem_t out_mt = H5FD_MEM_DEFAULT; - static const char *func = "H5FD_multi_unlock"; /* Function Name for error reporting */ + H5FD_multi_t *file = (H5FD_multi_t *)_file; + int nerrors = 0; + H5FD_mem_t out_mt = H5FD_MEM_DEFAULT; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -1908,7 +1807,7 @@ H5FD_multi_lock(H5FD_t *_file, bool rw) } /* end if */ if (nerrors) - H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_CANTLOCKFILE, "error locking member files", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_VFL, H5E_CANTLOCKFILE, "error locking member files", -1); return 0; } /* H5FD_multi_lock() */ @@ -1928,9 +1827,8 @@ H5FD_multi_lock(H5FD_t *_file, bool rw) static herr_t H5FD_multi_unlock(H5FD_t *_file) { - H5FD_multi_t *file = (H5FD_multi_t *)_file; - int nerrors = 0; - static const char *func = "H5FD_multi_unlock"; /* Function Name for error reporting */ + H5FD_multi_t *file = (H5FD_multi_t *)_file; + int nerrors = 0; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -1943,7 +1841,7 @@ H5FD_multi_unlock(H5FD_t *_file) END_MEMBERS if (nerrors) - H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_CANTUNLOCKFILE, "error unlocking member files", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_VFL, H5E_CANTUNLOCKFILE, "error unlocking member files", -1); return 0; } /* H5FD_multi_unlock() */ @@ -2010,10 +1908,9 @@ H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static int open_members(H5FD_multi_t *file) { - char tmp[H5FD_MULT_MAX_FILE_NAME_LEN]; - int nerrors = 0; - int nchars; - static const char *func = "(H5FD_multi)open_members"; /* Function Name for error reporting */ + char tmp[H5FD_MULT_MAX_FILE_NAME_LEN]; + int nerrors = 0; + int nchars; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -2025,7 +1922,7 @@ open_members(H5FD_multi_t *file) nchars = snprintf(tmp, sizeof(tmp), file->fa.memb_name[mt], file->name); if (nchars < 0 || nchars >= (int)sizeof(tmp)) - H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_BADVALUE, + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_VFL, H5E_BADVALUE, "filename is too long and would be truncated", -1); H5E_BEGIN_TRY @@ -2040,7 +1937,7 @@ open_members(H5FD_multi_t *file) } END_MEMBERS if (nerrors) - H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "error opening member files", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "error opening member files", -1); return 0; } @@ -2063,7 +1960,6 @@ H5FD_multi_delete(const char *filename, hid_t fapl_id) int nchars; const H5FD_multi_fapl_t *fa; H5FD_multi_fapl_t default_fa; - static const char *func = "H5FD_multi_delete"; /* Function Name for error reporting */ /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -2081,11 +1977,13 @@ H5FD_multi_delete(const char *filename, hid_t fapl_id) if (env && !strcmp(env, "split")) { if (H5FD_split_populate_config(NULL, H5P_DEFAULT, NULL, H5P_DEFAULT, true, &default_fa) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_CANTSET, "can't setup driver configuration", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_VFL, H5E_CANTSET, "can't setup driver configuration", + -1); } else { if (H5FD_multi_populate_config(NULL, NULL, NULL, NULL, true, &default_fa) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_CANTSET, "can't setup driver configuration", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_VFL, H5E_CANTSET, "can't setup driver configuration", + -1); } fa = &default_fa; @@ -2099,11 +1997,11 @@ H5FD_multi_delete(const char *filename, hid_t fapl_id) nchars = snprintf(full_filename, sizeof(full_filename), fa->memb_name[mt], filename); if (nchars < 0 || nchars >= (int)sizeof(full_filename)) - H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_BADVALUE, + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_VFL, H5E_BADVALUE, "filename is too long and would be truncated", -1); if (H5FDdelete(full_filename, fa->memb_fapl[mt]) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_BADVALUE, "error deleting member files", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_VFL, H5E_BADVALUE, "error deleting member files", -1); } END_MEMBERS @@ -2134,9 +2032,8 @@ H5_GCC_CLANG_DIAG_ON("format-nonliteral") static herr_t H5FD_multi_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, void **output) { - H5FD_multi_t *file = (H5FD_multi_t *)_file; - static const char *func = "H5FD_multi_ctl"; /* Function Name for error reporting */ - herr_t ret_value = 0; + H5FD_multi_t *file = (H5FD_multi_t *)_file; + herr_t ret_value = 0; /* Silence compiler */ (void)file; @@ -2150,7 +2047,7 @@ H5FD_multi_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *inpu /* Unknown op code */ default: if (flags & H5FD_CTL_FAIL_IF_UNKNOWN_FLAG) - H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_FCNTL, + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_VFL, H5E_FCNTL, "VFD ctl request failed (unknown op code and fail if unknown flag is set)", -1); break; diff --git a/src/H5FDmulti.h b/src/H5FDmulti.h index d32ed3ed66a..3ac0788a8dd 100644 --- a/src/H5FDmulti.h +++ b/src/H5FDmulti.h @@ -16,8 +16,11 @@ #ifndef H5FDmulti_H #define H5FDmulti_H -/** Initializer for the multi VFD */ -#define H5FD_MULTI (H5FDperform_init(H5FD_multi_init)) +/* Public header files */ +#include "H5FDpublic.h" /* File drivers */ + +/** ID for the multi VFD */ +#define H5FD_MULTI (H5OPEN H5FD_MULTI_id_g) #ifdef __cplusplus extern "C" { @@ -25,9 +28,9 @@ extern "C" { /** @private * - * \brief Private initializer for the multi VFD + * \brief ID for the multi VFD */ -H5_DLL hid_t H5FD_multi_init(void); +H5_DLLVAR hid_t H5FD_MULTI_id_g; /** * \ingroup FAPL diff --git a/src/H5FDmulti_int.c b/src/H5FDmulti_int.c new file mode 100644 index 00000000000..714aee2d518 --- /dev/null +++ b/src/H5FDmulti_int.c @@ -0,0 +1,83 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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 COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: Private routines for the multi VFD. + * + * Necessary for using internal library routines, which are + * disallowed within the actual multi VFD code. + * + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5FD_FRIEND /* Suppress error about including H5FDpkg */ + +/***********/ +/* Headers */ +/***********/ + +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Iprivate.h" /* IDs */ +#include "H5FDpkg.h" /* File drivers */ + +#include "H5FDmulti_private.h" /* multi VFD */ + +/* The driver identification number, initialized at runtime */ +hid_t H5FD_MULTI_id_g = H5I_INVALID_HID; + +/*------------------------------------------------------------------------- + * Function: H5FD__multi_register + * + * Purpose: Register the driver with the library. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD__multi_register(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + if (H5I_VFL != H5I_get_type(H5FD_MULTI_id_g)) + if ((H5FD_MULTI_id_g = H5FD_register(&H5FD_multi_g, sizeof(H5FD_class_t), false)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register multi driver"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__multi_register() */ + +/*--------------------------------------------------------------------------- + * Function: H5FD__multi_unregister + * + * Purpose: Reset library driver info. + * + * Returns: SUCCEED (Can't fail) + * + *--------------------------------------------------------------------------- + */ +herr_t +H5FD__multi_unregister(void) +{ + FUNC_ENTER_PACKAGE_NOERR + + /* Reset VFL ID */ + H5FD_MULTI_id_g = H5I_INVALID_HID; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5FD_multi_unregister() */ diff --git a/src/H5FDdrvr_module.h b/src/H5FDmulti_private.h similarity index 53% rename from src/H5FDdrvr_module.h rename to src/H5FDmulti_private.h index 6757f564b4b..47e3b7121b0 100644 --- a/src/H5FDdrvr_module.h +++ b/src/H5FDmulti_private.h @@ -11,17 +11,35 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* - * Purpose: This file contains declarations which define macros for the - * H5FD driver package. Including this header means that the source file - * is part of the H5FD driver package. + * Purpose: The private header file for the multi VFD */ -#ifndef H5FDdrvr_module_H -#define H5FDdrvr_module_H -/* Define the proper control macros for the generic FUNC_ENTER/LEAVE and error - * reporting macros. - */ -#define H5_MY_PKG H5FD -#define H5_MY_PKG_ERR H5E_FILE +#ifndef H5FDmulti_private_H +#define H5FDmulti_private_H + +/* Include VFD's public header */ +#include "H5FDmulti.h" /* multi VFD */ + +/* Private headers needed by this file */ +#include "H5FDprivate.h" /* File drivers */ + +/**************************/ +/* Library Private Macros */ +/**************************/ + +/****************************/ +/* Library Private Typedefs */ +/****************************/ + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + +/* multi VFD's class struct */ +H5_DLLVAR const H5FD_class_t H5FD_multi_g; + +/******************************/ +/* Library Private Prototypes */ +/******************************/ -#endif /* H5FDdrvr_module_H */ +#endif /* H5FDmulti_private_H */ diff --git a/src/H5FDonion.c b/src/H5FDonion.c index 2f77eebf5a9..c9b2567f25c 100644 --- a/src/H5FDonion.c +++ b/src/H5FDonion.c @@ -16,22 +16,20 @@ * Purpose: Provide in-file provenance and revision/version control. */ -/* This source code file is part of the H5FD driver module */ -#include "H5FDdrvr_module.h" +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* Files */ -#include "H5FDprivate.h" /* File drivers */ -#include "H5FDonion.h" /* Onion file driver */ +#include "H5FDsec2.h" /* Sec2 file driver */ +#include "H5FDpkg.h" /* File drivers */ #include "H5FDonion_priv.h" /* Onion file driver internals */ -#include "H5FDsec2.h" /* Sec2 file driver */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ /* The driver identification number, initialized at runtime */ -static hid_t H5FD_ONION_g = 0; +hid_t H5FD_ONION_id_g = H5I_INVALID_HID; /****************************************************************************** * @@ -160,7 +158,6 @@ static haddr_t H5FD__onion_get_eof(const H5FD_t *, H5FD_mem_t); static H5FD_t *H5FD__onion_open(const char *, unsigned int, hid_t, haddr_t); static herr_t H5FD__onion_read(H5FD_t *, H5FD_mem_t, hid_t, haddr_t, size_t, void *); static herr_t H5FD__onion_set_eoa(H5FD_t *, H5FD_mem_t, haddr_t); -static herr_t H5FD__onion_term(void); static herr_t H5FD__onion_write(H5FD_t *, H5FD_mem_t, hid_t, haddr_t, size_t, const void *); static herr_t H5FD__onion_open_rw(H5FD_onion_t *, unsigned int, haddr_t, bool new_open); @@ -180,7 +177,7 @@ static const H5FD_class_t H5FD_onion_g = { "onion", /* name */ MAXADDR, /* maxaddr */ H5F_CLOSE_WEAK, /* fc_degree */ - H5FD__onion_term, /* terminate */ + NULL, /* terminate */ H5FD__onion_sb_size, /* sb_size */ H5FD__onion_sb_encode, /* sb_encode */ H5FD__onion_sb_decode, /* sb_decode */ @@ -218,50 +215,48 @@ static const H5FD_class_t H5FD_onion_g = { }; /*----------------------------------------------------------------------------- - * Function: H5FD_onion_init + * Function: H5FD__onion_register * - * Purpose: Initialize this driver by registering the driver with the - * library. + * Purpose: Register the driver with the library. + * + * Return: SUCCEED/FAIL * - * Return: Success: The driver ID for the onion driver. - * Failure: Negative *----------------------------------------------------------------------------- */ -hid_t -H5FD_onion_init(void) +herr_t +H5FD__onion_register(void) { - hid_t ret_value = H5I_INVALID_HID; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR - - if (H5I_VFL != H5I_get_type(H5FD_ONION_g)) - H5FD_ONION_g = H5FD_register(&H5FD_onion_g, sizeof(H5FD_class_t), false); + FUNC_ENTER_PACKAGE - /* Set return value */ - ret_value = H5FD_ONION_g; + if (H5I_VFL != H5I_get_type(H5FD_ONION_id_g)) + if ((H5FD_ONION_id_g = H5FD_register(&H5FD_onion_g, sizeof(H5FD_class_t), false)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register onion driver"); +done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FD_onion_init() */ +} /* end H5FD__onion_register() */ /*----------------------------------------------------------------------------- - * Function: H5FD__onion_term + * Function: H5FD__onion_unregister * - * Purpose: Shut down the Onion VFD. + * Purpose: Reset library driver info. * * Returns: SUCCEED (Can't fail) + * *----------------------------------------------------------------------------- */ -static herr_t -H5FD__onion_term(void) +herr_t +H5FD__onion_unregister(void) { FUNC_ENTER_PACKAGE_NOERR /* Reset VFL ID */ - H5FD_ONION_g = 0; + H5FD_ONION_id_g = H5I_INVALID_HID; FUNC_LEAVE_NOAPI(SUCCEED) - -} /* end H5FD__onion_term() */ +} /* end H5FD__onion_unregister() */ /*----------------------------------------------------------------------------- * Function: H5Pget_fapl_onion diff --git a/src/H5FDonion.h b/src/H5FDonion.h index eefaf1f0f0c..5c374bb16dd 100644 --- a/src/H5FDonion.h +++ b/src/H5FDonion.h @@ -16,8 +16,11 @@ #ifndef H5FDonion_H #define H5FDonion_H -/** Initializer for the onion VFD */ -#define H5FD_ONION (H5FDperform_init(H5FD_onion_init)) +/* Public header files */ +#include "H5FDpublic.h" /* File drivers */ + +/** ID for the onion VFD */ +#define H5FD_ONION (H5OPEN H5FD_ONION_id_g) /** Identifier for the onion VFD */ #define H5FD_ONION_VALUE H5_VFD_ONION @@ -115,9 +118,9 @@ extern "C" { /** @private * - * \brief Private initializer for the onion VFD + * \brief ID for the onion VFD */ -H5_DLL hid_t H5FD_onion_init(void); +H5_DLLVAR hid_t H5FD_ONION_id_g; /** * -------------------------------------------------------------------------- diff --git a/src/H5FDonion_header.c b/src/H5FDonion_header.c index 46510a20f65..2411f6e712f 100644 --- a/src/H5FDonion_header.c +++ b/src/H5FDonion_header.c @@ -16,13 +16,11 @@ * Purpose: Code for the onion file's header */ -/* This source code file is part of the H5FD driver module */ -#include "H5FDdrvr_module.h" +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ -#include "H5FDprivate.h" /* File drivers */ -#include "H5FDonion.h" /* Onion file driver */ +#include "H5FDpkg.h" /* File drivers */ #include "H5FDonion_priv.h" /* Onion file driver internals */ #include "H5MMprivate.h" /* Memory management */ diff --git a/src/H5FDonion_history.c b/src/H5FDonion_history.c index 6ef1ad688a8..13231683a6b 100644 --- a/src/H5FDonion_history.c +++ b/src/H5FDonion_history.c @@ -16,13 +16,11 @@ * Purpose: Code for the onion file's history */ -/* This source code file is part of the H5FD driver module */ -#include "H5FDdrvr_module.h" +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ -#include "H5FDprivate.h" /* File drivers */ -#include "H5FDonion.h" /* Onion file driver */ +#include "H5FDpkg.h" /* File drivers */ #include "H5FDonion_priv.h" /* Onion file driver internals */ #include "H5MMprivate.h" /* Memory management */ diff --git a/src/H5FDonion_index.c b/src/H5FDonion_index.c index 639e69019ab..8e9512c102c 100644 --- a/src/H5FDonion_index.c +++ b/src/H5FDonion_index.c @@ -16,13 +16,11 @@ * Purpose: Code for the archival and revision indexes */ -/* This source code file is part of the H5FD driver module */ -#include "H5FDdrvr_module.h" +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ -#include "H5FDprivate.h" /* File drivers */ -#include "H5FDonion.h" /* Onion file driver */ +#include "H5FDpkg.h" /* File drivers */ #include "H5FDonion_priv.h" /* Onion file driver internals */ #include "H5MMprivate.h" /* Memory management */ diff --git a/src/H5FDonion_priv.h b/src/H5FDonion_priv.h index 5d6de960fb9..d95c5eb3bf0 100644 --- a/src/H5FDonion_priv.h +++ b/src/H5FDonion_priv.h @@ -21,6 +21,10 @@ #ifndef H5FDonion_priv_H #define H5FDonion_priv_H +/* Public headers */ +#include "H5FDonion.h" + +/* Private headers */ #include "H5FDonion_header.h" #include "H5FDonion_history.h" #include "H5FDonion_index.h" diff --git a/src/H5FDperform.c b/src/H5FDperform.c deleted file mode 100644 index dc6491ba2ef..00000000000 --- a/src/H5FDperform.c +++ /dev/null @@ -1,57 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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 LICENSE file, which can be found at the root of the source code * - * distribution tree, or in https://www.hdfgroup.org/licenses. * - * If you do not have access to either file, you may request a copy from * - * help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/****************/ -/* Module Setup */ -/****************/ - -#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ - -/***********/ -/* Headers */ -/***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5FDpkg.h" /* File Drivers */ -#include "H5Iprivate.h" /* IDs */ - -/*------------------------------------------------------------------------- - * Function: H5FDperform_init - * - * Purpose: Ensure that the library is initialized and then call - * the provided VFD initializer - * - * Return: Success: Identifier for the VFD just initialized - * Failure: H5I_INVALID_HID - *------------------------------------------------------------------------- - */ -hid_t -H5FDperform_init(H5FD_init_t op) -{ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ - - FUNC_ENTER_API_NOINIT - - /* It is possible that an application will evaluate an - * `H5FD_*` symbol (`H5FD_FAMILY`, `H5FD_MULTI`, `H5FD_SEC2`, etc. - * before the library has had an opportunity to initialize. Call - * H5_init_library() to make sure that the library has been initialized - * before `init` is run. - */ - if (H5_init_library() < 0) - HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, H5I_INVALID_HID, "library initialization failed"); - - ret_value = op(); - -done: - FUNC_LEAVE_API_NOINIT(ret_value) -} diff --git a/src/H5FDpkg.h b/src/H5FDpkg.h index 2c1bea9df69..2ba842df456 100644 --- a/src/H5FDpkg.h +++ b/src/H5FDpkg.h @@ -39,6 +39,9 @@ /* Package Private Variables */ /*****************************/ +/* Whether to ignore file locks when disabled (env var value) */ +H5_DLLVAR htri_t H5FD_ignore_disabled_file_locks_p; + /******************************/ /* Package Private Prototypes */ /******************************/ @@ -46,6 +49,52 @@ H5_DLL haddr_t H5FD__alloc_real(H5FD_t *file, H5FD_mem_t type, hsize_t size, had hsize_t *align_size); H5_DLL herr_t H5FD__free_real(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size); +/* Internal VFD init/term routines */ +H5_DLL herr_t H5FD__core_register(void); +H5_DLL herr_t H5FD__core_unregister(void); +#ifdef H5_HAVE_DIRECT +H5_DLL herr_t H5FD__direct_register(void); +H5_DLL herr_t H5FD__direct_unregister(void); +#endif +H5_DLL herr_t H5FD__family_register(void); +H5_DLL herr_t H5FD__family_unregister(void); +#ifdef H5_HAVE_LIBHDFS +H5_DLL herr_t H5FD__hdfs_register(void); +H5_DLL herr_t H5FD__hdfs_unregister(void); +#endif +#ifdef H5_HAVE_IOC_VFD +H5_DLL herr_t H5FD__ioc_register(void); +H5_DLL herr_t H5FD__ioc_unregister(void); +#endif +H5_DLL herr_t H5FD__log_register(void); +H5_DLL herr_t H5FD__log_unregister(void); +#ifdef H5_HAVE_MIRROR_VFD +H5_DLL herr_t H5FD__mirror_register(void); +H5_DLL herr_t H5FD__mirror_unregister(void); +#endif +#ifdef H5_HAVE_PARALLEL +H5_DLL herr_t H5FD__mpio_register(void); +H5_DLL herr_t H5FD__mpio_unregister(void); +#endif +H5_DLL herr_t H5FD__multi_register(void); +H5_DLL herr_t H5FD__multi_unregister(void); +H5_DLL herr_t H5FD__onion_register(void); +H5_DLL herr_t H5FD__onion_unregister(void); +#ifdef H5_HAVE_ROS3_VFD +H5_DLL herr_t H5FD__ros3_register(void); +H5_DLL herr_t H5FD__ros3_unregister(void); +#endif +H5_DLL herr_t H5FD__sec2_register(void); +H5_DLL herr_t H5FD__sec2_unregister(void); +H5_DLL herr_t H5FD__splitter_register(void); +H5_DLL herr_t H5FD__splitter_unregister(void); +H5_DLL herr_t H5FD__stdio_register(void); +H5_DLL herr_t H5FD__stdio_unregister(void); +#ifdef H5_HAVE_SUBFILING_VFD +H5_DLL herr_t H5FD__subfiling_register(void); +H5_DLL herr_t H5FD__subfiling_unregister(void); +#endif + /* Testing functions */ #ifdef H5FD_TESTING H5_DLL bool H5FD__supports_swmr_test(const char *vfd_name); diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index 86ed6f073b8..53e47902832 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -109,6 +109,7 @@ struct H5S_t; struct H5F_t; union H5PL_key_t; +H5_DLL herr_t H5FD_init(void); H5_DLL int H5FD_term_interface(void); H5_DLL herr_t H5FD_locate_signature(H5FD_t *file, haddr_t *sig_addr); H5_DLL H5FD_class_t *H5FD_get_class(hid_t id); @@ -197,7 +198,6 @@ H5_DLL herr_t H5FD_sort_selection_io_req(bool *selection_was_sorted, size_t coun H5_flexible_const_ptr_t bufs[], hid_t **s_mem_space_ids, hid_t **s_file_space_ids, haddr_t **s_offsets_ptr, size_t **s_element_sizes_ptr, H5_flexible_const_ptr_t **s_bufs_ptr); -H5_DLL herr_t H5FD_init(void); /* Function prototypes for MPI based VFDs*/ #ifdef H5_HAVE_PARALLEL diff --git a/src/H5FDros3.c b/src/H5FDros3.c index b68337e6dd7..253024e0d4a 100644 --- a/src/H5FDros3.c +++ b/src/H5FDros3.c @@ -17,21 +17,19 @@ * Relies on "s3comms" utility layer to implement the AWS REST API. */ +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ + +#include "H5private.h" /* Generic Functions */ + #ifdef H5_HAVE_ROS3_VFD -/* This source code file is part of the H5FD driver module */ -#include "H5FDdrvr_module.h" -#endif -#include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ -#include "H5FDprivate.h" /* File drivers */ +#include "H5FDpkg.h" /* File drivers */ #include "H5FDros3.h" /* ros3 file driver */ +#include "H5FDs3comms.h" /* S3 Communications */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ -#include "H5FDs3comms.h" /* S3 Communications */ - -#ifdef H5_HAVE_ROS3_VFD /* Define to turn on stats collection and reporting */ /* #define ROS3_STATS */ @@ -40,7 +38,12 @@ #define ROS3_MAX_CACHE_SIZE 16777216 /* The driver identification number, initialized at runtime */ -static hid_t H5FD_ROS3_g = 0; +hid_t H5FD_ROS3_id_g = H5I_INVALID_HID; + +/* Flag to indicate whether global driver resources & settings have been + * initialized. + */ +static bool H5FD_ros3_init_s = false; /* Session/security token property name */ #define ROS3_TOKEN_PROP_NAME "ros3_token_prop" @@ -139,7 +142,6 @@ typedef struct H5FD_ros3_t { #define ADDR_OVERFLOW(A) (HADDR_UNDEF == (A) || ((A) & ~(haddr_t)MAXADDR)) /* Prototypes */ -static herr_t H5FD__ros3_term(void); static void *H5FD__ros3_fapl_get(H5FD_t *_file); static void *H5FD__ros3_fapl_copy(const void *_old_fa); static herr_t H5FD__ros3_fapl_free(void *_fa); @@ -176,7 +178,7 @@ static const H5FD_class_t H5FD_ros3_g = { "ros3", /* name */ MAXADDR, /* maxaddr */ H5F_CLOSE_WEAK, /* fc_degree */ - H5FD__ros3_term, /* terminate */ + NULL, /* terminate */ NULL, /* sb_size */ NULL, /* sb_encode */ NULL, /* sb_decode */ @@ -217,59 +219,74 @@ static const H5FD_class_t H5FD_ros3_g = { H5FL_DEFINE_STATIC(H5FD_ros3_t); /*------------------------------------------------------------------------- - * Function: H5FD_ros3_init + * Function: H5FD__ros3_register + * + * Purpose: Register the driver with the library. * - * Purpose: Initialize this driver by registering the driver with the - * library. + * Return: SUCCEED/FAIL * - * Return: Success: The driver ID for the ros3 driver - * Failure: H5I_INVALID_HID *------------------------------------------------------------------------- */ -hid_t -H5FD_ros3_init(void) +herr_t +H5FD__ros3_register(void) { - hid_t ret_value = H5I_INVALID_HID; - - FUNC_ENTER_NOAPI(H5I_INVALID_HID) - - if (H5I_VFL != H5I_get_type(H5FD_ROS3_g)) { - H5FD_ROS3_g = H5FD_register(&H5FD_ros3_g, sizeof(H5FD_class_t), false); - if (H5I_INVALID_HID == H5FD_ROS3_g) { - HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register ros3"); - } + herr_t ret_value = SUCCEED; /* Return value */ -#ifdef ROS3_STATS - /* Pre-compute stats bin boundaries on powers of 2 >= 10 */ - for (int i = 0; i < ROS3_STATS_BIN_COUNT; i++) - ros3_stats_boundaries_g[i] = 1 << (10 + i); -#endif - } + FUNC_ENTER_PACKAGE - ret_value = H5FD_ROS3_g; + if (H5I_VFL != H5I_get_type(H5FD_ROS3_id_g)) + if ((H5FD_ROS3_id_g = H5FD_register(&H5FD_ros3_g, sizeof(H5FD_class_t), false)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register ros3 driver"); done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FD_ros3_init() */ +} /* end H5FD__ros3_register() */ /*--------------------------------------------------------------------------- - * Function: H5FD__ros3_term + * Function: H5FD__ros3_unregister * - * Purpose: Shut down the VFD + * Purpose: Reset library driver info. * * Returns: SUCCEED (Can't fail) + * *--------------------------------------------------------------------------- */ -static herr_t -H5FD__ros3_term(void) +herr_t +H5FD__ros3_unregister(void) { FUNC_ENTER_PACKAGE_NOERR /* Reset VFL ID */ - H5FD_ROS3_g = 0; + H5FD_ROS3_id_g = H5I_INVALID_HID; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5FD__ros3_unregister() */ + +/*------------------------------------------------------------------------- + * Function: H5FD__ros3_init + * + * Purpose: Singleton to initialize global driver settings & resources. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__ros3_init(void) +{ + FUNC_ENTER_PACKAGE_NOERR + +#ifdef ROS3_STATS + /* Pre-compute stats bin boundaries on powers of 2 >= 10 */ + for (int i = 0; i < ROS3_STATS_BIN_COUNT; i++) + ros3_stats_boundaries_g[i] = 1 << (10 + i); +#endif + + /* Indicate that driver is set up */ + H5FD_ros3_init_s = true; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5FD__ros3_term() */ +} /* end H5FD__ros3_init() */ /*------------------------------------------------------------------------- * Function: H5Pset_fapl_ros3 @@ -715,6 +732,11 @@ H5FD__ros3_open(const char *url, unsigned flags, hid_t fapl_id, haddr_t maxaddr) if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list"); + /* Initialize driver, if it's not yet */ + if (!H5FD_ros3_init_s) + if (H5FD__ros3_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "can't initialize driver"); + /* Init curl */ if (CURLE_OK != curl_global_init(CURL_GLOBAL_DEFAULT)) HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "unable to initialize curl global (placeholder flags)"); diff --git a/src/H5FDros3.h b/src/H5FDros3.h index 896d2e89f5d..8117ad8a1e5 100644 --- a/src/H5FDros3.h +++ b/src/H5FDros3.h @@ -16,12 +16,17 @@ #ifndef H5FDros3_H #define H5FDros3_H +/* Public header files */ +#include "H5FDpublic.h" /* File drivers */ + #ifdef H5_HAVE_ROS3_VFD -/** Initializer for the ros3 VFD */ -#define H5FD_ROS3 (H5FDperform_init(H5FD_ros3_init)) + +/** ID for the ros3 VFD */ +#define H5FD_ROS3 (H5OPEN H5FD_ROS3_id_g) /** Identifier for the ros3 VFD */ #define H5FD_ROS3_VALUE H5_VFD_ROS3 + #else /** Initializer for the ros3 VFD (disabled) */ #define H5FD_ROS3 (H5I_INVALID_HID) @@ -32,48 +37,6 @@ #ifdef H5_HAVE_ROS3_VFD -/**************************************************************************** - * - * Structure: H5FD_ros3_fapl_t - * - * Purpose: - * - * H5FD_ros3_fapl_t is a public structure that is used to pass S3 - * authentication data to the appropriate S3 VFD via the FAPL. A pointer - * to an instance of this structure is a parameter to H5Pset_fapl_ros3() - * and H5Pget_fapl_ros3(). - * - * - * - * `version` (int32_t) - * - * Version number of the H5FD_ros3_fapl_t structure. Any instance passed - * to the above calls must have a recognized version number, or an error - * will be flagged. - * - * This field should be set to H5FD_CURR_ROS3_FAPL_T_VERSION. - * - * `authenticate` (hbool_t) - * - * Flag true or false whether or not requests are to be authenticated - * with the AWS4 algorithm. - * If true, `aws_region`, `secret_id`, and `secret_key` must be populated. - * If false, those three components are unused. - * - * `aws_region` (char[]) - * - * String: name of the AWS "region" of the host, e.g. "us-east-1". - * - * `secret_id` (char[]) - * - * String: "Access ID" for the resource. - * - * `secret_key` (char[]) - * - * String: "Secret Access Key" associated with the ID and resource. - * - ****************************************************************************/ - /** * \def H5FD_CURR_ROS3_FAPL_T_VERSION * The version number of the H5FD_ros3_fapl_t configuration @@ -120,9 +83,11 @@ * \var hbool_t H5FD_ros3_fapl_t::authenticate * A Boolean which specifies if security credentials should be used for * accessing a S3 bucket. + * If true, `aws_region`, `secret_id`, and `secret_key` must be populated. + * If false, those three components are unused. * * \var char H5FD_ros3_fapl_t::aws_region[H5FD_ROS3_MAX_REGION_LEN + 1] - * A string which specifies the AWS region of the S3 bucket. + * A string which specifies the AWS region of the S3 bucket, e.g. "us-east-1". * * \var char H5FD_ros3_fapl_t::secret_id[H5FD_ROS3_MAX_SECRET_ID_LEN + 1] * A string which specifies the security ID. @@ -145,9 +110,9 @@ extern "C" { /** @private * - * \brief Private initializer for the ros3 VFD + * \brief ID for the ros3 VFD */ -H5_DLL hid_t H5FD_ros3_init(void); +H5_DLLVAR hid_t H5FD_ROS3_id_g; /** * \ingroup FAPL diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c index 3f3e93cb978..fa9c8849803 100644 --- a/src/H5FDsec2.c +++ b/src/H5FDsec2.c @@ -19,22 +19,19 @@ * application to the same file). */ -#include "H5FDdrvr_module.h" /* This source code file is part of the H5FD driver module */ +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ +#include "H5FDpkg.h" /* File drivers */ #include "H5FDsec2.h" /* Sec2 file driver */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5Pprivate.h" /* Property lists */ /* The driver identification number, initialized at runtime */ -static hid_t H5FD_SEC2_g = 0; - -/* Whether to ignore file locks when disabled (env var value) */ -static htri_t ignore_disabled_file_locks_s = FAIL; +hid_t H5FD_SEC2_id_g = H5I_INVALID_HID; /* The description of a file belonging to this driver. The 'eoa' and 'eof' * determine the amount of hdf5 address space in use and the high-water mark @@ -119,7 +116,6 @@ typedef struct H5FD_sec2_t { (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || HADDR_UNDEF == (A) + (Z) || (HDoff_t)((A) + (Z)) < (HDoff_t)(A)) /* Prototypes */ -static herr_t H5FD__sec2_term(void); static H5FD_t *H5FD__sec2_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr); static herr_t H5FD__sec2_close(H5FD_t *_file); static int H5FD__sec2_cmp(const H5FD_t *_f1, const H5FD_t *_f2); @@ -145,7 +141,7 @@ static const H5FD_class_t H5FD_sec2_g = { "sec2", /* name */ MAXADDR, /* maxaddr */ H5F_CLOSE_WEAK, /* fc_degree */ - H5FD__sec2_term, /* terminate */ + NULL, /* terminate */ NULL, /* sb_size */ NULL, /* sb_encode */ NULL, /* sb_decode */ @@ -186,61 +182,48 @@ static const H5FD_class_t H5FD_sec2_g = { H5FL_DEFINE_STATIC(H5FD_sec2_t); /*------------------------------------------------------------------------- - * Function: H5FD_sec2_init + * Function: H5FD__sec2_register * - * Purpose: Initialize this driver by registering the driver with the - * library. + * Purpose: Register the driver with the library. * - * Return: Success: The driver ID for the sec2 driver - * Failure: H5I_INVALID_HID + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ -hid_t -H5FD_sec2_init(void) +herr_t +H5FD__sec2_register(void) { - char *lock_env_var = NULL; /* Environment variable pointer */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ - - FUNC_ENTER_NOAPI_NOERR - - /* Check the use disabled file locks environment variable */ - lock_env_var = getenv(HDF5_USE_FILE_LOCKING); - if (lock_env_var && !strcmp(lock_env_var, "BEST_EFFORT")) - ignore_disabled_file_locks_s = true; /* Override: Ignore disabled locks */ - else if (lock_env_var && (!strcmp(lock_env_var, "TRUE") || !strcmp(lock_env_var, "1"))) - ignore_disabled_file_locks_s = false; /* Override: Don't ignore disabled locks */ - else - ignore_disabled_file_locks_s = FAIL; /* Environment variable not set, or not set correctly */ + herr_t ret_value = SUCCEED; /* Return value */ - if (H5I_VFL != H5I_get_type(H5FD_SEC2_g)) - H5FD_SEC2_g = H5FD_register(&H5FD_sec2_g, sizeof(H5FD_class_t), false); + FUNC_ENTER_PACKAGE - /* Set return value */ - ret_value = H5FD_SEC2_g; + if (H5I_VFL != H5I_get_type(H5FD_SEC2_id_g)) + if ((H5FD_SEC2_id_g = H5FD_register(&H5FD_sec2_g, sizeof(H5FD_class_t), false)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register sec2 driver"); +done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FD_sec2_init() */ +} /* end H5FD__sec2_register() */ /*--------------------------------------------------------------------------- - * Function: H5FD__sec2_term + * Function: H5FD__sec2_unregister * - * Purpose: Shut down the VFD + * Purpose: Reset library driver info. * * Returns: SUCCEED (Can't fail) * *--------------------------------------------------------------------------- */ -static herr_t -H5FD__sec2_term(void) +herr_t +H5FD__sec2_unregister(void) { FUNC_ENTER_PACKAGE_NOERR /* Reset VFL ID */ - H5FD_SEC2_g = 0; + H5FD_SEC2_id_g = H5I_INVALID_HID; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5FD__sec2_term() */ +} /* end H5FD__sec2_unregister() */ /*------------------------------------------------------------------------- * Function: H5Pset_fapl_sec2 @@ -361,9 +344,9 @@ H5FD__sec2_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, NULL, "not a file access property list"); /* Check the file locking flags in the fapl */ - if (ignore_disabled_file_locks_s != FAIL) + if (H5FD_ignore_disabled_file_locks_p != FAIL) /* The environment variable was set, so use that preferentially */ - file->ignore_disabled_file_locks = ignore_disabled_file_locks_s; + file->ignore_disabled_file_locks = H5FD_ignore_disabled_file_locks_p; else { /* Use the value in the property list */ if (H5P_get(plist, H5F_ACS_IGNORE_DISABLED_FILE_LOCKS_NAME, &file->ignore_disabled_file_locks) < 0) diff --git a/src/H5FDsec2.h b/src/H5FDsec2.h index b02e5a90c80..d748fc92ece 100644 --- a/src/H5FDsec2.h +++ b/src/H5FDsec2.h @@ -17,8 +17,11 @@ #ifndef H5FDsec2_H #define H5FDsec2_H -/** Initializer for the sec2 VFD */ -#define H5FD_SEC2 (H5FDperform_init(H5FD_sec2_init)) +/* Public header files */ +#include "H5FDpublic.h" /* File drivers */ + +/** ID for the sec2 VFD */ +#define H5FD_SEC2 (H5OPEN H5FD_SEC2_id_g) /** Identifier for the sec2 VFD */ #define H5FD_SEC2_VALUE H5_VFD_SEC2 @@ -29,9 +32,9 @@ extern "C" { /** @private * - * \brief Private initializer for the sec2 VFD + * \brief ID for the sec2 VFD */ -H5_DLL hid_t H5FD_sec2_init(void); +H5_DLLVAR hid_t H5FD_SEC2_id_g; /** * \ingroup FAPL diff --git a/src/H5FDsplitter.c b/src/H5FDsplitter.c index 325d8561956..cee2163fe5b 100644 --- a/src/H5FDsplitter.c +++ b/src/H5FDsplitter.c @@ -16,13 +16,12 @@ * another underlying VFD. Maintains two files simultaneously. */ -/* This source code file is part of the H5FD driver module */ -#include "H5FDdrvr_module.h" +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ +#include "H5FDpkg.h" /* File drivers */ #include "H5FDsplitter.h" /* Splitter file driver */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ @@ -30,7 +29,7 @@ #include "H5Pprivate.h" /* Property lists */ /* The driver identification number, initialized at runtime */ -static hid_t H5FD_SPLITTER_g = 0; +hid_t H5FD_SPLITTER_id_g = H5I_INVALID_HID; /* Driver-specific file access properties */ typedef struct H5FD_splitter_fapl_t { @@ -103,7 +102,6 @@ static herr_t H5FD__splitter_log_error(const H5FD_splitter_t *file, const char * static int H5FD__copy_plist(hid_t fapl_id, hid_t *id_out_ptr); /* Prototypes */ -static herr_t H5FD__splitter_term(void); static herr_t H5FD__splitter_populate_config(H5FD_splitter_vfd_config_t *vfd_config, H5FD_splitter_fapl_t *fapl_out); static herr_t H5FD__splitter_get_default_wo_path(char *new_path, size_t new_path_len, @@ -143,7 +141,7 @@ static const H5FD_class_t H5FD_splitter_g = { "splitter", /* name */ MAXADDR, /* maxaddr */ H5F_CLOSE_WEAK, /* fc_degree */ - H5FD__splitter_term, /* terminate */ + NULL, /* terminate */ H5FD__splitter_sb_size, /* sb_size */ H5FD__splitter_sb_encode, /* sb_encode */ H5FD__splitter_sb_decode, /* sb_decode */ @@ -187,52 +185,52 @@ H5FL_DEFINE_STATIC(H5FD_splitter_t); H5FL_DEFINE_STATIC(H5FD_splitter_fapl_t); /*------------------------------------------------------------------------- - * Function: H5FD_splitter_init + * Function: H5FD__splitter_register * - * Purpose: Initialize the splitter driver by registering it with the - * library. + * Purpose: Register the driver with the library. + * + * Return: SUCCEED/FAIL * - * Return: Success: The driver ID for the splitter driver. - * Failure: Negative *------------------------------------------------------------------------- */ -hid_t -H5FD_splitter_init(void) +herr_t +H5FD__splitter_register(void) { - hid_t ret_value = H5I_INVALID_HID; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_PACKAGE H5FD_SPLITTER_LOG_CALL(__func__); - if (H5I_VFL != H5I_get_type(H5FD_SPLITTER_g)) - H5FD_SPLITTER_g = H5FDregister(&H5FD_splitter_g); - - ret_value = H5FD_SPLITTER_g; + if (H5I_VFL != H5I_get_type(H5FD_SPLITTER_id_g)) + if ((H5FD_SPLITTER_id_g = H5FD_register(&H5FD_splitter_g, sizeof(H5FD_class_t), false)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register splitter driver"); +done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FD_splitter_init() */ +} /* end H5FD__splitter_register() */ /*--------------------------------------------------------------------------- - * Function: H5FD__splitter_term + * Function: H5FD__splitter_unregister * - * Purpose: Shut down the splitter VFD. + * Purpose: Reset library driver info. * * Returns: SUCCEED (Can't fail) + * *--------------------------------------------------------------------------- */ -static herr_t -H5FD__splitter_term(void) +herr_t +H5FD__splitter_unregister(void) { FUNC_ENTER_PACKAGE_NOERR H5FD_SPLITTER_LOG_CALL(__func__); /* Reset VFL ID */ - H5FD_SPLITTER_g = 0; + H5FD_SPLITTER_id_g = H5I_INVALID_HID; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5FD__splitter_term() */ +} /* end H5FD__splitter_unregister() */ /*------------------------------------------------------------------------- * Function: H5FD__copy_plist diff --git a/src/H5FDsplitter.h b/src/H5FDsplitter.h index ca91f433176..66e3ebaf38f 100644 --- a/src/H5FDsplitter.h +++ b/src/H5FDsplitter.h @@ -17,8 +17,11 @@ #ifndef H5FDsplitter_H #define H5FDsplitter_H -/** Initializer for the splitter VFD */ -#define H5FD_SPLITTER (H5FDperform_init(H5FD_splitter_init)) +/* Public header files */ +#include "H5FDpublic.h" /* File drivers */ + +/** ID for the splitter VFD */ +#define H5FD_SPLITTER (H5OPEN H5FD_SPLITTER_id_g) /** Identifier for the splitter VFD */ #define H5FD_SPLITTER_VALUE H5_VFD_SPLITTER @@ -61,9 +64,9 @@ extern "C" { /** @private * - * \brief Private initializer for the splitter VFD + * \brief ID for the splitter VFD */ -H5_DLL hid_t H5FD_splitter_init(void); +H5_DLLVAR hid_t H5FD_SPLITTER_id_g; /** * \ingroup FAPL diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c index 7c5cf6e2bf9..942d90c7352 100644 --- a/src/H5FDstdio.c +++ b/src/H5FDstdio.c @@ -47,8 +47,10 @@ #endif /* H5_HAVE_WIN32_API */ -/* The driver identification number, initialized at runtime */ -static hid_t H5FD_STDIO_g = 0; +/* Flag to indicate whether global driver resources & settings have been + * initialized. + */ +static bool H5FD_stdio_init_s = false; /* Whether to ignore file locks when disabled (env var value) */ static htri_t ignore_disabled_file_locks_s = -1; @@ -160,7 +162,6 @@ typedef struct H5FD_stdio_t { (file_offset_t)((A) + (Z)) < (file_offset_t)(A)) /* Prototypes */ -static herr_t H5FD_stdio_term(void); static H5FD_t *H5FD_stdio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr); static herr_t H5FD_stdio_close(H5FD_t *lf); static int H5FD_stdio_cmp(const H5FD_t *_f1, const H5FD_t *_f2); @@ -180,13 +181,13 @@ static herr_t H5FD_stdio_lock(H5FD_t *_file, bool rw); static herr_t H5FD_stdio_unlock(H5FD_t *_file); static herr_t H5FD_stdio_delete(const char *filename, hid_t fapl_id); -static const H5FD_class_t H5FD_stdio_g = { +const H5FD_class_t H5FD_stdio_g = { H5FD_CLASS_VERSION, /* struct version */ H5_VFD_STDIO, /* value */ "stdio", /* name */ MAXADDR, /* maxaddr */ H5F_CLOSE_WEAK, /* fc_degree */ - H5FD_stdio_term, /* terminate */ + NULL, /* terminate */ NULL, /* sb_size */ NULL, /* sb_encode */ NULL, /* sb_decode */ @@ -224,25 +225,19 @@ static const H5FD_class_t H5FD_stdio_g = { }; /*------------------------------------------------------------------------- - * Function: H5FD_stdio_init - * - * Purpose: Initialize this driver by registering the driver with the - * library. + * Function: H5FD__stdio_init * - * Return: Success: The driver ID for the stdio driver. + * Purpose: Singleton to initialize global driver settings & resources. * - * Failure: Negative. + * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ -hid_t -H5FD_stdio_init(void) +static herr_t +H5FD__stdio_init(void) { char *lock_env_var = NULL; /* Environment variable pointer */ - /* Clear the error stack */ - H5Eclear2(H5E_DEFAULT); - /* Check the use disabled file locks environment variable */ lock_env_var = getenv(HDF5_USE_FILE_LOCKING); if (lock_env_var && !strcmp(lock_env_var, "BEST_EFFORT")) @@ -252,29 +247,11 @@ H5FD_stdio_init(void) else ignore_disabled_file_locks_s = -1; /* Environment variable not set, or not set correctly */ - if (H5I_VFL != H5Iget_type(H5FD_STDIO_g)) - H5FD_STDIO_g = H5FDregister(&H5FD_stdio_g); - - return H5FD_STDIO_g; -} /* end H5FD_stdio_init() */ - -/*--------------------------------------------------------------------------- - * Function: H5FD_stdio_term - * - * Purpose: Shut down the VFD - * - * Returns: Non-negative on success or negative on failure - * - *--------------------------------------------------------------------------- - */ -static herr_t -H5FD_stdio_term(void) -{ - /* Reset VFL ID */ - H5FD_STDIO_g = 0; + /* Indicate that driver is set up */ + H5FD_stdio_init_s = true; return 0; -} /* end H5FD_stdio_term() */ +} /* end H5FD__stdio_init() */ /*------------------------------------------------------------------------- * Function: H5Pset_fapl_stdio @@ -290,13 +267,12 @@ H5FD_stdio_term(void) herr_t H5Pset_fapl_stdio(hid_t fapl_id) { - static const char *func = "H5FDset_fapl_stdio"; /*for error reporting*/ /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); if (0 == H5Pisa_class(fapl_id, H5P_FILE_ACCESS)) - H5Epush_ret(func, H5E_ERR_CLS, H5E_PLIST, H5E_BADTYPE, "not a file access property list", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_PLIST, H5E_BADTYPE, "not a file access property list", -1); return H5Pset_driver(fapl_id, H5FD_STDIO, NULL); } /* end H5Pset_fapl_stdio() */ @@ -325,10 +301,9 @@ H5Pset_fapl_stdio(hid_t fapl_id) static H5FD_t * H5FD_stdio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { - FILE *f = NULL; - unsigned write_access = 0; /* File opened with write access? */ - H5FD_stdio_t *file = NULL; - static const char *func = "H5FD_stdio_open"; /* Function Name for error reporting */ + FILE *f = NULL; + unsigned write_access = 0; /* File opened with write access? */ + H5FD_stdio_t *file = NULL; #ifdef H5_HAVE_WIN32_API struct _BY_HANDLE_FILE_INFORMATION fileinfo; #else /* H5_HAVE_WIN32_API */ @@ -344,13 +319,18 @@ H5FD_stdio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); + /* Initialize driver, if it's not yet */ + if (!H5FD_stdio_init_s) + if (H5FD__stdio_init() < 0) + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_VFL, H5E_CANTINIT, "can't initialize driver", NULL); + /* Check arguments */ if (!name || !*name) - H5Epush_ret(func, H5E_ERR_CLS, H5E_ARGS, H5E_BADVALUE, "invalid file name", NULL); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_ARGS, H5E_BADVALUE, "invalid file name", NULL); if (0 == maxaddr || HADDR_UNDEF == maxaddr) - H5Epush_ret(func, H5E_ERR_CLS, H5E_ARGS, H5E_BADRANGE, "bogus maxaddr", NULL); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_ARGS, H5E_BADRANGE, "bogus maxaddr", NULL); if (ADDR_OVERFLOW(maxaddr)) - H5Epush_ret(func, H5E_ERR_CLS, H5E_ARGS, H5E_OVERFLOW, "maxaddr too large", NULL); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_ARGS, H5E_OVERFLOW, "maxaddr too large", NULL); /* Tentatively open file in read-only mode, to check for existence */ if (flags & H5F_ACC_RDWR) @@ -366,14 +346,14 @@ H5FD_stdio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr write_access = 1; /* Note the write access */ } else - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_CANTOPENFILE, + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_CANTOPENFILE, "file doesn't exist and CREAT wasn't specified", NULL); } else if (flags & H5F_ACC_EXCL) { /* File exists, but EXCL is passed. Fail. */ assert(flags & H5F_ACC_CREAT); fclose(f); - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_FILEEXISTS, + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_FILEEXISTS, "file exists but CREAT and EXCL were specified", NULL); } else if (flags & H5F_ACC_RDWR) { @@ -385,12 +365,12 @@ H5FD_stdio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr * as the tentative open will work */ if (!f) - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_CANTOPENFILE, "fopen failed", NULL); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_CANTOPENFILE, "fopen failed", NULL); /* Build the return value */ if (NULL == (file = (H5FD_stdio_t *)calloc((size_t)1, sizeof(H5FD_stdio_t)))) { fclose(f); - H5Epush_ret(func, H5E_ERR_CLS, H5E_RESOURCE, H5E_NOSPACE, "memory allocation failed", NULL); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_RESOURCE, H5E_NOSPACE, "memory allocation failed", NULL); } /* end if */ file->fp = f; file->op = H5FD_STDIO_OP_SEEK; @@ -416,7 +396,7 @@ H5FD_stdio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr if (H5Pget_file_locking(fapl_id, &unused, &file->ignore_disabled_file_locks) < 0) { free(file); fclose(f); - H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTGET, + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_FILE, H5E_CANTGET, "unable to get use disabled file locks property", NULL); } } @@ -430,7 +410,7 @@ H5FD_stdio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr if (file->fd < 0) { free(file); fclose(f); - H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTOPENFILE, "unable to get file descriptor", NULL); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_FILE, H5E_CANTOPENFILE, "unable to get file descriptor", NULL); } /* end if */ #ifdef H5_HAVE_WIN32_API @@ -438,13 +418,14 @@ H5FD_stdio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr if (INVALID_HANDLE_VALUE == file->hFile) { free(file); fclose(f); - H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTOPENFILE, "unable to get Windows file handle", NULL); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_FILE, H5E_CANTOPENFILE, "unable to get Windows file handle", + NULL); } /* end if */ if (!GetFileInformationByHandle((HANDLE)file->hFile, &fileinfo)) { free(file); fclose(f); - H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTOPENFILE, + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_FILE, H5E_CANTOPENFILE, "unable to get Windows file descriptor information", NULL); } /* end if */ @@ -455,7 +436,7 @@ H5FD_stdio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr if (fstat(file->fd, &sb) < 0) { free(file); fclose(f); - H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_BADFILE, "unable to fstat file", NULL); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_FILE, H5E_BADFILE, "unable to fstat file", NULL); } /* end if */ file->device = sb.st_dev; file->inode = sb.st_ino; @@ -479,14 +460,13 @@ H5FD_stdio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr static herr_t H5FD_stdio_close(H5FD_t *_file) { - H5FD_stdio_t *file = (H5FD_stdio_t *)_file; - static const char *func = "H5FD_stdio_close"; /* Function Name for error reporting */ + H5FD_stdio_t *file = (H5FD_stdio_t *)_file; /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); if (fclose(file->fp) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_CLOSEERROR, "fclose failed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_CLOSEERROR, "fclose failed", -1); free(file); @@ -727,8 +707,7 @@ H5FD_stdio_get_eof(const H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type) static herr_t H5FD_stdio_get_handle(H5FD_t *_file, hid_t /*UNUSED*/ fapl, void **file_handle) { - H5FD_stdio_t *file = (H5FD_stdio_t *)_file; - static const char *func = "H5FD_stdio_get_handle"; /* Function Name for error reporting */ + H5FD_stdio_t *file = (H5FD_stdio_t *)_file; /* Quiet the compiler */ (void)fapl; @@ -738,7 +717,7 @@ H5FD_stdio_get_handle(H5FD_t *_file, hid_t /*UNUSED*/ fapl, void **file_handle) *file_handle = &(file->fp); if (*file_handle == NULL) - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "get handle failed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "get handle failed", -1); return 0; } /* end H5FD_stdio_get_handle() */ @@ -762,8 +741,7 @@ static herr_t H5FD_stdio_read(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxpl_id, haddr_t addr, size_t size, void /*OUT*/ *buf) { - H5FD_stdio_t *file = (H5FD_stdio_t *)_file; - static const char *func = "H5FD_stdio_read"; /* Function Name for error reporting */ + H5FD_stdio_t *file = (H5FD_stdio_t *)_file; /* Quiet the compiler */ (void)type; @@ -774,9 +752,9 @@ H5FD_stdio_read(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxpl /* Check for overflow */ if (HADDR_UNDEF == addr) - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_OVERFLOW, "file address overflowed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_OVERFLOW, "file address overflowed", -1); if (REGION_OVERFLOW(addr, size)) - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_OVERFLOW, "file address overflowed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_OVERFLOW, "file address overflowed", -1); /* Check easy cases */ if (0 == size) @@ -791,7 +769,7 @@ H5FD_stdio_read(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxpl if (file_fseek(file->fp, (file_offset_t)addr, SEEK_SET) < 0) { file->op = H5FD_STDIO_OP_UNKNOWN; file->pos = HADDR_UNDEF; - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "fseek failed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "fseek failed", -1); } file->pos = addr; } @@ -823,7 +801,7 @@ H5FD_stdio_read(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxpl if (0 == bytes_read && ferror(file->fp)) { /* error */ file->op = H5FD_STDIO_OP_UNKNOWN; file->pos = HADDR_UNDEF; - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_READERROR, "fread failed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_READERROR, "fread failed", -1); } /* end if */ if (0 == bytes_read && feof(file->fp)) { @@ -862,8 +840,7 @@ static herr_t H5FD_stdio_write(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxpl_id, haddr_t addr, size_t size, const void *buf) { - H5FD_stdio_t *file = (H5FD_stdio_t *)_file; - static const char *func = "H5FD_stdio_write"; /* Function Name for error reporting */ + H5FD_stdio_t *file = (H5FD_stdio_t *)_file; /* Quiet the compiler */ (void)dxpl_id; @@ -874,16 +851,16 @@ H5FD_stdio_write(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxp /* Check for overflow conditions */ if (HADDR_UNDEF == addr) - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_OVERFLOW, "file address overflowed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_OVERFLOW, "file address overflowed", -1); if (REGION_OVERFLOW(addr, size)) - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_OVERFLOW, "file address overflowed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_OVERFLOW, "file address overflowed", -1); /* Seek to the correct file position. */ if ((file->op != H5FD_STDIO_OP_WRITE && file->op != H5FD_STDIO_OP_SEEK) || file->pos != addr) { if (file_fseek(file->fp, (file_offset_t)addr, SEEK_SET) < 0) { file->op = H5FD_STDIO_OP_UNKNOWN; file->pos = HADDR_UNDEF; - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "fseek failed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "fseek failed", -1); } file->pos = addr; } @@ -908,7 +885,7 @@ H5FD_stdio_write(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxp if (bytes_wrote != bytes_in || (0 == bytes_wrote && ferror(file->fp))) { /* error */ file->op = H5FD_STDIO_OP_UNKNOWN; file->pos = HADDR_UNDEF; - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "fwrite failed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "fwrite failed", -1); } /* end if */ assert(bytes_wrote > 0); @@ -946,8 +923,7 @@ H5FD_stdio_write(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxp static herr_t H5FD_stdio_flush(H5FD_t *_file, hid_t /*UNUSED*/ dxpl_id, bool closing) { - H5FD_stdio_t *file = (H5FD_stdio_t *)_file; - static const char *func = "H5FD_stdio_flush"; /* Function Name for error reporting */ + H5FD_stdio_t *file = (H5FD_stdio_t *)_file; /* Quiet the compiler */ (void)dxpl_id; @@ -959,7 +935,7 @@ H5FD_stdio_flush(H5FD_t *_file, hid_t /*UNUSED*/ dxpl_id, bool closing) if (file->write_access) { if (!closing) { if (fflush(file->fp) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "fflush failed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "fflush failed", -1); /* Reset last file I/O information */ file->pos = HADDR_UNDEF; @@ -987,8 +963,7 @@ H5FD_stdio_flush(H5FD_t *_file, hid_t /*UNUSED*/ dxpl_id, bool closing) static herr_t H5FD_stdio_truncate(H5FD_t *_file, hid_t /*UNUSED*/ dxpl_id, bool /*UNUSED*/ closing) { - H5FD_stdio_t *file = (H5FD_stdio_t *)_file; - static const char *func = "H5FD_stdio_truncate"; /* Function Name for error reporting */ + H5FD_stdio_t *file = (H5FD_stdio_t *)_file; /* Quiet the compiler */ (void)dxpl_id; @@ -1025,12 +1000,13 @@ H5FD_stdio_truncate(H5FD_t *_file, hid_t /*UNUSED*/ dxpl_id, bool /*UNUSED*/ clo if (INVALID_SET_FILE_POINTER == dwPtrLow) { dwError = GetLastError(); if (dwError != NO_ERROR) - H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_FILEOPEN, "unable to set file pointer", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_FILE, H5E_FILEOPEN, "unable to set file pointer", + -1); } bError = SetEndOfFile(file->hFile); if (0 == bError) - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "unable to truncate/extend file properly", -1); #else /* H5_HAVE_WIN32_API */ /* Reset seek offset to beginning of file, so that file isn't re-extended later */ @@ -1038,7 +1014,7 @@ H5FD_stdio_truncate(H5FD_t *_file, hid_t /*UNUSED*/ dxpl_id, bool /*UNUSED*/ clo /* Truncate file to proper length */ if (-1 == file_ftruncate(file->fd, (file_offset_t)file->eoa)) - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "unable to truncate/extend file properly", -1); #endif /* H5_HAVE_WIN32_API */ @@ -1053,7 +1029,7 @@ H5FD_stdio_truncate(H5FD_t *_file, hid_t /*UNUSED*/ dxpl_id, bool /*UNUSED*/ clo else { /* Double-check for problems */ if (file->eoa > file->eof) - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_TRUNCATED, "eoa > eof!", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_TRUNCATED, "eoa > eof!", -1); } /* end else */ return 0; @@ -1076,9 +1052,8 @@ static herr_t H5FD_stdio_lock(H5FD_t *_file, bool rw) { #ifdef H5_HAVE_FLOCK - H5FD_stdio_t *file = (H5FD_stdio_t *)_file; /* VFD file struct */ - int lock_flags; /* file locking flags */ - static const char *func = "H5FD_stdio_lock"; /* Function Name for error reporting */ + H5FD_stdio_t *file = (H5FD_stdio_t *)_file; /* VFD file struct */ + int lock_flags; /* file locking flags */ /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -1096,12 +1071,12 @@ H5FD_stdio_lock(H5FD_t *_file, bool rw) */ errno = 0; else - H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_CANTLOCKFILE, "file lock failed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_VFL, H5E_CANTLOCKFILE, "file lock failed", -1); } /* end if */ /* Flush the stream */ if (fflush(file->fp) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "fflush failed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "fflush failed", -1); #endif /* H5_HAVE_FLOCK */ @@ -1125,8 +1100,7 @@ static herr_t H5FD_stdio_unlock(H5FD_t *_file) { #ifdef H5_HAVE_FLOCK - H5FD_stdio_t *file = (H5FD_stdio_t *)_file; /* VFD file struct */ - static const char *func = "H5FD_stdio_unlock"; /* Function Name for error reporting */ + H5FD_stdio_t *file = (H5FD_stdio_t *)_file; /* VFD file struct */ /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); @@ -1135,7 +1109,7 @@ H5FD_stdio_unlock(H5FD_t *_file) /* Flush the stream */ if (fflush(file->fp) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "fflush failed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "fflush failed", -1); /* Place a non-blocking lock on the file */ if (flock(file->fd, LOCK_UN) < 0) { @@ -1145,7 +1119,7 @@ H5FD_stdio_unlock(H5FD_t *_file) */ errno = 0; else - H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_CANTUNLOCKFILE, "file unlock failed", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_VFL, H5E_CANTUNLOCKFILE, "file unlock failed", -1); } /* end if */ #endif /* H5_HAVE_FLOCK */ @@ -1165,18 +1139,22 @@ H5FD_stdio_unlock(H5FD_t *_file) static herr_t H5FD_stdio_delete(const char *filename, hid_t /*UNUSED*/ fapl_id) { - static const char *func = "H5FD_stdio_delete"; /* Function Name for error reporting */ - - /* Clear the error stack */ - H5Eclear2(H5E_DEFAULT); assert(filename); /* Quiet compiler */ (void)fapl_id; + /* Clear the error stack */ + H5Eclear2(H5E_DEFAULT); + + /* Initialize driver, if it's not yet */ + if (!H5FD_stdio_init_s) + if (H5FD__stdio_init() < 0) + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_VFL, H5E_CANTINIT, "can't initialize driver", -1); + if (remove(filename) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_CANTDELETEFILE, "can't delete file)", -1); + H5Epush_ret(__func__, H5E_ERR_CLS, H5E_VFL, H5E_CANTDELETEFILE, "can't delete file)", -1); return 0; } /* end H5FD_stdio_delete() */ diff --git a/src/H5FDstdio.h b/src/H5FDstdio.h index 7d51ec73f08..087a2e5cbe3 100644 --- a/src/H5FDstdio.h +++ b/src/H5FDstdio.h @@ -16,10 +16,11 @@ #ifndef H5FDstdio_H #define H5FDstdio_H -#include "H5Ipublic.h" +/* Public header files */ +#include "H5FDpublic.h" /* File drivers */ -/** Initializer for the stdio VFD */ -#define H5FD_STDIO (H5FDperform_init(H5FD_stdio_init)) +/** ID for the stdio VFD */ +#define H5FD_STDIO (H5OPEN H5FD_STDIO_id_g) #ifdef __cplusplus extern "C" { @@ -27,9 +28,9 @@ extern "C" { /** @private * - * \brief Private initializer for the stdio VFD + * \brief ID for the stdio VFD */ -H5_DLL hid_t H5FD_stdio_init(void); +H5_DLLVAR hid_t H5FD_STDIO_id_g; /** * \ingroup FAPL diff --git a/src/H5FDstdio_int.c b/src/H5FDstdio_int.c new file mode 100644 index 00000000000..1f8cb63324c --- /dev/null +++ b/src/H5FDstdio_int.c @@ -0,0 +1,83 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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 COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: Private routines for the stdio VFD. + * + * Necessary for using internal library routines, which are + * disallowed within the actual stdio VFD code. + * + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5FD_FRIEND /* Suppress error about including H5FDpkg */ + +/***********/ +/* Headers */ +/***********/ + +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Iprivate.h" /* IDs */ +#include "H5FDpkg.h" /* File drivers */ + +#include "H5FDstdio_private.h" /* stdio VFD */ + +/* The driver identification number, initialized at runtime */ +hid_t H5FD_STDIO_id_g = H5I_INVALID_HID; + +/*------------------------------------------------------------------------- + * Function: H5FD__stdio_register + * + * Purpose: Register the driver with the library. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD__stdio_register(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + if (H5I_VFL != H5I_get_type(H5FD_STDIO_id_g)) + if ((H5FD_STDIO_id_g = H5FD_register(&H5FD_stdio_g, sizeof(H5FD_class_t), false)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register stdio driver"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__stdio_register() */ + +/*--------------------------------------------------------------------------- + * Function: H5FD_stdio_unregister + * + * Purpose: Reset library driver info. + * + * Returns: SUCCEED (Can't fail) + * + *--------------------------------------------------------------------------- + */ +herr_t +H5FD__stdio_unregister(void) +{ + FUNC_ENTER_PACKAGE_NOERR + + /* Reset VFL ID */ + H5FD_STDIO_id_g = H5I_INVALID_HID; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5FD_stdio_unregister() */ diff --git a/src/H5FDstdio_private.h b/src/H5FDstdio_private.h new file mode 100644 index 00000000000..af65eeb8f44 --- /dev/null +++ b/src/H5FDstdio_private.h @@ -0,0 +1,45 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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 COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Purpose: The private header file for the stdio VFD + */ + +#ifndef H5FDstdio_private_H +#define H5FDstdio_private_H + +/* Include VFD's public header */ +#include "H5FDstdio.h" /* stdio VFD */ + +/* Private headers needed by this file */ +#include "H5FDprivate.h" /* File drivers */ + +/**************************/ +/* Library Private Macros */ +/**************************/ + +/****************************/ +/* Library Private Typedefs */ +/****************************/ + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + +/* stdio VFD's class struct */ +H5_DLLVAR const H5FD_class_t H5FD_stdio_g; + +/******************************/ +/* Library Private Prototypes */ +/******************************/ + +#endif /* H5FDstdio_private_H */ diff --git a/src/H5FDsubfiling/H5FDioc.c b/src/H5FDsubfiling/H5FDioc.c index 5847630255f..ae42b3b58a1 100644 --- a/src/H5FDsubfiling/H5FDioc.c +++ b/src/H5FDsubfiling/H5FDioc.c @@ -16,27 +16,29 @@ * another underlying VFD. Maintains two files simultaneously. */ -/* This source code file is part of the H5FD driver module */ -#include "H5FDdrvr_module.h" +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ #include "H5private.h" /* Generic Functions */ -#include "H5FDpublic.h" /* Basic H5FD definitions */ #include "H5Eprivate.h" /* Error handling */ -#include "H5FDprivate.h" /* File drivers */ -#include "H5FDioc.h" /* IOC file driver */ -#include "H5FDioc_priv.h" /* IOC file driver */ +#include "H5Fprivate.h" /* File access */ +#include "H5FDpkg.h" /* File drivers */ +#include "H5FDioc_priv.h" /* I/O concetrator file driver */ #include "H5FDmpio.h" /* MPI I/O VFD */ #include "H5FLprivate.h" /* Free Lists */ -#include "H5Fprivate.h" /* File access */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ /* The driver identification number, initialized at runtime */ -static hid_t H5FD_IOC_g = H5I_INVALID_HID; +hid_t H5FD_IOC_id_g = H5I_INVALID_HID; + +/* Flag to indicate whether global driver resources & settings have been + * initialized. + */ +static bool H5FD_ioc_init_s = false; /* Whether the driver initialized MPI on its own */ -static bool H5FD_mpi_self_initialized = false; +static bool H5FD_mpi_self_initialized_s = false; /* Pointer to value for MPI_TAG_UB */ int *H5FD_IOC_tag_ub_val_ptr = NULL; @@ -113,7 +115,7 @@ static herr_t H5FD__ioc_read_vector(H5FD_t *file, hid_t dxpl_id, uint32_t count static herr_t H5FD__ioc_write_vector(H5FD_t *file, hid_t dxpl_id, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], const void *bufs[] /* in */); static herr_t H5FD__ioc_truncate(H5FD_t *_file, hid_t dxpl_id, bool closing); -static herr_t H5FD__ioc_del(const char *name, hid_t fapl); +static herr_t H5FD__ioc_delete(const char *name, hid_t fapl); /* static herr_t H5FD__ioc_ctl(H5FD_t *file, uint64_t op_code, uint64_t flags, const void *input, void **result); @@ -167,7 +169,7 @@ static const H5FD_class_t H5FD_ioc_g = { H5FD__ioc_truncate, /* truncate */ NULL, /* lock */ NULL, /* unlock */ - H5FD__ioc_del, /* del */ + H5FD__ioc_delete, /* del */ NULL, /* ctl */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -179,77 +181,112 @@ H5FL_DEFINE_STATIC(H5FD_ioc_t); H5FL_DEFINE_STATIC(H5FD_ioc_config_t); /*------------------------------------------------------------------------- - * Function: H5FD_ioc_init + * Function: H5FD__ioc_register * - * Purpose: Initialize the IOC driver by registering it with the - * library. + * Purpose: Register the driver with the library. + * + * Return: SUCCEED/FAIL * - * Return: Success: The driver ID for the ioc driver. - * Failure: Negative *------------------------------------------------------------------------- */ -hid_t -H5FD_ioc_init(void) +herr_t +H5FD__ioc_register(void) { - hid_t ret_value = H5I_INVALID_HID; + herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(H5I_INVALID_HID) + FUNC_ENTER_PACKAGE /* Register the IOC VFD, if it isn't already registered */ - if (H5I_VFL != H5I_get_type(H5FD_IOC_g)) { - char *env_var; - int key_val_retrieved = 0; - int mpi_code; - - if ((H5FD_IOC_g = H5FD_register(&H5FD_ioc_g, sizeof(H5FD_class_t), false)) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register IOC VFD"); - - /* Check if IOC VFD has been loaded dynamically */ - env_var = getenv(HDF5_DRIVER); - if (env_var && strlen(env_var) > 0 && !strcmp(env_var, H5FD_IOC_NAME)) { - int mpi_initialized = 0; - int provided = 0; - - /* Initialize MPI if not already initialized */ - if (MPI_SUCCESS != (mpi_code = MPI_Initialized(&mpi_initialized))) - HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Initialized failed", mpi_code); - if (mpi_initialized) { - /* If MPI is initialized, validate that it was initialized with MPI_THREAD_MULTIPLE */ - if (MPI_SUCCESS != (mpi_code = MPI_Query_thread(&provided))) - HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Query_thread failed", mpi_code); - if (provided != MPI_THREAD_MULTIPLE) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "IOC VFD requires the use of MPI_Init_thread with MPI_THREAD_MULTIPLE"); - } - else { - int required = MPI_THREAD_MULTIPLE; - - /* Otherwise, initialize MPI */ - if (MPI_SUCCESS != (mpi_code = MPI_Init_thread(NULL, NULL, required, &provided))) - HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Init_thread failed", mpi_code); - - H5FD_mpi_self_initialized = true; - - if (provided != required) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE"); - } + if (H5I_VFL != H5I_get_type(H5FD_IOC_id_g)) + if ((H5FD_IOC_id_g = H5FD_register(&H5FD_ioc_g, sizeof(H5FD_class_t), false)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "can't register IOC VFD"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__ioc_register() */ + +/*--------------------------------------------------------------------------- + * Function: H5FD__ioc_unregister + * + * Purpose: Reset library driver info. + * + * Return: SUCCEED/FAIL + * + *--------------------------------------------------------------------------- + */ +herr_t +H5FD__ioc_unregister(void) +{ + FUNC_ENTER_PACKAGE_NOERR + + /* Reset VFL ID */ + H5FD_IOC_id_g = H5I_INVALID_HID; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5FD__ioc_unregister() */ + +/*------------------------------------------------------------------------- + * Function: H5FD__ioc_init + * + * Purpose: Singleton to initialize global driver settings & resources. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__ioc_init(void) +{ + char *env_var; + int key_val_retrieved = 0; + int mpi_code; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Check if IOC VFD has been loaded dynamically */ + env_var = getenv(HDF5_DRIVER); + if (env_var && strlen(env_var) > 0 && !strcmp(env_var, H5FD_IOC_NAME)) { + int mpi_initialized = 0; + int provided = 0; + + /* Initialize MPI if not already initialized */ + if (MPI_SUCCESS != (mpi_code = MPI_Initialized(&mpi_initialized))) + HMPI_GOTO_ERROR(FAIL, "MPI_Initialized failed", mpi_code); + if (mpi_initialized) { + /* If MPI is initialized, validate that it was initialized with MPI_THREAD_MULTIPLE */ + if (MPI_SUCCESS != (mpi_code = MPI_Query_thread(&provided))) + HMPI_GOTO_ERROR(FAIL, "MPI_Query_thread failed", mpi_code); + if (provided != MPI_THREAD_MULTIPLE) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "IOC VFD requires the use of MPI_Init_thread with MPI_THREAD_MULTIPLE"); } + else { + /* Otherwise, initialize MPI */ + if (MPI_SUCCESS != (mpi_code = MPI_Init_thread(NULL, NULL, MPI_THREAD_MULTIPLE, &provided))) + HMPI_GOTO_ERROR(FAIL, "MPI_Init_thread failed", mpi_code); - /* Retrieve upper bound for MPI message tag value */ - if (MPI_SUCCESS != (mpi_code = MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_TAG_UB, &H5FD_IOC_tag_ub_val_ptr, - &key_val_retrieved))) - HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Comm_get_attr failed", mpi_code); + H5FD_mpi_self_initialized_s = true; - if (!key_val_retrieved) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, "couldn't retrieve value for MPI_TAG_UB"); + if (provided != MPI_THREAD_MULTIPLE) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE"); + } } - ret_value = H5FD_IOC_g; + /* Retrieve upper bound for MPI message tag value */ + if (MPI_SUCCESS != (mpi_code = MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_TAG_UB, &H5FD_IOC_tag_ub_val_ptr, + &key_val_retrieved))) + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_get_attr failed", mpi_code); + if (!key_val_retrieved) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't retrieve value for MPI_TAG_UB"); + + /* Indicate that driver is set up */ + H5FD_ioc_init_s = true; done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FD_ioc_init() */ +} /* end H5FD__ioc_init() */ /*--------------------------------------------------------------------------- * Function: H5FD__ioc_term @@ -257,6 +294,7 @@ H5FD_ioc_init(void) * Purpose: Shut down the IOC VFD. * * Return: SUCCEED/FAIL + * *--------------------------------------------------------------------------- */ static herr_t @@ -266,26 +304,21 @@ H5FD__ioc_term(void) FUNC_ENTER_PACKAGE - if (H5FD_IOC_g >= 0) { - /* Terminate MPI if the driver initialized it */ - if (H5FD_mpi_self_initialized) { - int mpi_finalized = 0; - int mpi_code; + /* Terminate MPI if the driver initialized it */ + if (H5FD_mpi_self_initialized_s) { + int mpi_finalized = 0; + int mpi_code; - if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) - HMPI_GOTO_ERROR(FAIL, "MPI_Finalized failed", mpi_code); - if (!mpi_finalized) - if (MPI_SUCCESS != (mpi_code = MPI_Finalize())) - HMPI_GOTO_ERROR(FAIL, "MPI_Finalize failed", mpi_code); + if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) + HMPI_GOTO_ERROR(FAIL, "MPI_Finalized failed", mpi_code); + if (!mpi_finalized) + if (MPI_SUCCESS != (mpi_code = MPI_Finalize())) + HMPI_GOTO_ERROR(FAIL, "MPI_Finalize failed", mpi_code); - H5FD_mpi_self_initialized = false; - } + H5FD_mpi_self_initialized_s = false; } done: - /* Reset VFL ID */ - H5FD_IOC_g = H5I_INVALID_HID; - FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_term() */ @@ -310,6 +343,11 @@ H5Pset_fapl_ioc(hid_t fapl_id, H5FD_ioc_config_t *vfd_config) if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + /* Initialize driver, if it's not yet */ + if (!H5FD_ioc_init_s) + if (H5FD__ioc_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize driver"); + if (vfd_config == NULL) { /* Get IOC VFD defaults */ if (H5FD__subfiling_get_default_ioc_config(&ioc_conf) < 0) @@ -355,6 +393,11 @@ H5Pget_fapl_ioc(hid_t fapl_id, H5FD_ioc_config_t *config_out) if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + /* Initialize driver, if it's not yet */ + if (!H5FD_ioc_init_s) + if (H5FD__ioc_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize driver"); + if (H5FD_IOC != H5P_peek_driver(plist)) use_default_config = true; else { @@ -679,6 +722,11 @@ H5FD__ioc_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) if (ADDR_OVERFLOW(maxaddr)) HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr"); + /* Initialize driver, if it's not yet */ + if (!H5FD_ioc_init_s) + if (H5FD__ioc_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "can't initialize driver"); + if (NULL == (file = (H5FD_ioc_t *)H5FL_CALLOC(H5FD_ioc_t))) HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate file struct"); file->comm = MPI_COMM_NULL; @@ -695,7 +743,7 @@ H5FD__ioc_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list"); - if (H5FD_mpi_self_initialized) { + if (H5FD_mpi_self_initialized_s) { file->comm = MPI_COMM_WORLD; file->info = MPI_INFO_NULL; @@ -1192,8 +1240,17 @@ H5FD__ioc_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, bool H5_ATTR_UNU FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_truncate */ +/*------------------------------------------------------------------------- + * Function: H5FD__ioc_delete + * + * Purpose: Delete a file + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ static herr_t -H5FD__ioc_del(const char *name, hid_t fapl) +H5FD__ioc_delete(const char *name, hid_t fapl) { H5P_genplist_t *plist; MPI_Comm comm = MPI_COMM_NULL; @@ -1208,11 +1265,16 @@ H5FD__ioc_del(const char *name, hid_t fapl) FUNC_ENTER_PACKAGE + /* Initialize driver, if it's not yet */ + if (!H5FD_ioc_init_s) + if (H5FD__ioc_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize driver"); + if (NULL == (plist = H5P_object_verify(fapl, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); assert(H5FD_IOC == H5P_peek_driver(plist)); - if (H5FD_mpi_self_initialized) + if (H5FD_mpi_self_initialized_s) comm = MPI_COMM_WORLD; else { /* Get the MPI communicator and info from the fapl */ @@ -1314,7 +1376,7 @@ H5FD__ioc_del(const char *name, hid_t fapl) HMPI_DONE_ERROR(FAIL, "MPI_Barrier failed", mpi_code); } - if (!H5FD_mpi_self_initialized) { + if (!H5FD_mpi_self_initialized_s) { /* Free duplicated MPI Communicator and Info objects */ if (H5_mpi_comm_free(&comm) < 0) HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI communicator"); diff --git a/src/H5FDsubfiling/H5FDioc.h b/src/H5FDsubfiling/H5FDioc.h index 820258ed2f0..c9fe0d751ae 100644 --- a/src/H5FDsubfiling/H5FDioc.h +++ b/src/H5FDsubfiling/H5FDioc.h @@ -20,14 +20,16 @@ #ifndef H5FDioc_H #define H5FDioc_H -#include "H5FDsubfiling.h" +/* Public header files */ +#include "H5FDpublic.h" /* File drivers */ #ifdef H5_HAVE_IOC_VFD + /** * \def H5FD_IOC * Macro that returns the identifier for the #H5FD_IOC driver. \hid_t{file driver} */ -#define H5FD_IOC (H5FDperform_init(H5FD_ioc_init)) +#define H5FD_IOC (H5OPEN H5FD_IOC_id_g) #else #define H5FD_IOC (H5I_INVALID_HID) #endif @@ -114,11 +116,12 @@ typedef struct H5FD_ioc_config_t { extern "C" { #endif -/** - * \brief Internal routine to initialize #H5FD_IOC driver. Not meant to be - * called directly by an HDF5 application +/** @private + * + * \brief ID for the IOC VFD */ -H5_DLL hid_t H5FD_ioc_init(void); +H5_DLLVAR hid_t H5FD_IOC_id_g; + /** * \ingroup FAPL * diff --git a/src/H5FDsubfiling/H5FDioc_int.c b/src/H5FDsubfiling/H5FDioc_int.c index 4a1f8486ba6..c334624726c 100644 --- a/src/H5FDsubfiling/H5FDioc_int.c +++ b/src/H5FDsubfiling/H5FDioc_int.c @@ -14,7 +14,12 @@ * Purpose: This is part of an I/O concentrator driver. */ -#include "H5FDioc_priv.h" +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ + +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FDpkg.h" /* File drivers */ +#include "H5FDioc_priv.h" /* I/O concetrator file driver */ /* * Given a file offset, the stripe size, the number of IOCs and the number of @@ -80,12 +85,12 @@ herr_t H5FD__ioc_write_independent_async(int64_t context_id, int64_t offset, int64_t elements, const void *data, io_req_t **io_req) { - subfiling_context_t *sf_context = NULL; - MPI_Request ack_request = MPI_REQUEST_NULL; - io_req_t *sf_io_request = NULL; - int64_t ioc_start; - int64_t ioc_offset; - int64_t ioc_subfile_idx; + subfiling_context_t *sf_context = NULL; + MPI_Request ack_request = MPI_REQUEST_NULL; + io_req_t *sf_io_request = NULL; + int64_t ioc_start = -1; + int64_t ioc_offset = -1; + int64_t ioc_subfile_idx = -1; int64_t msg[3] = {0}; int *io_concentrators = NULL; int num_io_concentrators; @@ -236,13 +241,13 @@ herr_t H5FD__ioc_read_independent_async(int64_t context_id, int64_t offset, int64_t elements, void *data, io_req_t **io_req) { - subfiling_context_t *sf_context = NULL; - MPI_Request ack_request = MPI_REQUEST_NULL; - io_req_t *sf_io_request = NULL; - bool need_data_tag = false; - int64_t ioc_start; - int64_t ioc_offset; - int64_t ioc_subfile_idx; + subfiling_context_t *sf_context = NULL; + MPI_Request ack_request = MPI_REQUEST_NULL; + io_req_t *sf_io_request = NULL; + bool need_data_tag = false; + int64_t ioc_start = -1; + int64_t ioc_offset = -1; + int64_t ioc_subfile_idx = -1; int64_t msg[3] = {0}; int *io_concentrators = NULL; int num_io_concentrators; diff --git a/src/H5FDsubfiling/H5FDioc_priv.h b/src/H5FDsubfiling/H5FDioc_priv.h index fa4c431c6c8..a506392a160 100644 --- a/src/H5FDsubfiling/H5FDioc_priv.h +++ b/src/H5FDsubfiling/H5FDioc_priv.h @@ -21,16 +21,12 @@ /* H5 Headers */ /**************/ +/* Public header */ +#include "H5FDioc.h" /* IOC VFD */ + +/* Private headers */ #include "H5private.h" /* Generic Functions */ -#include "H5CXprivate.h" /* API Contexts */ -#include "H5Dprivate.h" /* Datasets */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5FDioc.h" /* IOC VFD */ -#include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5Pprivate.h" /* Property lists */ #include "H5TSprivate.h" /* Threadsafety */ - #include "H5subfiling_common.h" /* diff --git a/src/H5FDsubfiling/H5FDioc_threads.c b/src/H5FDsubfiling/H5FDioc_threads.c index e3f267952fc..21999a0ed9b 100644 --- a/src/H5FDsubfiling/H5FDioc_threads.c +++ b/src/H5FDsubfiling/H5FDioc_threads.c @@ -10,9 +10,12 @@ * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include "H5FDioc_priv.h" +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ -#include "H5FDsubfiling.h" +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FDpkg.h" /* File drivers */ +#include "H5FDioc_priv.h" /* I/O concetrator file driver */ #define MIN_READ_RETRIES 10 diff --git a/src/H5FDsubfiling/H5FDsubfile_int.c b/src/H5FDsubfiling/H5FDsubfile_int.c index 6c687aa69a7..e073f5c8fdd 100644 --- a/src/H5FDsubfiling/H5FDsubfile_int.c +++ b/src/H5FDsubfiling/H5FDsubfile_int.c @@ -19,7 +19,12 @@ /* Headers */ /***********/ -#include "H5FDsubfiling_priv.h" +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ + +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FDpkg.h" /* File drivers */ +#include "H5FDsubfiling_priv.h" /* Subfiling file driver */ /*------------------------------------------------------------------------- * Function: H5FD__subfiling__truncate_sub_files diff --git a/src/H5FDsubfiling/H5FDsubfiling.c b/src/H5FDsubfiling/H5FDsubfiling.c index 6f14d8492f3..42891bb1bc4 100644 --- a/src/H5FDsubfiling/H5FDsubfiling.c +++ b/src/H5FDsubfiling/H5FDsubfiling.c @@ -16,27 +16,30 @@ * mirror, and family VFDs. */ -#include "H5FDdrvr_module.h" /* This source code file is part of the H5FD driver module */ +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ #include "H5private.h" /* Generic Functions */ #include "H5CXprivate.h" /* API contexts, etc. */ -#include "H5Dprivate.h" /* Dataset stuff */ #include "H5Eprivate.h" /* Error handling */ -#include "H5FDprivate.h" /* File drivers */ -#include "H5FDsubfiling.h" /* Subfiling file driver */ -#include "H5FDsubfiling_priv.h" /* Subfiling file driver */ +#include "H5Fprivate.h" /* File access */ +#include "H5FDpkg.h" /* File drivers */ #include "H5FDsec2.h" /* Sec2 VFD */ +#include "H5FDsubfiling_priv.h" /* Subfiling file driver */ #include "H5FLprivate.h" /* Free Lists */ -#include "H5Fprivate.h" /* File access */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ /* The driver identification number, initialized at runtime */ -static hid_t H5FD_SUBFILING_g = H5I_INVALID_HID; +hid_t H5FD_SUBFILING_id_g = H5I_INVALID_HID; + +/* Flag to indicate whether global driver resources & settings have been + * initialized. + */ +static bool H5FD_subfiling_init_s = false; /* Whether the driver initialized MPI on its own */ -static bool H5FD_mpi_self_initialized = false; +static bool H5FD_mpi_self_initialized_s = false; /* The description of a file belonging to this driver. The 'eoa' and 'eof' * determine the amount of hdf5 address space in use and the high-water mark @@ -178,7 +181,7 @@ static herr_t H5FD__subfiling_read_vector(H5FD_t *file, hid_t dxpl_id, uint32_t static herr_t H5FD__subfiling_write_vector(H5FD_t *file, hid_t dxpl_id, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], const void *bufs[] /* in */); static herr_t H5FD__subfiling_truncate(H5FD_t *_file, hid_t dxpl_id, bool closing); -static herr_t H5FD__subfiling_del(const char *name, hid_t fapl); +static herr_t H5FD__subfiling_delete(const char *name, hid_t fapl); static herr_t H5FD__subfiling_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, void **output); @@ -238,8 +241,6 @@ static void H5_subfiling_dump_iovecs(subfiling_context_t *sf_context, size_t ior haddr_t *io_addrs, size_t *io_sizes, H5_flexible_const_ptr_t *io_bufs); #endif -void H5FD__subfiling_mpi_finalize(void); - static const H5FD_class_t H5FD_subfiling_g = { H5FD_CLASS_VERSION, /* VFD interface version */ H5_VFD_SUBFILING, /* value */ @@ -278,7 +279,7 @@ static const H5FD_class_t H5FD_subfiling_g = { H5FD__subfiling_truncate, /* truncate */ NULL, /* lock */ NULL, /* unlock */ - H5FD__subfiling_del, /* del */ + H5FD__subfiling_delete, /* del */ H5FD__subfiling_ctl, /* ctl */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -286,101 +287,110 @@ static const H5FD_class_t H5FD_subfiling_g = { /* Declare a free list to manage the H5FD_subfiling_t struct */ H5FL_DEFINE_STATIC(H5FD_subfiling_t); -/* - * If this VFD initialized MPI, this routine will be registered - * as an atexit handler in order to finalize MPI before the - * application exits. +/*------------------------------------------------------------------------- + * Function: H5FD__subfiling_register + * + * Purpose: Register the driver with the library. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- */ -void -H5FD__subfiling_mpi_finalize(void) +herr_t +H5FD__subfiling_register(void) { - /* - * Don't call normal FUNC_ENTER() since we don't want to initialize the - * whole library just to release it all right away. It is safe to call - * this function for an uninitialized library. - */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + herr_t ret_value = SUCCEED; /* Return value */ - H5_term_library(); - MPI_Finalize(); + FUNC_ENTER_PACKAGE - FUNC_LEAVE_NOAPI_VOID -} + /* Register the Subfiling VFD, if it isn't already registered */ + if (H5I_VFL != H5I_get_type(H5FD_SUBFILING_id_g)) + if ((H5FD_SUBFILING_id_g = H5FD_register(&H5FD_subfiling_g, sizeof(H5FD_class_t), false)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "can't register subfiling VFD"); -/*------------------------------------------------------------------------- - * Function: H5FD_subfiling_init +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__subfiling_register() */ + +/*--------------------------------------------------------------------------- + * Function: H5FD__subfiling_unregister * - * Purpose: Initialize this driver by registering the driver with the - * library. + * Purpose: Reset library driver info. * - * Return: Success: The driver ID for the subfiling driver - * Failure: H5I_INVALID_HID + * Returns: SUCCEED (Can't fail) * - *------------------------------------------------------------------------- + *--------------------------------------------------------------------------- */ -hid_t -H5FD_subfiling_init(void) +herr_t +H5FD__subfiling_unregister(void) { - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + FUNC_ENTER_PACKAGE_NOERR - FUNC_ENTER_NOAPI(H5I_INVALID_HID) + /* Reset VFL ID */ + H5FD_SUBFILING_id_g = H5I_INVALID_HID; - /* Register the Subfiling VFD, if it isn't already registered */ - if (H5I_VFL != H5I_get_type(H5FD_SUBFILING_g)) { - int mpi_initialized = 0; - int provided = 0; - int mpi_code; - - if ((H5FD_SUBFILING_g = H5FD_register(&H5FD_subfiling_g, sizeof(H5FD_class_t), false)) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register subfiling VFD"); - - /* Initialize MPI if not already initialized */ - if (MPI_SUCCESS != (mpi_code = MPI_Initialized(&mpi_initialized))) - HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Initialized failed", mpi_code); - if (mpi_initialized) { - /* If MPI is initialized, validate that it was initialized with MPI_THREAD_MULTIPLE */ - if (MPI_SUCCESS != (mpi_code = MPI_Query_thread(&provided))) - HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Query_thread failed", mpi_code); - if (provided != MPI_THREAD_MULTIPLE) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "Subfiling VFD requires the use of MPI_Init_thread with MPI_THREAD_MULTIPLE"); - } - else { - int required = MPI_THREAD_MULTIPLE; + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5FD__subfiling_unregister() */ + +/*------------------------------------------------------------------------- + * Function: H5FD__subfiling_init + * + * Purpose: Singleton to initialize global driver settings & resources. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__subfiling_init(void) +{ + int mpi_initialized = 0; + int provided = 0; + int mpi_code; + herr_t ret_value = SUCCEED; /* Return value */ - if (MPI_SUCCESS != (mpi_code = MPI_Init_thread(NULL, NULL, required, &provided))) - HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Init_thread failed", mpi_code); + FUNC_ENTER_PACKAGE - H5FD_mpi_self_initialized = true; + /* Initialize MPI if not already initialized */ + if (MPI_SUCCESS != (mpi_code = MPI_Initialized(&mpi_initialized))) + HMPI_GOTO_ERROR(FAIL, "MPI_Initialized failed", mpi_code); + if (mpi_initialized) { + /* If MPI is initialized, validate that it was initialized with MPI_THREAD_MULTIPLE */ + if (MPI_SUCCESS != (mpi_code = MPI_Query_thread(&provided))) + HMPI_GOTO_ERROR(FAIL, "MPI_Query_thread failed", mpi_code); + if (provided != MPI_THREAD_MULTIPLE) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "Subfiling VFD requires the use of MPI_Init_thread with MPI_THREAD_MULTIPLE"); + } + else { + if (MPI_SUCCESS != (mpi_code = MPI_Init_thread(NULL, NULL, MPI_THREAD_MULTIPLE, &provided))) + HMPI_GOTO_ERROR(FAIL, "MPI_Init_thread failed", mpi_code); - if (provided != required) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE"); + H5FD_mpi_self_initialized_s = true; - if (atexit(H5FD__subfiling_mpi_finalize) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "can't register atexit handler for MPI_Finalize"); - } + if (provided != MPI_THREAD_MULTIPLE) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE"); + } - /* - * Create the MPI Datatype that will be used - * for sending/receiving RPC messages - */ - HDcompile_assert(sizeof(((sf_work_request_t *)NULL)->header) == 3 * sizeof(int64_t)); - if (H5_subfiling_rpc_msg_type == MPI_DATATYPE_NULL) { - if (MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(3, MPI_INT64_T, &H5_subfiling_rpc_msg_type))) - HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Type_contiguous failed", mpi_code); - if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(&H5_subfiling_rpc_msg_type))) - HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Type_commit failed", mpi_code); - } + /* + * Create the MPI Datatype that will be used + * for sending/receiving RPC messages + */ + HDcompile_assert(sizeof(((sf_work_request_t *)NULL)->header) == 3 * sizeof(int64_t)); + if (H5_subfiling_rpc_msg_type == MPI_DATATYPE_NULL) { + if (MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(3, MPI_INT64_T, &H5_subfiling_rpc_msg_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code); + if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(&H5_subfiling_rpc_msg_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code); } - /* Set return value */ - ret_value = H5FD_SUBFILING_g; + /* Indicate that driver is set up */ + H5FD_subfiling_init_s = true; done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FD_subfiling_init() */ +} /* end H5FD__subfiling_init() */ /*--------------------------------------------------------------------------- * Function: H5FD__subfiling_term @@ -394,44 +404,45 @@ H5FD_subfiling_init(void) static herr_t H5FD__subfiling_term(void) { + int mpi_finalized; + int mpi_code; herr_t ret_value = SUCCEED; FUNC_ENTER_PACKAGE - if (H5FD_SUBFILING_g >= 0) { - int mpi_finalized; - int mpi_code; - - /* - * Retrieve status of whether MPI has already been terminated. - * This can happen if an HDF5 ID is left unclosed and HDF5 - * shuts down after MPI_Finalize() is called in an application. - */ - if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) - HMPI_GOTO_ERROR(FAIL, "MPI_Finalized failed", mpi_code); + /* + * Retrieve status of whether MPI has already been terminated. + * This can happen if an HDF5 ID is left unclosed and HDF5 + * shuts down after MPI_Finalize() is called in an application. + */ + if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) + HMPI_GOTO_ERROR(FAIL, "MPI_Finalized failed", mpi_code); + if (!mpi_finalized) { /* Free RPC message MPI Datatype */ - if (H5_subfiling_rpc_msg_type != MPI_DATATYPE_NULL) { - if (!mpi_finalized) { - if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&H5_subfiling_rpc_msg_type))) - HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code); - } + if (H5_subfiling_rpc_msg_type != MPI_DATATYPE_NULL) + if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&H5_subfiling_rpc_msg_type))) + HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code); + + /* Terminate MPI if the driver initialized it */ + if (H5FD_mpi_self_initialized_s) { + if (MPI_SUCCESS != (mpi_code = MPI_Finalize())) + HMPI_GOTO_ERROR(FAIL, "MPI_Finalize failed", mpi_code); + + H5FD_mpi_self_initialized_s = false; + } + } #ifdef H5_SUBFILING_DEBUG - else - printf("** WARNING **: HDF5 is terminating the Subfiling VFD after MPI_Finalize() was called " - "- an HDF5 ID was probably left unclosed\n"); + else + printf("** WARNING **: HDF5 is terminating the Subfiling VFD after MPI_Finalize() was called " + "- an HDF5 ID was probably left unclosed\n"); #endif - } - /* Clean up resources */ - if (H5FD__subfiling_terminate() < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't cleanup internal subfiling resources"); - } + /* Clean up resources */ + if (H5FD__subfiling_terminate() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTRELEASE, FAIL, "can't cleanup internal subfiling resources"); done: - /* Reset VFL ID */ - H5FD_SUBFILING_g = H5I_INVALID_HID; - FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_term() */ @@ -461,13 +472,14 @@ H5Pset_fapl_subfiling(hid_t fapl_id, const H5FD_subfiling_config_t *vfd_config) FUNC_ENTER_API(FAIL) - /* Ensure Subfiling (and therefore MPI) is initialized before doing anything */ - if (H5FD_subfiling_init() < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize subfiling VFD"); - if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + /* Initialize driver, if it's not yet */ + if (!H5FD_subfiling_init_s) + if (H5FD__subfiling_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize driver"); + if (vfd_config == NULL) { if (NULL == (subfiling_conf = H5MM_calloc(sizeof(*subfiling_conf)))) HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate subfiling VFD configuration"); @@ -544,6 +556,11 @@ H5Pget_fapl_subfiling(hid_t fapl_id, H5FD_subfiling_config_t *config_out) if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + /* Initialize driver, if it's not yet */ + if (!H5FD_subfiling_init_s) + if (H5FD__subfiling_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize driver"); + if (H5FD_SUBFILING != H5P_peek_driver(plist)) use_default_config = true; else { @@ -1113,6 +1130,11 @@ H5FD__subfiling_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t ma if (ADDR_OVERFLOW(maxaddr)) HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr"); + /* Initialize driver, if it's not yet */ + if (!H5FD_subfiling_init_s) + if (H5FD__subfiling_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "can't initialize driver"); + if (NULL == (file = (H5FD_subfiling_t *)H5FL_CALLOC(H5FD_subfiling_t))) HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate file struct"); file->comm = MPI_COMM_NULL; @@ -1127,7 +1149,7 @@ H5FD__subfiling_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t ma if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list"); - if (H5FD_mpi_self_initialized) { + if (H5FD_mpi_self_initialized_s) { file->comm = MPI_COMM_WORLD; file->info = MPI_INFO_NULL; } @@ -1759,8 +1781,17 @@ H5FD__subfiling_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, bool H5_AT FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_truncate() */ +/*------------------------------------------------------------------------- + * Function: H5FD__subfiling_delete + * + * Purpose: Delete a file + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ static herr_t -H5FD__subfiling_del(const char *name, hid_t fapl) +H5FD__subfiling_delete(const char *name, hid_t fapl) { const H5FD_subfiling_config_t *subfiling_config = NULL; H5FD_subfiling_config_t default_config; @@ -1769,6 +1800,11 @@ H5FD__subfiling_del(const char *name, hid_t fapl) FUNC_ENTER_PACKAGE + /* Initialize driver, if it's not yet */ + if (!H5FD_subfiling_init_s) + if (H5FD__subfiling_init() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize driver"); + if (NULL == (plist = H5P_object_verify(fapl, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); diff --git a/src/H5FDsubfiling/H5FDsubfiling.h b/src/H5FDsubfiling/H5FDsubfiling.h index 7d546bca84a..01938e4f8d9 100644 --- a/src/H5FDsubfiling/H5FDsubfiling.h +++ b/src/H5FDsubfiling/H5FDsubfiling.h @@ -14,12 +14,16 @@ #ifndef H5FDsubfiling_H #define H5FDsubfiling_H +/* Public header files */ +#include "H5FDpublic.h" /* File drivers */ + #ifdef H5_HAVE_SUBFILING_VFD + /** * \def H5FD_SUBFILING * Macro that returns the identifier for the #H5FD_SUBFILING driver. \hid_t{file driver} */ -#define H5FD_SUBFILING (H5FDperform_init(H5FD_subfiling_init)) +#define H5FD_SUBFILING (H5OPEN H5FD_SUBFILING_id_g) #else #define H5FD_SUBFILING (H5I_INVALID_HID) #endif @@ -319,11 +323,12 @@ typedef struct H5FD_subfiling_config_t { extern "C" { #endif -/** - * \brief Internal routine to initialize #H5FD_SUBFILING driver. Not meant to be - * called directly by an HDF5 application +/** @private + * + * \brief ID for the SUBFILING VFD */ -H5_DLL hid_t H5FD_subfiling_init(void); +H5_DLLVAR hid_t H5FD_SUBFILING_id_g; + /** * \ingroup FAPL * diff --git a/src/H5FDsubfiling/H5FDsubfiling_priv.h b/src/H5FDsubfiling/H5FDsubfiling_priv.h index fd6779c4178..b746326959c 100644 --- a/src/H5FDsubfiling/H5FDsubfiling_priv.h +++ b/src/H5FDsubfiling/H5FDsubfiling_priv.h @@ -21,16 +21,11 @@ /* H5 Headers */ /**************/ -#include "H5private.h" /* Generic Functions */ -#include "H5CXprivate.h" /* API Contexts */ -#include "H5Dprivate.h" /* Datasets */ -#include "H5Eprivate.h" /* Error handling */ +/* Public header */ #include "H5FDsubfiling.h" /* Subfiling VFD */ -#include "H5FDioc.h" /* IOC VFD */ -#include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5Pprivate.h" /* Property lists */ +/* Private headers */ +#include "H5private.h" /* Generic Functions */ #include "H5subfiling_common.h" #define DRIVER_INFO_MESSAGE_MAX_INFO 65536 diff --git a/src/H5FDsubfiling/H5subfiling_common.c b/src/H5FDsubfiling/H5subfiling_common.c index 63078a3c031..9b393412242 100644 --- a/src/H5FDsubfiling/H5subfiling_common.c +++ b/src/H5FDsubfiling/H5subfiling_common.c @@ -14,12 +14,16 @@ * Generic code for integrating an HDF5 VFD with the subfiling feature */ +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ + +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FDpkg.h" /* File drivers */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5TSprivate.h" /* Threadsafety */ #include "H5subfiling_common.h" -#include "H5Eprivate.h" -#include "H5MMprivate.h" -#include "H5TSprivate.h" /* Threadsafety */ - typedef struct { /* Format of a context map entry */ uint64_t file_id; /* key value (linear search of the cache) */ int64_t sf_context_id; /* The return value if matching file_handle */ @@ -94,7 +98,7 @@ static int64_t H5FD__subfiling_new_object_id(sf_obj_type_t obj_type) { int64_t index_val = 0; - int64_t ret_value; + int64_t ret_value = 0; FUNC_ENTER_PACKAGE diff --git a/src/H5FDsubfiling/H5subfiling_common.h b/src/H5FDsubfiling/H5subfiling_common.h index 8dc08ac82f9..6e140cccb4c 100644 --- a/src/H5FDsubfiling/H5subfiling_common.h +++ b/src/H5FDsubfiling/H5subfiling_common.h @@ -17,14 +17,11 @@ #ifndef H5_SUBFILING_COMMON_H #define H5_SUBFILING_COMMON_H -#include "H5private.h" /* Generic Functions */ -#include "H5FDprivate.h" /* File Drivers */ -#include "H5Iprivate.h" /* IDs */ -#include "H5Pprivate.h" /* Property lists */ -#include "H5TSprivate.h" /* Threads */ - -#include "H5FDsubfiling.h" -#include "H5FDioc.h" +#include "H5private.h" /* Generic Functions */ +#include "H5FDsubfiling.h" /* Subfiling file driver */ +#include "H5FDioc.h" /* I/O concentrator file driver */ +#include "H5Pprivate.h" /* Property lists */ +#include "H5TSprivate.h" /* Threads */ #ifndef PATH_MAX #define PATH_MAX 4096 diff --git a/src/H5FDwindows.c b/src/H5FDwindows.c index c44de9935fc..182958fcb15 100644 --- a/src/H5FDwindows.c +++ b/src/H5FDwindows.c @@ -10,15 +10,18 @@ * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include "H5private.h" /* Generic Functions */ +#include "H5FDmodule.h" /* This source code file is part of the H5FD module */ + +#include "H5private.h" /* Generic Functions */ + +#ifdef H5_HAVE_WINDOWS + #include "H5Eprivate.h" /* Error handling */ -#include "H5FDprivate.h" /* File drivers */ -#include "H5FDwindows.h" /* Windows file driver */ #include "H5FDsec2.h" /* Windows file driver */ +#include "H5FDpkg.h" /* File drivers */ +#include "H5FDwindows.h" /* Windows file driver */ #include "H5Pprivate.h" /* Property lists */ -#ifdef H5_HAVE_WINDOWS - /*------------------------------------------------------------------------- * Function: H5Pset_fapl_windows * diff --git a/src/H5FDwindows.h b/src/H5FDwindows.h index 02e20008357..dccb73f80bc 100644 --- a/src/H5FDwindows.h +++ b/src/H5FDwindows.h @@ -20,13 +20,22 @@ #ifndef H5FDwindows_H #define H5FDwindows_H -/** Initializer for the Windows VFD */ -#define H5FD_WINDOWS (H5FD_sec2_init()) +/* Public header files */ +#include "H5FDpublic.h" /* File drivers */ + +/** ID for the windows VFD */ +#define H5FD_WINDOWS (H5OPEN H5FD_SEC2_id_g) #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ +/** @private + * + * \brief ID for the windows (sec2) VFD + */ +H5_DLLVAR hid_t H5FD_SEC2_id_g; + /** * \ingroup FAPL * diff --git a/src/H5FL.c b/src/H5FL.c index 4f7a94060f1..9430a109107 100644 --- a/src/H5FL.c +++ b/src/H5FL.c @@ -110,6 +110,9 @@ struct H5FL_fac_node_t { struct H5FL_fac_node_t *next; /* Pointer to next block in free list */ }; +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* The head of the list of factory things to garbage collect */ static H5FL_fac_gc_list_t H5FL_fac_gc_head = {0, NULL}; @@ -168,15 +171,20 @@ H5FL_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR + if (H5_PKG_INIT_VAR) { /* Garbage collect any nodes on the free lists */ - (void) - H5FL_garbage_coll(); - - /* Shut down the various kinds of free lists */ - n += H5FL__reg_term(); - n += H5FL__fac_term_all(); - n += H5FL__arr_term(); - n += H5FL__blk_term(); + (void)H5FL_garbage_coll(); + + /* Shut down the various kinds of free lists */ + n += H5FL__reg_term(); + n += H5FL__fac_term_all(); + n += H5FL__arr_term(); + n += H5FL__blk_term(); + + /* Mark interface closed */ + if (0 == n) + H5_PKG_INIT_VAR = false; + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5FL_term_package() */ diff --git a/src/H5FLmodule.h b/src/H5FLmodule.h index 172c13d1b55..97fbed8f345 100644 --- a/src/H5FLmodule.h +++ b/src/H5FLmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5FL_MODULE -#define H5_MY_PKG H5FL -#define H5_MY_PKG_ERR H5E_RESOURCE +#define H5_MY_PKG H5FL +#define H5_MY_PKG_ERR H5E_RESOURCE +#define H5_MY_PKG_INIT NO #endif /* H5FLmodule_H */ diff --git a/src/H5FS.c b/src/H5FS.c index 2f8d28fdec6..d00c870ff04 100644 --- a/src/H5FS.c +++ b/src/H5FS.c @@ -58,6 +58,9 @@ static herr_t H5FS__sinfo_free_node_cb(void *item, void *key, void *op_data); /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* Declare a free list to manage the H5FS_section_class_t sequence information */ H5FL_SEQ_DEFINE(H5FS_section_class_t); diff --git a/src/H5FSint.c b/src/H5FSint.c index 8db6d367bc5..7ccd7584a66 100644 --- a/src/H5FSint.c +++ b/src/H5FSint.c @@ -64,6 +64,28 @@ /* Local Variables */ /*******************/ +/*------------------------------------------------------------------------- + * Function: H5FS_init + * + * Purpose: Initialize the interface in case it is unable to initialize + * itself soon enough. + * + * Return: Success: non-negative + * Failure: negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5FS_init(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOERR + /* FUNC_ENTER() does all the work */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FS_init() */ + /*------------------------------------------------------------------------- * Function: H5FS__create_flush_depend * diff --git a/src/H5FSmodule.h b/src/H5FSmodule.h index a44bb4c4810..48ae8d37277 100644 --- a/src/H5FSmodule.h +++ b/src/H5FSmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5FS_MODULE -#define H5_MY_PKG H5FS -#define H5_MY_PKG_ERR H5E_FSPACE +#define H5_MY_PKG H5FS +#define H5_MY_PKG_ERR H5E_FSPACE +#define H5_MY_PKG_INIT NO #endif /* H5FSmodule_H */ diff --git a/src/H5FSprivate.h b/src/H5FSprivate.h index 9e92c7544b6..957f6f9a665 100644 --- a/src/H5FSprivate.h +++ b/src/H5FSprivate.h @@ -183,6 +183,9 @@ H5FL_SEQ_EXTERN(H5FS_section_class_t); /* Library-private Function Prototypes */ /***************************************/ +/* Package initialization routine */ +H5_DLL herr_t H5FS_init(void); + /* Free space manager routines */ H5_DLL H5FS_t *H5FS_create(H5F_t *f, haddr_t *fs_addr, const H5FS_create_t *fs_create, uint16_t nclasses, const H5FS_section_class_t *classes[], void *cls_init_udata, hsize_t alignment, diff --git a/src/H5Fcwfs.c b/src/H5Fcwfs.c index 62de3da6fe6..f6674b2d703 100644 --- a/src/H5Fcwfs.c +++ b/src/H5Fcwfs.c @@ -240,7 +240,7 @@ H5F_cwfs_advance_heap(H5F_t *f, H5HG_heap_t *heap, bool add_heap) unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Check args */ assert(f); @@ -260,6 +260,7 @@ H5F_cwfs_advance_heap(H5F_t *f, H5HG_heap_t *heap, bool add_heap) f->shared->cwfs[f->shared->ncwfs - 1] = heap; } /* end if */ +done: FUNC_LEAVE_NOAPI(ret_value) } /* H5F_cwfs_advance_heap() */ @@ -279,7 +280,7 @@ H5F_cwfs_remove_heap(H5F_shared_t *shared, H5HG_heap_t *heap) unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Check args */ assert(shared); @@ -294,5 +295,6 @@ H5F_cwfs_remove_heap(H5F_shared_t *shared, H5HG_heap_t *heap) } /* end if */ } /* end for */ +done: FUNC_LEAVE_NOAPI(ret_value) } /* H5F_cwfs_remove_heap() */ diff --git a/src/H5Fint.c b/src/H5Fint.c index c3d2e3ae82a..d2ede2f978d 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -91,6 +91,9 @@ static herr_t H5F__flush_phase2(H5F_t *f, bool closing); /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* Based on the value of the HDF5_USE_FILE_LOCKING environment variable. * true/false have obvious meanings. FAIL means the environment variable was * not set, so the code should ignore it and use the fapl value instead. @@ -136,6 +139,29 @@ H5F_init(void) herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_init() */ + +/*-------------------------------------------------------------------------- +NAME + H5F__init_package -- Initialize interface-specific information +USAGE + herr_t H5F__init_package() +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. + +--------------------------------------------------------------------------*/ +herr_t +H5F__init_package(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE /* Initialize the ID group for the file IDs */ if (H5I_register_type(H5I_FILE_CLS) < 0) @@ -147,7 +173,7 @@ H5F_init(void) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_init() */ +} /* H5F__init_package() */ /*------------------------------------------------------------------------- * Function: H5F_term_package @@ -171,17 +197,23 @@ H5F_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - if (H5I_nmembers(H5I_FILE) > 0) { - (void)H5I_clear_type(H5I_FILE, false, false); - n++; /*H5I*/ - } /* end if */ - else { - /* Make certain we've cleaned up all the shared file objects */ - H5F_sfile_assert_num(0); + if (H5_PKG_INIT_VAR) { + if (H5I_nmembers(H5I_FILE) > 0) { + (void)H5I_clear_type(H5I_FILE, false, false); + n++; /*H5I*/ + } /* end if */ + else { + /* Make certain we've cleaned up all the shared file objects */ + H5F_sfile_assert_num(0); - /* Destroy the file object id group */ - n += (H5I_dec_type_ref(H5I_FILE) > 0); - } /* end else */ + /* Destroy the file object id group */ + n += (H5I_dec_type_ref(H5I_FILE) > 0); + + /* Mark closed */ + if (0 == n) + H5_PKG_INIT_VAR = false; + } /* end else */ + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5F_term_package() */ diff --git a/src/H5Fmodule.h b/src/H5Fmodule.h index 23463226137..ba9ab98f4dc 100644 --- a/src/H5Fmodule.h +++ b/src/H5Fmodule.h @@ -22,8 +22,9 @@ * reporting macros. */ #define H5F_MODULE -#define H5_MY_PKG H5F -#define H5_MY_PKG_ERR H5E_FILE +#define H5_MY_PKG H5F +#define H5_MY_PKG_ERR H5E_FILE +#define H5_MY_PKG_INIT YES /** \page H5F_UG HDF5 File * diff --git a/src/H5Fmpi.c b/src/H5Fmpi.c index d3e38119524..78909aa1bf2 100644 --- a/src/H5Fmpi.c +++ b/src/H5Fmpi.c @@ -432,7 +432,7 @@ H5F_mpi_retrieve_comm(hid_t loc_id, hid_t acspl_id, MPI_Comm *mpi_comm) bool H5F_get_coll_metadata_reads(const H5F_t *file) { - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI_NOINIT_NOERR assert(file && file->shared); @@ -458,7 +458,7 @@ H5F_shared_get_coll_metadata_reads(const H5F_shared_t *f_sh) H5P_coll_md_read_flag_t file_flag = H5P_USER_FALSE; bool ret_value = false; - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI_NOINIT_NOERR assert(f_sh); @@ -536,7 +536,7 @@ H5F_set_coll_metadata_reads(H5F_t *file, H5P_coll_md_read_flag_t *file_flag, boo H5P_coll_md_read_flag_t prev_file_flag = H5P_USER_FALSE; bool prev_context_flag = false; - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI_NOINIT_NOERR assert(file && file->shared); assert(file_flag); diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index 4e9214f0a4b..c9b8b9e7731 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -20,48 +20,28 @@ #include "H5ACpublic.h" /* Metadata Cache */ #include "H5Ipublic.h" /* Identifiers */ -/* When this header is included from a private header, don't make calls to H5check() */ -#undef H5CHECK -#ifndef H5private_H -#define H5CHECK H5check(), -#else /* H5private_H */ -#define H5CHECK -#endif /* H5private_H */ - -/* When this header is included from a private HDF5 header, don't make calls to H5open() */ -#undef H5OPEN -#ifndef H5private_H -#define H5OPEN H5open(), -#else /* H5private_H */ -#define H5OPEN -#endif /* H5private_H */ - /* * These are the bits that can be passed to the `flags' argument of * H5Fcreate() and H5Fopen(). Use the bit-wise OR operator (|) to combine - * them as needed. As a side effect, they call H5check_version() to make sure - * that the application is compiled with a version of the hdf5 header files - * which are compatible with the library to which the application is linked. - * We're assuming that these constants are used rather early in the hdf5 - * session. - */ -#define H5F_ACC_RDONLY (H5CHECK H5OPEN 0x0000u) /**< Absence of RDWR: read-only */ -#define H5F_ACC_RDWR (H5CHECK H5OPEN 0x0001u) /**< Open for read and write */ -#define H5F_ACC_TRUNC (H5CHECK H5OPEN 0x0002u) /**< Overwrite existing files */ -#define H5F_ACC_EXCL (H5CHECK H5OPEN 0x0004u) /**< Fail if file already exists*/ + * them as needed. + */ +#define H5F_ACC_RDONLY (0x0000u) /**< Absence of RDWR: read-only */ +#define H5F_ACC_RDWR (0x0001u) /**< Open for read and write */ +#define H5F_ACC_TRUNC (0x0002u) /**< Overwrite existing files */ +#define H5F_ACC_EXCL (0x0004u) /**< Fail if file already exists*/ /* NOTE: 0x0008u was H5F_ACC_DEBUG, now deprecated */ -#define H5F_ACC_CREAT (H5CHECK H5OPEN 0x0010u) /**< Create non-existing files */ +#define H5F_ACC_CREAT (0x0010u) /**< Create non-existing files */ #define H5F_ACC_SWMR_WRITE \ - (H5CHECK 0x0020u) /**< Indicate that this file is open for writing in a \ - * single-writer/multi-reader (SWMR) scenario. \ - * Note that the process(es) opening the file for reading \ - * must open the file with #H5F_ACC_RDONLY and use the \ - * #H5F_ACC_SWMR_READ access flag. */ + (0x0020u) /**< Indicate that this file is open for writing in a \ + * single-writer/multi-reader (SWMR) scenario. \ + * Note that the process(es) opening the file for reading \ + * must open the file with #H5F_ACC_RDONLY and use the \ + * #H5F_ACC_SWMR_READ access flag. */ #define H5F_ACC_SWMR_READ \ - (H5CHECK 0x0040u) /**< Indicate that this file is open for reading in a \ - * single-writer/multi-reader (SWMR) scenario. Note that \ - * the process(es) opening the file for SWMR reading must \ - * also open the file with the #H5F_ACC_RDONLY flag. */ + (0x0040u) /**< Indicate that this file is open for reading in a \ + * single-writer/multi-reader (SWMR) scenario. Note that \ + * the process(es) opening the file for SWMR reading must \ + * also open the file with the #H5F_ACC_RDONLY flag. */ /** * Default property list identifier @@ -69,7 +49,7 @@ * \internal Value passed to H5Pset_elink_acc_flags to cause flags to be taken from the parent file. * \internal ignore setting on lapl */ -#define H5F_ACC_DEFAULT (H5CHECK H5OPEN 0xffffu) +#define H5F_ACC_DEFAULT (0xffffu) /* Flags for H5Fget_obj_count() & H5Fget_obj_ids() calls */ #define H5F_OBJ_FILE (0x0001u) /**< File objects */ @@ -1879,7 +1859,7 @@ H5_DLL herr_t H5Fformat_convert(hid_t fid); #ifndef H5_NO_DEPRECATED_SYMBOLS /* Macros */ -#define H5F_ACC_DEBUG (H5CHECK H5OPEN 0x0000u) /**< Print debug info \deprecated In which version? */ +#define H5F_ACC_DEBUG (0x0000u) /**< Print debug info \deprecated In which version? */ /* Typedefs */ diff --git a/src/H5Fquery.c b/src/H5Fquery.c index 5a119a287f6..89d2e70f0bc 100644 --- a/src/H5Fquery.c +++ b/src/H5Fquery.c @@ -1365,7 +1365,7 @@ H5F_get_use_file_locking(const H5F_t *f) bool H5F_has_vector_select_io(const H5F_t *f, bool is_write) { - bool ret_value; /* Return value */ + bool ret_value = false; /* Return value */ FUNC_ENTER_NOAPI_NOINIT_NOERR diff --git a/src/H5Gint.c b/src/H5Gint.c index 2a7dbf5e255..c037b99de8b 100644 --- a/src/H5Gint.c +++ b/src/H5Gint.c @@ -89,6 +89,9 @@ static herr_t H5G__close_cb(H5VL_object_t *grp_vol_obj, void **request); /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* Declare a free list to manage the H5G_t struct */ H5FL_DEFINE(H5G_t); H5FL_DEFINE(H5G_shared_t); @@ -112,6 +115,9 @@ static const H5I_class_t H5I_GROUP_CLS[1] = {{ (H5I_free_t)H5G__close_cb /* Callback routine for closing objects of this class */ }}; +/* Flag indicating "top" of interface has been initialized */ +static bool H5G_top_package_initialize_s = false; + /*------------------------------------------------------------------------- * Function: H5G_init * @@ -128,13 +134,48 @@ H5G_init(void) herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_init() */ + +/*------------------------------------------------------------------------- + * Function: H5G__init_package + * + * Purpose: Initializes the H5G interface. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Monday, January 5, 1998 + * + * Notes: The group creation properties are registered in the property + * list interface initialization routine (H5P_init_package) + * so that the file creation property class can inherit from it + * correctly. (Which allows the file creation property list to + * control the group creation properties of the root group of + * a file) QAK - 24/10/2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G__init_package(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + /* Initialize the ID group for the group IDs */ if (H5I_register_type(H5I_GROUP_CLS) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to initialize interface"); + /* Mark "top" of interface as initialized, too */ + H5G_top_package_initialize_s = true; + done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_init() */ +} /* end H5G__init_package() */ /*------------------------------------------------------------------------- * Function: H5G_top_term_package @@ -154,10 +195,16 @@ H5G_top_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - if (H5I_nmembers(H5I_GROUP) > 0) { - (void)H5I_clear_type(H5I_GROUP, false, false); - n++; - } + if (H5G_top_package_initialize_s) { + if (H5I_nmembers(H5I_GROUP) > 0) { + (void)H5I_clear_type(H5I_GROUP, false, false); + n++; + } + + /* Mark closed */ + if (0 == n) + H5G_top_package_initialize_s = false; + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5G_top_term_package() */ @@ -183,11 +230,18 @@ H5G_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - /* Sanity checks */ - assert(0 == H5I_nmembers(H5I_GROUP)); + if (H5_PKG_INIT_VAR) { + /* Sanity checks */ + assert(0 == H5I_nmembers(H5I_GROUP)); + assert(false == H5G_top_package_initialize_s); + + /* Destroy the group object id group */ + n += (H5I_dec_type_ref(H5I_GROUP) > 0); - /* Destroy the group object id group */ - n += (H5I_dec_type_ref(H5I_GROUP) > 0); + /* Mark closed */ + if (0 == n) + H5_PKG_INIT_VAR = false; + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5G_term_package() */ diff --git a/src/H5Gmodule.h b/src/H5Gmodule.h index d91afc4d601..3457db90b03 100644 --- a/src/H5Gmodule.h +++ b/src/H5Gmodule.h @@ -22,8 +22,9 @@ * reporting macros. */ #define H5G_MODULE -#define H5_MY_PKG H5G -#define H5_MY_PKG_ERR H5E_SYM +#define H5_MY_PKG H5G +#define H5_MY_PKG_ERR H5E_SYM +#define H5_MY_PKG_INIT YES /** \page H5G_UG HDF5 Groups * diff --git a/src/H5Gname.c b/src/H5Gname.c index 5ee05433d0c..a6c9afdd860 100644 --- a/src/H5Gname.c +++ b/src/H5Gname.c @@ -199,17 +199,23 @@ H5G__common_path(const H5RS_str_t *fullpath_r, const H5RS_str_t *prefix_r) size_t nchars1, nchars2; /* Number of characters in components */ htri_t ret_value = false; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Get component of each name */ - fullpath = H5RS_get_str(fullpath_r); - assert(fullpath); - fullpath = H5G__component(fullpath, &nchars1); - assert(fullpath); - prefix = H5RS_get_str(prefix_r); - assert(prefix); - prefix = H5G__component(prefix, &nchars2); - assert(prefix); + if (NULL == (fullpath = H5RS_get_str(fullpath_r))) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve full path"); + nchars1 = SIZE_MAX; + if (NULL == (fullpath = H5G__component(fullpath, &nchars1))) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve pointer to path component"); + if (SIZE_MAX == nchars1) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve component length"); + if (NULL == (prefix = H5RS_get_str(prefix_r))) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve path prefix"); + nchars2 = SIZE_MAX; + if (NULL == (prefix = H5G__component(prefix, &nchars2))) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve pointer to path component"); + if (SIZE_MAX == nchars2) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve component length"); /* Check if we have a real string for each component */ while (*fullpath && *prefix) { @@ -226,6 +232,15 @@ H5G__common_path(const H5RS_str_t *fullpath_r, const H5RS_str_t *prefix_r) assert(fullpath); prefix = H5G__component(prefix, &nchars2); assert(prefix); + if (NULL == (fullpath = H5G__component(fullpath, &nchars1))) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve pointer to path component"); + if (SIZE_MAX == nchars1) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve component length"); + nchars2 = SIZE_MAX; + if (NULL == (prefix = H5G__component(prefix, &nchars2))) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve pointer to path component"); + if (SIZE_MAX == nchars2) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve component length"); } /* end if */ else HGOTO_DONE(false); diff --git a/src/H5HF.c b/src/H5HF.c index acb37fa6c66..24af93a7a4e 100644 --- a/src/H5HF.c +++ b/src/H5HF.c @@ -59,6 +59,9 @@ /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /*****************************/ /* Library Private Variables */ /*****************************/ diff --git a/src/H5HFmodule.h b/src/H5HFmodule.h index 435b21a6c1b..ac617415c59 100644 --- a/src/H5HFmodule.h +++ b/src/H5HFmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5HF_MODULE -#define H5_MY_PKG H5HF -#define H5_MY_PKG_ERR H5E_HEAP +#define H5_MY_PKG H5HF +#define H5_MY_PKG_ERR H5E_HEAP +#define H5_MY_PKG_INIT NO #endif /* H5HFmodule_H */ diff --git a/src/H5HFsection.c b/src/H5HFsection.c index b008b3db01d..589b5f84693 100644 --- a/src/H5HFsection.c +++ b/src/H5HFsection.c @@ -673,10 +673,10 @@ H5HF__sect_single_reduce(H5HF_hdr_t *hdr, H5HF_free_section_t *sect, size_t amt) static herr_t H5HF__sect_single_full_dblock(H5HF_hdr_t *hdr, H5HF_free_section_t *sect) { - haddr_t dblock_addr; /* Section's direct block's address */ - size_t dblock_size; /* Section's direct block's size */ - size_t dblock_overhead; /* Direct block's overhead */ - herr_t ret_value = SUCCEED; /* Return value */ + haddr_t dblock_addr = HADDR_UNDEF; /* Section's direct block's address */ + size_t dblock_size = SIZE_MAX; /* Section's direct block's size */ + size_t dblock_overhead; /* Direct block's overhead */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -688,6 +688,10 @@ H5HF__sect_single_full_dblock(H5HF_hdr_t *hdr, H5HF_free_section_t *sect) /* Retrieve direct block address from section */ if (H5HF__sect_single_dblock_info(hdr, sect, &dblock_addr, &dblock_size) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve direct block information"); + if (!H5_addr_defined(dblock_addr)) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve data block address"); + if (SIZE_MAX == dblock_size) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve data block size"); /* Check for section occupying entire direct block */ /* (and not the root direct block) */ @@ -971,9 +975,9 @@ H5HF__sect_single_shrink(H5FS_section_info_t **_sect, void *_udata) H5HF_sect_add_ud_t *udata = (H5HF_sect_add_ud_t *)_udata; /* User callback data */ H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */ H5HF_direct_t *dblock; /* Pointer to direct block for section */ - haddr_t dblock_addr; /* Section's direct block's address */ - size_t dblock_size; /* Section's direct block's size */ - herr_t ret_value = SUCCEED; /* Return value */ + haddr_t dblock_addr = HADDR_UNDEF; /* Section's direct block's address */ + size_t dblock_size = SIZE_MAX; /* Section's direct block's size */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -990,6 +994,10 @@ H5HF__sect_single_shrink(H5FS_section_info_t **_sect, void *_udata) /* Retrieve direct block address from section */ if (H5HF__sect_single_dblock_info(hdr, (*sect), &dblock_addr, &dblock_size) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve direct block information"); + if (!H5_addr_defined(dblock_addr)) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve data block address"); + if (SIZE_MAX == dblock_size) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve data block size"); /* Protect the direct block for the section */ /* (should be a root direct block) */ @@ -1066,8 +1074,9 @@ static herr_t H5HF__sect_single_valid(const H5FS_section_class_t H5_ATTR_UNUSED *cls, const H5FS_section_info_t *_sect) { const H5HF_free_section_t *sect = (const H5HF_free_section_t *)_sect; /* Pointer to section to check */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_PACKAGE /* Check arguments. */ assert(sect); @@ -1077,8 +1086,8 @@ H5HF__sect_single_valid(const H5FS_section_class_t H5_ATTR_UNUSED *cls, const H5 /* (not enough information to check on a single section in a root direct block) */ if (sect->u.single.parent != NULL) { H5HF_indirect_t *iblock; /* Indirect block that section's direct block resides in */ - haddr_t dblock_addr; /* Direct block address */ - size_t dblock_size; /* Direct block size */ + haddr_t dblock_addr = HADDR_UNDEF; /* Direct block address */ + size_t dblock_size = SIZE_MAX; /* Direct block size */ unsigned dblock_status = 0; /* Direct block's status in the metadata cache */ size_t H5_ATTR_NDEBUG_UNUSED dblock_overhead; /* Direct block's overhead */ herr_t H5_ATTR_NDEBUG_UNUSED status; /* Generic status value */ @@ -1088,11 +1097,14 @@ H5HF__sect_single_valid(const H5FS_section_class_t H5_ATTR_UNUSED *cls, const H5 assert(H5_addr_defined(iblock->ents[sect->u.single.par_entry].addr)); /* Retrieve direct block address from section */ - status = H5HF__sect_single_dblock_info(iblock->hdr, (const H5HF_free_section_t *)sect, - &dblock_addr, &dblock_size); - assert(status >= 0); + if (H5HF__sect_single_dblock_info(iblock->hdr, (const H5HF_free_section_t *)sect, &dblock_addr, + &dblock_size) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve direct block information"); + if (!H5_addr_defined(dblock_addr)) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve data block address"); + if (SIZE_MAX == dblock_size) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve data block size"); assert(H5_addr_eq(iblock->ents[sect->u.single.par_entry].addr, dblock_addr)); - assert(dblock_size > 0); /* Check if the section is actually within the heap */ assert(sect->sect_info.addr < iblock->hdr->man_iter_off); @@ -1132,7 +1144,8 @@ H5HF__sect_single_valid(const H5FS_section_class_t H5_ATTR_UNUSED *cls, const H5 } /* end if */ } /* end if */ - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* H5HF__sect_single_valid() */ /*------------------------------------------------------------------------- @@ -3259,15 +3272,15 @@ H5HF__sect_indirect_get_iblock(H5HF_free_section_t *sect) static herr_t H5HF__sect_indirect_merge_row(H5HF_hdr_t *hdr, H5HF_free_section_t *row_sect1, H5HF_free_section_t *row_sect2) { - H5HF_free_section_t *sect1, *sect2; /* Indirect sections underlying row sections */ - unsigned start_entry1; /* Start entry for section #1 */ - unsigned start_row1, start_col1; /* Starting row & column for section #1 */ - unsigned end_entry1; /* End entry for section #1 */ - unsigned end_row1; /* Ending row for section #1 */ - unsigned start_row2; /* Starting row for section #2 */ - bool merged_rows; /* Flag to indicate that rows was merged together */ - unsigned u; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ + H5HF_free_section_t *sect1 = NULL, *sect2 = NULL; /* Indirect sections underlying row sections */ + unsigned start_entry1; /* Start entry for section #1 */ + unsigned start_row1, start_col1; /* Starting row & column for section #1 */ + unsigned end_entry1; /* End entry for section #1 */ + unsigned end_row1; /* Ending row for section #1 */ + unsigned start_row2; /* Starting row for section #2 */ + bool merged_rows; /* Flag to indicate that rows was merged together */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -3280,10 +3293,10 @@ H5HF__sect_indirect_merge_row(H5HF_hdr_t *hdr, H5HF_free_section_t *row_sect1, H assert(row_sect2->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW); /* Set up indirect section information */ - sect1 = H5HF__sect_indirect_top(row_sect1->u.row.under); - assert(sect1); - sect2 = H5HF__sect_indirect_top(row_sect2->u.row.under); - assert(sect2); + if (NULL == (sect1 = H5HF__sect_indirect_top(row_sect1->u.row.under))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve pointer to sections"); + if (NULL == (sect2 = H5HF__sect_indirect_top(row_sect2->u.row.under))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve pointer to sections"); /* Sanity check some assumptions about the indirect sections */ assert(sect1->u.indirect.span_size > 0); diff --git a/src/H5HG.c b/src/H5HG.c index 96f3fa3dc79..d28c457d6cb 100644 --- a/src/H5HG.c +++ b/src/H5HG.c @@ -81,6 +81,9 @@ static size_t H5HG__alloc(H5F_t *f, H5HG_heap_t *heap, size_t size, unsigned *h /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* Declare a free list to manage the H5HG_heap_t struct */ H5FL_DEFINE(H5HG_heap_t); diff --git a/src/H5HGmodule.h b/src/H5HGmodule.h index 0ed32ceb003..8ec5d9de5f1 100644 --- a/src/H5HGmodule.h +++ b/src/H5HGmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5HG_MODULE -#define H5_MY_PKG H5HG -#define H5_MY_PKG_ERR H5E_HEAP +#define H5_MY_PKG H5HG +#define H5_MY_PKG_ERR H5E_HEAP +#define H5_MY_PKG_INIT NO #endif /* H5HGmodule_H */ diff --git a/src/H5HL.c b/src/H5HL.c index 45df1b2e6e8..b55b3690617 100644 --- a/src/H5HL.c +++ b/src/H5HL.c @@ -64,6 +64,9 @@ static herr_t H5HL__dirty(H5HL_t *heap); /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* Declare a free list to manage the H5HL_free_t struct */ H5FL_DEFINE(H5HL_free_t); diff --git a/src/H5HLmodule.h b/src/H5HLmodule.h index e9d2ef5e45f..40e32563de7 100644 --- a/src/H5HLmodule.h +++ b/src/H5HLmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5HL_MODULE -#define H5_MY_PKG H5HL -#define H5_MY_PKG_ERR H5E_HEAP +#define H5_MY_PKG H5HL +#define H5_MY_PKG_ERR H5E_HEAP +#define H5_MY_PKG_INIT NO #endif /* H5HLmodule_H */ diff --git a/src/H5HLpkg.h b/src/H5HLpkg.h index aae0078a4c9..2018db25f8a 100644 --- a/src/H5HLpkg.h +++ b/src/H5HLpkg.h @@ -42,15 +42,6 @@ H5FL_BLK_EXTERN(lheap_chunk); /* Package Private Macros */ /**************************/ -/* If this package header is being included in one of the H5HL source files, - * define the proper control macros for the generic FUNC_ENTER/LEAVE and - * error reporting macros. - */ -#ifdef H5HL_PACKAGE -#define H5_MY_PKG H5HL -#define H5_MY_PKG_ERR H5E_HEAP -#endif - #define H5HL_SIZEOF_HDR(F) \ H5HL_ALIGN(H5_SIZEOF_MAGIC + /* heap signature */ \ 1 + /* version */ \ diff --git a/src/H5Iint.c b/src/H5Iint.c index 57bb75bbbd1..785dd9f0e86 100644 --- a/src/H5Iint.c +++ b/src/H5Iint.c @@ -84,6 +84,9 @@ static int H5I__find_id_cb(void *_item, void *_key, void *_udata); /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* Declared extern in H5Ipkg.h and documented there */ H5I_type_info_t *H5I_type_info_array_g[H5I_MAX_NUM_TYPES]; int H5I_next_type_g = (int)H5I_NTYPES; @@ -123,24 +126,30 @@ H5I_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - H5I_type_info_t *type_info = NULL; /* Pointer to ID type */ - int i; - - /* Count the number of types still in use */ - for (i = 0; i < H5I_next_type_g; i++) - if ((type_info = H5I_type_info_array_g[i]) && type_info->hash_table) - in_use++; - - /* If no types are still being used then clean up */ - if (0 == in_use) { - for (i = 0; i < H5I_next_type_g; i++) { - type_info = H5I_type_info_array_g[i]; - if (type_info) { - assert(NULL == type_info->hash_table); - type_info = H5MM_xfree(type_info); - H5I_type_info_array_g[i] = NULL; + if (H5_PKG_INIT_VAR) { + H5I_type_info_t *type_info = NULL; /* Pointer to ID type */ + int i; + + /* Count the number of types still in use */ + for (i = 0; i < H5I_next_type_g; i++) + if ((type_info = H5I_type_info_array_g[i]) && type_info->hash_table) in_use++; + + /* If no types are still being used then clean up */ + if (0 == in_use) { + for (i = 0; i < H5I_next_type_g; i++) { + type_info = H5I_type_info_array_g[i]; + if (type_info) { + assert(NULL == type_info->hash_table); + type_info = H5MM_xfree(type_info); + H5I_type_info_array_g[i] = NULL; + in_use++; + } } + + /* Mark interface closed */ + if (0 == in_use) + H5_PKG_INIT_VAR = false; } } diff --git a/src/H5Imodule.h b/src/H5Imodule.h index 6f9c4491fb0..45631409862 100644 --- a/src/H5Imodule.h +++ b/src/H5Imodule.h @@ -22,8 +22,9 @@ * reporting macros. */ #define H5I_MODULE -#define H5_MY_PKG H5I -#define H5_MY_PKG_ERR H5E_ID +#define H5_MY_PKG H5I +#define H5_MY_PKG_ERR H5E_ID +#define H5_MY_PKG_INIT NO /** \page H5I_UG HDF5 Identifiers * @todo Under Construction diff --git a/src/H5Lint.c b/src/H5Lint.c index 96f4a6937f9..ab066dd20fd 100644 --- a/src/H5Lint.c +++ b/src/H5Lint.c @@ -174,6 +174,9 @@ static herr_t H5L__get_name_by_idx_cb(H5G_loc_t *grp_loc /*in*/, const char *nam /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /*****************************/ /* Library Private Variables */ /*****************************/ @@ -204,6 +207,27 @@ H5L_init(void) herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_init() */ + +/*------------------------------------------------------------------------- + * Function: H5L__init_package + * + * Purpose: Initialize information specific to H5L interface. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5L__init_package(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE /* Initialize user-defined link classes */ if (H5L_register_external() < 0) @@ -211,12 +235,12 @@ H5L_init(void) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5L_init() */ +} /* end H5L_init_package() */ /*------------------------------------------------------------------------- * Function: H5L_term_package * - * Purpose: Terminate any resources allocated in H5L_init. + * Purpose: Terminate any resources allocated in H5L__init_package. * * Return: Non-negative on success/Negative on failure * @@ -229,11 +253,17 @@ H5L_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - /* Free the table of link types */ - if (H5L_table_g) { - H5L_table_g = (H5L_class_t *)H5MM_xfree(H5L_table_g); - H5L_table_used_g = H5L_table_alloc_g = 0; - n++; + if (H5_PKG_INIT_VAR) { + /* Free the table of link types */ + if (H5L_table_g) { + H5L_table_g = (H5L_class_t *)H5MM_xfree(H5L_table_g); + H5L_table_used_g = H5L_table_alloc_g = 0; + n++; + } /* end if */ + + /* Mark the interface as uninitialized */ + if (0 == n) + H5_PKG_INIT_VAR = false; } /* end if */ FUNC_LEAVE_NOAPI(n) diff --git a/src/H5Lmodule.h b/src/H5Lmodule.h index fda22a9b6ca..963005ab34e 100644 --- a/src/H5Lmodule.h +++ b/src/H5Lmodule.h @@ -22,8 +22,9 @@ * reporting macros. */ #define H5L_MODULE -#define H5_MY_PKG H5L -#define H5_MY_PKG_ERR H5E_LINK +#define H5_MY_PKG H5L +#define H5_MY_PKG_ERR H5E_LINK +#define H5_MY_PKG_INIT YES /** \page H5L_UG HDF5 Links * @todo Under Construction diff --git a/src/H5M.c b/src/H5M.c index a862bad54fe..8108303e43f 100644 --- a/src/H5M.c +++ b/src/H5M.c @@ -57,6 +57,9 @@ static herr_t H5M__get_api_common(hid_t map_id, hid_t key_mem_type_id, const voi /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /*****************************/ /* Library Private Variables */ /*****************************/ @@ -73,6 +76,9 @@ static const H5I_class_t H5I_MAP_CLS[1] = {{ (H5I_free_t)H5M__close_cb /* Callback routine for closing objects of this class */ }}; +/* Flag indicating "top" of interface has been initialized */ +static bool H5M_top_package_initialize_s = false; + /*------------------------------------------------------------------------- * Function: H5M_init * @@ -89,14 +95,40 @@ H5M_init(void) herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5M_init() */ + +/*------------------------------------------------------------------------- +NAME + H5M__init_package -- Initialize interface-specific information +USAGE + herr_t H5M__init_package() +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. +--------------------------------------------------------------------------- +*/ +herr_t +H5M__init_package(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE /* Initialize the ID group for the map IDs */ if (H5I_register_type(H5I_MAP_CLS) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, FAIL, "unable to initialize interface"); + /* Mark "top" of interface as initialized, too */ + H5M_top_package_initialize_s = true; + done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5M_init() */ +} /* end H5M__init_package() */ /*------------------------------------------------------------------------- * Function: H5M_top_term_package @@ -115,10 +147,16 @@ H5M_top_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - if (H5I_nmembers(H5I_MAP) > 0) { - (void)H5I_clear_type(H5I_MAP, false, false); - n++; - } + if (H5M_top_package_initialize_s) { + if (H5I_nmembers(H5I_MAP) > 0) { + (void)H5I_clear_type(H5I_MAP, false, false); + n++; + } + + /* Mark closed */ + if (0 == n) + H5M_top_package_initialize_s = false; + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5M_top_term_package() */ @@ -143,11 +181,18 @@ H5M_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - /* Sanity checks */ - assert(0 == H5I_nmembers(H5I_MAP)); + if (H5_PKG_INIT_VAR) { + /* Sanity checks */ + assert(0 == H5I_nmembers(H5I_MAP)); + assert(false == H5M_top_package_initialize_s); - /* Destroy the dataset object id group */ - n += (H5I_dec_type_ref(H5I_MAP) > 0); + /* Destroy the dataset object id group */ + n += (H5I_dec_type_ref(H5I_MAP) > 0); + + /* Mark closed */ + if (0 == n) + H5_PKG_INIT_VAR = false; + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5M_term_package() */ diff --git a/src/H5MF.c b/src/H5MF.c index a09bb3afcc3..f259318c0ac 100644 --- a/src/H5MF.c +++ b/src/H5MF.c @@ -111,6 +111,9 @@ static herr_t H5MF__sects_cb(H5FS_section_info_t *_sect, void *_udata); /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /*****************************/ /* Library Private Variables */ /*****************************/ @@ -1229,14 +1232,14 @@ H5MF_xfree(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size) htri_t H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, hsize_t extra_requested) { - H5AC_ring_t orig_ring = H5AC_RING_INV; /* Original ring value */ - H5AC_ring_t fsm_ring; /* Ring of FSM */ - haddr_t end; /* End of block to extend */ - H5FD_mem_t map_type; /* Mapped type */ - H5F_mem_page_t fs_type; /* free space type */ - htri_t allow_extend = true; /* Possible to extend the block */ - hsize_t frag_size = 0; /* Size of mis-aligned fragment */ - htri_t ret_value = false; /* Return value */ + H5AC_ring_t orig_ring = H5AC_RING_INV; /* Original ring value */ + H5AC_ring_t fsm_ring; /* Ring of FSM */ + haddr_t end; /* End of block to extend */ + H5FD_mem_t map_type; /* Mapped type */ + H5F_mem_page_t fs_type = H5F_MEM_PAGE_NTYPES; /* free space type */ + htri_t allow_extend = true; /* Possible to extend the block */ + hsize_t frag_size = 0; /* Size of mis-aligned fragment */ + htri_t ret_value = false; /* Return value */ FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL) #ifdef H5MF_ALLOC_DEBUG @@ -2552,14 +2555,14 @@ H5MF_settle_raw_data_fsm(H5F_t *f, bool *fsm_settled) { int pass_count; hsize_t alloc_size; - H5F_mem_t mem_type; /* Memory type for iteration */ - H5F_mem_page_t fsm_type; /* FSM type for iteration */ - H5O_fsinfo_t fsinfo; /* Free space manager info message */ - H5FS_stat_t fs_stat; /* Information for free-space manager */ - H5AC_ring_t orig_ring = H5AC_RING_INV; /* Original ring value */ - H5AC_ring_t curr_ring = H5AC_RING_INV; /* Current ring value */ - H5AC_ring_t needed_ring = H5AC_RING_INV; /* Ring value needed for this iteration */ - herr_t ret_value = SUCCEED; /* Return value */ + H5F_mem_t mem_type; /* Memory type for iteration */ + H5F_mem_page_t fsm_type = H5F_MEM_PAGE_NTYPES; /* FSM type for iteration */ + H5O_fsinfo_t fsinfo; /* Free space manager info message */ + H5FS_stat_t fs_stat; /* Information for free-space manager */ + H5AC_ring_t orig_ring = H5AC_RING_INV; /* Original ring value */ + H5AC_ring_t curr_ring = H5AC_RING_INV; /* Current ring value */ + H5AC_ring_t needed_ring = H5AC_RING_INV; /* Ring value needed for this iteration */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL) @@ -3018,8 +3021,8 @@ H5MF_settle_raw_data_fsm(H5F_t *f, bool *fsm_settled) herr_t H5MF_settle_meta_data_fsm(H5F_t *f, bool *fsm_settled) { - H5F_mem_page_t sm_fshdr_fs_type; /* small fs hdr fsm */ - H5F_mem_page_t sm_fssinfo_fs_type; /* small fs sinfo fsm */ + H5F_mem_page_t sm_fshdr_fs_type = H5F_MEM_PAGE_NTYPES; /* small fs hdr fsm */ + H5F_mem_page_t sm_fssinfo_fs_type = H5F_MEM_PAGE_NTYPES; /* small fs sinfo fsm */ H5F_mem_page_t lg_fshdr_fs_type = H5F_MEM_PAGE_DEFAULT; /* large fs hdr fsm */ H5F_mem_page_t lg_fssinfo_fs_type = H5F_MEM_PAGE_DEFAULT; /* large fs sinfo fsm */ H5FS_t *sm_hdr_fspace = NULL; /* ptr to sm FSM hdr alloc FSM */ @@ -3309,11 +3312,11 @@ H5MF__continue_alloc_fsm(H5F_shared_t *f_sh, H5FS_t *sm_hdr_fspace, H5FS_t *sm_s static bool H5MF__fsm_type_is_self_referential(H5F_shared_t *f_sh, H5F_mem_page_t fsm_type) { - H5F_mem_page_t sm_fshdr_fsm; - H5F_mem_page_t sm_fssinfo_fsm; - H5F_mem_page_t lg_fshdr_fsm; - H5F_mem_page_t lg_fssinfo_fsm; - bool result = false; + H5F_mem_page_t sm_fshdr_fsm = H5F_MEM_PAGE_NTYPES; + H5F_mem_page_t sm_fssinfo_fsm = H5F_MEM_PAGE_NTYPES; + H5F_mem_page_t lg_fshdr_fsm = H5F_MEM_PAGE_NTYPES; + H5F_mem_page_t lg_fssinfo_fsm = H5F_MEM_PAGE_NTYPES; + bool result = false; FUNC_ENTER_PACKAGE_NOERR @@ -3361,9 +3364,9 @@ H5MF__fsm_type_is_self_referential(H5F_shared_t *f_sh, H5F_mem_page_t fsm_type) static bool H5MF__fsm_is_self_referential(H5F_shared_t *f_sh, H5FS_t *fspace) { - H5F_mem_page_t sm_fshdr_fsm; - H5F_mem_page_t sm_fssinfo_fsm; - bool result = false; + H5F_mem_page_t sm_fshdr_fsm = H5F_MEM_PAGE_NTYPES; + H5F_mem_page_t sm_fssinfo_fsm = H5F_MEM_PAGE_NTYPES; + bool result = false; FUNC_ENTER_PACKAGE_NOERR @@ -3375,8 +3378,8 @@ H5MF__fsm_is_self_referential(H5F_shared_t *f_sh, H5FS_t *fspace) H5MF__alloc_to_fs_type(f_sh, H5FD_MEM_FSPACE_SINFO, (size_t)1, &sm_fssinfo_fsm); if (H5F_SHARED_PAGED_AGGR(f_sh)) { - H5F_mem_page_t lg_fshdr_fsm; - H5F_mem_page_t lg_fssinfo_fsm; + H5F_mem_page_t lg_fshdr_fsm = H5F_MEM_PAGE_NTYPES; + H5F_mem_page_t lg_fssinfo_fsm = H5F_MEM_PAGE_NTYPES; H5MF__alloc_to_fs_type(f_sh, H5FD_MEM_FSPACE_HDR, f_sh->fs_page_size + 1, &lg_fshdr_fsm); H5MF__alloc_to_fs_type(f_sh, H5FD_MEM_FSPACE_SINFO, f_sh->fs_page_size + 1, &lg_fssinfo_fsm); diff --git a/src/H5MFmodule.h b/src/H5MFmodule.h index 94ae9ed32e1..e196ab03e61 100644 --- a/src/H5MFmodule.h +++ b/src/H5MFmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5MF_MODULE -#define H5_MY_PKG H5MF -#define H5_MY_PKG_ERR H5E_RESOURCE +#define H5_MY_PKG H5MF +#define H5_MY_PKG_ERR H5E_RESOURCE +#define H5_MY_PKG_INIT NO #endif /* H5MFmodule_H */ diff --git a/src/H5Mmodule.h b/src/H5Mmodule.h index 2305cad9cb9..a143fe3f1a5 100644 --- a/src/H5Mmodule.h +++ b/src/H5Mmodule.h @@ -22,8 +22,9 @@ * reporting macros. */ #define H5M_MODULE -#define H5_MY_PKG H5M -#define H5_MY_PKG_ERR H5E_MAP +#define H5_MY_PKG H5M +#define H5_MY_PKG_ERR H5E_MAP +#define H5_MY_PKG_INIT YES /** * \page H5M_UG HDF5 VOL Data Mapping diff --git a/src/H5Oint.c b/src/H5Oint.c index 6077a9e99b0..070ff9b3162 100644 --- a/src/H5Oint.c +++ b/src/H5Oint.c @@ -82,6 +82,9 @@ static herr_t H5O__reset_info2(H5O_info2_t *oinfo); /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* Header message ID to class mapping * * Remember to increment H5O_MSG_TYPES in H5Opkg.h when adding a new @@ -180,10 +183,11 @@ static const H5O_obj_class_t *const H5O_obj_class_g[] = { /*------------------------------------------------------------------------- * Function: H5O_init * - * Purpose: Initialize the interface from some other layer. + * Purpose: Initialize the interface from some other package. + * + * Return: Success: non-negative + * Failure: negative * - * Return: Success: non-negative - * Failure: negative *------------------------------------------------------------------------- */ H5_ATTR_CONST herr_t @@ -191,7 +195,27 @@ H5O_init(void) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_init() */ + +/*------------------------------------------------------------------------- + * Function: H5O__init_package + * + * Purpose: Initialize information specific to H5O interface. + * + * Return: Success: non-negative + * Failure: negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5O__init_package(void) +{ + FUNC_ENTER_PACKAGE_NOERR /* H5O interface sanity checks */ HDcompile_assert(H5O_MSG_TYPES == NELMTS(H5O_msg_class_g)); @@ -199,8 +223,8 @@ H5O_init(void) HDcompile_assert(H5O_UNKNOWN_ID < H5O_MSG_TYPES); - FUNC_LEAVE_NOAPI(ret_value) -} + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5O__init_package() */ /*------------------------------------------------------------------------- * Function: H5O__set_version @@ -546,7 +570,7 @@ H5O_open(H5O_loc_t *loc) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Check args */ assert(loc); @@ -558,6 +582,7 @@ H5O_open(H5O_loc_t *loc) else H5F_INCR_NOPEN_OBJS(loc->file); +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_open() */ diff --git a/src/H5Omodule.h b/src/H5Omodule.h index de697a296d9..4cd06fe3b0a 100644 --- a/src/H5Omodule.h +++ b/src/H5Omodule.h @@ -22,8 +22,9 @@ * reporting macros. */ #define H5O_MODULE -#define H5_MY_PKG H5O -#define H5_MY_PKG_ERR H5E_OHDR +#define H5_MY_PKG H5O +#define H5_MY_PKG_ERR H5E_OHDR +#define H5_MY_PKG_INIT YES /** \page H5O_UG HDF5 Objects * @todo Under Construction diff --git a/src/H5P.c b/src/H5P.c index 41ba7da4422..daf998fc135 100644 --- a/src/H5P.c +++ b/src/H5P.c @@ -52,6 +52,9 @@ typedef struct { /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /*****************************/ /* Library Private Variables */ /*****************************/ @@ -1492,7 +1495,7 @@ H5Pclose(hid_t plist_id) EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -char * +H5_ATTR_MALLOC char * H5Pget_class_name(hid_t pclass_id) { H5P_genclass_t *pclass; /* Property class to query */ diff --git a/src/H5PB.c b/src/H5PB.c index 68b711185ff..37831d03e5d 100644 --- a/src/H5PB.c +++ b/src/H5PB.c @@ -130,6 +130,9 @@ static herr_t H5PB__write_entry(H5F_shared_t *f_sh, H5PB_entry_t *page_entry); /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /*****************************/ /* Library Private Variables */ /*****************************/ diff --git a/src/H5PBmodule.h b/src/H5PBmodule.h index ba89f9e7dda..647e8205407 100644 --- a/src/H5PBmodule.h +++ b/src/H5PBmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5PB_MODULE -#define H5_MY_PKG H5PB -#define H5_MY_PKG_ERR H5E_RESOURCE +#define H5_MY_PKG H5PB +#define H5_MY_PKG_ERR H5E_RESOURCE +#define H5_MY_PKG_INIT NO #endif /* H5PBmodule_H */ diff --git a/src/H5PLint.c b/src/H5PLint.c index 8b6cd32f360..a1003147944 100644 --- a/src/H5PLint.c +++ b/src/H5PLint.c @@ -45,6 +45,9 @@ /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /*****************************/ /* Library Private Variables */ /*****************************/ @@ -119,21 +122,22 @@ H5PL__set_plugin_control_mask(unsigned int mask) } /* end H5PL__set_plugin_control_mask() */ /*------------------------------------------------------------------------- - * Function: H5PL_init + * Function: H5PL__init_package * - * Purpose: Initialize the interface from some other layer. + * Purpose: Initialize any package-specific data and call any init + * routines for the package. * * Return: Success: non-negative * Failure: negative *------------------------------------------------------------------------- */ herr_t -H5PL_init(void) +H5PL__init_package(void) { char *env_var = NULL; herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Check the environment variable to determine if the user wants * to ignore plugins. The special symbol H5PL_NO_PLUGIN (defined in @@ -155,7 +159,7 @@ H5PL_init(void) done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5PL__init_package() */ /*------------------------------------------------------------------------- * Function: H5PL_term_package @@ -178,17 +182,23 @@ H5PL_term_package(void) FUNC_ENTER_NOAPI_NOINIT - /* Close the plugin cache. - * We need to bump the return value if we did any real work here. - */ - if (H5PL__close_plugin_cache(&already_closed) < 0) - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTFREE, (-1), "problem closing plugin cache"); - if (!already_closed) - ret_value++; + if (H5_PKG_INIT_VAR) { + /* Close the plugin cache. + * We need to bump the return value if we did any real work here. + */ + if (H5PL__close_plugin_cache(&already_closed) < 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTFREE, (-1), "problem closing plugin cache"); + if (!already_closed) + ret_value++; - /* Close the search path table and free the paths */ - if (H5PL__close_path_table() < 0) - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTFREE, (-1), "problem closing search path table"); + /* Close the search path table and free the paths */ + if (H5PL__close_path_table() < 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTFREE, (-1), "problem closing search path table"); + + /* Mark the interface as uninitialized */ + if (0 == ret_value) + H5_PKG_INIT_VAR = false; + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -504,9 +514,10 @@ H5PL_iterate(H5PL_iterate_type_t iter_type, H5PL_iterate_t iter_op, void *op_dat { herr_t ret_value = H5_ITER_CONT; - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(H5_ITER_ERROR) ret_value = H5PL__path_table_iterate(iter_type, iter_op, op_data); +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5PL_iterate() */ diff --git a/src/H5PLmodule.h b/src/H5PLmodule.h index 46b586c91dd..e750344ac32 100644 --- a/src/H5PLmodule.h +++ b/src/H5PLmodule.h @@ -23,8 +23,9 @@ * reporting macros. */ #define H5PL_MODULE -#define H5_MY_PKG H5PL -#define H5_MY_PKG_ERR H5E_PLUGIN +#define H5_MY_PKG H5PL +#define H5_MY_PKG_ERR H5E_PLUGIN +#define H5_MY_PKG_INIT YES /** \page H5PL_UG HDF5 Plugins * diff --git a/src/H5PLprivate.h b/src/H5PLprivate.h index 32ba263e56d..504b43f89ce 100644 --- a/src/H5PLprivate.h +++ b/src/H5PLprivate.h @@ -82,6 +82,5 @@ typedef herr_t (*H5PL_iterate_t)(H5PL_type_t plugin_type, const void *plugin_inf /* Internal API routines */ H5_DLL const void *H5PL_load(H5PL_type_t plugin_type, const H5PL_key_t *key); H5_DLL herr_t H5PL_iterate(H5PL_iterate_type_t iter_type, H5PL_iterate_t iter_op, void *op_data); -H5_DLL herr_t H5PL_init(void); #endif /* H5PLprivate_H */ diff --git a/src/H5Pint.c b/src/H5Pint.c index 4e9a41ff676..da6fbc89274 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -118,7 +118,7 @@ static herr_t H5P__free_del_name_cb(void *item, void H5_ATTR_UNUSED *key, void H /* * Predefined property list classes. These are initialized at runtime by - * H5P_init() in this source file. + * H5P__init_package() in this source file. */ hid_t H5P_CLS_ROOT_ID_g = H5I_INVALID_HID; H5P_genclass_t *H5P_CLS_ROOT_g = NULL; @@ -168,7 +168,7 @@ H5P_genclass_t *H5P_CLS_VOL_INITIALIZE_g = NULL; /* * Predefined property lists for each predefined class. These are initialized - * at runtime by H5P_init() in this source file. + * at runtime by H5P__init_package() in this source file. */ hid_t H5P_LST_ATTRIBUTE_ACCESS_ID_g = H5I_INVALID_HID; hid_t H5P_LST_ATTRIBUTE_CREATE_ID_g = H5I_INVALID_HID; @@ -421,13 +421,64 @@ static const H5I_class_t H5I_GENPROPLST_CLS[1] = {{ */ herr_t H5P_init_phase1(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_init_phase1() */ + +/*------------------------------------------------------------------------- + * Function: H5P_init_phase2 + * + * Purpose: Finish initializing the interface from some other package. + * + * Note: This is broken out as a separate routine so that the + * library's default VFL driver can be chosen and initialized + * after the entire H5P interface has been initialized. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5P_init_phase2(void) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Set up the default VFL driver */ + if (H5P__facc_set_def_driver() < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set default VFL driver"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_init_phase2() */ + +/*-------------------------------------------------------------------------- +NAME + H5P__init_package -- Initialize interface-specific information +USAGE + herr_t H5P__init_package() +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. +--------------------------------------------------------------------------*/ +herr_t +H5P__init_package(void) { size_t tot_init = 0; /* Total # of classes initialized */ size_t pass_init; /* # of classes initialized in each pass */ size_t u; herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Sanity check */ HDcompile_assert(H5P_TYPE_REFERENCE_ACCESS == (H5P_TYPE_MAX_TYPE - 1)); @@ -518,36 +569,7 @@ H5P_init_phase1(void) } FUNC_LEAVE_NOAPI(ret_value) -} - -/*------------------------------------------------------------------------- - * Function: H5P_init_phase2 - * - * Purpose: Finish initializing the interface from some other package. - * - * Note: This is broken out as a separate routine so that the - * library's default VFL driver can be chosen and initialized - * after the entire H5P interface has been initialized. - * - * Return: Success: Non-negative - * Failure: Negative - * - *------------------------------------------------------------------------- - */ -herr_t -H5P_init_phase2(void) -{ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(FAIL) - - /* Set up the default VFL driver */ - if (H5P__facc_set_def_driver() < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "unable to set default VFL driver"); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5P_init_phase2() */ +} /* end H5P__init_package() */ /*-------------------------------------------------------------------------- NAME @@ -573,107 +595,113 @@ H5P_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - int64_t nlist, nclass; - - /* Destroy HDF5 library property classes & lists */ - - /* Check if there are any open property list classes or lists */ - nclass = H5I_nmembers(H5I_GENPROP_CLS); - nlist = H5I_nmembers(H5I_GENPROP_LST); - - /* If there are any open classes or groups, attempt to get rid of them. */ - if ((nclass + nlist) > 0) { - /* Clear the lists */ - if (nlist > 0) { - (void)H5I_clear_type(H5I_GENPROP_LST, false, false); - - /* Reset the default property lists, if they've been closed */ - if (H5I_nmembers(H5I_GENPROP_LST) == 0) { - H5P_LST_ATTRIBUTE_ACCESS_ID_g = H5I_INVALID_HID; - H5P_LST_ATTRIBUTE_CREATE_ID_g = H5I_INVALID_HID; - H5P_LST_DATASET_ACCESS_ID_g = H5I_INVALID_HID; - H5P_LST_DATASET_CREATE_ID_g = H5I_INVALID_HID; - H5P_LST_DATASET_XFER_ID_g = H5I_INVALID_HID; - H5P_LST_DATATYPE_ACCESS_ID_g = H5I_INVALID_HID; - H5P_LST_DATATYPE_CREATE_ID_g = H5I_INVALID_HID; - H5P_LST_FILE_ACCESS_ID_g = H5I_INVALID_HID; - H5P_LST_FILE_CREATE_ID_g = H5I_INVALID_HID; - H5P_LST_FILE_MOUNT_ID_g = H5I_INVALID_HID; - H5P_LST_GROUP_ACCESS_ID_g = H5I_INVALID_HID; - H5P_LST_GROUP_CREATE_ID_g = H5I_INVALID_HID; - H5P_LST_LINK_ACCESS_ID_g = H5I_INVALID_HID; - H5P_LST_LINK_CREATE_ID_g = H5I_INVALID_HID; - H5P_LST_MAP_ACCESS_ID_g = H5I_INVALID_HID; - H5P_LST_MAP_CREATE_ID_g = H5I_INVALID_HID; - H5P_LST_OBJECT_COPY_ID_g = H5I_INVALID_HID; - H5P_LST_REFERENCE_ACCESS_ID_g = H5I_INVALID_HID; - H5P_LST_VOL_INITIALIZE_ID_g = H5I_INVALID_HID; + if (H5_PKG_INIT_VAR) { + int64_t nlist, nclass; + + /* Destroy HDF5 library property classes & lists */ + + /* Check if there are any open property list classes or lists */ + nclass = H5I_nmembers(H5I_GENPROP_CLS); + nlist = H5I_nmembers(H5I_GENPROP_LST); + + /* If there are any open classes or groups, attempt to get rid of them. */ + if ((nclass + nlist) > 0) { + /* Clear the lists */ + if (nlist > 0) { + (void)H5I_clear_type(H5I_GENPROP_LST, false, false); + + /* Reset the default property lists, if they've been closed */ + if (H5I_nmembers(H5I_GENPROP_LST) == 0) { + H5P_LST_ATTRIBUTE_ACCESS_ID_g = H5I_INVALID_HID; + H5P_LST_ATTRIBUTE_CREATE_ID_g = H5I_INVALID_HID; + H5P_LST_DATASET_ACCESS_ID_g = H5I_INVALID_HID; + H5P_LST_DATASET_CREATE_ID_g = H5I_INVALID_HID; + H5P_LST_DATASET_XFER_ID_g = H5I_INVALID_HID; + H5P_LST_DATATYPE_ACCESS_ID_g = H5I_INVALID_HID; + H5P_LST_DATATYPE_CREATE_ID_g = H5I_INVALID_HID; + H5P_LST_FILE_ACCESS_ID_g = H5I_INVALID_HID; + H5P_LST_FILE_CREATE_ID_g = H5I_INVALID_HID; + H5P_LST_FILE_MOUNT_ID_g = H5I_INVALID_HID; + H5P_LST_GROUP_ACCESS_ID_g = H5I_INVALID_HID; + H5P_LST_GROUP_CREATE_ID_g = H5I_INVALID_HID; + H5P_LST_LINK_ACCESS_ID_g = H5I_INVALID_HID; + H5P_LST_LINK_CREATE_ID_g = H5I_INVALID_HID; + H5P_LST_MAP_ACCESS_ID_g = H5I_INVALID_HID; + H5P_LST_MAP_CREATE_ID_g = H5I_INVALID_HID; + H5P_LST_OBJECT_COPY_ID_g = H5I_INVALID_HID; + H5P_LST_REFERENCE_ACCESS_ID_g = H5I_INVALID_HID; + H5P_LST_VOL_INITIALIZE_ID_g = H5I_INVALID_HID; + } } - } - /* Only attempt to close the classes after all the lists are closed */ - if (nlist == 0 && nclass > 0) { - (void)H5I_clear_type(H5I_GENPROP_CLS, false, false); - - /* Reset the default property classes and IDs if they've been closed */ - if (H5I_nmembers(H5I_GENPROP_CLS) == 0) { - H5P_CLS_ROOT_g = NULL; - - H5P_CLS_ATTRIBUTE_ACCESS_g = NULL; - H5P_CLS_ATTRIBUTE_CREATE_g = NULL; - H5P_CLS_DATASET_ACCESS_g = NULL; - H5P_CLS_DATASET_CREATE_g = NULL; - H5P_CLS_DATASET_XFER_g = NULL; - H5P_CLS_DATATYPE_ACCESS_g = NULL; - H5P_CLS_DATATYPE_CREATE_g = NULL; - H5P_CLS_FILE_ACCESS_g = NULL; - H5P_CLS_FILE_CREATE_g = NULL; - H5P_CLS_FILE_MOUNT_g = NULL; - H5P_CLS_GROUP_ACCESS_g = NULL; - H5P_CLS_GROUP_CREATE_g = NULL; - H5P_CLS_LINK_ACCESS_g = NULL; - H5P_CLS_LINK_CREATE_g = NULL; - H5P_CLS_MAP_ACCESS_g = NULL; - H5P_CLS_MAP_CREATE_g = NULL; - H5P_CLS_OBJECT_COPY_g = NULL; - H5P_CLS_OBJECT_CREATE_g = NULL; - H5P_CLS_REFERENCE_ACCESS_g = NULL; - H5P_CLS_STRING_CREATE_g = NULL; - H5P_CLS_VOL_INITIALIZE_g = NULL; - - H5P_CLS_ROOT_ID_g = H5I_INVALID_HID; - - H5P_CLS_ATTRIBUTE_ACCESS_ID_g = H5I_INVALID_HID; - H5P_CLS_ATTRIBUTE_CREATE_ID_g = H5I_INVALID_HID; - H5P_CLS_DATASET_ACCESS_ID_g = H5I_INVALID_HID; - H5P_CLS_DATASET_CREATE_ID_g = H5I_INVALID_HID; - H5P_CLS_DATASET_XFER_ID_g = H5I_INVALID_HID; - H5P_CLS_DATATYPE_ACCESS_ID_g = H5I_INVALID_HID; - H5P_CLS_DATATYPE_CREATE_ID_g = H5I_INVALID_HID; - H5P_CLS_FILE_ACCESS_ID_g = H5I_INVALID_HID; - H5P_CLS_FILE_CREATE_ID_g = H5I_INVALID_HID; - H5P_CLS_FILE_MOUNT_ID_g = H5I_INVALID_HID; - H5P_CLS_GROUP_ACCESS_ID_g = H5I_INVALID_HID; - H5P_CLS_GROUP_CREATE_ID_g = H5I_INVALID_HID; - H5P_CLS_LINK_ACCESS_ID_g = H5I_INVALID_HID; - H5P_CLS_LINK_CREATE_ID_g = H5I_INVALID_HID; - H5P_CLS_MAP_ACCESS_ID_g = H5I_INVALID_HID; - H5P_CLS_MAP_CREATE_ID_g = H5I_INVALID_HID; - H5P_CLS_OBJECT_COPY_ID_g = H5I_INVALID_HID; - H5P_CLS_OBJECT_CREATE_ID_g = H5I_INVALID_HID; - H5P_CLS_REFERENCE_ACCESS_ID_g = H5I_INVALID_HID; - H5P_CLS_STRING_CREATE_ID_g = H5I_INVALID_HID; - H5P_CLS_VOL_INITIALIZE_ID_g = H5I_INVALID_HID; + /* Only attempt to close the classes after all the lists are closed */ + if (nlist == 0 && nclass > 0) { + (void)H5I_clear_type(H5I_GENPROP_CLS, false, false); + + /* Reset the default property classes and IDs if they've been closed */ + if (H5I_nmembers(H5I_GENPROP_CLS) == 0) { + H5P_CLS_ROOT_g = NULL; + + H5P_CLS_ATTRIBUTE_ACCESS_g = NULL; + H5P_CLS_ATTRIBUTE_CREATE_g = NULL; + H5P_CLS_DATASET_ACCESS_g = NULL; + H5P_CLS_DATASET_CREATE_g = NULL; + H5P_CLS_DATASET_XFER_g = NULL; + H5P_CLS_DATATYPE_ACCESS_g = NULL; + H5P_CLS_DATATYPE_CREATE_g = NULL; + H5P_CLS_FILE_ACCESS_g = NULL; + H5P_CLS_FILE_CREATE_g = NULL; + H5P_CLS_FILE_MOUNT_g = NULL; + H5P_CLS_GROUP_ACCESS_g = NULL; + H5P_CLS_GROUP_CREATE_g = NULL; + H5P_CLS_LINK_ACCESS_g = NULL; + H5P_CLS_LINK_CREATE_g = NULL; + H5P_CLS_MAP_ACCESS_g = NULL; + H5P_CLS_MAP_CREATE_g = NULL; + H5P_CLS_OBJECT_COPY_g = NULL; + H5P_CLS_OBJECT_CREATE_g = NULL; + H5P_CLS_REFERENCE_ACCESS_g = NULL; + H5P_CLS_STRING_CREATE_g = NULL; + H5P_CLS_VOL_INITIALIZE_g = NULL; + + H5P_CLS_ROOT_ID_g = H5I_INVALID_HID; + + H5P_CLS_ATTRIBUTE_ACCESS_ID_g = H5I_INVALID_HID; + H5P_CLS_ATTRIBUTE_CREATE_ID_g = H5I_INVALID_HID; + H5P_CLS_DATASET_ACCESS_ID_g = H5I_INVALID_HID; + H5P_CLS_DATASET_CREATE_ID_g = H5I_INVALID_HID; + H5P_CLS_DATASET_XFER_ID_g = H5I_INVALID_HID; + H5P_CLS_DATATYPE_ACCESS_ID_g = H5I_INVALID_HID; + H5P_CLS_DATATYPE_CREATE_ID_g = H5I_INVALID_HID; + H5P_CLS_FILE_ACCESS_ID_g = H5I_INVALID_HID; + H5P_CLS_FILE_CREATE_ID_g = H5I_INVALID_HID; + H5P_CLS_FILE_MOUNT_ID_g = H5I_INVALID_HID; + H5P_CLS_GROUP_ACCESS_ID_g = H5I_INVALID_HID; + H5P_CLS_GROUP_CREATE_ID_g = H5I_INVALID_HID; + H5P_CLS_LINK_ACCESS_ID_g = H5I_INVALID_HID; + H5P_CLS_LINK_CREATE_ID_g = H5I_INVALID_HID; + H5P_CLS_MAP_ACCESS_ID_g = H5I_INVALID_HID; + H5P_CLS_MAP_CREATE_ID_g = H5I_INVALID_HID; + H5P_CLS_OBJECT_COPY_ID_g = H5I_INVALID_HID; + H5P_CLS_OBJECT_CREATE_ID_g = H5I_INVALID_HID; + H5P_CLS_REFERENCE_ACCESS_ID_g = H5I_INVALID_HID; + H5P_CLS_STRING_CREATE_ID_g = H5I_INVALID_HID; + H5P_CLS_VOL_INITIALIZE_ID_g = H5I_INVALID_HID; + } } + + n++; /*H5I*/ } + else { + /* Destroy the property list and class id groups */ + n += (H5I_dec_type_ref(H5I_GENPROP_LST) > 0); + n += (H5I_dec_type_ref(H5I_GENPROP_CLS) > 0); - n++; /*H5I*/ - } - else { - /* Destroy the property list and class id groups */ - n += (H5I_dec_type_ref(H5I_GENPROP_LST) > 0); - n += (H5I_dec_type_ref(H5I_GENPROP_CLS) > 0); - } /* end else */ + /* Mark closed */ + if (0 == n) + H5_PKG_INIT_VAR = false; + } /* end else */ + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5P_term_package() */ @@ -3541,7 +3569,7 @@ H5P_get_nprops_pclass(const H5P_genclass_t *pclass, size_t *nprops, bool recurse { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) assert(pclass); assert(nprops); @@ -3556,6 +3584,7 @@ H5P_get_nprops_pclass(const H5P_genclass_t *pclass, size_t *nprops, bool recurse *nprops += pclass->nprops; } /* end while */ +done: FUNC_LEAVE_NOAPI(ret_value) } /* H5P_get_nprops_pclass() */ @@ -3986,7 +4015,7 @@ H5P_class_isa(const H5P_genclass_t *pclass1, const H5P_genclass_t *pclass2) { htri_t ret_value = FAIL; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) assert(pclass1); assert(pclass2); @@ -5281,13 +5310,14 @@ H5P_get_class_name(H5P_genclass_t *pclass) { char *ret_value = NULL; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(NULL) assert(pclass); /* Get class name */ ret_value = H5MM_xstrdup(pclass->name); +done: FUNC_LEAVE_NOAPI(ret_value) } /* H5P_get_class_name() */ diff --git a/src/H5Pmodule.h b/src/H5Pmodule.h index 88cab4d3a12..b7eb4c78a75 100644 --- a/src/H5Pmodule.h +++ b/src/H5Pmodule.h @@ -22,8 +22,9 @@ * reporting macros. */ #define H5P_MODULE -#define H5_MY_PKG H5P -#define H5_MY_PKG_ERR H5E_PLIST +#define H5_MY_PKG H5P +#define H5_MY_PKG_ERR H5E_PLIST +#define H5_MY_PKG_INIT YES /** \page H5P_UG Properties and Property Lists in HDF5 * diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index fa4c3ba5b8c..4a7e3d0229b 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -34,14 +34,6 @@ /* Public Macros */ /*****************/ -/* When this header is included from a private HDF5 header, don't make calls to H5open() */ -#undef H5OPEN -#ifndef H5private_H -#define H5OPEN H5open(), -#else /* H5private_H */ -#define H5OPEN -#endif /* H5private_H */ - /* * The library's property list classes */ diff --git a/src/H5RS.c b/src/H5RS.c index 238390335eb..b83f6da8401 100644 --- a/src/H5RS.c +++ b/src/H5RS.c @@ -69,6 +69,9 @@ static herr_t H5RS__resize_for_append(H5RS_str_t *rs, size_t len); /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /*****************************/ /* Library Private Variables */ /*****************************/ diff --git a/src/H5RSmodule.h b/src/H5RSmodule.h index 578474a9729..5079f363447 100644 --- a/src/H5RSmodule.h +++ b/src/H5RSmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5RS_MODULE -#define H5_MY_PKG H5RS -#define H5_MY_PKG_ERR H5E_RS +#define H5_MY_PKG H5RS +#define H5_MY_PKG_ERR H5E_RS +#define H5_MY_PKG_INIT NO #endif /* H5RSmodule_H */ diff --git a/src/H5Rint.c b/src/H5Rint.c index 1c5b0b68841..85282b1d4d6 100644 --- a/src/H5Rint.c +++ b/src/H5Rint.c @@ -135,6 +135,9 @@ static herr_t H5R__decode_string(const unsigned char *buf, size_t *nbytes, char /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /*****************************/ /* Library Private Variables */ /*****************************/ @@ -143,27 +146,26 @@ static herr_t H5R__decode_string(const unsigned char *buf, size_t *nbytes, char /* Local Variables */ /*******************/ -/*------------------------------------------------------------------------- - * Function: H5R_init - * - * Purpose: Initialize the interface from some other layer. - * - * Return: Success: non-negative - * Failure: negative - *------------------------------------------------------------------------- - */ +/*-------------------------------------------------------------------------- +NAME + H5R__init_package -- Initialize interface-specific information +USAGE + herr_t H5R__init_package() +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. +--------------------------------------------------------------------------*/ herr_t -H5R_init(void) +H5R__init_package(void) { - herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check, if assert fails, H5R_REF_BUF_SIZE must be increased */ HDcompile_assert(sizeof(H5R_ref_priv_t) <= H5R_REF_BUF_SIZE); - FUNC_LEAVE_NOAPI(ret_value) -} + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5R__init_package() */ /*------------------------------------------------------------------------- * Function: H5R__create_object diff --git a/src/H5Rmodule.h b/src/H5Rmodule.h index 87a367796a6..78328effab5 100644 --- a/src/H5Rmodule.h +++ b/src/H5Rmodule.h @@ -21,8 +21,9 @@ * reporting macros. */ #define H5R_MODULE -#define H5_MY_PKG H5R -#define H5_MY_PKG_ERR H5E_REFERENCE +#define H5_MY_PKG H5R +#define H5_MY_PKG_ERR H5E_REFERENCE +#define H5_MY_PKG_INIT YES /** \page H5R_UG HDF5 References * diff --git a/src/H5Rprivate.h b/src/H5Rprivate.h index 723dd30e953..8a3102860a1 100644 --- a/src/H5Rprivate.h +++ b/src/H5Rprivate.h @@ -38,6 +38,4 @@ /* Library Private Prototypes */ /******************************/ -H5_DLL herr_t H5R_init(void); - #endif /* H5Rprivate_H */ diff --git a/src/H5S.c b/src/H5S.c index d39232776ad..69c4224c6ed 100644 --- a/src/H5S.c +++ b/src/H5S.c @@ -54,6 +54,9 @@ static htri_t H5S__is_simple(const H5S_t *sdim); /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* Format version bounds for dataspace */ const unsigned H5O_sdspace_ver_bounds[] = { H5O_SDSPACE_VERSION_1, /* H5F_LIBVER_EARLIEST */ @@ -95,6 +98,9 @@ static const H5I_class_t H5I_SPACE_SEL_ITER_CLS[1] = {{ (H5I_free_t)H5S__sel_iter_close_cb /* Callback routine for closing objects of this class */ }}; +/* Flag indicating "top" of interface has been initialized */ +static bool H5S_top_package_initialize_s = false; + /*------------------------------------------------------------------------- * Function: H5S_init * @@ -110,6 +116,28 @@ H5S_init(void) herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_init() */ + +/*-------------------------------------------------------------------------- +NAME + H5S__init_package -- Initialize interface-specific information +USAGE + herr_t H5S__init_package() +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. +--------------------------------------------------------------------------*/ +herr_t +H5S__init_package(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE /* Initialize the ID group for the dataspace IDs */ if (H5I_register_type(H5I_DATASPACE_CLS) < 0) @@ -120,9 +148,12 @@ H5S_init(void) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize dataspace selection iterator ID class"); + /* Mark "top" of interface as initialized, too */ + H5S_top_package_initialize_s = true; + done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_init() */ +} /* end H5S__init_package() */ /*-------------------------------------------------------------------------- NAME @@ -149,14 +180,20 @@ H5S_top_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - if (H5I_nmembers(H5I_DATASPACE) > 0) { - (void)H5I_clear_type(H5I_DATASPACE, false, false); - n++; - } - if (H5I_nmembers(H5I_SPACE_SEL_ITER) > 0) { - (void)H5I_clear_type(H5I_SPACE_SEL_ITER, false, false); - n++; - } + if (H5S_top_package_initialize_s) { + if (H5I_nmembers(H5I_DATASPACE) > 0) { + (void)H5I_clear_type(H5I_DATASPACE, false, false); + n++; + } + if (H5I_nmembers(H5I_SPACE_SEL_ITER) > 0) { + (void)H5I_clear_type(H5I_SPACE_SEL_ITER, false, false); + n++; + } + + /* Mark "top" of interface as closed */ + if (0 == n) + H5S_top_package_initialize_s = false; + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5S_top_term_package() */ @@ -188,15 +225,22 @@ H5S_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - /* Sanity checks */ - assert(0 == H5I_nmembers(H5I_DATASPACE)); - assert(0 == H5I_nmembers(H5I_SPACE_SEL_ITER)); + if (H5_PKG_INIT_VAR) { + /* Sanity checks */ + assert(0 == H5I_nmembers(H5I_DATASPACE)); + assert(0 == H5I_nmembers(H5I_SPACE_SEL_ITER)); + assert(false == H5S_top_package_initialize_s); + + /* Destroy the dataspace object id group */ + n += (H5I_dec_type_ref(H5I_DATASPACE) > 0); - /* Destroy the dataspace object id group */ - n += (H5I_dec_type_ref(H5I_DATASPACE) > 0); + /* Destroy the dataspace selection iterator object id group */ + n += (H5I_dec_type_ref(H5I_SPACE_SEL_ITER) > 0); - /* Destroy the dataspace selection iterator object id group */ - n += (H5I_dec_type_ref(H5I_SPACE_SEL_ITER) > 0); + /* Mark interface as closed */ + if (0 == n) + H5_PKG_INIT_VAR = false; + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5S_term_package() */ @@ -686,7 +730,7 @@ H5S_get_simple_extent_npoints(const H5S_t *ds) { hssize_t ret_value = -1; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(-1) /* check args */ assert(ds); @@ -694,6 +738,7 @@ H5S_get_simple_extent_npoints(const H5S_t *ds) /* Get the number of elements in extent */ ret_value = (hssize_t)ds->extent.nelem; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_get_simple_extent_npoints() */ @@ -1630,12 +1675,13 @@ H5S_get_simple_extent_type(const H5S_t *space) { H5S_class_t ret_value = H5S_NO_CLASS; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(H5S_NO_CLASS) assert(space); ret_value = H5S_GET_EXTENT_TYPE(space); +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_get_simple_extent_type() */ diff --git a/src/H5SL.c b/src/H5SL.c index 813a5961064..3b548b3ff54 100644 --- a/src/H5SL.c +++ b/src/H5SL.c @@ -509,6 +509,9 @@ static H5SL_node_t *H5SL__insert_common(H5SL_t *slist, void *item, const void *k static herr_t H5SL__release_common(H5SL_t *slist, H5SL_operator_t op, void *op_data); static herr_t H5SL__close_common(H5SL_t *slist, H5SL_operator_t op, void *op_data); +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* Declare a free list to manage the H5SL_t struct */ H5FL_DEFINE_STATIC(H5SL_t); @@ -520,21 +523,26 @@ static H5FL_fac_head_t **H5SL_fac_g; static size_t H5SL_fac_nused_g; static size_t H5SL_fac_nalloc_g; -/*------------------------------------------------------------------------- - * Function: H5SL_init - * - * Purpose: Initialize the interface from some other layer. - * - * Return: Success: non-negative - * Failure: negative - *------------------------------------------------------------------------- - */ +/*-------------------------------------------------------------------------- + NAME + H5SL__init_package + PURPOSE + Initialize interface-specific information + USAGE + herr_t H5SL__init_package() + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Initializes any interface-specific data or routines. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ herr_t -H5SL_init(void) +H5SL__init_package(void) { - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_PACKAGE_NOERR /* Allocate space for array of factories */ H5SL_fac_g = (H5FL_fac_head_t **)H5MM_malloc(sizeof(H5FL_fac_head_t *)); @@ -546,8 +554,8 @@ H5SL_init(void) assert(H5SL_fac_g[0]); H5SL_fac_nused_g = 1; - FUNC_LEAVE_NOAPI(ret_value) -} + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5SL__init_package() */ /*-------------------------------------------------------------------------- NAME @@ -575,26 +583,32 @@ H5SL_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - /* Terminate all the factories */ - if (H5SL_fac_nused_g > 0) { - size_t i; - herr_t H5_ATTR_NDEBUG_UNUSED ret; + if (H5_PKG_INIT_VAR) { + /* Terminate all the factories */ + if (H5SL_fac_nused_g > 0) { + size_t i; + herr_t H5_ATTR_NDEBUG_UNUSED ret; + + for (i = 0; i < H5SL_fac_nused_g; i++) { + ret = H5FL_fac_term(H5SL_fac_g[i]); + assert(ret >= 0); + } + H5SL_fac_nused_g = 0; - for (i = 0; i < H5SL_fac_nused_g; i++) { - ret = H5FL_fac_term(H5SL_fac_g[i]); - assert(ret >= 0); + n++; } - H5SL_fac_nused_g = 0; - n++; - } + /* Free the list of factories */ + if (H5SL_fac_g) { + H5SL_fac_g = (H5FL_fac_head_t **)H5MM_xfree((void *)H5SL_fac_g); + H5SL_fac_nalloc_g = 0; - /* Free the list of factories */ - if (H5SL_fac_g) { - H5SL_fac_g = (H5FL_fac_head_t **)H5MM_xfree((void *)H5SL_fac_g); - H5SL_fac_nalloc_g = 0; + n++; + } - n++; + /* Mark the interface as uninitialized */ + if (0 == n) + H5_PKG_INIT_VAR = false; } FUNC_LEAVE_NOAPI(n) diff --git a/src/H5SLmodule.h b/src/H5SLmodule.h index 83cfa591327..a3a42654c93 100644 --- a/src/H5SLmodule.h +++ b/src/H5SLmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5SL_MODULE -#define H5_MY_PKG H5SL -#define H5_MY_PKG_ERR H5E_SLIST +#define H5_MY_PKG H5SL +#define H5_MY_PKG_ERR H5E_SLIST +#define H5_MY_PKG_INIT YES #endif /* H5SLmodule_H */ diff --git a/src/H5SLprivate.h b/src/H5SLprivate.h index 14eee279509..cd42d92c706 100644 --- a/src/H5SLprivate.h +++ b/src/H5SLprivate.h @@ -81,7 +81,6 @@ H5_DLL herr_t H5SL_release(H5SL_t *slist); H5_DLL herr_t H5SL_free(H5SL_t *slist, H5SL_operator_t op, void *op_data); H5_DLL herr_t H5SL_close(H5SL_t *slist); H5_DLL herr_t H5SL_destroy(H5SL_t *slist, H5SL_operator_t op, void *op_data); -H5_DLL herr_t H5SL_init(void); H5_DLL int H5SL_term_interface(void); #endif /* H5SLprivate_H */ diff --git a/src/H5SM.c b/src/H5SM.c index f096a50c8b8..2b98bdbb98b 100644 --- a/src/H5SM.c +++ b/src/H5SM.c @@ -82,6 +82,9 @@ static herr_t H5SM__read_mesg(H5F_t *f, const H5SM_sohm_t *mesg, H5HF_t *fheap, /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + H5FL_DEFINE(H5SM_master_table_t); H5FL_ARR_DEFINE(H5SM_index_header_t, H5O_SHMESG_MAX_NINDEXES); H5FL_DEFINE(H5SM_list_t); diff --git a/src/H5SMmodule.h b/src/H5SMmodule.h index d0f247f3a00..d669d5dc76a 100644 --- a/src/H5SMmodule.h +++ b/src/H5SMmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5SM_MODULE -#define H5_MY_PKG H5SM -#define H5_MY_PKG_ERR H5E_SOHM +#define H5_MY_PKG H5SM +#define H5_MY_PKG_ERR H5E_SOHM +#define H5_MY_PKG_INIT NO #endif /* H5SMmodule_H */ diff --git a/src/H5Shyper.c b/src/H5Shyper.c index e0ca727bd09..560e2bf1c85 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -3725,10 +3725,10 @@ H5S__hyper_get_version_enc_size(H5S_t *space, hsize_t block_count, uint32_t *ver static hssize_t H5S__hyper_serial_size(H5S_t *space) { - hsize_t block_count = 0; /* block counter for regular hyperslabs */ - uint32_t version; /* Version number */ - uint8_t enc_size; /* Encoded size of hyperslab selection info */ - hssize_t ret_value = -1; /* return value */ + hsize_t block_count = 0; /* block counter for regular hyperslabs */ + uint32_t version = UINT_MAX; /* Version number */ + uint8_t enc_size; /* Encoded size of hyperslab selection info */ + hssize_t ret_value = -1; /* return value */ FUNC_ENTER_PACKAGE @@ -12100,7 +12100,7 @@ H5S_hyper_get_clip_extent(const H5S_t *clip_space, const H5S_t *match_space, boo hsize_t num_slices; /* Number of slices in unlimited dimension */ hsize_t ret_value = 0; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(0) /* Check parameters */ assert(clip_space); @@ -12122,6 +12122,7 @@ H5S_hyper_get_clip_extent(const H5S_t *clip_space, const H5S_t *match_space, boo /* Call "real" get_clip_extent function */ ret_value = H5S__hyper_get_clip_extent_real(clip_space, num_slices, incl_trail); +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_hyper_get_clip_extent() */ @@ -12157,7 +12158,7 @@ H5S_hyper_get_clip_extent_match(const H5S_t *clip_space, const H5S_t *match_spac hsize_t num_slices; /* Number of slices in unlimited dimension */ hsize_t ret_value = 0; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(0) /* Check parameters */ assert(clip_space); @@ -12203,6 +12204,7 @@ H5S_hyper_get_clip_extent_match(const H5S_t *clip_space, const H5S_t *match_spac /* Call "real" get_clip_extent function */ ret_value = H5S__hyper_get_clip_extent_real(clip_space, num_slices, incl_trail); +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_hyper_get_clip_extent_match() */ @@ -12318,7 +12320,7 @@ H5S_hyper_get_first_inc_block(const H5S_t *space, hsize_t clip_size, bool *parti H5S_hyper_dim_t *diminfo; /* Convenience pointer to diminfo in unlimited dimension */ hsize_t ret_value = 0; - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(0) /* Check parameters */ assert(space); @@ -12348,6 +12350,7 @@ H5S_hyper_get_first_inc_block(const H5S_t *space, hsize_t clip_size, bool *parti } /* end if */ } /* end else */ +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5S_hyper_get_first_inc_block */ diff --git a/src/H5Smodule.h b/src/H5Smodule.h index b0cdc574744..94103d05eb0 100644 --- a/src/H5Smodule.h +++ b/src/H5Smodule.h @@ -22,8 +22,9 @@ * reporting macros. */ #define H5S_MODULE -#define H5_MY_PKG H5S -#define H5_MY_PKG_ERR H5E_DATASPACE +#define H5_MY_PKG H5S +#define H5_MY_PKG_ERR H5E_DATASPACE +#define H5_MY_PKG_INIT YES /** \page H5S_UG Dataspaces and Partial I/O * diff --git a/src/H5T.c b/src/H5T.c index 9befc0836b5..dc8c59c963d 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -416,8 +416,11 @@ H5T_order_t H5T_native_order_g = H5T_ORDER_ERROR; /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* - * Predefined data types. These are initialized at runtime by H5T_init(). + * Predefined data types. These are initialized at runtime by H5T__init_package(). * * If more of these are added, the new ones must be added to the list of * types to reset in H5T_term_package(). @@ -642,6 +645,34 @@ static const H5I_class_t H5I_DATATYPE_CLS[1] = {{ (H5I_free_t)H5T__close_cb /* Callback routine for closing objects of this class */ }}; +/* Flag indicating "top" of interface has been initialized */ +static bool H5T_top_package_initialize_s = false; + +/*------------------------------------------------------------------------- + * Function: H5T_init + * + * Purpose: Initialize the interface from some other package. + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Robb Matzke + * Wednesday, December 16, 1998 + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_init(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_init() */ + /*------------------------------------------------------------------------- * Function: H5T__init_inf * @@ -794,17 +825,18 @@ H5T__init_inf(void) FUNC_LEAVE_NOAPI(ret_value) } /* end H5T__init_inf() */ -/*------------------------------------------------------------------------- - * Function: H5T_init - * - * Purpose: Initialize the interface from some other layer. - * - * Return: Success: non-negative - * Failure: negative - *------------------------------------------------------------------------- - */ +/*-------------------------------------------------------------------------- +NAME + H5T__init_package -- Initialize interface-specific information +USAGE + herr__t H5T_init_package() +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. +--------------------------------------------------------------------------*/ herr_t -H5T_init(void) +H5T__init_package(void) { H5T_t *native_schar = NULL; /* Datatype structure for native signed char */ H5T_t *native_uchar = NULL; /* Datatype structure for native unsigned char */ @@ -848,7 +880,7 @@ H5T_init(void) #endif herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_NOAPI_NOINIT /* Initialize the ID group for the file IDs */ if (H5I_register_type(H5I_DATATYPE_CLS) < 0) @@ -1595,7 +1627,7 @@ H5T_init(void) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to register conversion function(s)"); /* Register datatype creation property class properties here. See similar - * code in H5D_init(), etc. for example. + * code in H5D__init_package(), etc. for example. */ /* Only register the default property list if it hasn't been created yet */ @@ -1608,6 +1640,9 @@ H5T_init(void) HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class"); } /* end if */ + /* Mark "top" of interface as initialized, too */ + H5T_top_package_initialize_s = true; + done: /* General cleanup */ if (compound != NULL) @@ -1635,7 +1670,7 @@ H5T_init(void) } /* end if */ FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_init() */ +} /* end H5T__init_package() */ /*------------------------------------------------------------------------- * Function: H5T__unlock_cb @@ -1684,143 +1719,149 @@ H5T_top_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - /* Unregister all conversion functions */ - if (H5T_g.path) { - H5T_conv_ctx_t conv_ctx = {0}; + if (H5T_top_package_initialize_s) { + /* Unregister all conversion functions */ + if (H5T_g.path) { + H5T_conv_ctx_t conv_ctx = {0}; - conv_ctx.u.free.src_type_id = H5I_INVALID_HID; - conv_ctx.u.free.dst_type_id = H5I_INVALID_HID; + conv_ctx.u.free.src_type_id = H5I_INVALID_HID; + conv_ctx.u.free.dst_type_id = H5I_INVALID_HID; - for (int i = 0; i < H5T_g.npaths; i++) { - H5T_path_t *path = H5T_g.path[i]; + for (int i = 0; i < H5T_g.npaths; i++) { + H5T_path_t *path = H5T_g.path[i]; - (void)H5T__path_free(path, &conv_ctx); + (void)H5T__path_free(path, &conv_ctx); - H5T_g.path[i] = NULL; - } /* end for */ + H5T_g.path[i] = NULL; + } /* end for */ - /* Clear conversion tables */ - H5T_g.path = (H5T_path_t **)H5MM_xfree(H5T_g.path); - H5T_g.npaths = 0; - H5T_g.apaths = 0; - H5T_g.soft = (H5T_soft_t *)H5MM_xfree(H5T_g.soft); - H5T_g.nsoft = 0; - H5T_g.asoft = 0; + /* Clear conversion tables */ + H5T_g.path = (H5T_path_t **)H5MM_xfree(H5T_g.path); + H5T_g.npaths = 0; + H5T_g.apaths = 0; + H5T_g.soft = (H5T_soft_t *)H5MM_xfree(H5T_g.soft); + H5T_g.nsoft = 0; + H5T_g.asoft = 0; - n++; - } /* end if */ + n++; + } /* end if */ + + /* Unlock all datatypes, then free them */ + /* note that we are ignoring the return value from H5I_iterate() */ + /* Also note that we are incrementing 'n' in the callback */ + H5I_iterate(H5I_DATATYPE, H5T__unlock_cb, &n, false); + + /* Release all datatype IDs */ + if (H5I_nmembers(H5I_DATATYPE) > 0) { + (void)H5I_clear_type(H5I_DATATYPE, false, false); + n++; /*H5I*/ + } /* end if */ + + /* Reset all the datatype IDs */ + if (H5T_IEEE_F32BE_g > 0) { + H5T_IEEE_F16BE_g = H5I_INVALID_HID; + H5T_IEEE_F16LE_g = H5I_INVALID_HID; + H5T_IEEE_F32BE_g = H5I_INVALID_HID; + H5T_IEEE_F32LE_g = H5I_INVALID_HID; + H5T_IEEE_F64BE_g = H5I_INVALID_HID; + H5T_IEEE_F64LE_g = H5I_INVALID_HID; + + H5T_STD_I8BE_g = H5I_INVALID_HID; + H5T_STD_I8LE_g = H5I_INVALID_HID; + H5T_STD_I16BE_g = H5I_INVALID_HID; + H5T_STD_I16LE_g = H5I_INVALID_HID; + H5T_STD_I32BE_g = H5I_INVALID_HID; + H5T_STD_I32LE_g = H5I_INVALID_HID; + H5T_STD_I64BE_g = H5I_INVALID_HID; + H5T_STD_I64LE_g = H5I_INVALID_HID; + H5T_STD_U8BE_g = H5I_INVALID_HID; + H5T_STD_U8LE_g = H5I_INVALID_HID; + H5T_STD_U16BE_g = H5I_INVALID_HID; + H5T_STD_U16LE_g = H5I_INVALID_HID; + H5T_STD_U32BE_g = H5I_INVALID_HID; + H5T_STD_U32LE_g = H5I_INVALID_HID; + H5T_STD_U64BE_g = H5I_INVALID_HID; + H5T_STD_U64LE_g = H5I_INVALID_HID; + H5T_STD_B8BE_g = H5I_INVALID_HID; + H5T_STD_B8LE_g = H5I_INVALID_HID; + H5T_STD_B16BE_g = H5I_INVALID_HID; + H5T_STD_B16LE_g = H5I_INVALID_HID; + H5T_STD_B32BE_g = H5I_INVALID_HID; + H5T_STD_B32LE_g = H5I_INVALID_HID; + H5T_STD_B64BE_g = H5I_INVALID_HID; + H5T_STD_B64LE_g = H5I_INVALID_HID; + H5T_STD_REF_OBJ_g = H5I_INVALID_HID; + H5T_STD_REF_DSETREG_g = H5I_INVALID_HID; + H5T_STD_REF_g = H5I_INVALID_HID; + + H5T_UNIX_D32BE_g = H5I_INVALID_HID; + H5T_UNIX_D32LE_g = H5I_INVALID_HID; + H5T_UNIX_D64BE_g = H5I_INVALID_HID; + H5T_UNIX_D64LE_g = H5I_INVALID_HID; + + H5T_C_S1_g = H5I_INVALID_HID; + + H5T_FORTRAN_S1_g = H5I_INVALID_HID; + + H5T_NATIVE_SCHAR_g = H5I_INVALID_HID; + H5T_NATIVE_UCHAR_g = H5I_INVALID_HID; + H5T_NATIVE_SHORT_g = H5I_INVALID_HID; + H5T_NATIVE_USHORT_g = H5I_INVALID_HID; + H5T_NATIVE_INT_g = H5I_INVALID_HID; + H5T_NATIVE_UINT_g = H5I_INVALID_HID; + H5T_NATIVE_LONG_g = H5I_INVALID_HID; + H5T_NATIVE_ULONG_g = H5I_INVALID_HID; + H5T_NATIVE_LLONG_g = H5I_INVALID_HID; + H5T_NATIVE_ULLONG_g = H5I_INVALID_HID; + H5T_NATIVE_FLOAT16_g = H5I_INVALID_HID; + H5T_NATIVE_FLOAT_g = H5I_INVALID_HID; + H5T_NATIVE_DOUBLE_g = H5I_INVALID_HID; + H5T_NATIVE_LDOUBLE_g = H5I_INVALID_HID; + H5T_NATIVE_B8_g = H5I_INVALID_HID; + H5T_NATIVE_B16_g = H5I_INVALID_HID; + H5T_NATIVE_B32_g = H5I_INVALID_HID; + H5T_NATIVE_B64_g = H5I_INVALID_HID; + H5T_NATIVE_OPAQUE_g = H5I_INVALID_HID; + H5T_NATIVE_HADDR_g = H5I_INVALID_HID; + H5T_NATIVE_HSIZE_g = H5I_INVALID_HID; + H5T_NATIVE_HSSIZE_g = H5I_INVALID_HID; + H5T_NATIVE_HERR_g = H5I_INVALID_HID; + H5T_NATIVE_HBOOL_g = H5I_INVALID_HID; + + H5T_NATIVE_INT8_g = H5I_INVALID_HID; + H5T_NATIVE_UINT8_g = H5I_INVALID_HID; + H5T_NATIVE_INT_LEAST8_g = H5I_INVALID_HID; + H5T_NATIVE_UINT_LEAST8_g = H5I_INVALID_HID; + H5T_NATIVE_INT_FAST8_g = H5I_INVALID_HID; + H5T_NATIVE_UINT_FAST8_g = H5I_INVALID_HID; + + H5T_NATIVE_INT16_g = H5I_INVALID_HID; + H5T_NATIVE_UINT16_g = H5I_INVALID_HID; + H5T_NATIVE_INT_LEAST16_g = H5I_INVALID_HID; + H5T_NATIVE_UINT_LEAST16_g = H5I_INVALID_HID; + H5T_NATIVE_INT_FAST16_g = H5I_INVALID_HID; + H5T_NATIVE_UINT_FAST16_g = H5I_INVALID_HID; + + H5T_NATIVE_INT32_g = H5I_INVALID_HID; + H5T_NATIVE_UINT32_g = H5I_INVALID_HID; + H5T_NATIVE_INT_LEAST32_g = H5I_INVALID_HID; + H5T_NATIVE_UINT_LEAST32_g = H5I_INVALID_HID; + H5T_NATIVE_INT_FAST32_g = H5I_INVALID_HID; + H5T_NATIVE_UINT_FAST32_g = H5I_INVALID_HID; + + H5T_NATIVE_INT64_g = H5I_INVALID_HID; + H5T_NATIVE_UINT64_g = H5I_INVALID_HID; + H5T_NATIVE_INT_LEAST64_g = H5I_INVALID_HID; + H5T_NATIVE_UINT_LEAST64_g = H5I_INVALID_HID; + H5T_NATIVE_INT_FAST64_g = H5I_INVALID_HID; + H5T_NATIVE_UINT_FAST64_g = H5I_INVALID_HID; + + n++; + } /* end if */ - /* Unlock all datatypes, then free them */ - /* note that we are ignoring the return value from H5I_iterate() */ - /* Also note that we are incrementing 'n' in the callback */ - H5I_iterate(H5I_DATATYPE, H5T__unlock_cb, &n, false); - - /* Release all datatype IDs */ - if (H5I_nmembers(H5I_DATATYPE) > 0) { - (void)H5I_clear_type(H5I_DATATYPE, false, false); - n++; /*H5I*/ - } /* end if */ - - /* Reset all the datatype IDs */ - if (H5T_IEEE_F32BE_g > 0) { - H5T_IEEE_F16BE_g = H5I_INVALID_HID; - H5T_IEEE_F16LE_g = H5I_INVALID_HID; - H5T_IEEE_F32BE_g = H5I_INVALID_HID; - H5T_IEEE_F32LE_g = H5I_INVALID_HID; - H5T_IEEE_F64BE_g = H5I_INVALID_HID; - H5T_IEEE_F64LE_g = H5I_INVALID_HID; - - H5T_STD_I8BE_g = H5I_INVALID_HID; - H5T_STD_I8LE_g = H5I_INVALID_HID; - H5T_STD_I16BE_g = H5I_INVALID_HID; - H5T_STD_I16LE_g = H5I_INVALID_HID; - H5T_STD_I32BE_g = H5I_INVALID_HID; - H5T_STD_I32LE_g = H5I_INVALID_HID; - H5T_STD_I64BE_g = H5I_INVALID_HID; - H5T_STD_I64LE_g = H5I_INVALID_HID; - H5T_STD_U8BE_g = H5I_INVALID_HID; - H5T_STD_U8LE_g = H5I_INVALID_HID; - H5T_STD_U16BE_g = H5I_INVALID_HID; - H5T_STD_U16LE_g = H5I_INVALID_HID; - H5T_STD_U32BE_g = H5I_INVALID_HID; - H5T_STD_U32LE_g = H5I_INVALID_HID; - H5T_STD_U64BE_g = H5I_INVALID_HID; - H5T_STD_U64LE_g = H5I_INVALID_HID; - H5T_STD_B8BE_g = H5I_INVALID_HID; - H5T_STD_B8LE_g = H5I_INVALID_HID; - H5T_STD_B16BE_g = H5I_INVALID_HID; - H5T_STD_B16LE_g = H5I_INVALID_HID; - H5T_STD_B32BE_g = H5I_INVALID_HID; - H5T_STD_B32LE_g = H5I_INVALID_HID; - H5T_STD_B64BE_g = H5I_INVALID_HID; - H5T_STD_B64LE_g = H5I_INVALID_HID; - H5T_STD_REF_OBJ_g = H5I_INVALID_HID; - H5T_STD_REF_DSETREG_g = H5I_INVALID_HID; - H5T_STD_REF_g = H5I_INVALID_HID; - - H5T_UNIX_D32BE_g = H5I_INVALID_HID; - H5T_UNIX_D32LE_g = H5I_INVALID_HID; - H5T_UNIX_D64BE_g = H5I_INVALID_HID; - H5T_UNIX_D64LE_g = H5I_INVALID_HID; - - H5T_C_S1_g = H5I_INVALID_HID; - - H5T_FORTRAN_S1_g = H5I_INVALID_HID; - - H5T_NATIVE_SCHAR_g = H5I_INVALID_HID; - H5T_NATIVE_UCHAR_g = H5I_INVALID_HID; - H5T_NATIVE_SHORT_g = H5I_INVALID_HID; - H5T_NATIVE_USHORT_g = H5I_INVALID_HID; - H5T_NATIVE_INT_g = H5I_INVALID_HID; - H5T_NATIVE_UINT_g = H5I_INVALID_HID; - H5T_NATIVE_LONG_g = H5I_INVALID_HID; - H5T_NATIVE_ULONG_g = H5I_INVALID_HID; - H5T_NATIVE_LLONG_g = H5I_INVALID_HID; - H5T_NATIVE_ULLONG_g = H5I_INVALID_HID; - H5T_NATIVE_FLOAT16_g = H5I_INVALID_HID; - H5T_NATIVE_FLOAT_g = H5I_INVALID_HID; - H5T_NATIVE_DOUBLE_g = H5I_INVALID_HID; - H5T_NATIVE_LDOUBLE_g = H5I_INVALID_HID; - H5T_NATIVE_B8_g = H5I_INVALID_HID; - H5T_NATIVE_B16_g = H5I_INVALID_HID; - H5T_NATIVE_B32_g = H5I_INVALID_HID; - H5T_NATIVE_B64_g = H5I_INVALID_HID; - H5T_NATIVE_OPAQUE_g = H5I_INVALID_HID; - H5T_NATIVE_HADDR_g = H5I_INVALID_HID; - H5T_NATIVE_HSIZE_g = H5I_INVALID_HID; - H5T_NATIVE_HSSIZE_g = H5I_INVALID_HID; - H5T_NATIVE_HERR_g = H5I_INVALID_HID; - H5T_NATIVE_HBOOL_g = H5I_INVALID_HID; - - H5T_NATIVE_INT8_g = H5I_INVALID_HID; - H5T_NATIVE_UINT8_g = H5I_INVALID_HID; - H5T_NATIVE_INT_LEAST8_g = H5I_INVALID_HID; - H5T_NATIVE_UINT_LEAST8_g = H5I_INVALID_HID; - H5T_NATIVE_INT_FAST8_g = H5I_INVALID_HID; - H5T_NATIVE_UINT_FAST8_g = H5I_INVALID_HID; - - H5T_NATIVE_INT16_g = H5I_INVALID_HID; - H5T_NATIVE_UINT16_g = H5I_INVALID_HID; - H5T_NATIVE_INT_LEAST16_g = H5I_INVALID_HID; - H5T_NATIVE_UINT_LEAST16_g = H5I_INVALID_HID; - H5T_NATIVE_INT_FAST16_g = H5I_INVALID_HID; - H5T_NATIVE_UINT_FAST16_g = H5I_INVALID_HID; - - H5T_NATIVE_INT32_g = H5I_INVALID_HID; - H5T_NATIVE_UINT32_g = H5I_INVALID_HID; - H5T_NATIVE_INT_LEAST32_g = H5I_INVALID_HID; - H5T_NATIVE_UINT_LEAST32_g = H5I_INVALID_HID; - H5T_NATIVE_INT_FAST32_g = H5I_INVALID_HID; - H5T_NATIVE_UINT_FAST32_g = H5I_INVALID_HID; - - H5T_NATIVE_INT64_g = H5I_INVALID_HID; - H5T_NATIVE_UINT64_g = H5I_INVALID_HID; - H5T_NATIVE_INT_LEAST64_g = H5I_INVALID_HID; - H5T_NATIVE_UINT_LEAST64_g = H5I_INVALID_HID; - H5T_NATIVE_INT_FAST64_g = H5I_INVALID_HID; - H5T_NATIVE_UINT_FAST64_g = H5I_INVALID_HID; - - n++; + /* Mark "top" of interface as closed */ + if (0 == n) + H5T_top_package_initialize_s = false; } /* end if */ FUNC_LEAVE_NOAPI(n) @@ -1848,11 +1889,18 @@ H5T_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - /* Sanity check */ - assert(0 == H5I_nmembers(H5I_DATATYPE)); + if (H5_PKG_INIT_VAR) { + /* Sanity check */ + assert(0 == H5I_nmembers(H5I_DATATYPE)); + assert(false == H5T_top_package_initialize_s); - /* Destroy the datatype object id group */ - n += (H5I_dec_type_ref(H5I_DATATYPE) > 0); + /* Destroy the datatype object id group */ + n += (H5I_dec_type_ref(H5I_DATATYPE) > 0); + + /* Mark interface as closed */ + if (0 == n) + H5_PKG_INIT_VAR = false; + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5T_term_package() */ @@ -2248,7 +2296,7 @@ H5T_get_class(const H5T_t *dt, htri_t internal) { H5T_class_t ret_value = H5T_NO_CLASS; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(H5T_NO_CLASS) assert(dt); @@ -2263,6 +2311,7 @@ H5T_get_class(const H5T_t *dt, htri_t internal) ret_value = dt->shared->type; } +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_get_class() */ @@ -2314,7 +2363,7 @@ H5T_detect_class(const H5T_t *dt, H5T_class_t cls, bool from_api) unsigned i; htri_t ret_value = false; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) assert(dt); assert(cls > H5T_NO_CLASS && cls < H5T_NCLASSES); @@ -6023,13 +6072,14 @@ H5T_is_immutable(const H5T_t *dt) { htri_t ret_value = false; - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) assert(dt); if (dt->shared->state == H5T_STATE_IMMUTABLE) ret_value = true; +done: FUNC_LEAVE_NOAPI(ret_value) } @@ -6047,7 +6097,7 @@ H5T_is_named(const H5T_t *dt) { htri_t ret_value = false; - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) assert(dt); @@ -6056,6 +6106,7 @@ H5T_is_named(const H5T_t *dt) else ret_value = (H5T_STATE_OPEN == dt->shared->state || H5T_STATE_NAMED == dt->shared->state); +done: FUNC_LEAVE_NOAPI(ret_value) } @@ -6131,13 +6182,14 @@ H5T_get_ref_type(const H5T_t *dt) { H5R_type_t ret_value = H5R_BADTYPE; - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(H5R_BADTYPE) assert(dt); if (dt->shared->type == H5T_REFERENCE) ret_value = dt->shared->u.atomic.u.r.rtype; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_get_ref_type() */ @@ -6158,7 +6210,7 @@ H5T_is_sensible(const H5T_t *dt) { htri_t ret_value = FAIL; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) assert(dt); @@ -6196,6 +6248,7 @@ H5T_is_sensible(const H5T_t *dt) break; } /* end switch */ +done: FUNC_LEAVE_NOAPI(ret_value) } @@ -6385,7 +6438,7 @@ H5T_is_relocatable(const H5T_t *dt) { htri_t ret_value = false; - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ assert(dt); @@ -6394,6 +6447,7 @@ H5T_is_relocatable(const H5T_t *dt) if (H5T_detect_class(dt, H5T_VLEN, false) || H5T_detect_class(dt, H5T_REFERENCE, false)) ret_value = true; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_is_relocatable() */ @@ -6478,7 +6532,7 @@ H5T_is_vl_storage(const H5T_t *dt) { htri_t ret_value = false; - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ assert(dt); @@ -6491,6 +6545,7 @@ H5T_is_vl_storage(const H5T_t *dt) else ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_is_vl_storage() */ @@ -6633,7 +6688,7 @@ H5T_patch_file(H5T_t *dt, H5F_t *f) { herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ assert(dt); @@ -6644,6 +6699,7 @@ H5T_patch_file(H5T_t *dt, H5F_t *f) dt->sh_loc.file = f; } /* end if */ +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_patch_file() */ diff --git a/src/H5TSint.c b/src/H5TSint.c index 410ae408a23..6f0c49648e2 100644 --- a/src/H5TSint.c +++ b/src/H5TSint.c @@ -79,6 +79,9 @@ static H5TS_tinfo_node_t *H5TS__tinfo_create(void); /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* Per-thread info */ H5TS_key_t H5TS_thrd_info_key_g; diff --git a/src/H5TSmodule.h b/src/H5TSmodule.h index e550d3a9edb..71d0de45349 100644 --- a/src/H5TSmodule.h +++ b/src/H5TSmodule.h @@ -22,7 +22,8 @@ * reporting macros. */ #define H5TS_MODULE -#define H5_MY_PKG H5TS -#define H5_MY_PKG_ERR H5E_THREADSAFE +#define H5_MY_PKG H5TS +#define H5_MY_PKG_ERR H5E_THREADSAFE +#define H5_MY_PKG_INIT YES #endif /* H5TSmodule_H */ diff --git a/src/H5TSwin.c b/src/H5TSwin.c index d6198dab0ba..c1f281360c1 100644 --- a/src/H5TSwin.c +++ b/src/H5TSwin.c @@ -70,7 +70,7 @@ static herr_t H5TS__win32_thread_exit(void); * * Purpose: Per-process setup on Windows when using Win32 threads. * - * Returns: true on success, FALSE on failure + * Returns: TRUE on success, FALSE on failure * *-------------------------------------------------------------------------- */ diff --git a/src/H5Tfields.c b/src/H5Tfields.c index 8d3ec8f6fb8..2b6ab80a62c 100644 --- a/src/H5Tfields.c +++ b/src/H5Tfields.c @@ -106,7 +106,7 @@ H5T_get_nmembers(const H5T_t *dt) * *------------------------------------------------------------------------- */ -char * +H5_ATTR_MALLOC char * H5Tget_member_name(hid_t type_id, unsigned membno) { H5T_t *dt = NULL; diff --git a/src/H5Tmodule.h b/src/H5Tmodule.h index 55ba2d9d478..139414fcf78 100644 --- a/src/H5Tmodule.h +++ b/src/H5Tmodule.h @@ -22,8 +22,9 @@ * reporting macros. */ #define H5T_MODULE -#define H5_MY_PKG H5T -#define H5_MY_PKG_ERR H5E_DATATYPE +#define H5_MY_PKG H5T +#define H5_MY_PKG_ERR H5E_DATATYPE +#define H5_MY_PKG_INIT YES /** \page H5T_UG HDF5 Datatypes * diff --git a/src/H5Topaque.c b/src/H5Topaque.c index c4165b15c0e..2875b388bab 100644 --- a/src/H5Topaque.c +++ b/src/H5Topaque.c @@ -72,7 +72,7 @@ H5Tset_tag(hid_t type_id, const char *tag) * *------------------------------------------------------------------------- */ -char * +H5_ATTR_MALLOC char * H5Tget_tag(hid_t type_id) { H5T_t *dt = NULL; diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index 8de42d507e8..ecededcfda7 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -239,14 +239,6 @@ typedef H5T_conv_ret_t (*H5T_conv_except_func_t)(H5T_conv_except_t except_type, void *src_buf, void *dst_buf, void *user_data); //! -/* When this header is included from a private header, don't make calls to H5open() */ -#undef H5OPEN -#ifndef H5private_H -#define H5OPEN H5open(), -#else /* H5private_H */ -#define H5OPEN -#endif /* H5private_H */ - /* * The IEEE floating point types in various byte orders. */ diff --git a/src/H5VLint.c b/src/H5VLint.c index 938b33588ba..c3c4cd744b5 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -105,6 +105,9 @@ static herr_t H5VL__free_vol_wrapper(H5VL_wrap_ctx_t *vol_wrap_ctx); /* Package Variables */ /*********************/ +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /*****************************/ /* Library Private Variables */ /*****************************/ @@ -160,9 +163,7 @@ H5VL_init_phase1(void) FUNC_ENTER_NOAPI(FAIL) - /* Initialize the ID group for the VL IDs */ - if (H5I_register_type(H5I_VOL_CLS) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize H5VL interface"); + /* FUNC_ENTER() does all the work */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -184,38 +185,23 @@ H5VL_init_phase1(void) herr_t H5VL_init_phase2(void) { - size_t i; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) - /* clang-format off */ - struct { - herr_t (*func)(void); - const char *descr; - } initializer[] = { - {H5T_init, "datatype"} - , {H5O_init, "object header"} - , {H5D_init, "dataset"} - , {H5F_init, "file"} - , {H5G_init, "group"} - , {H5A_init, "attribute"} - , {H5M_init, "map"} - , {H5CX_init, "context"} - , {H5ES_init, "event set"} - , {H5Z_init, "transform"} - , {H5R_init, "reference"} - }; - /* Initialize all packages for VOL-managed objects */ - for (i = 0; i < NELMTS(initializer); i++) { - if (initializer[i].func() < 0) { - HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, - "unable to initialize %s interface", initializer[i].descr); - } - } - - /* clang-format on */ + if (H5T_init() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize datatype interface"); + if (H5D_init() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize dataset interface"); + if (H5F_init() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize file interface"); + if (H5G_init() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize group interface"); + if (H5A_init() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize attribute interface"); + if (H5M_init() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize map interface"); /* Register internal VOL connectors */ if (H5VL__native_register() < 0) @@ -235,6 +221,32 @@ H5VL_init_phase2(void) FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_init_phase2() */ +/*------------------------------------------------------------------------- + * Function: H5VL__init_package + * + * Purpose: Initialize interface-specific information + * + * Return: Success: Non-negative + * + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL__init_package(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Initialize the ID group for the VL IDs */ + if (H5I_register_type(H5I_VOL_CLS) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize H5VL interface"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__init_package() */ + /*------------------------------------------------------------------------- * Function: H5VL_term_package * @@ -253,36 +265,42 @@ H5VL_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - if (H5VL_def_conn_s.connector) { - /* Release the default VOL connector */ - (void)H5VL_conn_prop_free(&H5VL_def_conn_s); - H5VL_def_conn_s.connector = NULL; - H5VL_def_conn_s.connector_info = NULL; - n++; - } /* end if */ - else { - if (H5I_nmembers(H5I_VOL) > 0) { - /* Unregister all VOL connectors */ - (void)H5I_clear_type(H5I_VOL, true, false); - - /* Reset internal VOL connectors' global vars */ - (void)H5VL__native_unregister(); - (void)H5VL__passthru_unregister(); - + if (H5_PKG_INIT_VAR) { + if (H5VL_def_conn_s.connector) { + /* Release the default VOL connector */ + (void)H5VL_conn_prop_free(&H5VL_def_conn_s); + H5VL_def_conn_s.connector = NULL; + H5VL_def_conn_s.connector_info = NULL; n++; } /* end if */ else { - if (H5VL__num_opt_operation() > 0) { - /* Unregister all dynamically registered optional operations */ - (void)H5VL__term_opt_operation(); + if (H5I_nmembers(H5I_VOL) > 0) { + /* Unregister all VOL connectors */ + (void)H5I_clear_type(H5I_VOL, true, false); + + /* Reset internal VOL connectors' global vars */ + (void)H5VL__native_unregister(); + (void)H5VL__passthru_unregister(); + n++; } /* end if */ else { - /* Destroy the VOL connector ID group */ - n += (H5I_dec_type_ref(H5I_VOL) > 0); - } /* end else */ - } /* end else */ - } /* end else */ + if (H5VL__num_opt_operation() > 0) { + /* Unregister all dynamically registered optional operations */ + (void)H5VL__term_opt_operation(); + n++; + } /* end if */ + else { + /* Destroy the VOL connector ID group */ + n += (H5I_dec_type_ref(H5I_VOL) > 0); + + /* Mark interface as closed */ + if (0 == n) + H5_PKG_INIT_VAR = false; + } /* end else */ + } /* end else */ + } /* end else */ + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5VL_term_package() */ @@ -959,7 +977,7 @@ H5VL_conn_inc_rc(H5VL_connector_t *connector) { int64_t ret_value = -1; - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(-1) /* Check arguments */ assert(connector); @@ -970,6 +988,7 @@ H5VL_conn_inc_rc(H5VL_connector_t *connector) /* Set return value */ ret_value = connector->nrefs; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_conn_inc_rc() */ @@ -1031,7 +1050,7 @@ H5VL_conn_same_class(const H5VL_connector_t *conn1, const H5VL_connector_t *conn if (conn1 == conn2) HGOTO_DONE(true); else { - int cmp_value; /* Comparison result */ + int cmp_value = 0; /* Comparison result */ /* Compare connector classes */ if (H5VL_cmp_connector_cls(&cmp_value, conn1->cls, conn2->cls) < 0) @@ -1124,7 +1143,7 @@ H5VL__conn_free_id(H5VL_connector_t *connector, void H5_ATTR_UNUSED **request) hsize_t H5VL_object_inc_rc(H5VL_object_t *vol_obj) { - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI_NOINIT_NOERR /* Check arguments */ assert(vol_obj); @@ -1180,7 +1199,7 @@ H5VL_object_is_native(const H5VL_object_t *obj, bool *is_native) { const H5VL_class_t *cls; /* VOL connector class structs for object */ H5VL_connector_t *native; /* Native VOL connector */ - int cmp_value; /* Comparison result */ + int cmp_value = 0; /* Comparison result */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1222,7 +1241,7 @@ H5VL_file_is_same(const H5VL_object_t *vol_obj1, const H5VL_object_t *vol_obj2, { const H5VL_class_t *cls1; /* VOL connector class struct for first object */ const H5VL_class_t *cls2; /* VOL connector class struct for second object */ - int cmp_value; /* Comparison result */ + int cmp_value = 0; /* Comparison result */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1512,7 +1531,7 @@ H5VL__register_connector_by_value(H5VL_class_value_t value, hid_t vipl_id) * *------------------------------------------------------------------------- */ -htri_t +H5_ATTR_PURE htri_t H5VL__is_connector_registered_by_name(const char *name) { H5VL_connector_t *connector = NULL; /* Connector for class */ @@ -1549,7 +1568,7 @@ H5VL__is_connector_registered_by_name(const char *name) * *------------------------------------------------------------------------- */ -htri_t +H5_ATTR_PURE htri_t H5VL__is_connector_registered_by_value(H5VL_class_value_t value) { H5VL_connector_t *connector = NULL; /* Connector for class */ @@ -1663,7 +1682,7 @@ H5VL__get_connector_by_value(H5VL_class_value_t value) size_t H5VL__get_connector_name(const H5VL_connector_t *connector, char *name /*out*/, size_t size) { - size_t len; + size_t len = 0; FUNC_ENTER_PACKAGE_NOERR @@ -1943,7 +1962,7 @@ H5VL_cmp_connector_cls(int *cmp_value, const H5VL_class_t *cls1, const H5VL_clas { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Sanity checks */ assert(cls1); @@ -2450,7 +2469,7 @@ H5VL_check_plugin_load(const H5VL_class_t *cls, const H5PL_key_t *key, bool *suc { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Sanity checks */ assert(cls); @@ -2476,6 +2495,7 @@ H5VL_check_plugin_load(const H5VL_class_t *cls, const H5PL_key_t *key, bool *suc if (*success && cls->version != H5VL_VERSION) *success = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_check_plugin_load() */ diff --git a/src/H5VLmodule.h b/src/H5VLmodule.h index 8359118998c..9f22cec9c1a 100644 --- a/src/H5VLmodule.h +++ b/src/H5VLmodule.h @@ -23,8 +23,9 @@ * reporting macros. */ #define H5VL_MODULE -#define H5_MY_PKG H5VL -#define H5_MY_PKG_ERR H5E_VOL +#define H5_MY_PKG H5VL +#define H5_MY_PKG_ERR H5E_VOL +#define H5_MY_PKG_INIT YES /** \page H5VL_UG HDF5 Virtual Object Layer (VOL) * diff --git a/src/H5VLnative.h b/src/H5VLnative.h index 3653c2668cc..6b1cc5652ec 100644 --- a/src/H5VLnative.h +++ b/src/H5VLnative.h @@ -25,14 +25,6 @@ /* Public Macros */ /*****************/ -/* When this header is included from a private header, don't make calls to H5open() */ -#undef H5OPEN -#ifndef H5private_H -#define H5OPEN H5open(), -#else /* H5private_H */ -#define H5OPEN -#endif /* H5private_H */ - /* Identifier for the native VOL connector */ #define H5VL_NATIVE (H5OPEN H5VL_NATIVE_g) diff --git a/src/H5VLpassthru.h b/src/H5VLpassthru.h index d3723b72c67..ffe953cea87 100644 --- a/src/H5VLpassthru.h +++ b/src/H5VLpassthru.h @@ -20,14 +20,6 @@ /* Public headers needed by this file */ #include "H5VLpublic.h" /* Virtual Object Layer */ -/* When this header is included from a private header, don't make calls to H5open() */ -#undef H5OPEN -#ifndef H5private_H -#define H5OPEN H5open(), -#else /* H5private_H */ -#define H5OPEN -#endif /* H5private_H */ - /* Identifier for the pass-through VOL connector */ #define H5VL_PASSTHRU (H5OPEN H5VL_PASSTHRU_g) diff --git a/src/H5Z.c b/src/H5Z.c index 67b1a31154f..4ad75a6668c 100644 --- a/src/H5Z.c +++ b/src/H5Z.c @@ -58,6 +58,9 @@ typedef enum { H5Z_PRELUDE_SET_LOCAL /* Call "set local" callback */ } H5Z_prelude_type_t; +/* Package initialization variable */ +bool H5_PKG_INIT_VAR = false; + /* Local variables */ static size_t H5Z_table_alloc_g = 0; static size_t H5Z_table_used_g = 0; @@ -75,23 +78,20 @@ static int H5Z__check_unregister_group_cb(void *obj_ptr, hid_t obj_id, void *key static int H5Z__flush_file_cb(void *obj_ptr, hid_t obj_id, void *key); /*------------------------------------------------------------------------- - * Function: H5Z_init + * Function: H5Z__init_package * - * Purpose: Initialize the interface from some other layer. + * Purpose: Initializes the data filter layer. * * Return: Success: non-negative * Failure: negative *------------------------------------------------------------------------- */ herr_t -H5Z_init(void) +H5Z__init_package(void) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) - - if (H5_TERM_GLOBAL) - HGOTO_DONE(SUCCEED); + FUNC_ENTER_PACKAGE /* Internal filters */ if (H5Z_register(H5Z_SHUFFLE) < 0) @@ -122,7 +122,7 @@ H5Z_init(void) done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5Z__init_package() */ /*------------------------------------------------------------------------- * Function: H5Z_term_package @@ -139,70 +139,76 @@ H5Z_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR + if (H5_PKG_INIT_VAR) { #ifdef H5Z_DEBUG - char comment[16], bandwidth[32]; - int dir, nprint = 0; - size_t i; - - if (DUMP_DEBUG_STATS_g) { - for (i = 0; i < H5Z_table_used_g; i++) { - for (dir = 0; dir < 2; dir++) { - struct { - char *user; - char *system; - char *elapsed; - } timestrs = {H5_timer_get_time_string(H5Z_stat_table_g[i].stats[dir].times.user), - H5_timer_get_time_string(H5Z_stat_table_g[i].stats[dir].times.system), - H5_timer_get_time_string(H5Z_stat_table_g[i].stats[dir].times.elapsed)}; - if (0 == H5Z_stat_table_g[i].stats[dir].total) - goto next; - - if (0 == nprint++) { - /* Print column headers */ - fprintf(stdout, "H5Z: filter statistics " - "accumulated over life of library:\n"); - fprintf(stdout, " %-16s %10s %10s %8s %8s %8s %10s\n", "Filter", "Total", "Errors", - "User", "System", "Elapsed", "Bandwidth"); - fprintf(stdout, " %-16s %10s %10s %8s %8s %8s %10s\n", "------", "-----", "------", - "----", "------", "-------", "---------"); - } /* end if */ - - /* Truncate the comment to fit in the field */ - strncpy(comment, H5Z_table_g[i].name, sizeof comment); - comment[sizeof(comment) - 1] = '\0'; + char comment[16], bandwidth[32]; + int dir, nprint = 0; + size_t i; + + if (DUMP_DEBUG_STATS_g) { + for (i = 0; i < H5Z_table_used_g; i++) { + for (dir = 0; dir < 2; dir++) { + struct { + char *user; + char *system; + char *elapsed; + } timestrs = {H5_timer_get_time_string(H5Z_stat_table_g[i].stats[dir].times.user), + H5_timer_get_time_string(H5Z_stat_table_g[i].stats[dir].times.system), + H5_timer_get_time_string(H5Z_stat_table_g[i].stats[dir].times.elapsed)}; + if (0 == H5Z_stat_table_g[i].stats[dir].total) + goto next; + + if (0 == nprint++) { + /* Print column headers */ + fprintf(stdout, "H5Z: filter statistics " + "accumulated over life of library:\n"); + fprintf(stdout, " %-16s %10s %10s %8s %8s %8s %10s\n", "Filter", "Total", "Errors", + "User", "System", "Elapsed", "Bandwidth"); + fprintf(stdout, " %-16s %10s %10s %8s %8s %8s %10s\n", "------", "-----", "------", + "----", "------", "-------", "---------"); + } /* end if */ - /* - * Format bandwidth to have four significant digits and - * units of `B/s', `kB/s', `MB/s', `GB/s', or `TB/s' or - * the word `Inf' if the elapsed time is zero. - */ - H5_bandwidth(bandwidth, sizeof(bandwidth), (double)(H5Z_stat_table_g[i].stats[dir].total), - H5Z_stat_table_g[i].stats[dir].times.elapsed); - - /* Print the statistics */ - fprintf(stdout, " %s%-15s %10" PRIdHSIZE " %10" PRIdHSIZE " %8s %8s %8s %10s\n", - (dir ? "<" : ">"), comment, H5Z_stat_table_g[i].stats[dir].total, - H5Z_stat_table_g[i].stats[dir].errors, timestrs.user, timestrs.system, - timestrs.elapsed, bandwidth); + /* Truncate the comment to fit in the field */ + strncpy(comment, H5Z_table_g[i].name, sizeof comment); + comment[sizeof(comment) - 1] = '\0'; + + /* + * Format bandwidth to have four significant digits and + * units of `B/s', `kB/s', `MB/s', `GB/s', or `TB/s' or + * the word `Inf' if the elapsed time is zero. + */ + H5_bandwidth(bandwidth, sizeof(bandwidth), (double)(H5Z_stat_table_g[i].stats[dir].total), + H5Z_stat_table_g[i].stats[dir].times.elapsed); + + /* Print the statistics */ + fprintf(stdout, " %s%-15s %10" PRIdHSIZE " %10" PRIdHSIZE " %8s %8s %8s %10s\n", + (dir ? "<" : ">"), comment, H5Z_stat_table_g[i].stats[dir].total, + H5Z_stat_table_g[i].stats[dir].errors, timestrs.user, timestrs.system, + timestrs.elapsed, bandwidth); next: - free(timestrs.user); - free(timestrs.system); - free(timestrs.elapsed); - } /* end for */ - } /* end for */ - } /* end if */ -#endif /* H5Z_DEBUG */ - - /* Free the table of filters */ - if (H5Z_table_g) { - H5Z_table_g = (H5Z_class2_t *)H5MM_xfree(H5Z_table_g); + free(timestrs.user); + free(timestrs.system); + free(timestrs.elapsed); + } /* end for */ + } /* end for */ + } /* end if */ +#endif /* H5Z_DEBUG */ + + /* Free the table of filters */ + if (H5Z_table_g) { + H5Z_table_g = (H5Z_class2_t *)H5MM_xfree(H5Z_table_g); #ifdef H5Z_DEBUG - H5Z_stat_table_g = (H5Z_stats_t *)H5MM_xfree(H5Z_stat_table_g); + H5Z_stat_table_g = (H5Z_stats_t *)H5MM_xfree(H5Z_stat_table_g); #endif /* H5Z_DEBUG */ - H5Z_table_used_g = H5Z_table_alloc_g = 0; + H5Z_table_used_g = H5Z_table_alloc_g = 0; + + n++; + } /* end if */ - n++; + /* Mark interface as closed */ + if (0 == n) + H5_PKG_INIT_VAR = false; } /* end if */ FUNC_LEAVE_NOAPI(n) @@ -1571,7 +1577,7 @@ H5Z_filter_in_pline(const H5O_pline_t *pline, H5Z_filter_t filter) size_t idx; /* Index of filter in pipeline */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) assert(pline); assert(filter >= 0 && filter <= H5Z_FILTER_MAX); @@ -1585,6 +1591,7 @@ H5Z_filter_in_pline(const H5O_pline_t *pline, H5Z_filter_t filter) if (idx >= pline->nused) ret_value = false; +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5Z_filter_in_pline() */ @@ -1604,7 +1611,7 @@ H5Z_all_filters_avail(const H5O_pline_t *pline) size_t i, j; /* Local index variable */ htri_t ret_value = true; /* Return value */ - FUNC_ENTER_NOAPI_NOERR + FUNC_ENTER_NOAPI(FAIL) /* Check args */ assert(pline); diff --git a/src/H5Zmodule.h b/src/H5Zmodule.h index 23d38368047..8c1dc467042 100644 --- a/src/H5Zmodule.h +++ b/src/H5Zmodule.h @@ -22,8 +22,9 @@ * reporting macros. */ #define H5Z_MODULE -#define H5_MY_PKG H5Z -#define H5_MY_PKG_ERR H5E_PLINE +#define H5_MY_PKG H5Z +#define H5_MY_PKG_ERR H5E_PLINE +#define H5_MY_PKG_INIT YES /** \page H5Z_UG HDF5 Filters * @todo Under Construction diff --git a/src/H5module.h b/src/H5module.h index 918630f1646..c0fb5ad348a 100644 --- a/src/H5module.h +++ b/src/H5module.h @@ -22,8 +22,9 @@ * reporting macros. */ #define H5_MODULE -#define H5_MY_PKG H5 -#define H5_MY_PKG_ERR H5E_LIB +#define H5_MY_PKG H5 +#define H5_MY_PKG_ERR H5E_LIB +#define H5_MY_PKG_INIT YES /** \page H5DM_UG HDF5 Data Model and File Structure * diff --git a/src/H5private.h b/src/H5private.h index b46dc8f7651..6bd1f292e2d 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -114,14 +114,8 @@ #include #endif -/* Define the default VFD for this platform. Since the removal of the - * Windows VFD, this is sec2 for all platforms. - * - * Note well: if you change the default, then be sure to change - * H5_default_vfd_init() to call that default's initializer. Also, - * make sure that the initializer for each *non*-default VFD calls - * H5_init_library(); also, make sure that the initializer for default - * VFD does *not* call H5_init_library(). +/* Define the default VFD for this platform. + * Since the removal of the Windows VFD, this is sec2 for all platforms. */ #define H5_DEFAULT_VFD H5FD_SEC2 #define H5_DEFAULT_VFD_NAME "sec2" @@ -171,18 +165,6 @@ #define HASH_NONFATAL_OOM 1 /* Don't abort() on out-of-memory */ #include "uthash.h" -/* - * Does the compiler support the __builtin_expect() syntax? - * It's not a problem if not. - */ -#if H5_HAVE_BUILTIN_EXPECT -#define H5_LIKELY(expression) __builtin_expect(!!(expression), 1) -#define H5_UNLIKELY(expression) __builtin_expect(!!(expression), 0) -#else -#define H5_LIKELY(expression) (expression) -#define H5_UNLIKELY(expression) (expression) -#endif - /* * Does the compiler support the __attribute__(()) syntax? It's no * big deal if we don't. @@ -1111,14 +1093,37 @@ extern char H5_lib_vers_info_g[]; #endif /* H5_HAVE_THREADSAFE */ -/* Library init / term status (global) */ -extern bool H5_libinit_g; /* Has the library been initialized? */ -extern bool H5_libterm_g; /* Is the library being shutdown? */ - /* Macros for accessing the global variables */ #define H5_INIT_GLOBAL (H5_libinit_g) #define H5_TERM_GLOBAL (H5_libterm_g) +/* Macros for referencing package initialization symbols */ +#define H5_PACKAGE_INIT_VAR(x) H5_GLUE(x, _init_g) +#define H5_PACKAGE_INIT_FUNC(x) H5_GLUE(x, __init_package) + +/* Macros for defining package initialization routines */ +#ifdef H5_MY_PKG +#define H5_PKG_INIT_VAR H5_PACKAGE_INIT_VAR(H5_MY_PKG) +#define H5_PKG_INIT_FUNC H5_PACKAGE_INIT_FUNC(H5_MY_PKG) +#define H5_PACKAGE_YES_INIT(err) \ + /* Initialize this interface or bust */ \ + if (H5_UNLIKELY(!H5_PKG_INIT_VAR && !H5_TERM_GLOBAL)) { \ + H5_PKG_INIT_VAR = true; \ + if (H5_PKG_INIT_FUNC() < 0) { \ + H5_PKG_INIT_VAR = false; \ + HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, err, "interface initialization failed"); \ + } \ + } +#define H5_PACKAGE_NO_INIT(err) \ + /* Mark a package without an init interface call as initialized */ \ + if (H5_UNLIKELY(!H5_PKG_INIT_VAR && !H5_TERM_GLOBAL)) \ + H5_PKG_INIT_VAR = true; +#define H5_PACKAGE_INIT(pkg_init, err) H5_GLUE3(H5_PACKAGE_, pkg_init, _INIT)(err) +#else /* H5_MY_PKG */ +#define H5_PKG_INIT_VAR (true) +#define H5_PACKAGE_INIT(pkg_init, err) +#endif /* H5_MY_PKG */ + /* Forward declaration of H5CXpush() / H5CXpop() */ /* (Including H5CXprivate.h creates bad circular dependencies - QAK, 3/18/2018) */ H5_DLL herr_t H5CX_push(void); @@ -1160,10 +1165,12 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); #define FUNC_ENTER_API_INIT(err) \ /* Initialize the library */ \ - if (H5_UNLIKELY(!H5_INIT_GLOBAL && !H5_TERM_GLOBAL)) { \ + if (H5_UNLIKELY(!H5_INIT_GLOBAL && !H5_TERM_GLOBAL)) \ if (H5_UNLIKELY(H5_init_library() < 0)) \ HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, err, "library initialization failed"); \ - } + \ + /* Initialize the package, if appropriate */ \ + H5_PACKAGE_INIT(H5_MY_PKG_INIT, err) #define FUNC_ENTER_API_PUSH(err) \ /* Push the API context */ \ @@ -1214,12 +1221,11 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); /* * Use this macro for API functions that shouldn't perform _any_ initialization - * of the library or an interface or push themselves on the function - * stack, just perform tracing, etc. Examples + * of the library or an interface and also don't return errors. Examples * are: H5close, H5check_version, etc. * */ -#define FUNC_ENTER_API_NOINIT_NOERR_NOFS \ +#define FUNC_ENTER_API_NOINIT_NOERR \ { \ { \ { \ @@ -1264,17 +1270,24 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); FUNC_ENTER_COMMON_NOERR(H5_IS_API(__func__)); \ { +/* Note: this macro only works when there's _no_ interface initialization routine for the module */ +#define FUNC_ENTER_NOAPI_INIT(err) \ + /* Initialize the package, if appropriate */ \ + H5_PACKAGE_INIT(H5_MY_PKG_INIT, err) + /* Use this macro for all "normal" non-API functions */ #define FUNC_ENTER_NOAPI(err) \ { \ FUNC_ENTER_COMMON(!H5_IS_API(__func__)); \ - { + FUNC_ENTER_NOAPI_INIT(err) \ + if (H5_LIKELY(H5_PKG_INIT_VAR || !H5_TERM_GLOBAL)) { /* Use this macro for all non-API functions, which propagate errors, but don't issue them */ #define FUNC_ENTER_NOAPI_NOERR \ { \ FUNC_ENTER_COMMON_NOERR(!H5_IS_API(__func__)); \ - { + FUNC_ENTER_NOAPI_INIT(-) \ + if (H5_LIKELY(H5_PKG_INIT_VAR || !H5_TERM_GLOBAL)) { /* * Use this macro for non-API functions which fall into these categories: @@ -1287,7 +1300,7 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); #define FUNC_ENTER_NOAPI_NOINIT \ { \ FUNC_ENTER_COMMON(!H5_IS_API(__func__)); \ - { + if (H5_LIKELY(H5_PKG_INIT_VAR || !H5_TERM_GLOBAL)) { /* * Use this macro for non-API functions which fall into these categories: @@ -1301,7 +1314,7 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); #define FUNC_ENTER_NOAPI_NOINIT_NOERR \ { \ FUNC_ENTER_COMMON_NOERR(!H5_IS_API(__func__)); \ - { + if (H5_LIKELY(H5_PKG_INIT_VAR || !H5_TERM_GLOBAL)) { /* * Use this macro for non-API functions that shouldn't perform _any_ initialization @@ -1323,7 +1336,8 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); \ FUNC_ENTER_COMMON(!H5_IS_API(__func__)); \ H5AC_tag(tag, &prev_tag); \ - { + FUNC_ENTER_NOAPI_INIT(err) \ + if (H5_LIKELY(H5_PKG_INIT_VAR || !H5_TERM_GLOBAL)) { #define FUNC_ENTER_NOAPI_NOINIT_TAG(tag) \ { \ @@ -1331,19 +1345,19 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); \ FUNC_ENTER_COMMON(!H5_IS_API(__func__)); \ H5AC_tag(tag, &prev_tag); \ - { + if (H5_LIKELY(H5_PKG_INIT_VAR || !H5_TERM_GLOBAL)) { /* Use this macro for all "normal" package-level functions */ #define FUNC_ENTER_PACKAGE \ { \ FUNC_ENTER_COMMON(H5_IS_PKG(__func__)); \ - { + if (H5_LIKELY(H5_PKG_INIT_VAR || !H5_TERM_GLOBAL)) { /* Use this macro for package-level functions which propagate errors, but don't issue them */ #define FUNC_ENTER_PACKAGE_NOERR \ { \ FUNC_ENTER_COMMON_NOERR(H5_IS_PKG(__func__)); \ - { + if (H5_LIKELY(H5_PKG_INIT_VAR || !H5_TERM_GLOBAL)) { /* Use the following macro as replacement for the FUNC_ENTER_PACKAGE * macro when the function needs to set up a metadata tag. */ @@ -1353,14 +1367,7 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); \ FUNC_ENTER_COMMON(H5_IS_PKG(__func__)); \ H5AC_tag(tag, &prev_tag); \ - { - -/* Use this macro for staticly-scoped functions which propagate errors, but don't issue them */ -/* And that shouldn't push their name on the function stack */ -#define FUNC_ENTER_PACKAGE_NOERR_NOFS \ - { \ - FUNC_ENTER_COMMON_NOERR(H5_IS_PKG(__func__)); \ - { + if (H5_LIKELY(H5_PKG_INIT_VAR || !H5_TERM_GLOBAL)) { /* * Use this macro for non-API functions that shouldn't perform _any_ initialization @@ -1405,8 +1412,8 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); } \ } /*end scope from beginning of FUNC_ENTER*/ -/* Use this macro to match the FUNC_ENTER_API_NOINIT_NOERR_NOFS macro */ -#define FUNC_LEAVE_API_NOFS(ret_value) \ +/* Use this macro to match the FUNC_ENTER_API_NOINIT_NOERR macro */ +#define FUNC_LEAVE_API_NOERR(ret_value) \ ; \ } /*end scope from end of FUNC_ENTER*/ \ H5_API_UNLOCK \ @@ -1470,6 +1477,19 @@ H5_DLL herr_t H5CX_pop(bool update_dxpl_props); return (ret_value); \ } /*end scope from beginning of FUNC_ENTER*/ +/* Macros to declare package initialization function, if a package initialization routine is defined */ +#define H5_PKG_DECLARE_YES_FUNC(pkg) extern herr_t H5_PACKAGE_INIT_FUNC(pkg)(void); +#define H5_PKG_DECLARE_NO_FUNC(pkg) + +/* Declare package initialization symbols (if in a package) */ +#define H5_PKG_DECLARE_VAR(pkg) extern bool H5_PACKAGE_INIT_VAR(pkg); +#define H5_PKG_DECLARE_FUNC(pkg_init, pkg) H5_GLUE3(H5_PKG_DECLARE_, pkg_init, _FUNC)(pkg) + +#ifdef H5_MY_PKG +H5_PKG_DECLARE_VAR(H5_MY_PKG) +H5_PKG_DECLARE_FUNC(H5_MY_PKG_INIT, H5_MY_PKG) +#endif + /* Macro to begin/end tagging (when FUNC_ENTER_*TAG macros are insufficient). * Make sure to use HGOTO_ERROR_TAG and HGOTO_DONE_TAG between these macros! */ #define H5_BEGIN_TAG(tag) \ diff --git a/src/H5public.h b/src/H5public.h index d898e75b353..d25d2946e48 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -430,10 +430,43 @@ typedef void (*H5_atclose_func_t)(void *ctx); /* API adapter header (defines H5_DLL, etc.) */ #include "H5api_adpt.h" +/* + * Does the compiler support the __builtin_expect() syntax? + * It's not a problem if not. + */ +#if H5_HAVE_BUILTIN_EXPECT +#define H5_LIKELY(expression) __builtin_expect(!!(expression), 1) +#define H5_UNLIKELY(expression) __builtin_expect(!!(expression), 0) +#else +#define H5_LIKELY(expression) (expression) +#define H5_UNLIKELY(expression) (expression) +#endif + +/* Definition of H5OPEN macro used for returning library defined IDs to + * applications with macros, e.g. H5FD_SEC2. Will only call H5open() for + * the application once per library init/term epoch, and will not call + * H5open() when a macro that uses it is used within the library. + * Note: for library source, this coding pattern requires that H5private.h + * is the first library private header file included in the source file. + */ +#undef H5OPEN +#ifndef H5private_H +#define H5OPEN (H5_UNLIKELY(!H5_libinit_g && !H5_libterm_g) ? H5open() : 0), +#else /* H5private_H */ +#define H5OPEN +#endif /* H5private_H */ + #ifdef __cplusplus extern "C" { #endif +/** @private + * + * \brief Library init / term status (global) + */ +H5_DLLVAR bool H5_libinit_g; /* Has the library been initialized? */ +H5_DLLVAR bool H5_libterm_g; /* Is the library being shutdown? */ + /* Functions in H5.c */ /** * \ingroup H5 diff --git a/src/Makefile.am b/src/Makefile.am index b9306775480..51bb011ff3e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -53,9 +53,10 @@ libhdf5_la_SOURCES= H5.c H5build_settings.c H5checksum.c H5dbg.c H5system.c \ H5FA.c H5FAcache.c H5FAdbg.c H5FAdblock.c H5FAdblkpage.c H5FAhdr.c \ H5FAint.c H5FAstat.c H5FAtest.c \ H5FD.c H5FDcore.c H5FDfamily.c H5FDint.c H5FDlog.c H5FDmulti.c \ + H5FDmulti_int.c \ H5FDonion.c H5FDonion_header.c H5FDonion_history.c H5FDonion_index.c \ - H5FDperform.c H5FDsec2.c H5FDspace.c \ - H5FDsplitter.c H5FDstdio.c H5FDtest.c H5FDwindows.c \ + H5FDsec2.c H5FDspace.c \ + H5FDsplitter.c H5FDstdio.c H5FDstdio_int.c H5FDtest.c H5FDwindows.c \ H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSint.c H5FSsection.c \ H5FSstat.c H5FStest.c \ H5G.c H5Gbtree2.c H5Gcache.c H5Gcompact.c H5Gdense.c H5Gdeprec.c \