Skip to content

Commit

Permalink
Revert PR#1024
Browse files Browse the repository at this point in the history
Gets rid of public API call (H5FDperform_init) within the library code and
returns to original way of initializing packages in the library.

Signed-off-by: Quincey Koziol <[email protected]>
  • Loading branch information
qkoziol committed Sep 27, 2024
1 parent 013b1cd commit c5f00f9
Show file tree
Hide file tree
Showing 134 changed files with 1,589 additions and 604 deletions.
1 change: 0 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,6 @@ set (H5FD_SOURCES
${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
Expand Down
293 changes: 125 additions & 168 deletions src/H5.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@
#include "H5SLprivate.h" /* Skip lists */
#include "H5Tprivate.h" /* Datatypes */

#include "H5FDsec2.h" /* for H5FD_sec2_init() */

/****************/
/* Local Macros */
/****************/
Expand Down Expand Up @@ -65,6 +63,9 @@ static int H5__mpi_delete_cb(MPI_Comm comm, int keyval, void *attr_val, int *fla
/* Package Variables */
/*********************/

/* Package initialization variable */
bool H5_PKG_INIT_VAR = false;

/*****************************/
/* Library Private Variables */
/*****************************/
Expand All @@ -91,30 +92,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
Expand All @@ -133,7 +135,6 @@ H5_default_vfd_init(void)
herr_t
H5_init_library(void)
{
size_t i;
herr_t ret_value = SUCCEED;

FUNC_ENTER_NOAPI(FAIL)
Expand Down Expand Up @@ -239,35 +240,26 @@ H5_init_library(void)
* The dataspace interface needs to be initialized so that future IDs for
* dataspaces work.
*/
{
/* 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 (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 (H5AC_init() < 0)
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize metadata caching interface");
if (H5L_init() < 0)
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize link 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");

/* 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");
Expand All @@ -291,11 +283,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 */
Expand Down Expand Up @@ -337,147 +327,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:
*/
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.
/* Try to organize these so the "higher" level components get shut
* down before "lower" level components that they might rely on. -QAK
*/
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)
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)
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 */
, TERMINATOR(F, true)
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
*/
, TERMINATOR(P, true)
* 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.
*
* Shut down the "bottom" of the attribute, dataset, group,
*/
if (pending == 0) {
/* Shut down the "bottom" of the attribute, dataset, group,
* reference, 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.
pending += DOWN(A);
pending += DOWN(D);
pending += DOWN(G);
pending += DOWN(M);
pending += DOWN(R);
pending += DOWN(S);
pending += DOWN(T);
} /* end if */

/* 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
*/
, TERMINATOR(AC, true)
if (pending == 0) {
pending += DOWN(AC);
/* 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);

/* clang-format on */
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
}
}
}

Expand Down
Loading

0 comments on commit c5f00f9

Please sign in to comment.