summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt13
-rw-r--r--src/H5.c48
-rw-r--r--src/H5A.c1478
-rw-r--r--src/H5Adense.c28
-rw-r--r--src/H5Aint.c24
-rw-r--r--src/H5Apkg.h7
-rw-r--r--src/H5Aprivate.h8
-rw-r--r--src/H5Apublic.h87
-rw-r--r--src/H5B.c36
-rw-r--r--src/H5B2.c60
-rw-r--r--src/H5B2private.h2
-rw-r--r--src/H5Bprivate.h4
-rw-r--r--src/H5C.c2
-rw-r--r--src/H5CX.c6
-rw-r--r--src/H5D.c804
-rw-r--r--src/H5Dbtree.c29
-rw-r--r--src/H5Dbtree2.c17
-rw-r--r--src/H5Dmpio.c14
-rw-r--r--src/H5Dpkg.h6
-rw-r--r--src/H5Dpublic.h60
-rw-r--r--src/H5Dscatgath.c1
-rw-r--r--src/H5Dvirtual.c4
-rw-r--r--src/H5E.c109
-rw-r--r--src/H5EAtest.c6
-rw-r--r--src/H5ES.c378
-rw-r--r--src/H5ESevent.c197
-rw-r--r--src/H5ESint.c666
-rw-r--r--src/H5ESlist.c215
-rw-r--r--src/H5ESmodule.h32
-rw-r--r--src/H5ESpkg.h101
-rw-r--r--src/H5ESprivate.h54
-rw-r--r--src/H5ESpublic.h89
-rw-r--r--src/H5Epublic.h1
-rw-r--r--src/H5F.c658
-rw-r--r--src/H5FAtest.c8
-rw-r--r--src/H5FScache.c9
-rw-r--r--src/H5Fint.c5
-rw-r--r--src/H5Fprivate.h71
-rw-r--r--src/H5Fpublic.h259
-rw-r--r--src/H5G.c671
-rw-r--r--src/H5Gcompact.c22
-rw-r--r--src/H5Gdense.c17
-rw-r--r--src/H5Gloc.c3
-rw-r--r--src/H5Gname.c1
-rw-r--r--src/H5Gnode.c24
-rw-r--r--src/H5Gobj.c16
-rw-r--r--src/H5Gpkg.h10
-rw-r--r--src/H5Gprivate.h4
-rw-r--r--src/H5Gpublic.h41
-rw-r--r--src/H5Gstab.c17
-rw-r--r--src/H5Gtest.c1
-rw-r--r--src/H5Gtraverse.c5
-rw-r--r--src/H5HFcache.c6
-rw-r--r--src/H5HFhuge.c42
-rw-r--r--src/H5I.c36
-rw-r--r--src/H5Idbg.c1
-rw-r--r--src/H5Iint.c235
-rw-r--r--src/H5Ipkg.h15
-rw-r--r--src/H5Iprivate.h2
-rw-r--r--src/H5Ipublic.h93
-rw-r--r--src/H5L.c796
-rw-r--r--src/H5Lexternal.c3
-rw-r--r--src/H5Lpkg.h2
-rw-r--r--src/H5Lprivate.h2
-rw-r--r--src/H5Lpublic.h38
-rw-r--r--src/H5M.c536
-rw-r--r--src/H5MM.c3
-rw-r--r--src/H5MMprivate.h6
-rw-r--r--src/H5Mpublic.h32
-rw-r--r--src/H5O.c824
-rw-r--r--src/H5Oattribute.c40
-rw-r--r--src/H5Ocopy.c8
-rw-r--r--src/H5Oflush.c2
-rw-r--r--src/H5Oint.c1
-rw-r--r--src/H5Oprivate.h30
-rw-r--r--src/H5Opublic.h85
-rw-r--r--src/H5PLpublic.h6
-rw-r--r--src/H5Ppkg.h3
-rw-r--r--src/H5Ppublic.h104
-rw-r--r--src/H5R.c338
-rw-r--r--src/H5Rpublic.h21
-rw-r--r--src/H5S.c21
-rw-r--r--src/H5SM.c10
-rw-r--r--src/H5Spkg.h40
-rw-r--r--src/H5Sprivate.h1
-rw-r--r--src/H5Spublic.h12
-rw-r--r--src/H5T.c72
-rw-r--r--src/H5TS.c219
-rw-r--r--src/H5TSprivate.h5
-rw-r--r--src/H5TSpublic.h52
-rw-r--r--src/H5Tcommit.c250
-rw-r--r--src/H5Tpkg.h3
-rw-r--r--src/H5Tprivate.h8
-rw-r--r--src/H5Tpublic.h235
-rw-r--r--src/H5VL.c4
-rw-r--r--src/H5VLcallback.c46
-rw-r--r--src/H5VLconnector.h32
-rw-r--r--src/H5VLconnector_passthru.h5
-rw-r--r--src/H5VLint.c359
-rw-r--r--src/H5VLnative.c25
-rw-r--r--src/H5VLnative_attr.c9
-rw-r--r--src/H5VLnative_dataset.c7
-rw-r--r--src/H5VLnative_file.c8
-rw-r--r--src/H5VLnative_link.c4
-rw-r--r--src/H5VLpassthru.c36
-rw-r--r--src/H5VLpassthru.h2
-rw-r--r--src/H5VLprivate.h36
-rw-r--r--src/H5VLpublic.h32
-rw-r--r--src/H5Znbit.c12
-rw-r--r--src/H5Zpublic.h16
-rw-r--r--src/H5Zscaleoffset.c18
-rw-r--r--src/H5Zshuffle.c2
-rw-r--r--src/H5err.txt10
-rw-r--r--src/H5private.h1
-rw-r--r--src/H5public.h13
-rw-r--r--src/H5trace.c42
-rw-r--r--src/H5win32defs.h2
-rw-r--r--src/Makefile.am3
-rw-r--r--src/hdf5.h1
119 files changed, 9283 insertions, 2108 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a7e3f57..1bc878f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -174,6 +174,10 @@ IDE_GENERATED_PROPERTIES ("H5EA" "${H5EA_HDRS}" "${H5EA_SOURCES}" )
set (H5ES_SOURCES
+ ${HDF5_SRC_DIR}/H5ES.c
+ ${HDF5_SRC_DIR}/H5ESevent.c
+ ${HDF5_SRC_DIR}/H5ESint.c
+ ${HDF5_SRC_DIR}/H5ESlist.c
)
set (H5ES_HDRS
${HDF5_SRC_DIR}/H5ESpublic.h
@@ -181,6 +185,7 @@ set (H5ES_HDRS
IDE_GENERATED_PROPERTIES ("H5ES" "${H5ES_HDRS}" "${H5ES_SOURCES}" )
+
set (H5F_SOURCES
${HDF5_SRC_DIR}/H5F.c
${HDF5_SRC_DIR}/H5Faccum.c
@@ -440,6 +445,7 @@ set (H5MP_HDRS
)
IDE_GENERATED_PROPERTIES ("H5MP" "${H5MP_HDRS}" "${H5MP_SOURCES}" )
+
set (H5O_SOURCES
${HDF5_SRC_DIR}/H5O.c
${HDF5_SRC_DIR}/H5Oainfo.c
@@ -640,6 +646,7 @@ set (H5TS_SOURCES
${HDF5_SRC_DIR}/H5TS.c
)
set (H5TS_HDRS
+ ${HDF5_SRC_DIR}/H5TSpublic.h
)
IDE_GENERATED_PROPERTIES ("H5TS" "${H5TS_HDRS}" "${H5TS_SOURCES}" )
@@ -726,6 +733,7 @@ set (H5_MODULE_HEADERS
${HDF5_SRC_DIR}/H5Dmodule.h
${HDF5_SRC_DIR}/H5Emodule.h
${HDF5_SRC_DIR}/H5EAmodule.h
+ ${HDF5_SRC_DIR}/H5ESmodule.h
${HDF5_SRC_DIR}/H5Fmodule.h
${HDF5_SRC_DIR}/H5FAmodule.h
${HDF5_SRC_DIR}/H5FDdrvr_module.h
@@ -767,6 +775,7 @@ set (common_SRCS
${H5D_SOURCES}
${H5E_SOURCES}
${H5EA_SOURCES}
+ ${H5ES_SOURCES}
${H5F_SOURCES}
${H5FA_SOURCES}
${H5FD_SOURCES}
@@ -836,6 +845,7 @@ set (H5_PUBLIC_HEADERS
${H5S_HDRS}
${H5SM_HDRS}
${H5T_HDRS}
+ ${H5TS_HDRS}
${H5VL_HDRS}
${H5Z_HDRS}
)
@@ -875,6 +885,9 @@ set (H5_PRIVATE_HEADERS
${HDF5_SRC_DIR}/H5EApkg.h
${HDF5_SRC_DIR}/H5EAprivate.h
+ ${HDF5_SRC_DIR}/H5ESpkg.h
+ ${HDF5_SRC_DIR}/H5ESprivate.h
+
${HDF5_SRC_DIR}/H5Fpkg.h
${HDF5_SRC_DIR}/H5Fprivate.h
diff --git a/src/H5.c b/src/H5.c
index e5583be..bec41da 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -254,6 +254,8 @@ H5_init_library(void)
* 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.
*/
if (H5E_init() < 0)
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize error interface")
@@ -267,6 +269,8 @@ H5_init_library(void)
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 (H5VL_init_phase2() < 0)
@@ -357,21 +361,31 @@ H5_term_library(void)
/* Try to organize these so the "higher" level components get shut
* down before "lower" level components that they might rely on. -QAK
*/
- 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.
+ /* Close the event sets first, so that all asynchronous operations
+ * complete before anything else attempts to shut down.
*/
- pending += DOWN(A_top);
- pending += DOWN(D_top);
- pending += DOWN(G_top);
- pending += DOWN(M_top);
- pending += DOWN(R_top);
- pending += DOWN(S_top);
- pending += DOWN(T_top);
+ 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.
+ */
+ pending += DOWN(A_top);
+ pending += DOWN(D_top);
+ pending += DOWN(G_top);
+ pending += DOWN(M_top);
+ pending += DOWN(R_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)
@@ -1183,12 +1197,12 @@ H5free_memory(void *mem)
herr_t
H5is_library_threadsafe(hbool_t *is_ts /*out*/)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API_NOINIT
H5TRACE1("e", "x", is_ts);
- if(is_ts) {
+ if (is_ts) {
#ifdef H5_HAVE_THREADSAFE
*is_ts = TRUE;
#else /* H5_HAVE_THREADSAFE */
@@ -1218,14 +1232,14 @@ H5is_library_threadsafe(hbool_t *is_ts /*out*/)
herr_t
H5is_library_terminating(hbool_t *is_terminating /*out*/)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API_NOINIT
H5TRACE1("e", "x", is_terminating);
HDassert(is_terminating);
- if(is_terminating)
+ if (is_terminating)
*is_terminating = H5_TERM_GLOBAL;
else
ret_value = FAIL;
diff --git a/src/H5A.c b/src/H5A.c
index 20d6107..f5c981f 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -25,6 +25,7 @@
#include "H5Apkg.h" /* Attributes */
#include "H5CXprivate.h" /* API Contexts */
#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event Sets */
#include "H5FLprivate.h" /* Free Lists */
#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
@@ -48,6 +49,45 @@
/* Local Prototypes */
/********************/
+/* Helper routines for sync/async API calls */
+static hid_t H5A__create_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name,
+ hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id,
+ void **token_ptr);
+static hid_t H5A__create_api_common(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id,
+ hid_t acpl_id, hid_t aapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static hid_t H5A__create_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name,
+ hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id,
+ hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr);
+static hid_t H5A__open_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name,
+ hid_t aapl_id, void **token_ptr);
+static hid_t H5A__open_api_common(hid_t loc_id, const char *attr_name, hid_t aapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static hid_t H5A__open_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name,
+ hid_t aapl_id, hid_t lapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static hid_t H5A__open_by_idx_api_common(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
+ H5_iter_order_t order, hsize_t n, hid_t aapl_id, hid_t lapl_id,
+ void **token_ptr, H5VL_object_t **_vol_obj_ptr);
+static herr_t H5A__write_api_common(hid_t attr_id, hid_t type_id, const void *buf, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static herr_t H5A__read_api_common(hid_t attr_id, hid_t dtype_id, void *buf, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static herr_t H5A__rename_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *old_name,
+ const char *new_name, void **token_ptr);
+static herr_t H5A__rename_api_common(hid_t loc_id, const char *old_name, const char *new_name,
+ void **token_ptr, H5VL_object_t **_vol_obj_ptr);
+static herr_t H5A__rename_by_name_api_common(hid_t loc_id, const char *obj_name, const char *old_attr_name,
+ const char *new_attr_name, hid_t lapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static herr_t H5A__exists_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name,
+ hbool_t *attr_exists, void **token_ptr);
+static herr_t H5A__exists_api_common(hid_t obj_id, const char *attr_name, hbool_t *attr_exists,
+ void **token_ptr, H5VL_object_t **_vol_obj_ptr);
+static herr_t H5A__exists_by_name_api_common(hid_t obj_id, const char *obj_name, const char *attr_name,
+ hbool_t *attr_exists, hid_t lapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+
/*********************/
/* Package Variables */
/*********************/
@@ -61,6 +101,95 @@
/*******************/
/*--------------------------------------------------------------------------
+ * Function: H5A__create_common
+ *
+ * Purpose: This is the common function for creating HDF5 datasets.
+ *
+ * Return: Success: A attribute ID
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+H5A__create_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name,
+ hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, void **token_ptr)
+{
+ void *attr = NULL; /* Attribute created */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity checks */
+ HDassert(vol_obj);
+ HDassert(loc_params);
+ HDassert(attr_name);
+
+ /* Create the attribute */
+ if (NULL == (attr = H5VL_attr_create(vol_obj, loc_params, attr_name, type_id, space_id, acpl_id, aapl_id,
+ H5P_DATASET_XFER_DEFAULT, token_ptr)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5I_INVALID_HID, "unable to create attribute")
+
+ /* Register the new attribute and get an ID for it */
+ if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register attribute for ID")
+
+done:
+ /* Cleanup on failure */
+ if (H5I_INVALID_HID == ret_value)
+ if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A__create_common() */
+
+/*--------------------------------------------------------------------------
+ * Function: H5A__create_api_common
+ *
+ * Purpose: This is the common function for creating HDF5 attributes
+ *
+ * Return: Success: A attribute ID
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+H5A__create_api_common(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id,
+ hid_t aapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check arguments */
+ if (H5I_ATTR == H5I_get_type(loc_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute")
+ if (!attr_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "attr_name parameter cannot be NULL")
+ if (!*attr_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "attr_name parameter cannot be an empty string")
+
+ /* Set up object access arguments */
+ if (H5VL_setup_acc_args(loc_id, H5P_CLS_AACC, TRUE, &aapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")
+
+ /* Get correct property list */
+ if (H5P_DEFAULT == acpl_id)
+ acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT;
+
+ /* Create the attribute */
+ if ((ret_value = H5A__create_common(*vol_obj_ptr, &loc_params, attr_name, type_id, space_id, acpl_id,
+ aapl_id, token_ptr)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create attribute")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A__create_api_common() */
+
+/*--------------------------------------------------------------------------
* Function: H5Acreate2
*
* Purpose: Creates an attribute on an object
@@ -96,14 +225,90 @@
hid_t
H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id)
{
- void * attr = NULL; /* Attribute created */
- H5VL_object_t * vol_obj = NULL; /* Object of loc_id */
- H5VL_loc_params_t loc_params;
- hid_t ret_value = H5I_INVALID_HID; /* Return value */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
FUNC_ENTER_API(H5I_INVALID_HID)
H5TRACE6("i", "i*siiii", loc_id, attr_name, type_id, space_id, acpl_id, aapl_id);
+ /* Create the attribute synchronously */
+ if ((ret_value =
+ H5A__create_api_common(loc_id, attr_name, type_id, space_id, acpl_id, aapl_id, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously create attribute")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Acreate2() */
+
+/*--------------------------------------------------------------------------
+ * Function: H5Acreate_sync
+ *
+ * Purpose: Asynchronous version of H5Acreate
+ *
+ * Return: Success: A attribute ID
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Acreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id,
+ hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE10("i", "*s*sIui*siiiii", app_file, app_func, app_line, loc_id, attr_name, type_id, space_id,
+ acpl_id, aapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Create the attribute asynchronously */
+ if ((ret_value = H5A__create_api_common(loc_id, attr_name, type_id, space_id, acpl_id, aapl_id, token_ptr,
+ &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously create attribute")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE10(FUNC, "*s*sIui*siiiii", app_file, app_func, app_line, loc_id, attr_name,
+ type_id, space_id, acpl_id, aapl_id, es_id)) < 0) {
+ if (H5I_dec_app_ref(ret_value) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID")
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Acreate_async() */
+
+/*--------------------------------------------------------------------------
+ * Function: H5A__create_by_name_api_common
+ *
+ * Purpose: This is the common function for creating HDF5 attributes by name
+ *
+ * Return: Success: A attribute ID
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+H5A__create_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t type_id,
+ hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t lapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_STATIC
+
/* Check arguments */
if (H5I_ATTR == H5I_get_type(loc_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute")
@@ -112,39 +317,27 @@ H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, h
if (!*attr_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "attr_name parameter cannot be an empty string")
- /* Get correct property list */
- if (H5P_DEFAULT == acpl_id)
- acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT;
+ /* obj_name is verified in H5VL_setup_name_args() */
+ /* Set up object access arguments */
+ if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")
/* Verify access property list and set up collective metadata if appropriate */
if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, TRUE) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
-
- /* Get the location object */
- if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info")
- /* Set location parameters */
- loc_params.type = H5VL_OBJECT_BY_SELF;
- loc_params.obj_type = H5I_get_type(loc_id);
+ /* Get correct property list */
+ if (H5P_DEFAULT == acpl_id)
+ acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT;
/* Create the attribute */
- if (NULL == (attr = H5VL_attr_create(vol_obj, &loc_params, attr_name, type_id, space_id, acpl_id, aapl_id,
- H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5I_INVALID_HID, "unable to create attribute")
-
- /* Register the new attribute and get an ID for it */
- if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register attribute for ID")
+ if ((ret_value = H5A__create_common(*vol_obj_ptr, &loc_params, attr_name, type_id, space_id, acpl_id,
+ aapl_id, token_ptr)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create attribute")
done:
- /* Cleanup on failure */
- if (H5I_INVALID_HID == ret_value)
- if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
- HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute")
-
- FUNC_LEAVE_API(ret_value)
-} /* H5Acreate2() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A__create_by_name_api_common() */
/*--------------------------------------------------------------------------
NAME
@@ -180,48 +373,97 @@ hid_t
H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t type_id, hid_t space_id,
hid_t acpl_id, hid_t aapl_id, hid_t lapl_id)
{
- void * attr = NULL; /* attr object from VOL connector */
- H5VL_object_t * vol_obj = NULL; /* object of loc_id */
- H5VL_loc_params_t loc_params;
- hid_t ret_value = H5I_INVALID_HID; /* Return value */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
FUNC_ENTER_API(H5I_INVALID_HID)
H5TRACE8("i", "i*s*siiiii", loc_id, obj_name, attr_name, type_id, space_id, acpl_id, aapl_id, lapl_id);
- /* Check arguments */
- if (H5I_ATTR == H5I_get_type(loc_id))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute")
- if (!obj_name || !*obj_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no object name")
- if (!attr_name || !*attr_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no attribute name")
+ /* Create the attribute synchronously */
+ if ((ret_value = H5A__create_by_name_api_common(loc_id, obj_name, attr_name, type_id, space_id, acpl_id,
+ aapl_id, lapl_id, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously create attribute")
- /* Get correct property list */
- if (H5P_DEFAULT == acpl_id)
- acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT;
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Acreate_by_name() */
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, TRUE) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info")
- if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set link access property list info")
+/*--------------------------------------------------------------------------
+ * Function: H5Acreate_by_name_async
+ *
+ * Purpose: Asynchronous version of H5Acreate_by_name
+ *
+ * Return: Success: A attribute ID
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Acreate_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *obj_name, const char *attr_name, hid_t type_id, hid_t space_id,
+ hid_t acpl_id, hid_t aapl_id, hid_t lapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
- /* Set up location struct */
- loc_params.type = H5VL_OBJECT_BY_NAME;
- loc_params.obj_type = H5I_get_type(loc_id);
- loc_params.loc_data.loc_by_name.name = obj_name;
- loc_params.loc_data.loc_by_name.lapl_id = lapl_id;
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE12("i", "*s*sIui*s*siiiiii", app_file, app_func, app_line, loc_id, obj_name, attr_name, type_id,
+ space_id, acpl_id, aapl_id, lapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Create the attribute asynchronously */
+ if ((ret_value = H5A__create_by_name_api_common(loc_id, obj_name, attr_name, type_id, space_id, acpl_id,
+ aapl_id, lapl_id, token_ptr, &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously create attribute")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE12(FUNC, "*s*sIui*s*siiiiii", app_file, app_func, app_line, loc_id,
+ obj_name, attr_name, type_id, space_id, acpl_id, aapl_id, lapl_id,
+ es_id)) < 0) {
+ if (H5I_dec_app_ref(ret_value) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID")
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
- /* Get the location object */
- if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Acreate_by_name_async() */
- /* Create the attribute */
- if (NULL == (attr = H5VL_attr_create(vol_obj, &loc_params, attr_name, type_id, space_id, acpl_id, aapl_id,
- H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5I_INVALID_HID, "unable to create attribute")
+/*-------------------------------------------------------------------------
+ * Function: H5A__open_common
+ *
+ * Purpose: This is the common function for opening an attribute
+ *
+ * Return: Success: A group ID
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+H5A__open_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name, hid_t aapl_id,
+ void **token_ptr)
+{
+ void *attr = NULL; /* attr object from VOL connector */
+ hid_t ret_value = H5I_INVALID_HID;
- /* Register the new attribute and get an ID for it */
+ FUNC_ENTER_STATIC
+
+ /* Sanity checks */
+ HDassert(vol_obj);
+ HDassert(loc_params);
+
+ /* Open the attribute */
+ if (NULL ==
+ (attr = H5VL_attr_open(vol_obj, loc_params, attr_name, aapl_id, H5P_DATASET_XFER_DEFAULT, token_ptr)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute: '%s'", attr_name)
+
+ /* Register the attribute and get an ID for it */
if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register attribute for ID")
@@ -231,8 +473,50 @@ done:
if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute")
- FUNC_LEAVE_API(ret_value)
-} /* H5Acreate_by_name() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A__open_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5A__open_api_common
+ *
+ * Purpose: This is the common function for opening an attribute
+ *
+ * Return: Success: A group ID
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+H5A__open_api_common(hid_t loc_id, const char *attr_name, hid_t aapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check arguments */
+ if (H5I_ATTR == H5I_get_type(loc_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute")
+ if (!attr_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL")
+ if (!*attr_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string")
+
+ /* Set up object access arguments */
+ if (H5VL_setup_acc_args(loc_id, H5P_CLS_AACC, FALSE, &aapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")
+
+ /* Open the attribute */
+ if ((ret_value = H5A__open_common(*vol_obj_ptr, &loc_params, attr_name, aapl_id, token_ptr)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute: '%s'", attr_name)
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A__open_api_common() */
/*--------------------------------------------------------------------------
NAME
@@ -256,51 +540,108 @@ done:
hid_t
H5Aopen(hid_t loc_id, const char *attr_name, hid_t aapl_id)
{
- void * attr = NULL; /* attr object from VOL connector */
- H5VL_object_t * vol_obj = NULL; /* object of loc_id */
- H5VL_loc_params_t loc_params;
- hid_t ret_value = H5I_INVALID_HID;
+ hid_t ret_value = H5I_INVALID_HID;
FUNC_ENTER_API(H5I_INVALID_HID)
H5TRACE3("i", "i*si", loc_id, attr_name, aapl_id);
+ /* Open the attribute synchronously */
+ if ((ret_value = H5A__open_api_common(loc_id, attr_name, aapl_id, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously open attribute")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Aopen() */
+
+/*--------------------------------------------------------------------------
+ * NAME
+ * H5Aopen_async
+ * PURPOSE
+ * Asynchronous version of H5Aopen
+ *
+ * RETURNS
+ * ID of attribute on success, H5I_INVALID_HID on failure
+ *
+ *--------------------------------------------------------------------------*/
+hid_t
+H5Aopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *attr_name, hid_t aapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE7("i", "*s*sIui*sii", app_file, app_func, app_line, loc_id, attr_name, aapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Open the attribute asynchronously */
+ if ((ret_value = H5A__open_api_common(loc_id, attr_name, aapl_id, token_ptr, &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously open attribute")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE7(FUNC, "*s*sIui*sii", app_file, app_func, app_line, loc_id, attr_name,
+ aapl_id, es_id)) < 0) {
+ if (H5I_dec_app_ref(ret_value) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID")
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Aopen_async() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5A__open_by_name_api_common
+ *
+ * Purpose: This is the common function for opening an attribute
+ *
+ * Return: Success: A group ID
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+H5A__open_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t aapl_id,
+ hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ hid_t ret_value = H5I_INVALID_HID;
+
+ FUNC_ENTER_STATIC
+
/* Check arguments */
if (H5I_ATTR == H5I_get_type(loc_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute")
- if (!attr_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL")
- if (!*attr_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string")
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, FALSE) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
+ if (!attr_name || !*attr_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no attribute name")
- /* Set location struct fields */
- loc_params.type = H5VL_OBJECT_BY_SELF;
- loc_params.obj_type = H5I_get_type(loc_id);
+ /* obj_name is verified in H5VL_setup_name_args() */
+ /* Set up object access arguments */
+ if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")
- /* Get the location object */
- if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
+ /* Verify access property list and set up collective metadata if appropriate */
+ if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, FALSE) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info")
/* Open the attribute */
- if (NULL == (attr = H5VL_attr_open(vol_obj, &loc_params, attr_name, aapl_id, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL)))
+ if ((ret_value = H5A__open_common(*vol_obj_ptr, &loc_params, attr_name, aapl_id, token_ptr)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute: '%s'", attr_name)
- /* Register the attribute and get an ID for it */
- if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register attribute for ID")
-
done:
- /* Cleanup on failure */
- if (H5I_INVALID_HID == ret_value)
- if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
- HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute")
-
- FUNC_LEAVE_API(ret_value)
-} /* H5Aopen() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A__open_by_name_api_common() */
/*--------------------------------------------------------------------------
NAME
@@ -326,55 +667,115 @@ done:
hid_t
H5Aopen_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t aapl_id, hid_t lapl_id)
{
- void * attr = NULL; /* attr object from VOL connector */
- H5VL_object_t * vol_obj = NULL; /* object of loc_id */
- H5VL_loc_params_t loc_params;
- hid_t ret_value = H5I_INVALID_HID;
+ hid_t ret_value = H5I_INVALID_HID;
FUNC_ENTER_API(H5I_INVALID_HID)
H5TRACE5("i", "i*s*sii", loc_id, obj_name, attr_name, aapl_id, lapl_id);
+ /* Open the attribute by name asynchronously */
+ if ((ret_value =
+ H5A__open_by_name_api_common(loc_id, obj_name, attr_name, aapl_id, lapl_id, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to synchronously open attribute")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Aopen_by_name() */
+
+/*--------------------------------------------------------------------------
+ * NAME
+ * H5Aopen_by_name_async
+ * PURPOSE
+ * Asynchronous version of H5Aopen_by_name
+ *
+ * RETURNS
+ * ID of attribute on success, H5I_INVALID_HID on failure
+ *
+ *--------------------------------------------------------------------------*/
+hid_t
+H5Aopen_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *obj_name, const char *attr_name, hid_t aapl_id, hid_t lapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID;
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE9("i", "*s*sIui*s*siii", app_file, app_func, app_line, loc_id, obj_name, attr_name, aapl_id,
+ lapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Open the attribute by name asynchronously */
+ if ((ret_value = H5A__open_by_name_api_common(loc_id, obj_name, attr_name, aapl_id, lapl_id, token_ptr,
+ &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to asynchronously open attribute")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE9(FUNC, "*s*sIui*s*siii", app_file, app_func, app_line, loc_id, obj_name,
+ attr_name, aapl_id, lapl_id, es_id)) < 0) {
+ if (H5I_dec_app_ref(ret_value) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID")
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Aopen_by_name_async() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5A__open_by_idx_api_common
+ *
+ * Purpose: This is the common function for opening an attribute
+ *
+ * Return: Success: A group ID
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+H5A__open_by_idx_api_common(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order,
+ hsize_t n, hid_t aapl_id, hid_t lapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ hid_t ret_value = H5I_INVALID_HID;
+
+ FUNC_ENTER_STATIC
+
/* Check arguments */
if (H5I_ATTR == H5I_get_type(loc_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute")
if (!obj_name || !*obj_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no object name")
- if (!attr_name || !*attr_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no attribute name")
+ if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid index type specified")
+ if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid iteration order specified")
+
+ /* Set up object access arguments */
+ if (H5VL_setup_idx_args(loc_id, obj_name, idx_type, order, n, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr,
+ &loc_params) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")
/* Verify access property list and set up collective metadata if appropriate */
if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, FALSE) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info")
- if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set link access property list info")
-
- /* Fill in location struct fields */
- loc_params.type = H5VL_OBJECT_BY_NAME;
- loc_params.loc_data.loc_by_name.name = obj_name;
- loc_params.loc_data.loc_by_name.lapl_id = lapl_id;
- loc_params.obj_type = H5I_get_type(loc_id);
-
- /* Get the location object */
- if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
/* Open the attribute */
- if (NULL == (attr = H5VL_attr_open(vol_obj, &loc_params, attr_name, aapl_id, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL)))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "can't open attribute")
-
- /* Register the attribute and get an ID for it */
- if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register attribute handle")
+ if ((ret_value = H5A__open_common(*vol_obj_ptr, &loc_params, NULL, aapl_id, token_ptr)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute")
done:
- /* Cleanup on failure */
- if (H5I_INVALID_HID == ret_value)
- if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
- HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute")
-
- FUNC_LEAVE_API(ret_value)
-} /* end H5Aopen_by_name() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A__open_by_idx_api_common() */
/*--------------------------------------------------------------------------
NAME
@@ -404,60 +805,103 @@ hid_t
H5Aopen_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
hid_t aapl_id, hid_t lapl_id)
{
- void * attr = NULL; /* Attribute opened */
- H5VL_object_t * vol_obj = NULL; /* object of loc_id */
- H5VL_loc_params_t loc_params;
- hid_t ret_value = H5I_INVALID_HID; /* Return value */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
FUNC_ENTER_API(H5I_INVALID_HID)
H5TRACE7("i", "i*sIiIohii", loc_id, obj_name, idx_type, order, n, aapl_id, lapl_id);
- /* Check arguments */
- if (H5I_ATTR == H5I_get_type(loc_id))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute")
- if (!obj_name || !*obj_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no object name")
- if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid index type specified")
- if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid iteration order specified")
+ /* Open the attribute by idx synchronously */
+ if ((ret_value = H5A__open_by_idx_api_common(loc_id, obj_name, idx_type, order, n, aapl_id, lapl_id, NULL,
+ NULL)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously open attribute")
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, FALSE) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info")
- if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set link access property list info")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Aopen_by_idx() */
- /* Fill in location struct parameters */
- loc_params.type = H5VL_OBJECT_BY_IDX;
- loc_params.loc_data.loc_by_idx.name = obj_name;
- loc_params.loc_data.loc_by_idx.idx_type = idx_type;
- loc_params.loc_data.loc_by_idx.order = order;
- loc_params.loc_data.loc_by_idx.n = n;
- loc_params.loc_data.loc_by_idx.lapl_id = lapl_id;
- loc_params.obj_type = H5I_get_type(loc_id);
+/*--------------------------------------------------------------------------
+ * NAME
+ * H5Aopen_by_idx_async
+ * PURPOSE
+ * Asynchronous version of H5Aopen_by_idx
+ *
+ * RETURNS
+ * ID of attribute on success, H5I_INVALID_HID on failure
+ *
+ *--------------------------------------------------------------------------*/
+hid_t
+H5Aopen_by_idx_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
+ hid_t aapl_id, hid_t lapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID;
- /* Get the location object */
- if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE11("i", "*s*sIui*sIiIohiii", app_file, app_func, app_line, loc_id, obj_name, idx_type, order, n,
+ aapl_id, lapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Open the attribute by idx asynchronously */
+ if ((ret_value = H5A__open_by_idx_api_common(loc_id, obj_name, idx_type, order, n, aapl_id, lapl_id,
+ token_ptr, &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously open attribute")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE11(FUNC, "*s*sIui*sIiIohiii", app_file, app_func, app_line, loc_id,
+ obj_name, idx_type, order, n, aapl_id, lapl_id, es_id)) < 0) {
+ if (H5I_dec_app_ref(ret_value) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID")
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
- /* Open the attribute */
- if (NULL == (attr = H5VL_attr_open(vol_obj, &loc_params, NULL, aapl_id, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL)))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Aopen_by_idx_async() */
- /* Register the attribute and get an ID for it */
- if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register attribute handle")
+/*--------------------------------------------------------------------------
+ NAME
+ H5A__write_api_common
+ PURPOSE
+ Common helper routine for sync/async dataset write operations.
+ RETURNS
+ Non-negative on success/Negative on failure
+--------------------------------------------------------------------------*/
+static herr_t
+H5A__write_api_common(hid_t attr_id, hid_t type_id, const void *buf, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ herr_t ret_value = SUCCEED; /* Return value */
-done:
- /* Cleanup on failure */
- if (H5I_INVALID_HID == ret_value)
- if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
- HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute")
+ FUNC_ENTER_STATIC
- FUNC_LEAVE_API(ret_value)
-} /* H5Aopen_by_idx() */
+ /* Check arguments */
+ if (H5I_DATATYPE != H5I_get_type(type_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+ if (NULL == buf)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf parameter can't be NULL")
+
+ /* Get attribute pointer */
+ if (H5VL_setup_args(attr_id, H5I_ATTR, vol_obj_ptr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get VOL object for attribute")
+
+ /* Write the attribute data */
+ if (H5VL_attr_write(*vol_obj_ptr, type_id, buf, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "unable to write attribute")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A__write_api_common() */
/*--------------------------------------------------------------------------
NAME
@@ -478,31 +922,93 @@ done:
herr_t
H5Awrite(hid_t attr_id, hid_t dtype_id, const void *buf)
{
- H5VL_object_t *vol_obj; /* Attribute object for ID */
- herr_t ret_value; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE3("e", "ii*x", attr_id, dtype_id, buf);
+ /* Synchronously write the data */
+ if (H5A__write_api_common(attr_id, dtype_id, buf, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't synchronously write data")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Awrite() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Awrite_async
+ PURPOSE
+ Asynchronous version of H5Awrite
+ RETURNS
+ Non-negative on success/Negative on failure
+--------------------------------------------------------------------------*/
+herr_t
+H5Awrite_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, hid_t dtype_id,
+ const void *buf, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for attr_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE7("e", "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Asynchronously write the data */
+ if (H5A__write_api_common(attr_id, dtype_id, buf, token_ptr, &vol_obj) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't asynchronously write data")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE7(FUNC, "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id,
+ buf, es_id)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Awrite_async() */
+
+/*--------------------------------------------------------------------------
+ * NAME
+ * H5A__read_api_common
+ * PURPOSE
+ * Common helper routine for sync/async attribute read operations.
+ * RETURNS
+ * Non-negative on success/Negative on failure
+ *--------------------------------------------------------------------------*/
+static herr_t
+H5A__read_api_common(hid_t attr_id, hid_t dtype_id, void *buf, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
/* Check arguments */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
if (H5I_DATATYPE != H5I_get_type(dtype_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
if (NULL == buf)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf parameter can't be NULL")
- /* Set up collective metadata if appropriate */
- if (H5CX_set_loc(attr_id) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set collective metadata read")
+ /* Get attribute object pointer */
+ if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
- /* Write the attribute data */
- if ((ret_value = H5VL_attr_write(vol_obj, dtype_id, buf, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "unable to write attribute")
+ /* Read the attribute data */
+ if (H5VL_attr_read(*vol_obj_ptr, dtype_id, buf, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "unable to read attribute")
done:
- FUNC_LEAVE_API(ret_value)
-} /* H5Awrite() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A__read_api_common() */
/*--------------------------------------------------------------------------
NAME
@@ -523,29 +1029,59 @@ done:
herr_t
H5Aread(hid_t attr_id, hid_t dtype_id, void *buf /*out*/)
{
- H5VL_object_t *vol_obj; /* Attribute object for ID */
- herr_t ret_value; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE3("e", "iix", attr_id, dtype_id, buf);
- /* Check arguments */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
- if (H5I_DATATYPE != H5I_get_type(dtype_id))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
- if (NULL == buf)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf parameter can't be NULL")
-
- /* Read the attribute data */
- if ((ret_value = H5VL_attr_read(vol_obj, dtype_id, buf, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "unable to read attribute")
+ /* Synchronously read the data */
+ if (H5A__read_api_common(attr_id, dtype_id, buf, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't synchronously read data")
done:
FUNC_LEAVE_API(ret_value)
} /* H5Aread() */
/*--------------------------------------------------------------------------
+ * NAME
+ * H5Aread_async
+ * PURPOSE
+ * Asynchronous version of H5Aread
+ * RETURNS
+ * Non-negative on success/Negative on failure
+ *--------------------------------------------------------------------------*/
+herr_t
+H5Aread_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, hid_t dtype_id,
+ void *buf, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for attr_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE7("e", "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Asynchronously read the data */
+ if (H5A__read_api_common(attr_id, dtype_id, buf, token_ptr, &vol_obj) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't asynchronously read data")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE7(FUNC, "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id,
+ buf, es_id)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Aread_async() */
+
+/*--------------------------------------------------------------------------
NAME
H5Aget_space
PURPOSE
@@ -976,6 +1512,84 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Aget_info_by_idx() */
+/*--------------------------------------------------------------------------
+ NAME
+ H5A__rename_common
+ PURPOSE
+ Common helper routine for sync/async attribute rename operations
+ RETURNS
+ Non-negative on success/Negative on failure
+--------------------------------------------------------------------------*/
+static herr_t
+H5A__rename_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *old_name,
+ const char *new_name, void **token_ptr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity checks */
+ HDassert(vol_obj);
+ HDassert(loc_params);
+ HDassert(old_name);
+ HDassert(new_name);
+
+ /* Avoid thrashing things if the names are the same */
+ if (HDstrcmp(old_name, new_name))
+ /* Rename the attribute */
+ if (H5VL_attr_specific(vol_obj, loc_params, H5VL_ATTR_RENAME, H5P_DATASET_XFER_DEFAULT, token_ptr,
+ old_name, new_name) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute from '%s' to '%s'", old_name,
+ new_name)
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A__rename_common() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5A__rename_api_common
+ PURPOSE
+ Common helper routine for sync/async attribute rename operations
+ RETURNS
+ Non-negative on success/Negative on failure
+--------------------------------------------------------------------------*/
+static herr_t
+H5A__rename_api_common(hid_t loc_id, const char *old_name, const char *new_name, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check arguments */
+ if (H5I_ATTR == H5I_get_type(loc_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
+ if (!old_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "old attribute name cannot be NULL")
+ if (!*old_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "old attribute name cannot be an empty string")
+ if (!new_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new attribute name cannot be NULL")
+ if (!*new_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new attribute name cannot be an empty string")
+
+ /* Set up object access arguments */
+ if (H5VL_setup_loc_args(loc_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments")
+
+ /* Rename the attribute */
+ if (H5A__rename_common(*vol_obj_ptr, &loc_params, old_name, new_name, token_ptr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A__rename_api_common() */
+
/*-------------------------------------------------------------------------
* Function: H5Arename
*
@@ -997,9 +1611,77 @@ H5Arename(hid_t loc_id, const char *old_name, const char *new_name)
FUNC_ENTER_API(FAIL)
H5TRACE3("e", "i*s*s", loc_id, old_name, new_name);
+ /* Synchronously rename the attribute */
+ if (H5A__rename_api_common(loc_id, old_name, new_name, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Arename() */
+
+/*--------------------------------------------------------------------------
+ * NAME
+ * H5Arename_async
+ * PURPOSE
+ * Asynchronous version of H5Arename
+ * RETURNS
+ * Non-negative on success/Negative on failure
+ *--------------------------------------------------------------------------*/
+herr_t
+H5Arename_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *old_name, const char *new_name, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE7("e", "*s*sIui*s*si", app_file, app_func, app_line, loc_id, old_name, new_name, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Asynchronously rename the attribute */
+ if (H5A__rename_api_common(loc_id, old_name, new_name, token_ptr, &vol_obj) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't asynchronously rename attribute")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE7(FUNC, "*s*sIui*s*si", app_file, app_func, app_line, loc_id, old_name,
+ new_name, es_id)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Arename_async() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5A__rename_by_name_api_common
+ PURPOSE
+ Common helper routine for sync/async attribute rename operations
+ RETURNS
+ Non-negative on success/Negative on failure
+--------------------------------------------------------------------------*/
+static herr_t
+H5A__rename_by_name_api_common(hid_t loc_id, const char *obj_name, const char *old_name, const char *new_name,
+ hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
/* Check arguments */
if (H5I_ATTR == H5I_get_type(loc_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
+
if (!old_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "old attribute name cannot be NULL")
if (!*old_name)
@@ -1009,30 +1691,18 @@ H5Arename(hid_t loc_id, const char *old_name, const char *new_name)
if (!*new_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new attribute name cannot be an empty string")
- /* Avoid thrashing things if the names are the same */
- if (HDstrcmp(old_name, new_name)) {
- H5VL_object_t * vol_obj;
- H5VL_loc_params_t loc_params;
-
- loc_params.type = H5VL_OBJECT_BY_SELF;
- loc_params.obj_type = H5I_get_type(loc_id);
-
- if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+ /* obj_name is verified in H5VL_setup_name_args() */
+ /* Set up object access arguments */
+ if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments")
- /* Set up collective metadata if appropriate */
- if (H5CX_set_loc(loc_id) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set collective metadata read")
-
- /* Rename the attribute */
- if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_RENAME, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL, old_name, new_name) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute")
- } /* end if */
+ /* Rename the attribute */
+ if (H5A__rename_common(*vol_obj_ptr, &loc_params, old_name, new_name, token_ptr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute")
done:
- FUNC_LEAVE_API(ret_value)
-} /* H5Arename() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A__rename_by_name_api_common() */
/*-------------------------------------------------------------------------
* Function: H5Arename_by_name
@@ -1056,43 +1726,56 @@ H5Arename_by_name(hid_t loc_id, const char *obj_name, const char *old_attr_name,
FUNC_ENTER_API(FAIL)
H5TRACE5("e", "i*s*s*si", loc_id, obj_name, old_attr_name, new_attr_name, lapl_id);
- /* check arguments */
- if (H5I_ATTR == H5I_get_type(loc_id))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
- if (!obj_name || !*obj_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
- if (!old_attr_name || !*old_attr_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no old attribute name")
- if (!new_attr_name || !*new_attr_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new attribute name")
+ /* Synchronously rename the attribute */
+ if (H5A__rename_by_name_api_common(loc_id, obj_name, old_attr_name, new_attr_name, lapl_id, NULL, NULL) <
+ 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute")
- /* Avoid thrashing things if the names are the same */
- if (HDstrcmp(old_attr_name, new_attr_name)) {
- H5VL_object_t * vol_obj;
- H5VL_loc_params_t loc_params;
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Arename_by_name() */
+
+/*--------------------------------------------------------------------------
+ * NAME
+ * H5Arename_by_name_async
+ * PURPOSE
+ * Asynchronous version of H5Arename_by_name
+ * RETURNS
+ * Non-negative on success/Negative on failure
+ *--------------------------------------------------------------------------*/
+herr_t
+H5Arename_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *obj_name, const char *old_attr_name, const char *new_attr_name,
+ hid_t lapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info")
+ FUNC_ENTER_API(FAIL)
+ H5TRACE9("e", "*s*sIui*s*s*sii", app_file, app_func, app_line, loc_id, obj_name, old_attr_name,
+ new_attr_name, lapl_id, es_id);
- loc_params.type = H5VL_OBJECT_BY_NAME;
- loc_params.loc_data.loc_by_name.name = obj_name;
- loc_params.loc_data.loc_by_name.lapl_id = lapl_id;
- loc_params.obj_type = H5I_get_type(loc_id);
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
- /* Get the location object */
- if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+ /* Asynchronously rename the attribute */
+ if (H5A__rename_by_name_api_common(loc_id, obj_name, old_attr_name, new_attr_name, lapl_id, token_ptr,
+ &vol_obj) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute")
- /* Rename the attribute */
- if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_RENAME, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL, old_attr_name, new_attr_name) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute")
- } /* end if */
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE9(FUNC, "*s*sIui*s*s*sii", app_file, app_func, app_line, loc_id, obj_name,
+ old_attr_name, new_attr_name, lapl_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set")
done:
FUNC_LEAVE_API(ret_value)
-} /* H5Arename_by_name() */
+} /* H5Arename_by_name_async() */
/*--------------------------------------------------------------------------
NAME
@@ -1136,8 +1819,8 @@ done:
attribute.
--------------------------------------------------------------------------*/
herr_t
-H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx /*in,out */, H5A_operator2_t op,
- void *op_data)
+H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx /*in,out */,
+ H5A_operator2_t op, void *op_data)
{
H5VL_object_t * vol_obj = NULL; /* object of loc_id */
H5VL_loc_params_t loc_params;
@@ -1470,6 +2153,138 @@ done:
} /* H5Aclose() */
/*-------------------------------------------------------------------------
+ * Function: H5Aclose_async
+ *
+ * Purpose: Asynchronous version of H5Aclose
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Aclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ H5VL_t * connector = NULL; /* VOL connector */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, attr_id, es_id);
+
+ /* Check arguments */
+ if (H5I_ATTR != H5I_get_type(attr_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a attribute ID")
+
+ /* Prepare for possible asynchronous operation */
+ if (H5ES_NONE != es_id) {
+ /* Get attribute object's connector */
+ if (NULL == (vol_obj = H5VL_vol_object(attr_id)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get VOL object for attribute")
+
+ /* Increase connector's refcount, so it doesn't get closed if closing
+ * the attribute closes the file */
+ connector = vol_obj->connector;
+ H5VL_conn_inc_rc(connector);
+
+ /* Point at token for operation to set up */
+ token_ptr = &token;
+ } /* end if */
+
+ /* Decrement the counter on the attribute ID. It will be freed if the count
+ * reaches zero.
+ */
+ if (H5I_dec_app_ref_async(attr_id, token_ptr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "decrementing attribute ID failed")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, attr_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ if (connector && H5VL_conn_dec_rc(connector) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "can't decrement ref count on connector")
+
+ FUNC_LEAVE_API(ret_value)
+} /* H5Aclose_async() */
+
+/*--------------------------------------------------------------------------
+ * NAME
+ * H5A__exists_common
+ * PURPOSE
+ * Common helper routine for sync/async check if an attribute exists
+ * RETURNS
+ * Non-negative on success/Negative on failure
+ *--------------------------------------------------------------------------*/
+static herr_t
+H5A__exists_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name,
+ hbool_t *attr_exists, void **token_ptr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity checks */
+ HDassert(vol_obj);
+ HDassert(loc_params);
+
+ /* Check arguments */
+ if (!attr_name || !*attr_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
+
+ /* Check if the attribute exists */
+ if (H5VL_attr_specific(vol_obj, loc_params, H5VL_ATTR_EXISTS, H5P_DATASET_XFER_DEFAULT, token_ptr,
+ attr_name, attr_exists) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A__exists_common() */
+
+/*--------------------------------------------------------------------------
+ * NAME
+ * H5A__exists_api_common
+ * PURPOSE
+ * Common helper routine for sync/async check if an attribute exists
+ * RETURNS
+ * Non-negative on success/Negative on failure
+ *--------------------------------------------------------------------------*/
+static herr_t
+H5A__exists_api_common(hid_t obj_id, const char *attr_name, hbool_t *attr_exists, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check arguments */
+ if (H5I_ATTR == H5I_get_type(obj_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
+ if (!attr_name || !*attr_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
+ if (NULL == attr_exists)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer for attribute existence")
+
+ /* Set up object access arguments */
+ if (H5VL_setup_self_args(obj_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments")
+
+ /* Check if the attribute exists */
+ if (H5A__exists_common(*vol_obj_ptr, &loc_params, attr_name, attr_exists, token_ptr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A__exists_api_common() */
+
+/*-------------------------------------------------------------------------
* Function: H5Aexists
*
* Purpose: Checks if an attribute with a given name exists on an opened
@@ -1486,34 +2301,104 @@ done:
htri_t
H5Aexists(hid_t obj_id, const char *attr_name)
{
- H5VL_object_t * vol_obj;
- H5VL_loc_params_t loc_params;
- htri_t ret_value; /* Return value */
+ hbool_t exists; /* Flag for attribute existance */
+ htri_t ret_value = FAIL; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE2("t", "i*s", obj_id, attr_name);
+ /* Synchronously check if an attribute exists */
+ exists = FALSE;
+ if (H5A__exists_api_common(obj_id, attr_name, &exists, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute")
+
+ /* Set return value */
+ ret_value = (htri_t)exists;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Aexists() */
+
+/*--------------------------------------------------------------------------
+ * NAME
+ * H5Aexists_async
+ * PURPOSE
+ * Asynchronous version of H5Aexists
+ * RETURNS
+ * Non-negative on success/Negative on failure
+ *--------------------------------------------------------------------------*/
+herr_t
+H5Aexists_async(const char *app_file, const char *app_func, unsigned app_line, hid_t obj_id,
+ const char *attr_name, hbool_t *attr_exists, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE7("e", "*s*sIui*s*bi", app_file, app_func, app_line, obj_id, attr_name, attr_exists, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Asynchronously check if an attribute exists */
+ if (H5A__exists_api_common(obj_id, attr_name, attr_exists, token_ptr, &vol_obj) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't asynchronously check if attribute exists")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE7(FUNC, "*s*sIui*s*bi", app_file, app_func, app_line, obj_id, attr_name,
+ attr_exists, es_id)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Aexists_async() */
+
+/*--------------------------------------------------------------------------
+ * NAME
+ * H5A__exists_by_name_api_common
+ * PURPOSE
+ * Common helper routine for sync/async check if an attribute exists
+ * RETURNS
+ * Non-negative on success/Negative on failure
+ *--------------------------------------------------------------------------*/
+static herr_t
+H5A__exists_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name,
+ hbool_t *attr_exists, hid_t lapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
/* Check arguments */
- if (H5I_ATTR == H5I_get_type(obj_id))
+ if (H5I_ATTR == H5I_get_type(loc_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
if (!attr_name || !*attr_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
+ if (NULL == attr_exists)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer for attribute existence")
- /* get the object */
- if (NULL == (vol_obj = H5VL_vol_object(obj_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier")
-
- loc_params.type = H5VL_OBJECT_BY_SELF;
- loc_params.obj_type = H5I_get_type(obj_id);
+ /* obj_name is verified in H5VL_setup_name_args() */
+ /* Set up object access arguments */
+ if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments")
/* Check if the attribute exists */
- if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_EXISTS, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL,
- attr_name, &ret_value) < 0)
+ if (H5A__exists_common(*vol_obj_ptr, &loc_params, attr_name, attr_exists, token_ptr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists")
done:
- FUNC_LEAVE_API(ret_value)
-} /* H5Aexists() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A__exists_by_name_api_common() */
/*-------------------------------------------------------------------------
* Function: H5Aexists_by_name
@@ -1521,7 +2406,7 @@ done:
* Purpose: Checks if an attribute with a given name exists on an object.
*
* Return: Success: TRUE/FALSE
- * Failure: Negative
+ * Failure: Negative
*
* Programmer: Quincey Koziol
* Thursday, November 1, 2007
@@ -1531,39 +2416,62 @@ done:
htri_t
H5Aexists_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t lapl_id)
{
- H5VL_object_t * vol_obj;
- H5VL_loc_params_t loc_params;
- htri_t ret_value; /* Return value */
+ hbool_t exists; /* Flag for attribute existance */
+ htri_t ret_value = FAIL; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE4("t", "i*s*si", loc_id, obj_name, attr_name, lapl_id);
- /* check arguments */
- if (H5I_ATTR == H5I_get_type(loc_id))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
- if (!obj_name || !*obj_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name")
- if (!attr_name || !*attr_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name")
+ /* Synchronously check if an attribute exists */
+ exists = FALSE;
+ if (H5A__exists_by_name_api_common(loc_id, obj_name, attr_name, &exists, lapl_id, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute")
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info")
+ /* Set return value */
+ ret_value = (htri_t)exists;
- /* get the object */
- if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Aexists_by_name() */
- loc_params.type = H5VL_OBJECT_BY_NAME;
- loc_params.loc_data.loc_by_name.name = obj_name;
- loc_params.loc_data.loc_by_name.lapl_id = lapl_id;
- loc_params.obj_type = H5I_get_type(loc_id);
+/*--------------------------------------------------------------------------
+ * NAME
+ * H5Aexists_by_name_async
+ * PURPOSE
+ * Asynchronous version of H5Aexists_by_name
+ * RETURNS
+ * Non-negative on success/Negative on failure
+ *--------------------------------------------------------------------------*/
+herr_t
+H5Aexists_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *obj_name, const char *attr_name, hbool_t *attr_exists, hid_t lapl_id,
+ hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Check existence of attribute */
- if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_EXISTS, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL,
- attr_name, &ret_value) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists")
+ FUNC_ENTER_API(FAIL)
+ H5TRACE9("e", "*s*sIui*s*s*bii", app_file, app_func, app_line, loc_id, obj_name, attr_name, attr_exists,
+ lapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Asynchronously check if an attribute exists */
+ if (H5A__exists_by_name_api_common(loc_id, obj_name, attr_name, attr_exists, lapl_id, token_ptr,
+ &vol_obj) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't asynchronously rename attribute")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE9(FUNC, "*s*sIui*s*s*bii", app_file, app_func, app_line, loc_id, obj_name,
+ attr_name, attr_exists, lapl_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set")
done:
FUNC_LEAVE_API(ret_value)
-} /* H5Aexists_by_name() */
+} /* H5Aexists_by_name_async() */
diff --git a/src/H5Adense.c b/src/H5Adense.c
index 1efe45d..69f2a15 100644
--- a/src/H5Adense.c
+++ b/src/H5Adense.c
@@ -338,7 +338,7 @@ H5A__dense_open(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name)
H5HF_t * shared_fheap = NULL; /* Fractal heap handle for shared header messages */
H5B2_t * bt2_name = NULL; /* v2 B-tree handle for name index */
htri_t attr_sharable; /* Flag indicating attributes are sharable */
- htri_t attr_exists; /* Attribute exists in v2 B-tree */
+ hbool_t attr_exists; /* Attribute exists in v2 B-tree */
H5A_t * ret_value = NULL; /* Return value */
FUNC_ENTER_PACKAGE
@@ -388,9 +388,10 @@ H5A__dense_open(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name)
udata.found_op_data = &ret_value;
/* Find & copy the attribute in the 'name' index */
- if ((attr_exists = H5B2_find(bt2_name, &udata, NULL, NULL)) < 0)
+ attr_exists = FALSE;
+ if (H5B2_find(bt2_name, &udata, &attr_exists, NULL, NULL) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "can't search for attribute in name index")
- else if (attr_exists == FALSE)
+ if (attr_exists == FALSE)
HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "can't locate attribute in name index")
done:
@@ -866,7 +867,7 @@ H5A__dense_rename(H5F_t *f, const H5O_ainfo_t *ainfo, const char *old_name, cons
H5A_t * attr_copy = NULL; /* Copy of attribute to rename */
htri_t attr_sharable; /* Flag indicating attributes are sharable */
htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */
- htri_t attr_exists; /* Attribute exists in v2 B-tree */
+ hbool_t attr_exists; /* Attribute exists in v2 B-tree */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
@@ -917,9 +918,10 @@ H5A__dense_rename(H5F_t *f, const H5O_ainfo_t *ainfo, const char *old_name, cons
udata.found_op_data = &attr_copy;
/* Get copy of attribute through 'name' tracking v2 B-tree */
- if ((attr_exists = H5B2_find(bt2_name, &udata, NULL, NULL)) < 0)
+ attr_exists = FALSE;
+ if (H5B2_find(bt2_name, &udata, &attr_exists, NULL, NULL) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't search for attribute in name index")
- else if (attr_exists == FALSE)
+ if (attr_exists == FALSE)
HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't locate attribute in name index")
HDassert(attr_copy);
@@ -942,7 +944,7 @@ H5A__dense_rename(H5F_t *f, const H5O_ainfo_t *ainfo, const char *old_name, cons
/* Need to remove the attribute from the creation order index v2 B-tree */
if (ainfo->index_corder) {
- htri_t corder_attr_exists; /* Attribute exists in v2 B-tree */
+ hbool_t corder_attr_exists; /* Attribute exists in v2 B-tree */
/* Open the creation order index v2 B-tree */
HDassert(H5F_addr_defined(ainfo->corder_bt2_addr));
@@ -952,7 +954,8 @@ H5A__dense_rename(H5F_t *f, const H5O_ainfo_t *ainfo, const char *old_name, cons
/* Set up the creation order to search for */
udata.corder = attr_copy->shared->crt_idx;
- if ((corder_attr_exists = H5B2_find(bt2_corder, &udata, NULL, NULL)) < 0)
+ corder_attr_exists = FALSE;
+ if (H5B2_find(bt2_corder, &udata, &corder_attr_exists, NULL, NULL) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't search for attribute in name index")
if (corder_attr_exists) {
@@ -1665,15 +1668,15 @@ done:
*
*-------------------------------------------------------------------------
*/
-htri_t
-H5A__dense_exists(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name)
+herr_t
+H5A__dense_exists(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name, hbool_t *attr_exists)
{
H5A_bt2_ud_common_t udata; /* User data for v2 B-tree modify */
H5HF_t * fheap = NULL; /* Fractal heap handle */
H5HF_t * shared_fheap = NULL; /* Fractal heap handle for shared header messages */
H5B2_t * bt2_name = NULL; /* v2 B-tree handle for name index */
htri_t attr_sharable; /* Flag indicating attributes are sharable */
- htri_t ret_value = TRUE; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
@@ -1681,6 +1684,7 @@ H5A__dense_exists(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name)
HDassert(f);
HDassert(ainfo);
HDassert(name);
+ HDassert(attr_exists);
/* Open the fractal heap */
if (NULL == (fheap = H5HF_open(f, ainfo->fheap_addr)))
@@ -1722,7 +1726,7 @@ H5A__dense_exists(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name)
udata.found_op_data = NULL;
/* Find the attribute in the 'name' index */
- if ((ret_value = H5B2_find(bt2_name, &udata, NULL, NULL)) < 0)
+ if (H5B2_find(bt2_name, &udata, attr_exists, NULL, NULL) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't search for attribute in name index")
done:
diff --git a/src/H5Aint.c b/src/H5Aint.c
index 9b24950..de9d36a 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -294,7 +294,7 @@ H5A__create(const H5G_loc_t *loc, const char *attr_name, const H5T_t *type, cons
H5A_t * attr = NULL; /* Attribute created */
hssize_t snelmts; /* elements in attribute */
size_t nelmts; /* elements in attribute */
- htri_t exists; /* Whether attribute exists */
+ hbool_t exists; /* Whether attribute exists */
H5A_t * ret_value = NULL; /* Return value */
FUNC_ENTER_PACKAGE_TAG(loc->oloc->addr)
@@ -310,9 +310,10 @@ H5A__create(const H5G_loc_t *loc, const char *attr_name, const H5T_t *type, cons
* name, but it's going to be hard to unwind all the special cases on
* failure, so just check first, for now - QAK)
*/
- if ((exists = H5O__attr_exists(loc->oloc, attr_name)) < 0)
+ exists = FALSE;
+ if (H5O__attr_exists(loc->oloc, attr_name, &exists) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "error checking attributes")
- else if (exists > 0)
+ if (exists)
HGOTO_ERROR(H5E_ATTR, H5E_ALREADYEXISTS, NULL, "attribute already exists")
/* Check if the dataspace has an extent set (or is NULL) */
@@ -1467,20 +1468,21 @@ done:
*
*-------------------------------------------------------------------------
*/
-htri_t
-H5A__exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name)
+herr_t
+H5A__exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name, hbool_t *attr_exists)
{
- H5G_loc_t obj_loc; /* Location used to open group */
- H5G_name_t obj_path; /* Opened object group hier. path */
- H5O_loc_t obj_oloc; /* Opened object object location */
- hbool_t loc_found = FALSE; /* Entry at 'obj_name' found */
- htri_t ret_value = FAIL; /* Return value */
+ H5G_loc_t obj_loc; /* Location used to open group */
+ H5G_name_t obj_path; /* Opened object group hier. path */
+ H5O_loc_t obj_oloc; /* Opened object object location */
+ hbool_t loc_found = FALSE; /* Entry at 'obj_name' found */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
/* Sanity check */
HDassert(obj_name);
HDassert(attr_name);
+ HDassert(attr_exists);
/* Set up opened group location to fill in */
obj_loc.oloc = &obj_oloc;
@@ -1493,7 +1495,7 @@ H5A__exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name)
loc_found = TRUE;
/* Check if the attribute exists */
- if ((ret_value = H5O__attr_exists(obj_loc.oloc, attr_name)) < 0)
+ if (H5O__attr_exists(obj_loc.oloc, attr_name, attr_exists) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists")
done:
diff --git a/src/H5Apkg.h b/src/H5Apkg.h
index 5a64a1b..e4c8551 100644
--- a/src/H5Apkg.h
+++ b/src/H5Apkg.h
@@ -203,7 +203,8 @@ H5_DLL herr_t H5A__iterate_old(hid_t loc_id, unsigned *attr_num, H5A_operator1_t
H5_DLL herr_t H5A__delete_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_name);
H5_DLL herr_t H5A__delete_by_idx(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n);
-H5_DLL htri_t H5A__exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name);
+H5_DLL herr_t H5A__exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name,
+ hbool_t *attr_exists);
H5_DLL herr_t H5A__write(H5A_t *attr, const H5T_t *mem_type, const void *buf);
H5_DLL herr_t H5A__read(const H5A_t *attr, const H5T_t *mem_type, void *buf);
H5_DLL ssize_t H5A__get_name(H5A_t *attr, size_t buf_size, char *buf);
@@ -221,7 +222,7 @@ H5_DLL herr_t H5A__dense_iterate(H5F_t *f, hid_t loc_id, const H5O_ainfo_t *ainf
H5_DLL herr_t H5A__dense_remove(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name);
H5_DLL herr_t H5A__dense_remove_by_idx(H5F_t *f, const H5O_ainfo_t *ainfo, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n);
-H5_DLL htri_t H5A__dense_exists(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name);
+H5_DLL herr_t H5A__dense_exists(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name, hbool_t *attr_exists);
H5_DLL herr_t H5A__dense_delete(H5F_t *f, H5O_ainfo_t *ainfo);
/* Attribute table operations */
@@ -246,7 +247,7 @@ H5_DLL herr_t H5O__attr_iterate(hid_t loc_id, H5_index_t idx_type, H5_iter_order
H5_DLL herr_t H5O__attr_remove(const H5O_loc_t *loc, const char *name);
H5_DLL herr_t H5O__attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, H5_iter_order_t order,
hsize_t n);
-H5_DLL htri_t H5O__attr_exists(const H5O_loc_t *loc, const char *name);
+H5_DLL herr_t H5O__attr_exists(const H5O_loc_t *loc, const char *name, hbool_t *attr_exists);
H5_DLL H5A_t *H5A__attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_size,
H5O_copy_t *cpy_info);
H5_DLL herr_t H5A__attr_post_copy_file(const H5O_loc_t *src_oloc, const H5A_t *mesg_src, H5O_loc_t *dst_oloc,
diff --git a/src/H5Aprivate.h b/src/H5Aprivate.h
index 4164154..69fba40 100644
--- a/src/H5Aprivate.h
+++ b/src/H5Aprivate.h
@@ -43,8 +43,8 @@ typedef herr_t (*H5A_lib_iterate_t)(const H5A_t *attr, void *op_data);
/* Describe kind of callback to make for each attribute */
typedef enum H5A_attr_iter_op_type_t {
#ifndef H5_NO_DEPRECATED_SYMBOLS
- H5A_ATTR_OP_APP, /* Application callback */
-#endif /* H5_NO_DEPRECATED_SYMBOLS */
+ H5A_ATTR_OP_APP, /* Application callback */
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
H5A_ATTR_OP_APP2, /* Revised application callback */
H5A_ATTR_OP_LIB /* Library internal callback */
} H5A_attr_iter_op_type_t;
@@ -53,8 +53,8 @@ typedef struct H5A_attr_iter_op_t {
H5A_attr_iter_op_type_t op_type;
union {
#ifndef H5_NO_DEPRECATED_SYMBOLS
- H5A_operator1_t app_op; /* Application callback for each attribute */
-#endif /* H5_NO_DEPRECATED_SYMBOLS */
+ H5A_operator1_t app_op; /* Application callback for each attribute */
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
H5A_operator2_t app_op2; /* Revised application callback for each attribute */
H5A_lib_iterate_t lib_op; /* Library internal callback for each attribute */
} u;
diff --git a/src/H5Apublic.h b/src/H5Apublic.h
index c3442b8..847f053 100644
--- a/src/H5Apublic.h
+++ b/src/H5Apublic.h
@@ -92,8 +92,11 @@ extern "C" {
* \see H5Aclose()
*
*/
-H5_DLL hid_t H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id,
- hid_t aapl_id);
+H5_DLL hid_t H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id,
+ hid_t aapl_id);
+H5_DLL hid_t H5Acreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id,
+ hid_t aapl_id, hid_t es_id);
/*--------------------------------------------------------------------------*/
/**
* \ingroup H5A
@@ -141,8 +144,12 @@ H5_DLL hid_t H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hi
* \since 1.8.0
*
*/
-H5_DLL hid_t H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t type_id,
- hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t lapl_id);
+H5_DLL hid_t H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t type_id,
+ hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t lapl_id);
+H5_DLL hid_t H5Acreate_by_name_async(const char *app_file, const char *app_func, unsigned app_line,
+ hid_t loc_id, const char *obj_name, const char *attr_name, hid_t type_id,
+ hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t lapl_id,
+ hid_t es_id);
/*--------------------------------------------------------------------------*/
/**
* \ingroup H5A
@@ -173,7 +180,9 @@ H5_DLL hid_t H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char
*
* \see H5Aclose(), H5Acreate()
*/
-H5_DLL hid_t H5Aopen(hid_t obj_id, const char *attr_name, hid_t aapl_id);
+H5_DLL hid_t H5Aopen(hid_t obj_id, const char *attr_name, hid_t aapl_id);
+H5_DLL hid_t H5Aopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t obj_id,
+ const char *attr_name, hid_t aapl_id, hid_t es_id);
/*--------------------------------------------------------------------------*/
/**
* \ingroup H5A
@@ -219,8 +228,11 @@ H5_DLL hid_t H5Aopen(hid_t obj_id, const char *attr_name, hid_t aapl_id);
* \since 1.8.0
*
*/
-H5_DLL hid_t H5Aopen_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order,
- hsize_t n, hid_t aapl_id, hid_t lapl_id);
+H5_DLL hid_t H5Aopen_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order,
+ hsize_t n, hid_t aapl_id, hid_t lapl_id);
+H5_DLL hid_t H5Aopen_by_idx_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
+ hid_t aapl_id, hid_t lapl_id, hid_t es_id);
/*--------------------------------------------------------------------------*/
/**
* \ingroup H5A
@@ -262,8 +274,11 @@ H5_DLL hid_t H5Aopen_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx
* \since 1.8.0
*
*/
-H5_DLL hid_t H5Aopen_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t aapl_id,
- hid_t lapl_id);
+H5_DLL hid_t H5Aopen_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t aapl_id,
+ hid_t lapl_id);
+H5_DLL hid_t H5Aopen_by_name_async(const char *app_file, const char *app_func, unsigned app_line,
+ hid_t loc_id, const char *obj_name, const char *attr_name, hid_t aapl_id,
+ hid_t lapl_id, hid_t es_id);
/*-------------------------------------------------------------------------- */
/**
* \ingroup H5A
@@ -290,8 +305,10 @@ H5_DLL hid_t H5Aopen_by_name(hid_t loc_id, const char *obj_name, const char *a
*
* \see H5Awrite()
*
-*/
-H5_DLL herr_t H5Aread(hid_t attr_id, hid_t type_id, void *buf);
+ */
+H5_DLL herr_t H5Aread(hid_t attr_id, hid_t type_id, void *buf);
+H5_DLL herr_t H5Aread_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id,
+ hid_t dtype_id, void *buf, hid_t es_id);
/*--------------------------------------------------------------------------*/
/**
* \ingroup H5A
@@ -324,6 +341,8 @@ H5_DLL herr_t H5Aread(hid_t attr_id, hid_t type_id, void *buf);
*
*/
H5_DLL herr_t H5Awrite(hid_t attr_id, hid_t type_id, const void *buf);
+H5_DLL herr_t H5Awrite_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id,
+ hid_t type_id, const void *buf, hid_t es_id);
H5_DLL hid_t H5Aget_space(hid_t attr_id);
H5_DLL hid_t H5Aget_type(hid_t attr_id);
H5_DLL hid_t H5Aget_create_plist(hid_t attr_id);
@@ -338,8 +357,13 @@ H5_DLL herr_t H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const cha
H5_DLL herr_t H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, H5A_info_t *ainfo /*out*/, hid_t lapl_id);
H5_DLL herr_t H5Arename(hid_t loc_id, const char *old_name, const char *new_name);
+H5_DLL herr_t H5Arename_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *old_name, const char *new_name, hid_t es_id);
H5_DLL herr_t H5Arename_by_name(hid_t loc_id, const char *obj_name, const char *old_attr_name,
const char *new_attr_name, hid_t lapl_id);
+H5_DLL herr_t H5Arename_by_name_async(const char *app_file, const char *app_func, unsigned app_line,
+ hid_t loc_id, const char *obj_name, const char *old_attr_name,
+ const char *new_attr_name, hid_t lapl_id, hid_t es_id);
H5_DLL herr_t H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx,
H5A_operator2_t op, void *op_data);
H5_DLL herr_t H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
@@ -350,7 +374,12 @@ H5_DLL herr_t H5Adelete_by_name(hid_t loc_id, const char *obj_name, const char
H5_DLL herr_t H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order,
hsize_t n, hid_t lapl_id);
H5_DLL htri_t H5Aexists(hid_t obj_id, const char *attr_name);
+H5_DLL herr_t H5Aexists_async(const char *app_file, const char *app_func, unsigned app_line, hid_t obj_id,
+ const char *attr_name, hbool_t *exists, hid_t es_id);
H5_DLL htri_t H5Aexists_by_name(hid_t obj_id, const char *obj_name, const char *attr_name, hid_t lapl_id);
+H5_DLL herr_t H5Aexists_by_name_async(const char *app_file, const char *app_func, unsigned app_line,
+ hid_t loc_id, const char *obj_name, const char *attr_name,
+ hbool_t *exists, hid_t lapl_id, hid_t es_id);
/*-------------------------------------------------------------------------*/
/**
* \ingroup H5A
@@ -372,6 +401,42 @@ H5_DLL htri_t H5Aexists_by_name(hid_t obj_id, const char *obj_name, const char *
* \see H5Acreate(), H5Aopen()
*/
H5_DLL herr_t H5Aclose(hid_t attr_id);
+H5_DLL herr_t H5Aclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id,
+ hid_t es_id);
+
+/* API Wrappers for async routines */
+/* (Must be defined _after_ the function prototype) */
+/* (And must only defined when included in application code, not the library) */
+#ifndef H5A_MODULE
+#define H5Acreate_async(...) H5Acreate_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Acreate_by_name_async(...) H5Acreate_by_name_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Aopen_async(...) H5Aopen_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Aopen_by_name_async(...) H5Aopen_by_name_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Aopen_by_idx_async(...) H5Aopen_by_idx_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Awrite_async(...) H5Awrite_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Aread_async(...) H5Aread_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Arename_async(...) H5Arename_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Arename_by_name_async(...) H5Arename_by_name_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Aexists_async(...) H5Aexists_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Aexists_by_name_async(...) H5Aexists_by_name_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Aclose_async(...) H5Aclose_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+
+/* Define "wrapper" versions of function calls, to allow compile-time values to
+ * be passed in by language wrapper or library layer on top of HDF5.
+ */
+#define H5Acreate_async_wrap H5_NO_EXPAND(H5Acreate_async)
+#define H5Acreate_by_name_async_wrap H5_NO_EXPAND(H5Acreate_by_name_async)
+#define H5Aopen_async_wrap H5_NO_EXPAND(H5Aopen_async)
+#define H5Aopen_by_name_async_wrap H5_NO_EXPAND(H5Aopen_by_name_async)
+#define H5Aopen_by_idx_async_wrap H5_NO_EXPAND(H5Aopen_by_idx_async)
+#define H5Awrite_async_wrap H5_NO_EXPAND(H5Awrite_async)
+#define H5Aread_async_wrap H5_NO_EXPAND(H5Aread_async)
+#define H5Arename_async_wrap H5_NO_EXPAND(H5Arename_async)
+#define H5Arename_by_name_async_wrap H5_NO_EXPAND(H5Arename_by_name_async)
+#define H5Aexists_async_wrap H5_NO_EXPAND(H5Aexists_async)
+#define H5Aexists_by_name_async_wrap H5_NO_EXPAND(H5Aexists_by_name_async)
+#define H5Aclose_async_wrap H5_NO_EXPAND(H5Aclose_async)
+#endif /* H5A_MODULE */
/* Symbols defined for compatibility with previous versions of the HDF5 API.
*
diff --git a/src/H5B.c b/src/H5B.c
index c92d429..d3cf5d2 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -286,8 +286,8 @@ done:
*
*-------------------------------------------------------------------------
*/
-htri_t
-H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
+herr_t
+H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, hbool_t *found, void *udata)
{
H5B_t * bt = NULL;
H5UC_t * rc_shared; /* Ref-counted shared info */
@@ -295,7 +295,7 @@ H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
H5B_cache_ud_t cache_udata; /* User-data for metadata cache callback */
unsigned idx = 0, lt = 0, rt; /* Final, left & right key indices */
int cmp = 1; /* Key comparison value */
- htri_t ret_value = FAIL; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
@@ -334,23 +334,25 @@ H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
else
lt = idx + 1;
} /* end while */
+
/* Check if not found */
if (cmp)
- HGOTO_DONE(FALSE)
-
- /*
- * Follow the link to the subtree or to the data node.
- */
- HDassert(idx < bt->nchildren);
-
- if (bt->level > 0) {
- if ((ret_value = H5B_find(f, type, bt->child[idx], udata)) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "can't lookup key in subtree")
- } /* end if */
+ *found = FALSE;
else {
- if ((ret_value = (type->found)(f, bt->child[idx], H5B_NKEY(bt, shared, idx), udata)) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "can't lookup key in leaf node")
- } /* end else */
+ /*
+ * Follow the link to the subtree or to the data node.
+ */
+ HDassert(idx < bt->nchildren);
+
+ if (bt->level > 0) {
+ if ((ret_value = H5B_find(f, type, bt->child[idx], found, udata)) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "can't lookup key in subtree")
+ } /* end if */
+ else {
+ if ((ret_value = (type->found)(f, bt->child[idx], H5B_NKEY(bt, shared, idx), found, udata)) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "can't lookup key in leaf node")
+ } /* end else */
+ } /* end else */
done:
if (bt && H5AC_unprotect(f, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0)
diff --git a/src/H5B2.c b/src/H5B2.c
index ecf95cb..f8e0778 100644
--- a/src/H5B2.c
+++ b/src/H5B2.c
@@ -445,29 +445,30 @@ H5B2_iterate(H5B2_t *bt2, H5B2_operator_t op, void *op_data)
* If 'OP' is NULL, then this routine just returns "TRUE" when
* a record is present in the B-tree.
*
- * Return: Non-negative (TRUE/FALSE) on success, negative on failure.
+ * Return: SUCCEED/FAIL
*
* Programmer: Quincey Koziol
* Feb 23 2005
*
*-------------------------------------------------------------------------
*/
-htri_t
-H5B2_find(H5B2_t *bt2, void *udata, H5B2_found_t op, void *op_data)
+herr_t
+H5B2_find(H5B2_t *bt2, void *udata, hbool_t *found, H5B2_found_t op, void *op_data)
{
- H5B2_hdr_t * hdr; /* Pointer to the B-tree header */
- H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */
- void * parent = NULL; /* Parent of current node */
- uint16_t depth; /* Current depth of the tree */
- int cmp; /* Comparison value of records */
- unsigned idx; /* Location of record which matches key */
- H5B2_nodepos_t curr_pos; /* Position of the current node */
- htri_t ret_value = TRUE; /* Return value */
+ H5B2_hdr_t * hdr; /* Pointer to the B-tree header */
+ H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */
+ void * parent = NULL; /* Parent of current node */
+ uint16_t depth; /* Current depth of the tree */
+ int cmp; /* Comparison value of records */
+ unsigned idx; /* Location of record which matches key */
+ H5B2_nodepos_t curr_pos; /* Position of the current node */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* Check arguments. */
HDassert(bt2);
+ HDassert(found);
/* Set the shared v2 B-tree header's file context for this operation */
bt2->hdr->f = bt2->f;
@@ -479,8 +480,10 @@ H5B2_find(H5B2_t *bt2, void *udata, H5B2_found_t op, void *op_data)
curr_node_ptr = hdr->root;
/* Check for empty tree */
- if (curr_node_ptr.node_nrec == 0)
- HGOTO_DONE(FALSE)
+ if (curr_node_ptr.node_nrec == 0) {
+ *found = FALSE;
+ HGOTO_DONE(SUCCEED)
+ }
/* Check record against min & max records in tree, to attempt to quickly
* find candidates or avoid further searching.
@@ -488,25 +491,31 @@ H5B2_find(H5B2_t *bt2, void *udata, H5B2_found_t op, void *op_data)
if (hdr->min_native_rec != NULL) {
if ((hdr->cls->compare)(udata, hdr->min_native_rec, &cmp) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records")
- if (cmp < 0)
- HGOTO_DONE(FALSE) /* Less than the least record--not found */
- else if (cmp == 0) { /* Record is found */
+ if (cmp < 0) {
+ *found = FALSE; /* Less than the least record--not found */
+ HGOTO_DONE(SUCCEED)
+ }
+ else if (cmp == 0) { /* Record is found */
if (op && (op)(hdr->min_native_rec, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL,
"'found' callback failed for B-tree find operation")
- HGOTO_DONE(TRUE)
+ *found = TRUE;
+ HGOTO_DONE(SUCCEED)
} /* end if */
} /* end if */
if (hdr->max_native_rec != NULL) {
if ((hdr->cls->compare)(udata, hdr->max_native_rec, &cmp) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records")
- if (cmp > 0)
- HGOTO_DONE(FALSE) /* Less than the least record--not found */
- else if (cmp == 0) { /* Record is found */
+ if (cmp > 0) {
+ *found = FALSE; /* Greater than the largest record--not found */
+ HGOTO_DONE(SUCCEED)
+ }
+ else if (cmp == 0) { /* Record is found */
if (op && (op)(hdr->max_native_rec, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL,
"'found' callback failed for B-tree find operation")
- HGOTO_DONE(TRUE)
+ *found = TRUE;
+ HGOTO_DONE(SUCCEED)
} /* end if */
} /* end if */
@@ -597,7 +606,8 @@ H5B2_find(H5B2_t *bt2, void *udata, H5B2_found_t op, void *op_data)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
/* Indicate record found */
- HGOTO_DONE(TRUE)
+ *found = TRUE;
+ HGOTO_DONE(SUCCEED)
} /* end else */
/* Decrement depth we're at in B-tree */
@@ -632,7 +642,8 @@ H5B2_find(H5B2_t *bt2, void *udata, H5B2_found_t op, void *op_data)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
/* Record not found */
- HGOTO_DONE(FALSE)
+ *found = FALSE;
+ HGOTO_DONE(SUCCEED)
} /* end if */
else {
/* Make callback for current record */
@@ -672,6 +683,9 @@ H5B2_find(H5B2_t *bt2, void *udata, H5B2_found_t op, void *op_data)
/* Unlock current node */
if (H5AC_unprotect(hdr->f, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
+
+ /* Indicate record found */
+ *found = TRUE;
} /* end block */
done:
diff --git a/src/H5B2private.h b/src/H5B2private.h
index e511897..0030bf4 100644
--- a/src/H5B2private.h
+++ b/src/H5B2private.h
@@ -131,7 +131,7 @@ H5_DLL H5B2_t *H5B2_open(H5F_t *f, haddr_t addr, void *ctx_udata);
H5_DLL herr_t H5B2_get_addr(const H5B2_t *bt2, haddr_t *addr /*out*/);
H5_DLL herr_t H5B2_insert(H5B2_t *bt2, void *udata);
H5_DLL herr_t H5B2_iterate(H5B2_t *bt2, H5B2_operator_t op, void *op_data);
-H5_DLL htri_t H5B2_find(H5B2_t *bt2, void *udata, H5B2_found_t op, void *op_data);
+H5_DLL herr_t H5B2_find(H5B2_t *bt2, void *udata, hbool_t *found, H5B2_found_t op, void *op_data);
H5_DLL herr_t H5B2_index(H5B2_t *bt2, H5_iter_order_t order, hsize_t idx, H5B2_found_t op, void *op_data);
H5_DLL herr_t H5B2_neighbor(H5B2_t *bt2, H5B2_compare_t range, void *udata, H5B2_found_t op, void *op_data);
H5_DLL herr_t H5B2_modify(H5B2_t *bt2, void *udata, H5B2_modify_t op, void *op_data);
diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h
index ae47162..6f2925f 100644
--- a/src/H5Bprivate.h
+++ b/src/H5Bprivate.h
@@ -110,7 +110,7 @@ typedef struct H5B_class_t {
herr_t (*new_node)(H5F_t *, H5B_ins_t, void *, void *, void *, haddr_t *);
int (*cmp2)(void *, void *, void *); /*compare 2 keys */
int (*cmp3)(void *, void *, void *); /*compare 3 keys */
- htri_t (*found)(H5F_t *, haddr_t, const void *, void *);
+ htri_t (*found)(H5F_t *, haddr_t, const void *, hbool_t *, void *);
/* insert new data */
H5B_ins_t (*insert)(H5F_t *, haddr_t, void *, hbool_t *, void *, void *, void *, hbool_t *, haddr_t *);
@@ -145,7 +145,7 @@ typedef struct H5B_info_t {
/* Library-private Function Prototypes */
/***************************************/
H5_DLL herr_t H5B_create(H5F_t *f, const H5B_class_t *type, void *udata, haddr_t *addr_p /*out*/);
-H5_DLL herr_t H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata);
+H5_DLL herr_t H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, hbool_t *found, void *udata);
H5_DLL herr_t H5B_insert(H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata);
H5_DLL herr_t H5B_iterate(H5F_t *f, const H5B_class_t *type, haddr_t addr, H5B_operator_t op, void *udata);
H5_DLL herr_t H5B_get_info(H5F_t *f, const H5B_class_t *type, haddr_t addr, H5B_info_t *bt_info,
diff --git a/src/H5C.c b/src/H5C.c
index ce6c7f8..f75b950 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -7131,7 +7131,7 @@ H5C__load_entry(H5F_t *f,
MPI_Comm comm = MPI_COMM_NULL; /* File MPI Communicator */
int mpi_code; /* MPI error code */
#endif /* H5_HAVE_PARALLEL */
- void *ret_value = NULL; /* Return value */
+ void *ret_value = NULL; /* Return value */
FUNC_ENTER_STATIC
diff --git a/src/H5CX.c b/src/H5CX.c
index ef89a87..af9f724 100644
--- a/src/H5CX.c
+++ b/src/H5CX.c
@@ -370,9 +370,9 @@ typedef struct H5CX_dxpl_cache_t {
uint32_t mpio_global_no_coll_cause; /* Global reason for breaking collective I/O
(H5D_MPIO_GLOBAL_NO_COLLECTIVE_CAUSE_NAME) */
H5FD_mpio_chunk_opt_t
- mpio_chunk_opt_mode; /* Collective chunk option (H5D_XFER_MPIO_CHUNK_OPT_HARD_NAME) */
- unsigned mpio_chunk_opt_num; /* Collective chunk thrreshold (H5D_XFER_MPIO_CHUNK_OPT_NUM_NAME) */
- unsigned mpio_chunk_opt_ratio; /* Collective chunk ratio (H5D_XFER_MPIO_CHUNK_OPT_RATIO_NAME) */
+ mpio_chunk_opt_mode; /* Collective chunk option (H5D_XFER_MPIO_CHUNK_OPT_HARD_NAME) */
+ unsigned mpio_chunk_opt_num; /* Collective chunk thrreshold (H5D_XFER_MPIO_CHUNK_OPT_NUM_NAME) */
+ unsigned mpio_chunk_opt_ratio; /* Collective chunk ratio (H5D_XFER_MPIO_CHUNK_OPT_RATIO_NAME) */
#endif /* H5_HAVE_PARALLEL */
H5Z_EDC_t err_detect; /* Error detection info (H5D_XFER_EDC_NAME) */
H5Z_cb_t filter_cb; /* Filter callback function (H5D_XFER_FILTER_CB_NAME) */
diff --git a/src/H5D.c b/src/H5D.c
index ff5fa6a..07a4630 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -24,6 +24,7 @@
#include "H5CXprivate.h" /* API Contexts */
#include "H5Dpkg.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event Sets */
#include "H5FLprivate.h" /* Free lists */
#include "H5Iprivate.h" /* IDs */
#include "H5VLprivate.h" /* Virtual Object Layer */
@@ -42,6 +43,21 @@
/* Local Prototypes */
/********************/
+/* Helper routines for sync/async API calls */
+static hid_t H5D__create_api_common(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
+ hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static hid_t H5D__open_api_common(hid_t loc_id, const char *name, hid_t dapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static hid_t H5D__get_space_api_common(hid_t dset_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr);
+static herr_t H5D__read_api_common(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
+ hid_t dxpl_id, void *buf, void **token_ptr, H5VL_object_t **_vol_obj_ptr);
+static herr_t H5D__write_api_common(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
+ hid_t dxpl_id, const void *buf, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static herr_t H5D__set_extent_api_common(hid_t dset_id, const hsize_t size[], void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+
/*********************/
/* Package Variables */
/*********************/
@@ -64,42 +80,27 @@ H5FL_BLK_EXTERN(type_conv);
/*******************/
/*-------------------------------------------------------------------------
- * Function: H5Dcreate2
- *
- * Purpose: Creates a new dataset named NAME at LOC_ID, opens the
- * dataset for access, and associates with that dataset constant
- * and initial persistent properties including the type of each
- * datapoint as stored in the file (TYPE_ID), the size of the
- * dataset (SPACE_ID), and other initial miscellaneous
- * properties (DCPL_ID).
- *
- * All arguments are copied into the dataset, so the caller is
- * allowed to derive new types, dataspaces, and creation
- * parameters from the old ones and reuse them in calls to
- * create other datasets.
+ * Function: H5D__create_api_common
*
- * Return: Success: The object ID of the new dataset. At this
- * point, the dataset is ready to receive its
- * raw data. Attempting to read raw data from
- * the dataset will probably return the fill
- * value. The dataset should be closed when the
- * caller is no longer interested in it.
+ * Purpose: This is the common function for creating HDF5 datasets.
*
+ * Return: Success: A dataset ID
* Failure: H5I_INVALID_HID
*
*-------------------------------------------------------------------------
*/
-hid_t
-H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t lcpl_id, hid_t dcpl_id,
- hid_t dapl_id)
+static hid_t
+H5D__create_api_common(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t lcpl_id,
+ hid_t dcpl_id, hid_t dapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
{
- void * dset = NULL; /* New dataset's info */
- H5VL_object_t * vol_obj = NULL; /* object of loc_id */
- H5VL_loc_params_t loc_params;
- hid_t ret_value = H5I_INVALID_HID; /* Return value */
+ void * dset = NULL; /* New dataset's info */
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
- FUNC_ENTER_API(H5I_INVALID_HID)
- H5TRACE7("i", "i*siiiii", loc_id, name, type_id, space_id, lcpl_id, dcpl_id, dapl_id);
+ FUNC_ENTER_STATIC
/* Check arguments */
if (!name)
@@ -107,6 +108,10 @@ H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t
if (!*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string")
+ /* Set up object access arguments */
+ if (H5VL_setup_acc_args(loc_id, H5P_CLS_DACC, TRUE, &dapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")
+
/* Get link creation property list */
if (H5P_DEFAULT == lcpl_id)
lcpl_id = H5P_LINK_CREATE_DEFAULT;
@@ -126,36 +131,114 @@ H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t
/* Set the LCPL for the API context */
H5CX_set_lcpl(lcpl_id);
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&dapl_id, H5P_CLS_DACC, loc_id, TRUE) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
-
- /* Get the location object */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
-
- /* Set location parameters */
- loc_params.type = H5VL_OBJECT_BY_SELF;
- loc_params.obj_type = H5I_get_type(loc_id);
-
/* Create the dataset */
- if (NULL == (dset = H5VL_dataset_create(vol_obj, &loc_params, name, lcpl_id, type_id, space_id, dcpl_id,
- dapl_id, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)))
+ if (NULL == (dset = H5VL_dataset_create(*vol_obj_ptr, &loc_params, name, lcpl_id, type_id, space_id,
+ dcpl_id, dapl_id, H5P_DATASET_XFER_DEFAULT, token_ptr)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create dataset")
/* Get an ID for the dataset */
- if ((ret_value = H5VL_register(H5I_DATASET, dset, vol_obj->connector, TRUE)) < 0)
+ if ((ret_value = H5VL_register(H5I_DATASET, dset, (*vol_obj_ptr)->connector, TRUE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register dataset")
done:
if (H5I_INVALID_HID == ret_value)
- if (dset && H5VL_dataset_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
+ if (dset && H5VL_dataset_close(*vol_obj_ptr, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release dataset")
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__create_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dcreate2
+ *
+ * Purpose: Creates a new dataset named NAME at LOC_ID, opens the
+ * dataset for access, and associates with that dataset constant
+ * and initial persistent properties including the type of each
+ * datapoint as stored in the file (TYPE_ID), the size of the
+ * dataset (SPACE_ID), and other initial miscellaneous
+ * properties (DCPL_ID).
+ *
+ * All arguments are copied into the dataset, so the caller is
+ * allowed to derive new types, dataspaces, and creation
+ * parameters from the old ones and reuse them in calls to
+ * create other datasets.
+ *
+ * Return: Success: The object ID of the new dataset. At this
+ * point, the dataset is ready to receive its
+ * raw data. Attempting to read raw data from
+ * the dataset will probably return the fill
+ * value. The dataset should be closed when the
+ * caller is no longer interested in it.
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t lcpl_id, hid_t dcpl_id,
+ hid_t dapl_id)
+{
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE7("i", "i*siiiii", loc_id, name, type_id, space_id, lcpl_id, dcpl_id, dapl_id);
+
+ /* Create the dataset synchronously */
+ if ((ret_value = H5D__create_api_common(loc_id, name, type_id, space_id, lcpl_id, dcpl_id, dapl_id, NULL,
+ NULL)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously create dataset")
+
+done:
FUNC_LEAVE_API(ret_value)
} /* end H5Dcreate2() */
/*-------------------------------------------------------------------------
+ * Function: H5Dcreate_async
+ *
+ * Purpose: Asynchronous version of H5Dcreate
+ *
+ * Return: Success: A dataset ID
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Dcreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name,
+ hid_t type_id, hid_t space_id, hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE11("i", "*s*sIui*siiiiii", app_file, app_func, app_line, loc_id, name, type_id, space_id, lcpl_id,
+ dcpl_id, dapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Create the dataset asynchronously */
+ if ((ret_value = H5D__create_api_common(loc_id, name, type_id, space_id, lcpl_id, dcpl_id, dapl_id,
+ token_ptr, &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously create dataset")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE11(FUNC, "*s*sIui*siiiiii", app_file, app_func, app_line, loc_id, name,
+ type_id, space_id, lcpl_id, dcpl_id, dapl_id, es_id)) < 0) {
+ if (H5I_dec_app_ref_always_close(ret_value) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on dataset ID")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Dcreate_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5Dcreate_anon
*
* Purpose: Creates a new dataset named NAME at LOC_ID, opens the
@@ -239,30 +322,27 @@ done:
} /* end H5Dcreate_anon() */
/*-------------------------------------------------------------------------
- * Function: H5Dopen2
+ * Function: H5D__open_api_common
*
- * Purpose: Finds a dataset named NAME at LOC_ID, opens it, and returns
- * its ID. The dataset should be close when the caller is no
- * longer interested in it.
- *
- * Takes a dataset access property list
+ * Purpose: This is the common function for opening a dataset
*
* Return: Success: Object ID of the dataset
- *
* Failure: H5I_INVALID_HID
*
*-------------------------------------------------------------------------
*/
-hid_t
-H5Dopen2(hid_t loc_id, const char *name, hid_t dapl_id)
+static hid_t
+H5D__open_api_common(hid_t loc_id, const char *name, hid_t dapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
{
- void * dset = NULL; /* dset object from VOL connector */
- H5VL_object_t * vol_obj = NULL; /* object of loc_id */
- H5VL_loc_params_t loc_params;
- hid_t ret_value = H5I_INVALID_HID; /* Return value */
+ void * dset = NULL; /* dset object from VOL connector */
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
- FUNC_ENTER_API(H5I_INVALID_HID)
- H5TRACE3("i", "i*si", loc_id, name, dapl_id);
+ FUNC_ENTER_STATIC
/* Check args */
if (!name)
@@ -270,36 +350,103 @@ H5Dopen2(hid_t loc_id, const char *name, hid_t dapl_id)
if (!*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string")
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&dapl_id, H5P_CLS_DACC, loc_id, FALSE) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
-
- /* get the location object */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
-
- /* Set the location parameters */
- loc_params.type = H5VL_OBJECT_BY_SELF;
- loc_params.obj_type = H5I_get_type(loc_id);
+ /* Set up object access arguments */
+ if (H5VL_setup_acc_args(loc_id, H5P_CLS_DACC, FALSE, &dapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")
/* Open the dataset */
- if (NULL == (dset = H5VL_dataset_open(vol_obj, &loc_params, name, dapl_id, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL)))
+ if (NULL == (dset = H5VL_dataset_open(*vol_obj_ptr, &loc_params, name, dapl_id, H5P_DATASET_XFER_DEFAULT,
+ token_ptr)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open dataset")
- /* Register an ID for the dataset */
- if ((ret_value = H5VL_register(H5I_DATASET, dset, vol_obj->connector, TRUE)) < 0)
+ /* Register an atom for the dataset */
+ if ((ret_value = H5VL_register(H5I_DATASET, dset, (*vol_obj_ptr)->connector, TRUE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register dataset ID")
done:
if (H5I_INVALID_HID == ret_value)
- if (dset && H5VL_dataset_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
+ if (dset && H5VL_dataset_close(*vol_obj_ptr, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release dataset")
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5D__open_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dopen2
+ *
+ * Purpose: Finds a dataset named NAME at LOC_ID, opens it, and returns
+ * its ID. The dataset should be close when the caller is no
+ * longer interested in it.
+ *
+ * Takes a dataset access property list
+ *
+ * Return: Success: Object ID of the dataset
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Dopen2(hid_t loc_id, const char *name, hid_t dapl_id)
+{
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE3("i", "i*si", loc_id, name, dapl_id);
+
+ /* Open the dataset synchronously */
+ if ((ret_value = H5D__open_api_common(loc_id, name, dapl_id, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to synchronously open dataset")
+
+done:
FUNC_LEAVE_API(ret_value)
} /* end H5Dopen2() */
/*-------------------------------------------------------------------------
+ * Function: H5Dopen_async
+ *
+ * Purpose: Asynchronous version of H5Dopen2
+ *
+ * Return: Success: A group ID
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Dopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name,
+ hid_t dapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE7("i", "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, dapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Open the dataset asynchronously */
+ if ((ret_value = H5D__open_api_common(loc_id, name, dapl_id, token_ptr, &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to asynchronously open dataset")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE7(FUNC, "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, dapl_id,
+ es_id)) < 0) {
+ if (H5I_dec_app_ref_always_close(ret_value) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on dataset ID")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Dopen_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5Dclose
*
* Purpose: Closes access to a dataset and releases resources used by
@@ -333,6 +480,98 @@ done:
} /* end H5Dclose() */
/*-------------------------------------------------------------------------
+ * Function: H5Dclose_async
+ *
+ * Purpose: Asynchronous version of H5Dclose
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id, hid_t es_id)
+{
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ H5VL_object_t *vol_obj = NULL; /* VOL object of dset_id */
+ H5VL_t * connector = NULL; /* VOL connector */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, dset_id, es_id);
+
+ /* Check args */
+ if (H5I_DATASET != H5I_get_type(dset_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset ID")
+
+ /* Get dataset object's connector */
+ if (NULL == (vol_obj = H5VL_vol_object(dset_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get VOL object for dataset")
+
+ /* Prepare for possible asynchronous operation */
+ if (H5ES_NONE != es_id) {
+ /* Increase connector's refcount, so it doesn't get closed if closing
+ * the dataset closes the file */
+ connector = vol_obj->connector;
+ H5VL_conn_inc_rc(connector);
+
+ /* Point at token for operation to set up */
+ token_ptr = &token;
+ } /* end if */
+
+ /* Decrement the counter on the dataset. It will be freed if the count
+ * reaches zero.
+ */
+ if (H5I_dec_app_ref_always_close_async(dset_id, token_ptr) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, dset_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ if (connector && H5VL_conn_dec_rc(connector) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't decrement ref count on connector")
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Dclose_async() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5D__get_space_api_common
+ *
+ * Purpose: This is the common function for getting a dataset's dataspace
+ *
+ * Return: Success: ID for a copy of the dataspace.
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+H5D__get_space_api_common(hid_t dset_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check args */
+ if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid dataset identifier")
+
+ /* Get the dataspace */
+ if (H5VL_dataset_get(*vol_obj_ptr, H5VL_DATASET_GET_SPACE, H5P_DATASET_XFER_DEFAULT, token_ptr,
+ &ret_value) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataspace")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5D__get_space_api_common() */
+
+/*-------------------------------------------------------------------------
* Function: H5Dget_space
*
* Purpose: Returns a copy of the file dataspace for a dataset.
@@ -348,26 +587,66 @@ done:
hid_t
H5Dget_space(hid_t dset_id)
{
- H5VL_object_t *vol_obj = NULL; /* Dataset structure */
- hid_t ret_value = H5I_INVALID_HID; /* Return value */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
FUNC_ENTER_API(H5I_INVALID_HID)
H5TRACE1("i", "i", dset_id);
- /* Check args */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid dataset identifier")
-
- /* Get the dataspace */
- if (H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_SPACE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL,
- &ret_value) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataspace")
+ /* Get the dataset's dataspace synchronously */
+ if ((ret_value = H5D__get_space_api_common(dset_id, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, H5I_INVALID_HID, "unable to synchronously get dataspace")
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Dget_space() */
/*-------------------------------------------------------------------------
+ * Function: H5Dget_space_async
+ *
+ * Purpose: Asynchronous version of H5Dget_space
+ *
+ * Return: Success: ID for a copy of the dataspace. The data
+ * space should be released by calling
+ * H5Sclose().
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Dget_space_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE5("i", "*s*sIuii", app_file, app_func, app_line, dset_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Get the dataset's dataspace asynchronously */
+ if ((ret_value = H5D__get_space_api_common(dset_id, token_ptr, &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, H5I_INVALID_HID, "unable to asynchronously get dataspace")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, dset_id, es_id)) < 0) {
+ if (H5I_dec_app_ref(ret_value) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, H5I_INVALID_HID,
+ "can't decrement count on dataspace ID")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Dget_space_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5Dget_space_status
*
* Purpose: Returns the status of dataspace allocation.
@@ -597,6 +876,51 @@ done:
} /* end H5Dget_offset() */
/*-------------------------------------------------------------------------
+ * Function: H5D__read_api_common
+ *
+ * Purpose: Common helper routine for sync/async dataset read operations.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__read_api_common(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id,
+ void *buf, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check arguments */
+ if (mem_space_id < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid memory dataspace ID")
+ if (file_space_id < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file dataspace ID")
+
+ /* Get dataset pointer */
+ if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id is not a dataset ID")
+
+ /* Get the default dataset transfer property list if the user didn't provide one */
+ if (H5P_DEFAULT == dxpl_id)
+ dxpl_id = H5P_DATASET_XFER_DEFAULT;
+ else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
+
+ /* Read the data */
+ if (H5VL_dataset_read(*vol_obj_ptr, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, token_ptr) <
+ 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__read_api_common() */
+
+/*-------------------------------------------------------------------------
* Function: H5Dread
*
* Purpose: Reads (part of) a DSET from the file into application
@@ -630,36 +954,63 @@ herr_t
H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id,
void *buf /*out*/)
{
- H5VL_object_t *vol_obj = NULL;
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE6("e", "iiiiix", dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf);
- /* Check arguments */
- if (mem_space_id < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid memory dataspace ID")
- if (file_space_id < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file dataspace ID")
+ /* Read the data */
+ if (H5D__read_api_common(dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't synchronously read data")
- /* Get dataset pointer */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id is not a dataset ID")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Dread() */
- /* Get the default dataset transfer property list if the user didn't provide one */
- if (H5P_DEFAULT == dxpl_id)
- dxpl_id = H5P_DATASET_XFER_DEFAULT;
- else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
+/*-------------------------------------------------------------------------
+ * Function: H5Dread_async
+ *
+ * Purpose: Asynchronously read dataset elements.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Houjun Tang
+ * Oct 15, 2019
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dread_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id, hid_t mem_type_id,
+ hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, void *buf /*out*/, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Dataset VOL object */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE10("e", "*s*sIuiiiiixi", app_file, app_func, app_line, dset_id, mem_type_id, mem_space_id,
+ file_space_id, dxpl_id, buf, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
/* Read the data */
- if ((ret_value = H5VL_dataset_read(vol_obj, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf,
- H5_REQUEST_NULL)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data")
+ if (H5D__read_api_common(dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, token_ptr,
+ &vol_obj) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't asynchronously read data")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE10(FUNC, "*s*sIuiiiiixi", app_file, app_func, app_line, dset_id,
+ mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, es_id)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "can't insert token into event set")
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Dread() */
+} /* end H5Dread_async() */
/*-------------------------------------------------------------------------
* Function: H5Dread_chunk
@@ -708,6 +1059,51 @@ done:
} /* end H5Dread_chunk() */
/*-------------------------------------------------------------------------
+ * Function: H5D__write_api_common
+ *
+ * Purpose: Common helper routine for sync/async dataset write operations.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__write_api_common(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
+ hid_t dxpl_id, const void *buf, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check arguments */
+ if (mem_space_id < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid memory dataspace ID")
+ if (file_space_id < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file dataspace ID")
+
+ /* Get dataset pointer */
+ if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id is not a dataset ID")
+
+ /* Get the default dataset transfer property list if the user didn't provide one */
+ if (H5P_DEFAULT == dxpl_id)
+ dxpl_id = H5P_DATASET_XFER_DEFAULT;
+ else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
+
+ /* Write the data */
+ if (H5VL_dataset_write(*vol_obj_ptr, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, token_ptr) <
+ 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D__write_api_common() */
+
+/*-------------------------------------------------------------------------
* Function: H5Dwrite
*
* Purpose: Writes (part of) a DSET from application memory BUF to the
@@ -742,36 +1138,65 @@ herr_t
H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id,
const void *buf)
{
- H5VL_object_t *vol_obj = NULL;
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE6("e", "iiiii*x", dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf);
- /* Check arguments */
- if (mem_space_id < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid memory dataspace ID")
- if (file_space_id < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file dataspace ID")
+ /* Write the data */
+ if (H5D__write_api_common(dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, NULL, NULL) <
+ 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't synchronously write data")
- /* Get dataset pointer */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id is not a dataset ID")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Dwrite() */
- /* Get the default dataset transfer property list if the user didn't provide one */
- if (H5P_DEFAULT == dxpl_id)
- dxpl_id = H5P_DATASET_XFER_DEFAULT;
- else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
+/*-------------------------------------------------------------------------
+ * Function: H5Dwrite_async
+ *
+ * Purpose: For asynchronous VOL with request token
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Houjun Tang
+ * Oct 15, 2019
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dwrite_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id,
+ hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, const void *buf,
+ hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Dataset VOL object */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE10("e", "*s*sIuiiiii*xi", app_file, app_func, app_line, dset_id, mem_type_id, mem_space_id,
+ file_space_id, dxpl_id, buf, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
/* Write the data */
- if ((ret_value = H5VL_dataset_write(vol_obj, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf,
- H5_REQUEST_NULL)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
+ if (H5D__write_api_common(dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, token_ptr,
+ &vol_obj) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't asynchronously write data")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE10(FUNC, "*s*sIuiiiii*xi", app_file, app_func, app_line, dset_id,
+ mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, es_id)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "can't insert token into event set")
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Dwrite() */
+} /* end H5Dwrite_async() */
/*-------------------------------------------------------------------------
* Function: H5Dwrite_chunk
@@ -1207,8 +1632,7 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, hsize_t *s
supported = 0;
if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_DATASET, H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE,
&supported) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
- "can't check for 'get vlen buf size' operation")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check for 'get vlen buf size' operation")
if (supported & H5VL_OPT_QUERY_SUPPORTED) {
/* Make the 'get_vlen_buf_size' callback */
if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE, H5P_DATASET_XFER_DEFAULT,
@@ -1226,27 +1650,28 @@ done:
} /* end H5Dvlen_get_buf_size() */
/*-------------------------------------------------------------------------
- * Function: H5Dset_extent
+ * Function: H5D__set_extent_api_common
*
- * Purpose: Modifies the dimensions of a dataset.
- * Can change to a smaller dimension.
+ * Purpose: This is the common function for changing a dataset's dimensions
*
- * Return: Non-negative on success, negative on failure
+ * Return: Non-negative on success, negative on failure
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5Dset_extent(hid_t dset_id, const hsize_t size[])
+static herr_t
+H5D__set_extent_api_common(hid_t dset_id, const hsize_t size[], void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
{
- H5VL_object_t *vol_obj; /* Dataset for this operation */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_API(FAIL)
- H5TRACE2("e", "i*h", dset_id, size);
+ FUNC_ENTER_STATIC
/* Check args */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id parameter is not a valid dataset identifier")
+ if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier")
if (!size)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "size array cannot be NULL")
@@ -1255,15 +1680,81 @@ H5Dset_extent(hid_t dset_id, const hsize_t size[])
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set collective metadata read info")
/* Set the extent */
- if ((ret_value = H5VL_dataset_specific(vol_obj, H5VL_DATASET_SET_EXTENT, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL, size)) < 0)
+ if ((ret_value = H5VL_dataset_specific(*vol_obj_ptr, H5VL_DATASET_SET_EXTENT, H5P_DATASET_XFER_DEFAULT,
+ token_ptr, size)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set dataset extent")
done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5D__set_extent_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dset_extent
+ *
+ * Purpose: Modifies the dimensions of a dataset.
+ * Can change to a smaller dimension.
+ *
+ * Return: Non-negative on success, negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dset_extent(hid_t dset_id, const hsize_t size[])
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*h", dset_id, size);
+
+ /* Change a datset's dimenions synchronously */
+ if ((ret_value = H5D__set_extent_api_common(dset_id, size, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to synchronously change a dataset's dimensions")
+
+done:
FUNC_LEAVE_API(ret_value)
} /* end H5Dset_extent() */
/*-------------------------------------------------------------------------
+ * Function: H5Dset_extent_async
+ *
+ * Purpose: Asynchronous version of H5Dset_extent
+ *
+ * Return: Non-negative on success, negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dset_extent_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id,
+ const hsize_t size[], hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "*s*sIui*hi", app_file, app_func, app_line, dset_id, size, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Change a datset's dimenions asynchronously */
+ if (H5D__set_extent_api_common(dset_id, size, token_ptr, &vol_obj) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to asynchronously change a dataset's dimensions")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(
+ es_id, vol_obj->connector, token,
+ H5ARG_TRACE6(FUNC, "*s*sIui*hi", app_file, app_func, app_line, dset_id, size, es_id)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Dset_extent_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5Dflush
*
* Purpose: Flushes all buffers associated with a dataset.
@@ -1302,6 +1793,41 @@ done:
} /* H5Dflush */
/*-------------------------------------------------------------------------
+ * Function: H5Dwait
+ *
+ * Purpose: Wait for all operations on a dataset.
+ * Tang: added for async
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dwait(hid_t dset_id)
+{
+ H5VL_object_t *vol_obj; /* Dataset for this operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("e", "i", dset_id);
+
+ /* Check args */
+ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id parameter is not a valid dataset identifier")
+
+ /* Set up collective metadata if appropriate */
+ if (H5CX_set_loc(dset_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set collective metadata read info")
+
+ if ((ret_value = H5VL_dataset_specific(vol_obj, H5VL_DATASET_WAIT, H5P_DATASET_XFER_DEFAULT,
+ H5_REQUEST_NULL, dset_id)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTOPERATE, FAIL, "unable to wait dataset")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Dwait*/
+
+/*-------------------------------------------------------------------------
* Function: H5Drefresh
*
* Purpose: Refreshes all buffers associated with a dataset.
diff --git a/src/H5Dbtree.c b/src/H5Dbtree.c
index d0a191f..9147f0e 100644
--- a/src/H5Dbtree.c
+++ b/src/H5Dbtree.c
@@ -102,7 +102,7 @@ static herr_t H5D__btree_new_node(H5F_t *f, H5B_ins_t, void *_lt_key, void *_
haddr_t *addr_p /*out*/);
static int H5D__btree_cmp2(void *_lt_key, void *_udata, void *_rt_key);
static int H5D__btree_cmp3(void *_lt_key, void *_udata, void *_rt_key);
-static htri_t H5D__btree_found(H5F_t *f, haddr_t addr, const void *_lt_key, void *_udata);
+static htri_t H5D__btree_found(H5F_t *f, haddr_t addr, const void *_lt_key, hbool_t *found, void *_udata);
static H5B_ins_t H5D__btree_insert(H5F_t *f, haddr_t addr, void *_lt_key, hbool_t *lt_key_changed,
void *_md_key, void *_udata, void *_rt_key, hbool_t *rt_key_changed,
haddr_t *new_node /*out*/);
@@ -407,8 +407,9 @@ H5D__btree_cmp3(void *_lt_key, void *_udata, void *_rt_key)
* called with the maximum stored chunk indices less than the
* requested chunk indices.
*
- * Return: Non-negative (TRUE/FALSE) on success with information about the
- * chunk returned through the UDATA argument. Negative on failure.
+ * Return: Non-negative on success with information about the
+ * chunk returned through the UDATA argument, if *FOUND is true.
+ * Negative on failure.
*
* Programmer: Robb Matzke
* Thursday, October 9, 1997
@@ -416,31 +417,35 @@ H5D__btree_cmp3(void *_lt_key, void *_udata, void *_rt_key)
*-------------------------------------------------------------------------
*/
static htri_t
-H5D__btree_found(H5F_t H5_ATTR_UNUSED *f, haddr_t addr, const void *_lt_key, void *_udata)
+H5D__btree_found(H5F_t H5_ATTR_UNUSED *f, haddr_t addr, const void *_lt_key, hbool_t *found, void *_udata)
{
H5D_chunk_ud_t * udata = (H5D_chunk_ud_t *)_udata;
const H5D_btree_key_t *lt_key = (const H5D_btree_key_t *)_lt_key;
unsigned u;
- htri_t ret_value = TRUE; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC_NOERR
/* Check arguments */
HDassert(f);
HDassert(H5F_addr_defined(addr));
- HDassert(udata);
HDassert(lt_key);
+ HDassert(found);
+ HDassert(udata);
/* Is this *really* the requested chunk? */
for (u = 0; u < udata->common.layout->ndims; u++)
- if (udata->common.scaled[u] >= (lt_key->scaled[u] + 1))
- HGOTO_DONE(FALSE)
+ if (udata->common.scaled[u] >= (lt_key->scaled[u] + 1)) {
+ *found = FALSE;
+ HGOTO_DONE(SUCCEED)
+ }
/* Initialize return values */
HDassert(lt_key->nbytes > 0);
udata->chunk_block.offset = addr;
udata->chunk_block.length = lt_key->nbytes;
udata->filter_mask = lt_key->filter_mask;
+ *found = TRUE;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -990,7 +995,8 @@ done:
static herr_t
H5D__btree_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ hbool_t found; /* Whether chunk was found */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
@@ -1004,8 +1010,9 @@ H5D__btree_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udat
HDassert(udata);
/* Go get the chunk information from the B-tree */
- if (H5B_find(idx_info->f, H5B_BTREE, idx_info->storage->idx_addr, udata) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk info")
+ found = FALSE;
+ if (H5B_find(idx_info->f, H5B_BTREE, idx_info->storage->idx_addr, &found, udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFIND, FAIL, "can't check for chunk in B-tree")
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Dbtree2.c b/src/H5Dbtree2.c
index 866b794..aa26bf8 100644
--- a/src/H5Dbtree2.c
+++ b/src/H5Dbtree2.c
@@ -969,6 +969,7 @@ H5D__bt2_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata)
H5D_bt2_ud_t bt2_udata; /* User data for v2 B-tree calls */
H5D_chunk_rec_t found_rec; /* Record found from searching for object */
unsigned u; /* Local index variable */
+ hbool_t found; /* Whether chunk was found */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
@@ -1010,17 +1011,18 @@ H5D__bt2_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata)
bt2_udata.rec.scaled[u] = udata->common.scaled[u];
/* Go get chunk information from v2 B-tree */
- if (H5B2_find(bt2, &bt2_udata, H5D__bt2_found_cb, &found_rec) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree")
+ found = FALSE;
+ if (H5B2_find(bt2, &bt2_udata, &found, H5D__bt2_found_cb, &found_rec) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFIND, FAIL, "can't check for chunk in v2 B-tree")
- /* Set common info for the chunk */
- udata->chunk_block.offset = found_rec.chunk_addr;
-
- /* Check for setting other info */
- if (H5F_addr_defined(udata->chunk_block.offset)) {
+ /* Check if chunk was found */
+ if (found) {
/* Sanity check */
HDassert(0 != found_rec.nbytes);
+ /* Set common info for the chunk */
+ udata->chunk_block.offset = found_rec.chunk_addr;
+
/* Set other info for the chunk */
if (idx_info->pline->nused > 0) { /* filtered chunk */
udata->chunk_block.length = found_rec.nbytes;
@@ -1032,6 +1034,7 @@ H5D__bt2_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata)
} /* end else */
} /* end if */
else {
+ udata->chunk_block.offset = HADDR_UNDEF;
udata->chunk_block.length = 0;
udata->filter_mask = 0;
} /* end else */
diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c
index 273901a..22b8feb 100644
--- a/src/H5Dmpio.c
+++ b/src/H5Dmpio.c
@@ -886,14 +886,13 @@ H5D__chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL,
"couldn't finish optimized multiple filtered chunk MPI-IO")
} /* end if */
- else
- if (H5D__link_chunk_filtered_collective_io(io_info, type_info, fm) < 0)
- HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish filtered linked chunk MPI-IO")
+ else if (H5D__link_chunk_filtered_collective_io(io_info, type_info, fm) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish filtered linked chunk MPI-IO")
} /* end if */
else
/* Perform unfiltered link chunk collective IO */
if (H5D__link_chunk_collective_io(io_info, type_info, fm, sum_chunk) < 0)
- HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish linked chunk MPI-IO")
+ HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish linked chunk MPI-IO")
break;
case H5D_MULTI_CHUNK_IO: /* direct request to do multi-chunk IO */
@@ -907,7 +906,7 @@ H5D__chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type_inf
else
/* Perform unfiltered multi chunk collective IO */
if (H5D__multi_chunk_collective_io(io_info, type_info, fm) < 0)
- HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish optimized multiple chunk MPI-IO")
+ HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "couldn't finish optimized multiple chunk MPI-IO")
break;
} /* end switch */
@@ -1378,7 +1377,8 @@ H5D__link_chunk_filtered_collective_io(H5D_io_info_t *io_info, const H5D_type_in
H5CX_set_mpio_actual_io_mode(H5D_MPIO_CHUNK_COLLECTIVE);
/* Build a list of selected chunks in the collective io operation */
- if (H5D__construct_filtered_io_info_list(io_info, type_info, fm, &chunk_list, &chunk_list_num_entries) < 0)
+ if (H5D__construct_filtered_io_info_list(io_info, type_info, fm, &chunk_list, &chunk_list_num_entries) <
+ 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "couldn't construct filtered I/O info list")
if (io_info->op_type == H5D_IO_OP_WRITE) { /* Filtered collective write */
@@ -2967,7 +2967,7 @@ H5D__chunk_redistribute_shared_chunks(const H5D_io_info_t *io_info, const H5D_ty
num_send_requests++;
} /* end if */
- } /* end for */
+ } /* end for */
/* Perform all the recvs on the chunks this rank owns */
for (i = 0, last_assigned_idx = 0; i < *local_chunk_array_num_entries; i++) {
diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h
index fa83fda..095445b 100644
--- a/src/H5Dpkg.h
+++ b/src/H5Dpkg.h
@@ -216,9 +216,9 @@ typedef struct H5D_io_info_t {
/* QAK: Delete the f_sh field when oloc has a shared file pointer? */
H5F_shared_t *f_sh; /* Pointer to shared file struct that dataset is within */
#ifdef H5_HAVE_PARALLEL
- MPI_Comm comm; /* MPI communicator for file */
- hbool_t using_mpi_vfd; /* Whether the file is using an MPI-based VFD */
-#endif /* H5_HAVE_PARALLEL */
+ MPI_Comm comm; /* MPI communicator for file */
+ hbool_t using_mpi_vfd; /* Whether the file is using an MPI-based VFD */
+#endif /* H5_HAVE_PARALLEL */
H5D_storage_t * store; /* Dataset storage info */
H5D_layout_ops_t layout_ops; /* Dataset layout I/O operation function pointers */
H5D_io_ops_t io_ops; /* I/O operation function pointers */
diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h
index 4e40d27..507f75b 100644
--- a/src/H5Dpublic.h
+++ b/src/H5Dpublic.h
@@ -127,15 +127,22 @@ typedef herr_t (*H5D_gather_func_t)(const void *dst_buf, size_t dst_buf_bytes_us
extern "C" {
#endif
-H5_DLL hid_t H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t lcpl_id,
- hid_t dcpl_id, hid_t dapl_id);
-H5_DLL hid_t H5Dcreate_anon(hid_t file_id, hid_t type_id, hid_t space_id, hid_t plist_id, hid_t dapl_id);
-H5_DLL hid_t H5Dopen2(hid_t file_id, const char *name, hid_t dapl_id);
-H5_DLL hid_t H5Dget_space(hid_t dset_id);
-H5_DLL herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation);
-H5_DLL hid_t H5Dget_type(hid_t dset_id);
-H5_DLL hid_t H5Dget_create_plist(hid_t dset_id);
-H5_DLL hid_t H5Dget_access_plist(hid_t dset_id);
+H5_DLL hid_t H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t lcpl_id,
+ hid_t dcpl_id, hid_t dapl_id);
+H5_DLL hid_t H5Dcreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *name, hid_t type_id, hid_t space_id, hid_t lcpl_id, hid_t dcpl_id,
+ hid_t dapl_id, hid_t es_id);
+H5_DLL hid_t H5Dcreate_anon(hid_t file_id, hid_t type_id, hid_t space_id, hid_t plist_id, hid_t dapl_id);
+H5_DLL hid_t H5Dopen2(hid_t file_id, const char *name, hid_t dapl_id);
+H5_DLL hid_t H5Dopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *name, hid_t dapl_id, hid_t es_id);
+H5_DLL hid_t H5Dget_space(hid_t dset_id);
+H5_DLL hid_t H5Dget_space_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id,
+ hid_t es_id);
+H5_DLL herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation);
+H5_DLL hid_t H5Dget_type(hid_t dset_id);
+H5_DLL hid_t H5Dget_create_plist(hid_t dset_id);
+H5_DLL hid_t H5Dget_access_plist(hid_t dset_id);
H5_DLL hsize_t H5Dget_storage_size(hid_t dset_id);
H5_DLL herr_t H5Dget_chunk_storage_size(hid_t dset_id, const hsize_t *offset, hsize_t *chunk_bytes);
H5_DLL herr_t H5Dget_num_chunks(hid_t dset_id, hid_t fspace_id, hsize_t *nchunks);
@@ -146,8 +153,14 @@ H5_DLL herr_t H5Dget_chunk_info(hid_t dset_id, hid_t fspace_id, hsize_t chk_idx
H5_DLL haddr_t H5Dget_offset(hid_t dset_id);
H5_DLL herr_t H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
hid_t plist_id, void *buf /*out*/);
+H5_DLL herr_t H5Dread_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id,
+ hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id,
+ void *buf /*out*/, hid_t es_id);
H5_DLL herr_t H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
hid_t plist_id, const void *buf);
+H5_DLL herr_t H5Dwrite_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id,
+ hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id,
+ const void *buf, hid_t es_id);
H5_DLL herr_t H5Dwrite_chunk(hid_t dset_id, hid_t dxpl_id, uint32_t filters, const hsize_t *offset,
size_t data_size, const void *buf);
H5_DLL herr_t H5Dread_chunk(hid_t dset_id, hid_t dxpl_id, const hsize_t *offset, uint32_t *filters,
@@ -156,19 +169,48 @@ H5_DLL herr_t H5Diterate(void *buf, hid_t type_id, hid_t space_id, H5D_operator
H5_DLL herr_t H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, hsize_t *size);
H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type, void *buf, hid_t buf_type, hid_t space);
H5_DLL herr_t H5Dset_extent(hid_t dset_id, const hsize_t size[]);
+H5_DLL herr_t H5Dset_extent_async(const char *app_file, const char *app_func, unsigned app_line,
+ hid_t dset_id, const hsize_t size[], hid_t es_id);
H5_DLL herr_t H5Dflush(hid_t dset_id);
+H5_DLL herr_t H5Dwait(hid_t dset_id);
H5_DLL herr_t H5Drefresh(hid_t dset_id);
H5_DLL herr_t H5Dscatter(H5D_scatter_func_t op, void *op_data, hid_t type_id, hid_t dst_space_id,
void *dst_buf);
H5_DLL herr_t H5Dgather(hid_t src_space_id, const void *src_buf, hid_t type_id, size_t dst_buf_size,
void *dst_buf, H5D_gather_func_t op, void *op_data);
H5_DLL herr_t H5Dclose(hid_t dset_id);
+H5_DLL herr_t H5Dclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id,
+ hid_t es_id);
/* Internal API routines */
H5_DLL herr_t H5Ddebug(hid_t dset_id);
H5_DLL herr_t H5Dformat_convert(hid_t dset_id);
H5_DLL herr_t H5Dget_chunk_index_type(hid_t did, H5D_chunk_index_t *idx_type);
+/* API Wrappers for async routines */
+/* (Must be defined _after_ the function prototype) */
+/* (And must only defined when included in application code, not the library) */
+#ifndef H5D_MODULE
+#define H5Dcreate_async(...) H5Dcreate_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Dopen_async(...) H5Dopen_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Dget_space_async(...) H5Dget_space_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Dread_async(...) H5Dread_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Dwrite_async(...) H5Dwrite_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Dset_extent_async(...) H5Dset_extent_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Dclose_async(...) H5Dclose_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+
+/* Define "wrapper" versions of function calls, to allow compile-time values to
+ * be passed in by language wrapper or library layer on top of HDF5.
+ */
+#define H5Dcreate_async_wrap H5_NO_EXPAND(H5Dcreate_async)
+#define H5Dopen_async_wrap H5_NO_EXPAND(H5Dopen_async)
+#define H5Dget_space_async_wrap H5_NO_EXPAND(H5Dget_space_async)
+#define H5Dread_async_wrap H5_NO_EXPAND(H5Dread_async)
+#define H5Dwrite_async_wrap H5_NO_EXPAND(H5Dwrite_async)
+#define H5Dset_extent_async_wrap H5_NO_EXPAND(H5Dset_extent_async)
+#define H5Dclose_async_wrap H5_NO_EXPAND(H5Dclose_async)
+#endif /* H5D_MODULE */
+
/* Symbols defined for compatibility with previous versions of the HDF5 API.
*
* Use of these symbols is deprecated.
diff --git a/src/H5Dscatgath.c b/src/H5Dscatgath.c
index 65bc28a..2976709 100644
--- a/src/H5Dscatgath.c
+++ b/src/H5Dscatgath.c
@@ -898,4 +898,3 @@ H5D__compound_opt_write(size_t nelmts, const H5D_type_info_t *type_info)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5D__compound_opt_write() */
-
diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c
index 77f1c8c..1df5d0b 100644
--- a/src/H5Dvirtual.c
+++ b/src/H5Dvirtual.c
@@ -833,8 +833,8 @@ herr_t
H5D__virtual_delete(H5F_t *f, H5O_storage_t *storage)
{
#ifdef NOT_YET
- int heap_rc; /* Reference count of global heap object */
-#endif /* NOT_YET */
+ int heap_rc; /* Reference count of global heap object */
+#endif /* NOT_YET */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
diff --git a/src/H5E.c b/src/H5E.c
index 2153549..3065d8a 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -85,6 +85,7 @@ static H5E_t * H5E__get_current_stack(void);
static herr_t H5E__set_current_stack(H5E_t *estack);
static herr_t H5E__close_stack(H5E_t *err_stack, void **request);
static ssize_t H5E__get_num(const H5E_t *err_stack);
+static herr_t H5E__append_stack(H5E_t *dst_estack, const H5E_t *src_stack);
/*********************/
/* Package Variables */
@@ -1667,3 +1668,111 @@ H5Eauto_is_v2(hid_t estack_id, unsigned *is_stack)
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Eauto_is_v2() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Eappend_stack
+ *
+ * Purpose: Appends one error stack to another, optionally closing the
+ * source stack.
+ *
+ * Return: Non-negative value on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, October 7, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Eappend_stack(hid_t dst_stack_id, hid_t src_stack_id, hbool_t close_source_stack)
+{
+ H5E_t *dst_stack, *src_stack; /* Error stacks */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ /* Don't clear the error stack! :-) */
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "iib", dst_stack_id, src_stack_id, close_source_stack);
+
+ /* Check args */
+ if (NULL == (dst_stack = (H5E_t *)H5I_object_verify(dst_stack_id, H5I_ERROR_STACK)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dst_stack_id not a error stack ID")
+ if (NULL == (src_stack = (H5E_t *)H5I_object_verify(src_stack_id, H5I_ERROR_STACK)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "src_stack_id not a error stack ID")
+
+ /* Append the source stack to the destination stack */
+ if (H5E__append_stack(dst_stack, src_stack) < 0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTAPPEND, FAIL, "can't append stack")
+
+ /* Close source error stack, if requested */
+ if (close_source_stack)
+ /* Decrement the counter on the error stack. It will be freed if the
+ * count reaches zero.
+ */
+ if (H5I_dec_app_ref(src_stack_id) < 0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on source error stack")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Eappend_stack() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5E__append_stack
+ *
+ * Purpose: Private function to append error stacks.
+ *
+ * Return: Non-negative value on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, October 7, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5E__append_stack(H5E_t *dst_stack, const H5E_t *src_stack)
+{
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity checks */
+ HDassert(dst_stack);
+ HDassert(src_stack);
+
+ /* Copy the errors from the source stack to the destination stack */
+ for (u = 0; u < src_stack->nused; u++) {
+ const H5E_error2_t *src_error; /* Pointers to source error on stack */
+ H5E_error2_t * dst_error; /* Pointers to destination error on stack */
+
+ /* Get pointers into the current error stack location */
+ src_error = &(src_stack->slot[u]);
+ dst_error = &(dst_stack->slot[dst_stack->nused]);
+
+ /* Increment the IDs to indicate that they are used in this stack */
+ if (H5I_inc_ref(src_error->cls_id, FALSE) < 0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error class")
+ dst_error->cls_id = src_error->cls_id;
+ if (H5I_inc_ref(src_error->maj_num, FALSE) < 0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error message")
+ dst_error->maj_num = src_error->maj_num;
+ if (H5I_inc_ref(src_error->min_num, FALSE) < 0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error message")
+ dst_error->min_num = src_error->min_num;
+ if (NULL == (dst_error->func_name = H5MM_xstrdup(src_error->func_name)))
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "memory allocation failed")
+ if (NULL == (dst_error->file_name = H5MM_xstrdup(src_error->file_name)))
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "memory allocation failed")
+ dst_error->line = src_error->line;
+ if (NULL == (dst_error->desc = H5MM_xstrdup(src_error->desc)))
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "memory allocation failed")
+
+ /* Increment # of errors in destination stack */
+ dst_stack->nused++;
+
+ /* Check for destination stack full */
+ if (dst_stack->nused >= H5E_NSLOTS)
+ break;
+ } /* end for */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5E__append_stack() */
diff --git a/src/H5EAtest.c b/src/H5EAtest.c
index bbd436e..9a7db42 100644
--- a/src/H5EAtest.c
+++ b/src/H5EAtest.c
@@ -262,9 +262,9 @@ BEGIN_FUNC(STATIC, NOERR, herr_t, SUCCEED, -,
/* Local variables */
#ifndef NDEBUG
H5EA__test_ctx_t *ctx = (H5EA__test_ctx_t *)_ctx; /* Callback context to destroy */
-#endif /* NDEBUG */
- uint64_t * elmt = (uint64_t *)_elmt; /* Convenience pointer to native elements */
- const uint8_t *raw = (const uint8_t *)_raw; /* Convenience pointer to raw elements */
+#endif /* NDEBUG */
+ uint64_t * elmt = (uint64_t *)_elmt; /* Convenience pointer to native elements */
+ const uint8_t *raw = (const uint8_t *)_raw; /* Convenience pointer to raw elements */
/* Sanity checks */
HDassert(raw);
diff --git a/src/H5ES.c b/src/H5ES.c
new file mode 100644
index 0000000..746406e
--- /dev/null
+++ b/src/H5ES.c
@@ -0,0 +1,378 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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://support.hdfgroup.org/ftp/HDF5/releases. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5ES.c
+ * Apr 6 2020
+ * Quincey Koziol
+ *
+ * Purpose: Implements an "event set" for managing asynchronous
+ * operations.
+ *
+ * Please see the asynchronous I/O RFC document
+ * for a full description of how they work, etc.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#include "H5ESmodule.h" /* This source code file is part of the H5ES module */
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5ESpkg.h" /* Event Sets */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5Iprivate.h" /* IDs */
+
+/****************/
+/* Local Macros */
+/****************/
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/*-------------------------------------------------------------------------
+ * Function: H5EScreate
+ *
+ * Purpose: Creates an event set.
+ *
+ * Return: Success: An ID for the event set
+ * Failure: H5I_INVALID_HID
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, April 8, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5EScreate(void)
+{
+ H5ES_t *es; /* Pointer to event set object */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE0("i", "");
+
+ /* Create the new event set object */
+ if (NULL == (es = H5ES__create()))
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTCREATE, H5I_INVALID_HID, "can't create event set")
+
+ /* Register the new event set to get an ID for it */
+ if ((ret_value = H5I_register(H5I_EVENTSET, es, TRUE)) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register event set")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5EScreate() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ESget_count
+ *
+ * Purpose: Retrieve the # of events in an event set
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, April 8, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESget_count(hid_t es_id, size_t *count /*out*/)
+{
+ H5ES_t *es; /* Event set */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ix", es_id, count);
+
+ /* Check arguments */
+ if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier")
+
+ /* Retrieve the count, if non-NULL */
+ if (count)
+ *count = H5ES__list_count(&es->active);
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESget_count() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ESget_op_counter
+ *
+ * Purpose: Retrieve the counter that will be assigned to the next operation
+ * inserted into the event set.
+ *
+ * Note: This is designed for wrapper libraries mainly, to use as a
+ * mechanism for matching operations inserted into the event
+ * set with [possible] errors that occur.
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Fiiday, November 6, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESget_op_counter(hid_t es_id, uint64_t *op_counter /*out*/)
+{
+ H5ES_t *es; /* Event set */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ix", es_id, op_counter);
+
+ /* Check arguments */
+ if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier")
+
+ /* Retrieve the operation counter, if non-NULL */
+ if (op_counter)
+ *op_counter = es->op_counter;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESget_op_counter() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ESwait
+ *
+ * Purpose: Wait (with timeout) for operations in event set to complete
+ *
+ * Note: Timeout value is in ns, and is for the H5ESwait call, not each
+ * individual operation. For example: if '10' is passed as
+ * a timeout value and the event set waited 4ns for the first
+ * operation to complete, the remaining operations would be
+ * allowed to wait for at most 6ns more. i.e. the timeout value
+ * is "used up" across all operations, until it reaches 0, then
+ * any remaining operations are only checked for completion, not
+ * waited on.
+ *
+ * Note: This call will stop waiting on operations and will return
+ * immediately if an operation fails. If a failure occurs, the
+ * value returned for the # of operations in progress may be
+ * inaccurate.
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, July 13, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESwait(hid_t es_id, uint64_t timeout, size_t *num_in_progress /*out*/, hbool_t *op_failed /*out*/)
+{
+ H5ES_t *es; /* Event set */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE4("e", "iULxx", es_id, timeout, num_in_progress, op_failed);
+
+ /* Check arguments */
+ if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier")
+ if (NULL == num_in_progress)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL num_in_progress pointer")
+ if (NULL == op_failed)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL op_failed pointer")
+
+ /* Wait for operations */
+ if (H5ES__wait(es, timeout, num_in_progress, op_failed) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTWAIT, FAIL, "can't wait on operations")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESwait() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ESget_err_status
+ *
+ * Purpose: Check if event set has failed operations
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, October 15, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESget_err_status(hid_t es_id, hbool_t *err_status /*out*/)
+{
+ H5ES_t *es; /* Event set */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ix", es_id, err_status);
+
+ /* Check arguments */
+ if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier")
+
+ /* Retrieve the error flag, if non-NULL */
+ if (err_status)
+ *err_status = es->err_occurred;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESget_err_status() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ESget_err_count
+ *
+ * Purpose: Retrieve # of failed operations
+ *
+ * Note: Does not wait for active operations to complete, so count may
+ * not include all failures.
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, October 15, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESget_err_count(hid_t es_id, size_t *num_errs /*out*/)
+{
+ H5ES_t *es; /* Event set */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ix", es_id, num_errs);
+
+ /* Check arguments */
+ if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier")
+
+ /* Retrieve the error flag, if non-NULL */
+ if (num_errs) {
+ if (es->err_occurred)
+ *num_errs = H5ES__list_count(&es->failed);
+ else
+ *num_errs = 0;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESget_err_count() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ESget_err_info
+ *
+ * Purpose: Retrieve information about failed operations
+ *
+ * Note: The strings retrieved for each error info must be released
+ * by calling H5free_memory().
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Friday, November 6, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESget_err_info(hid_t es_id, size_t num_err_info, H5ES_err_info_t err_info[] /*out*/,
+ size_t *num_cleared /*out*/)
+{
+ H5ES_t *es; /* Event set */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE4("e", "izxx", es_id, num_err_info, err_info, num_cleared);
+
+ /* Check arguments */
+ if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier")
+ if (0 == num_err_info)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "err_info array size is 0")
+ if (NULL == err_info)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL err_info array pointer")
+ if (NULL == num_cleared)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL errors cleared pointer")
+
+ /* Retrieve the error information */
+ if (H5ES__get_err_info(es, num_err_info, err_info, num_cleared) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, FAIL, "can't retrieve error info for failed operation(s)")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESget_err_info() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ESclose
+ *
+ * Purpose: Closes an event set.
+ *
+ * Note: Fails if active operations are present.
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, April 8, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESclose(hid_t es_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("e", "i", es_id);
+
+ /* Check arguments */
+ if (H5I_EVENTSET != H5I_get_type(es_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an event set")
+
+ /*
+ * Decrement the counter on the object. It will be freed if the count
+ * reaches zero.
+ */
+ if (H5I_dec_app_ref(es_id) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTDEC, FAIL, "unable to decrement ref count on event set")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESclose() */
diff --git a/src/H5ESevent.c b/src/H5ESevent.c
new file mode 100644
index 0000000..ffef76d
--- /dev/null
+++ b/src/H5ESevent.c
@@ -0,0 +1,197 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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://support.hdfgroup.org/ftp/HDF5/releases. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5ESevent.c
+ * Nov 7 2020
+ * Quincey Koziol
+ *
+ * Purpose: Operations on "events" for managing asynchronous
+ * operations.
+ *
+ * Please see the asynchronous I/O RFC document
+ * for a full description of how they work, etc.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#include "H5ESmodule.h" /* This source code file is part of the H5ES module */
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5ESpkg.h" /* Event Sets */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5MMprivate.h" /* Memory management */
+
+/****************/
+/* Local Macros */
+/****************/
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a static free list to manage H5ES_event_t structs */
+H5FL_DEFINE_STATIC(H5ES_event_t);
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__event_new
+ *
+ * Purpose: Allocate and initialize a new event
+ *
+ * Return: Non-NULL pointer to new event on success, NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, November 7, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+H5ES_event_t *
+H5ES__event_new(H5VL_t *connector, void *token)
+{
+ H5ES_event_t * ev = NULL; /* New event */
+ H5VL_object_t *request = NULL; /* Async request token VOL object */
+ H5ES_event_t * ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity check */
+ HDassert(connector);
+ HDassert(token);
+
+ /* Create vol object for token */
+ if (NULL == (request = H5VL_create_object(token, connector))) {
+ if (H5VL_request_free(token) < 0)
+ HDONE_ERROR(H5E_EVENTSET, H5E_CANTFREE, NULL, "can't free request")
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTINIT, NULL, "can't create vol object for request token")
+ } /* end if */
+
+ /* Allocate space for new event */
+ if (NULL == (ev = H5FL_CALLOC(H5ES_event_t)))
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, NULL, "can't allocate event object")
+
+ /* Set request for event */
+ ev->request = request;
+
+ /* Set return value */
+ ret_value = ev;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5ES__event_new() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__event_free
+ *
+ * Purpose: Free an event
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, November 7, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ES__event_free(H5ES_event_t *ev)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity check */
+ HDassert(ev);
+
+ if (ev->api_name)
+ H5MM_xfree_const(ev->api_name);
+ if (ev->api_args)
+ H5MM_xfree_const(ev->api_args);
+ if (ev->app_file)
+ H5MM_xfree_const(ev->app_file);
+ if (ev->app_func)
+ H5MM_xfree_const(ev->app_func);
+ if (ev->request) {
+ /* Free the request */
+ if (H5VL_request_free(ev->request) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTFREE, FAIL, "unable to free request")
+
+ /* Free the VOL object for the request */
+ if (H5VL_free_object(ev->request) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, FAIL, "can't free VOL request object")
+ } /* end if */
+
+ H5FL_FREE(H5ES_event_t, ev);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES__event_free() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__event_completed
+ *
+ * Purpose: Handle a completed event
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, November 8, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ES__event_completed(H5ES_event_t *ev, H5ES_event_list_t *el)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity check */
+ HDassert(ev);
+
+ /* Remove the event from the event list */
+ H5ES__list_remove(el, ev);
+
+ /* Free the event */
+ if (H5ES__event_free(ev) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTFREE, FAIL, "unable to free event")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES__event_completed() */
diff --git a/src/H5ESint.c b/src/H5ESint.c
new file mode 100644
index 0000000..17d7806
--- /dev/null
+++ b/src/H5ESint.c
@@ -0,0 +1,666 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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://support.hdfgroup.org/ftp/HDF5/releases. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5ESint.c
+ * Apr 8 2020
+ * Quincey Koziol
+ *
+ * Purpose: Internal "event set" routines for managing asynchronous
+ * operations.
+ *
+ * Please see the asynchronous I/O RFC document
+ * for a full description of how they work, etc.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#include "H5ESmodule.h" /* This source code file is part of the H5ES module */
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5ESpkg.h" /* Event Sets */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5RSprivate.h" /* Reference-counted strings */
+
+/****************/
+/* Local Macros */
+/****************/
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/* Callback context for wait operations */
+typedef struct H5ES_wait_ctx_t {
+ H5ES_t * es; /* Event set being operated on */
+ uint64_t timeout; /* Timeout for wait operation */
+ size_t * num_in_progress; /* Count of # of operations that have not completed */
+ hbool_t *op_failed; /* Flag to indicate an operation failed */
+} H5ES_wait_ctx_t;
+
+/* Callback context for get error info (gei) operations */
+typedef struct H5ES_gei_ctx_t {
+ H5ES_t * es; /* Event set being operated on */
+ size_t num_err_info; /* # of elements in err_info[] array */
+ size_t curr_err; /* Index of current error in array */
+ H5ES_err_info_t *curr_err_info; /* Pointer to current element in err_info[] array */
+} H5ES_gei_ctx_t;
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+/********************/
+/* Local Prototypes */
+/********************/
+static herr_t H5ES__close_cb(void *es, void **request_token);
+static herr_t H5ES__handle_fail(H5ES_t *es, H5ES_event_t *ev);
+static int H5ES__wait_cb(H5ES_event_t *ev, void *_ctx);
+static int H5ES__get_err_info_cb(H5ES_event_t *ev, void *_ctx);
+static int H5ES__close_failed_cb(H5ES_event_t *ev, void *_ctx);
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Package initialization variable */
+hbool_t H5_PKG_INIT_VAR = FALSE;
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Event Set ID class */
+static const H5I_class_t H5I_EVENTSET_CLS[1] = {{
+ H5I_EVENTSET, /* ID class value */
+ 0, /* Class flags */
+ 0, /* # of reserved IDs for class */
+ (H5I_free_t)H5ES__close_cb /* Callback routine for closing objects of this class */
+}};
+
+/* Declare a static free list to manage H5ES_t structs */
+H5FL_DEFINE_STATIC(H5ES_t);
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__init_package
+ *
+ * Purpose: Initializes any interface-specific data or routines.
+ *
+ * Return: Non-negative on success / Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, April 6, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ES__init_package(void)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Initialize the ID group for the event set IDs */
+ if (H5I_register_type(H5I_EVENTSET_CLS) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTINIT, FAIL, "unable to initialize interface")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES__init_package() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES_term_package
+ *
+ * Purpose: Terminate this interface.
+ *
+ * Return: Success: Positive if anything is done that might
+ * affect other interfaces; zero otherwise.
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Monday, April 6, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5ES_term_package(void)
+{
+ int n = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ 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() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__close_cb
+ *
+ * Purpose: Called when the ref count reaches zero on an event set's ID
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, April 6, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5ES__close_cb(void *_es, void H5_ATTR_UNUSED **rt)
+{
+ H5ES_t *es = (H5ES_t *)_es; /* The event set to close */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity check */
+ HDassert(es);
+
+ /* Close the event set object */
+ if (H5ES__close(es) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CLOSEERROR, FAIL, "unable to close event set");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES__close_cb() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__create
+ *
+ * Purpose: Private function to create an event set object
+ *
+ * Return: Success: Pointer to an event set struct
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, April 8, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+H5ES_t *
+H5ES__create(void)
+{
+ H5ES_t *es = NULL; /* Pointer to event set */
+ H5ES_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Allocate space for new event set */
+ if (NULL == (es = H5FL_CALLOC(H5ES_t)))
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, NULL, "can't allocate event set object")
+
+ /* Set the return value */
+ ret_value = es;
+
+done:
+ if (!ret_value)
+ if (es && H5ES__close(es) < 0)
+ HDONE_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, NULL, "unable to free event set")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES__create() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES_insert
+ *
+ * Purpose: Insert a request token into an event set
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, April 8, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ES_insert(hid_t es_id, H5VL_t *connector, void *token, const char *caller, const char *caller_args, ...)
+{
+ H5ES_t * es = NULL; /* Event set for the operation */
+ H5ES_event_t *ev = NULL; /* Event for request */
+ H5RS_str_t * rs = NULL; /* Ref-counted string to compose formatted argument string in */
+ const char * app_file; /* Application source file name */
+ const char * app_func; /* Application source function name */
+ const char * s; /* Pointer to internal string from ref-counted string */
+ va_list ap; /* Varargs for caller */
+ hbool_t arg_started = FALSE; /* Whether the va_list has been started */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity check */
+ HDassert(connector);
+ HDassert(token);
+ HDassert(caller);
+ HDassert(caller_args);
+
+ /* Get event set */
+ if (NULL == (es = (H5ES_t *)H5I_object_verify(es_id, H5I_EVENTSET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an event set")
+
+ /* Check for errors in event set */
+ if (es->err_occurred)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTINSERT, FAIL, "event set has failed operations")
+
+ /* Create new event */
+ if (NULL == (ev = H5ES__event_new(connector, token)))
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTCREATE, FAIL, "can't create event object")
+
+ /* Start working on the API routines arguments */
+ HDva_start(ap, caller_args);
+ arg_started = TRUE;
+
+ /* Copy the app source information */
+ (void)HDva_arg(ap, char *); /* Toss the 'app_file' parameter name */
+ app_file = HDva_arg(ap, char *);
+ if (NULL == (ev->app_file = H5MM_strdup(app_file)))
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy app source file name")
+ (void)HDva_arg(ap, char *); /* Toss the 'app_func' parameter name */
+ app_func = HDva_arg(ap, char *);
+ if (NULL == (ev->app_func = H5MM_strdup(app_func)))
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy app source function name")
+ (void)HDva_arg(ap, char *); /* Toss the 'app_line' parameter name */
+ ev->app_line = HDva_arg(ap, unsigned);
+
+ /* Set the event's operation counter */
+ ev->ev_count = es->op_counter++;
+
+ /* Set the event's timestamp */
+ ev->ev_time = H5_now_usec();
+
+ /* Copy the API routine's name */
+ if (NULL == (ev->api_name = H5MM_strdup(caller)))
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy API routine name")
+
+ /* Create the string for the API routine's arguments */
+ if (NULL == (rs = H5RS_create(NULL)))
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't allocate ref-counted string")
+
+ /* Copy the string for the API routine's arguments */
+ /* (skip the six characters from the app's file, function and line # arguments) */
+ HDassert(0 == HDstrncmp(caller_args, "*s*sIu", 6));
+ if (H5_trace_args(rs, caller_args + 6, ap) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTSET, FAIL, "can't create formatted API arguments")
+ if (NULL == (s = H5RS_get_str(rs)))
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, FAIL, "can't get pointer to formatted API arguments")
+ if (NULL == (ev->api_args = H5MM_strdup(s)))
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy API routine arguments")
+
+ /* Append fully initialized event onto the event set's 'active' list */
+ H5ES__list_append(&es->active, ev);
+
+done:
+ /* Clean up */
+ if (arg_started)
+ HDva_end(ap);
+ if (rs)
+ H5RS_decr(rs);
+
+ /* Release resources on error */
+ if (ret_value < 0)
+ if (ev && H5ES__event_free(ev) < 0)
+ HDONE_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, FAIL, "unable to release event")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES_insert() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__handle_fail
+ *
+ * Purpose: Handle a failed event
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, October 15, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5ES__handle_fail(H5ES_t *es, H5ES_event_t *ev)
+{
+ FUNC_ENTER_STATIC_NOERR
+
+ /* Sanity check */
+ HDassert(es);
+ HDassert(es->active.head);
+ HDassert(ev);
+
+ /* Set error flag for event set */
+ es->err_occurred = TRUE;
+
+ /* Remove event from normal list */
+ H5ES__list_remove(&es->active, ev);
+
+ /* Append event onto the event set's error list */
+ H5ES__list_append(&es->failed, ev);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5ES__handle_fail() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__wait_cb
+ *
+ * Purpose: Common routine for testing / waiting on an operation
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, November 7, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5ES__wait_cb(H5ES_event_t *ev, void *_ctx)
+{
+ H5ES_wait_ctx_t * ctx = (H5ES_wait_ctx_t *)_ctx; /* Callback context */
+ H5VL_request_status_t ev_status = H5VL_REQUEST_STATUS_SUCCEED; /* Status from event's operation */
+ uint64_t start_time = 0, elapsed_time = 0; /* Start and elapsed times for waiting on an operation */
+ int ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity check */
+ HDassert(ev);
+ HDassert(ctx);
+
+ /* Wait on the request */
+ if (ctx->timeout != H5ES_WAIT_NONE && ctx->timeout != H5ES_WAIT_FOREVER)
+ start_time = H5_now_usec();
+ if (H5VL_request_wait(ev->request, ctx->timeout, &ev_status) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTWAIT, H5_ITER_ERROR, "unable to test operation")
+ if (ctx->timeout != H5ES_WAIT_NONE && ctx->timeout != H5ES_WAIT_FOREVER)
+ elapsed_time = H5_now_usec() - start_time;
+
+ /* Check for status values that indicate we should break out of the loop */
+ if (ev_status == H5VL_REQUEST_STATUS_FAIL) {
+ /* Handle failure */
+ if (H5ES__handle_fail(ctx->es, ev) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTSET, H5_ITER_ERROR, "unable to handle failed event")
+
+ /* Record the error */
+ *ctx->op_failed = TRUE;
+
+ /* Exit from the iteration */
+ ret_value = H5_ITER_STOP;
+ } /* end if */
+ else if (ev_status == H5VL_REQUEST_STATUS_SUCCEED) {
+ if (H5ES__event_completed(ev, &ctx->es->active) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, H5_ITER_ERROR, "unable to release completed event")
+ } /* end else-if */
+ else if (ev_status == H5VL_REQUEST_STATUS_CANCELED)
+ /* Should never get a status of 'cancel' back from test / wait operation */
+ HGOTO_ERROR(H5E_EVENTSET, H5E_BADVALUE, H5_ITER_ERROR, "received 'cancel' status for operation")
+ else {
+ /* Sanity check */
+ HDassert(ev_status == H5VL_REQUEST_STATUS_IN_PROGRESS);
+
+ /* Increment "in progress operation" counter */
+ (*ctx->num_in_progress)++;
+ } /* end if */
+
+ /* Check for updateable timeout */
+ if (ctx->timeout != H5ES_WAIT_NONE && ctx->timeout != H5ES_WAIT_FOREVER) {
+ /* Update timeout for next operation */
+ if ((elapsed_time * 1000) > ctx->timeout)
+ ctx->timeout = H5ES_WAIT_NONE;
+ else
+ ctx->timeout -= (elapsed_time * 1000); /* Convert us to ns */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES__wait_cb() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__wait
+ *
+ * Purpose: Wait for operations in event set to complete
+ *
+ * Note: Timeout value is in ns, and is for H5ES__wait itself.
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, July 13, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ES__wait(H5ES_t *es, uint64_t timeout, size_t *num_in_progress, hbool_t *op_failed)
+{
+ H5ES_wait_ctx_t ctx; /* Iterator callback context info */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity check */
+ HDassert(es);
+ HDassert(num_in_progress);
+ HDassert(op_failed);
+
+ /* Set user's parameters to known values */
+ *num_in_progress = 0;
+ *op_failed = FALSE;
+
+ /* Set up context for iterator callbacks */
+ ctx.es = es;
+ ctx.timeout = timeout;
+ ctx.num_in_progress = num_in_progress;
+ ctx.op_failed = op_failed;
+
+ /* Iterate over the events in the set, waiting for them to complete */
+ if (H5ES__list_iterate(&es->active, H5ES__wait_cb, &ctx) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_BADITER, FAIL, "iteration failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES__wait() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__get_err_info_cb
+ *
+ * Purpose: Retrieve information about a failed operation
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, November 11, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5ES__get_err_info_cb(H5ES_event_t *ev, void *_ctx)
+{
+ H5ES_gei_ctx_t *ctx = (H5ES_gei_ctx_t *)_ctx; /* Callback context */
+ int ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity check */
+ HDassert(ev);
+ HDassert(ctx);
+
+ /* Copy operation info for event */
+ if (NULL == (ctx->curr_err_info->api_name = H5MM_strdup(ev->api_name)))
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 API name")
+ if (NULL == (ctx->curr_err_info->api_args = H5MM_strdup(ev->api_args)))
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 API routine arguments")
+ if (NULL == (ctx->curr_err_info->app_file_name = H5MM_strdup(ev->app_file)))
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy app source file name")
+ if (NULL == (ctx->curr_err_info->app_func_name = H5MM_strdup(ev->app_func)))
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy app function name")
+ ctx->curr_err_info->app_line_num = ev->app_line;
+ ctx->curr_err_info->op_ins_count = ev->ev_count;
+ ctx->curr_err_info->op_ins_ts = ev->ev_time;
+
+ /* Get error stack for event */
+ if (H5VL_request_specific(ev->request, H5VL_REQUEST_GET_ERR_STACK, &ctx->curr_err_info->err_stack_id) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, H5_ITER_ERROR, "unable to retrieve error stack for operation")
+
+ /* Remove event from event set's failed list */
+ H5ES__list_remove(&ctx->es->failed, ev);
+
+ /* Free event node */
+ if (H5ES__event_free(ev) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, H5_ITER_ERROR, "unable to release failed event")
+
+ /* Advance to next element of err_info[] array */
+ ctx->curr_err++;
+ ctx->curr_err_info++;
+
+ /* Stop iteration if err_info[] array is full */
+ if (ctx->curr_err == ctx->num_err_info)
+ ret_value = H5_ITER_STOP;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES__get_err_info_cb() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__get_err_info
+ *
+ * Purpose: Retrieve information about failed operations
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Friday, November 6, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ES__get_err_info(H5ES_t *es, size_t num_err_info, H5ES_err_info_t err_info[], size_t *num_cleared)
+{
+ H5ES_gei_ctx_t ctx; /* Iterator callback context info */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity check */
+ HDassert(es);
+ HDassert(num_err_info);
+ HDassert(err_info);
+ HDassert(num_cleared);
+
+ /* Set up context for iterator callbacks */
+ ctx.es = es;
+ ctx.num_err_info = num_err_info;
+ ctx.curr_err = 0;
+ ctx.curr_err_info = &err_info[0];
+
+ /* Iterate over the failed events in the set, copying their error info */
+ if (H5ES__list_iterate(&es->failed, H5ES__get_err_info_cb, &ctx) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_BADITER, FAIL, "iteration failed")
+
+ /* Set # of failed events cleared from event set's failed list */
+ *num_cleared = ctx.curr_err;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES__get_err_info() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__close_failed_cb
+ *
+ * Purpose: Release a failed event
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, November 11, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5ES__close_failed_cb(H5ES_event_t *ev, void *_ctx)
+{
+ H5ES_t *es = (H5ES_t *)_ctx; /* Callback context */
+ int ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity check */
+ HDassert(ev);
+ HDassert(es);
+
+ /* Remove event from event set's failed list */
+ H5ES__list_remove(&es->failed, ev);
+
+ /* Free event node */
+ if (H5ES__event_free(ev) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, H5_ITER_ERROR, "unable to release failed event")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES__close_failed_cb() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__close
+ *
+ * Purpose: Destroy an event set object
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, April 6, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ES__close(H5ES_t *es)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity check */
+ HDassert(es);
+
+ /* Fail if active operations still present */
+ if (H5ES__list_count(&es->active) > 0)
+ HGOTO_ERROR(
+ H5E_EVENTSET, H5E_CANTCLOSEOBJ, FAIL,
+ "can't close event set while unfinished operations are present (i.e. wait on event set first)")
+
+ /* Iterate over the failed events in the set, releasing them */
+ if (H5ES__list_iterate(&es->failed, H5ES__close_failed_cb, (void *)es) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_BADITER, FAIL, "iteration failed")
+
+ /* Release the event set */
+ es = H5FL_FREE(H5ES_t, es);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES__close() */
diff --git a/src/H5ESlist.c b/src/H5ESlist.c
new file mode 100644
index 0000000..231820c
--- /dev/null
+++ b/src/H5ESlist.c
@@ -0,0 +1,215 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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://support.hdfgroup.org/ftp/HDF5/releases. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5ESlist.c
+ * Nov 7 2020
+ * Quincey Koziol
+ *
+ * Purpose: Operations on "event lists" for managing asynchronous
+ * operations.
+ *
+ * Please see the asynchronous I/O RFC document
+ * for a full description of how they work, etc.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#include "H5ESmodule.h" /* This source code file is part of the H5ES module */
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5ESpkg.h" /* Event Sets */
+#include "H5FLprivate.h" /* Free Lists */
+
+/****************/
+/* Local Macros */
+/****************/
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__list_insert
+ *
+ * Purpose: Append an event into an event list
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, November 7, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5ES__list_append(H5ES_event_list_t *el, H5ES_event_t *ev)
+{
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Sanity check */
+ HDassert(el);
+ HDassert(ev);
+
+ /* Append event onto the event list */
+ if (NULL == el->tail)
+ el->head = el->tail = ev;
+ else {
+ ev->prev = el->tail;
+ el->tail->next = ev;
+ el->tail = ev;
+ } /* end else */
+
+ /* Increment the # of events in list */
+ el->count++;
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5ES__list_append() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__list_count
+ *
+ * Purpose: Retrieve # of events in an event list
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, November 7, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+H5_ATTR_PURE size_t
+H5ES__list_count(const H5ES_event_list_t *el)
+{
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Sanity check */
+ HDassert(el);
+
+ FUNC_LEAVE_NOAPI(el->count)
+} /* end H5ES__list_count() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__list_iterate
+ *
+ * Purpose: Iterate over events in a list, calling callback for
+ * each event.
+ *
+ * Note: Iteration is safe for deleting the current event. Modifying
+ * the list in other ways is likely unsafe.
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, November 7, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5ES__list_iterate(H5ES_event_list_t *el, H5ES_list_iter_func_t cb, void *ctx)
+{
+ H5ES_event_t *ev; /* Event in list */
+ int ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Sanity check */
+ HDassert(el);
+ HDassert(cb);
+
+ /* Iterate over events in list */
+ ev = el->head;
+ while (ev) {
+ H5ES_event_t *tmp; /* Temporary event */
+
+ /* Get pointer to next node, so it's safe if this one is removed */
+ tmp = ev->next;
+
+ /* Perform iterator callback */
+ if ((ret_value = (*cb)(ev, ctx)) != H5_ITER_CONT) {
+ if (ret_value < 0)
+ HERROR(H5E_EVENTSET, H5E_CANTNEXT, "iteration operator failed");
+ break;
+ } /* end if */
+
+ /* Advance to next node */
+ ev = tmp;
+ } /* end while */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5ES__list_iterate() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ES__list_remove
+ *
+ * Purpose: Remove an event from an event list
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Houjun Tang
+ * Thursday, July 30, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+H5ES__list_remove(H5ES_event_list_t *el, const H5ES_event_t *ev)
+{
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Sanity check */
+ HDassert(el);
+ HDassert(el->head);
+ HDassert(ev);
+
+ /* Stitch event out of list */
+ if (ev == el->head)
+ el->head = ev->next;
+ if (NULL != ev->next)
+ ev->next->prev = ev->prev;
+ if (NULL != ev->prev)
+ ev->prev->next = ev->next;
+ if (NULL == el->head)
+ el->tail = NULL;
+
+ /* Decrement the # of events in list */
+ el->count--;
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5ES__list_remove() */
diff --git a/src/H5ESmodule.h b/src/H5ESmodule.h
new file mode 100644
index 0000000..716b96c
--- /dev/null
+++ b/src/H5ESmodule.h
@@ -0,0 +1,32 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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://support.hdfgroup.org/ftp/HDF5/releases. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Quincey Koziol
+ * Monday, April 6, 2020
+ *
+ * Purpose: This file contains declarations which define macros for the
+ * H5ES package. Including this header means that the source file
+ * is part of the H5ES package.
+ */
+#ifndef _H5ESmodule_H
+#define _H5ESmodule_H
+
+/* Define the proper control macros for the generic FUNC_ENTER/LEAVE and error
+ * reporting macros.
+ */
+#define H5ES_MODULE
+#define H5_MY_PKG H5ES
+#define H5_MY_PKG_ERR H5E_EVENTSET
+#define H5_MY_PKG_INIT YES
+
+#endif /* _H5ESmodule_H */
diff --git a/src/H5ESpkg.h b/src/H5ESpkg.h
new file mode 100644
index 0000000..e4a46cb
--- /dev/null
+++ b/src/H5ESpkg.h
@@ -0,0 +1,101 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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://support.hdfgroup.org/ftp/HDF5/releases. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Quincey Koziol
+ * Wednesday, April 8, 2020
+ *
+ * Purpose: This file contains declarations which are visible only within
+ * the H5ES package. Source files outside the H5ES package should
+ * include H5ESprivate.h instead.
+ */
+#if !(defined H5ES_FRIEND || defined H5ES_MODULE)
+#error "Do not include this file outside the H5ES package!"
+#endif
+
+#ifndef _H5ESpkg_H
+#define _H5ESpkg_H
+
+/* Get package's private header */
+#include "H5ESprivate.h"
+
+/* Other private headers needed by this file */
+
+/**************************/
+/* Package Private Macros */
+/**************************/
+
+/****************************/
+/* Package Private Typedefs */
+/****************************/
+
+/* Typedef for event nodes */
+typedef struct H5ES_event_t {
+ H5VL_object_t * request; /* Request token for event */
+ struct H5ES_event_t *prev, *next; /* Previous and next event nodes */
+
+ /* Useful info for debugging and error reporting */
+ const char *api_name; /* Name of API routine for event */
+ const char *api_args; /* Arguments to API routine */
+ const char *app_file; /* Name of source file from application */
+ const char *app_func; /* Name of source function from application */
+ unsigned app_line; /* Line # of source file from application */
+ uint64_t ev_count; /* This event is the n'th operation in the event set */
+ uint64_t ev_time; /* Timestamp for this event (in ms from UNIX epoch) */
+} H5ES_event_t;
+
+/* Typedef for lists of event set operations */
+typedef struct H5ES_event_list_t {
+ size_t count; /* # of events in list */
+ H5ES_event_t *head, *tail; /* Head & tail of events in list */
+} H5ES_event_list_t;
+
+/* Typedef for event set objects */
+struct H5ES_t {
+ uint64_t op_counter; /* Count of operations inserted into this set */
+
+ /* Active events */
+ H5ES_event_list_t active; /* List of active events in set */
+
+ /* Failed events */
+ hbool_t err_occurred; /* Flag for error from an operation */
+ H5ES_event_list_t failed; /* List of failed events in set */
+};
+
+/* Event list iterator callback function */
+typedef int (*H5ES_list_iter_func_t)(H5ES_event_t *ev, void *ctx);
+
+/*****************************/
+/* Package Private Variables */
+/*****************************/
+
+/******************************/
+/* Package Private Prototypes */
+/******************************/
+H5_DLL H5ES_t *H5ES__create(void);
+H5_DLL herr_t H5ES__wait(H5ES_t *es, uint64_t timeout, size_t *num_in_progress, hbool_t *op_failed);
+H5_DLL herr_t H5ES__get_err_info(H5ES_t *es, size_t num_err_info, H5ES_err_info_t err_info[],
+ size_t *num_cleared);
+H5_DLL herr_t H5ES__close(H5ES_t *es);
+
+/* Event list operations */
+H5_DLL void H5ES__list_append(H5ES_event_list_t *el, H5ES_event_t *ev);
+H5_DLL size_t H5ES__list_count(const H5ES_event_list_t *el);
+H5_DLL int H5ES__list_iterate(H5ES_event_list_t *el, H5ES_list_iter_func_t cb, void *ctx);
+H5_DLL void H5ES__list_remove(H5ES_event_list_t *el, const H5ES_event_t *ev);
+
+/* Event operations */
+H5_DLL H5ES_event_t *H5ES__event_new(H5VL_t *connector, void *token);
+H5_DLL herr_t H5ES__event_free(H5ES_event_t *ev);
+H5_DLL herr_t H5ES__event_completed(H5ES_event_t *ev, H5ES_event_list_t *el);
+
+#endif /* _H5ESpkg_H */
diff --git a/src/H5ESprivate.h b/src/H5ESprivate.h
new file mode 100644
index 0000000..87765c0
--- /dev/null
+++ b/src/H5ESprivate.h
@@ -0,0 +1,54 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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://support.hdfgroup.org/ftp/HDF5/releases. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5ESprivate.h
+ * Apr 6 2020
+ * Quincey Koziol
+ *
+ * Purpose: Private header for library accessible event set routines.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef _H5ESprivate_H
+#define _H5ESprivate_H
+
+/* Include package's public header */
+#include "H5ESpublic.h" /* Event Sets */
+
+/* Private headers needed by this file */
+#include "H5VLprivate.h" /* Virtual Object Layer */
+
+/**************************/
+/* Library Private Macros */
+/**************************/
+
+/****************************/
+/* Library Private Typedefs */
+/****************************/
+
+/* Typedef for event set objects */
+typedef struct H5ES_t H5ES_t;
+
+/*****************************/
+/* Library-private Variables */
+/*****************************/
+
+/***************************************/
+/* Library-private Function Prototypes */
+/***************************************/
+herr_t H5ES_insert(hid_t es_id, H5VL_t *connector, void *token, const char *caller, const char *caller_args,
+ ...);
+
+#endif /* _H5ESprivate_H */
diff --git a/src/H5ESpublic.h b/src/H5ESpublic.h
index dad929e..2884198 100644
--- a/src/H5ESpublic.h
+++ b/src/H5ESpublic.h
@@ -24,18 +24,89 @@
/* Public Macros */
/*****************/
+/* Default value for "no event set" / synchronous execution */
+#define H5ES_NONE (hid_t)0
+
+/* Special "wait" timeout values */
+#define H5ES_WAIT_FOREVER (UINT64_MAX) /* Wait until all operations complete */
+#define H5ES_WAIT_NONE \
+ (0) /* Don't wait for operations to complete, \
+ * just check their status. \
+ * (this allows H5ESwait to behave \
+ * like a 'test' operation) \
+ */
+
/*******************/
/* Public Typedefs */
/*******************/
/* Asynchronous operation status */
typedef enum H5ES_status_t {
- H5ES_STATUS_IN_PROGRESS, /* Operation has not yet completed */
- H5ES_STATUS_SUCCEED, /* Operation has completed, successfully */
- H5ES_STATUS_FAIL, /* Operation has completed, but failed */
- H5ES_STATUS_CANCELED /* Operation has not completed and was canceled */
+ H5ES_STATUS_IN_PROGRESS, /* Operation(s) have not yet completed */
+ H5ES_STATUS_SUCCEED, /* Operation(s) have completed, successfully */
+ H5ES_STATUS_FAIL /* An operation has completed, but failed */
} H5ES_status_t;
+/* Information about failed operations in event set */
+typedef struct H5ES_err_info_t {
+ /* Operation info */
+ char * api_name; /* Name of HDF5 API routine called */
+ char * api_args; /* "Argument string" for arguments to HDF5 API routine called */
+ char * app_file_name; /* Name of source file where the HDF5 API routine was called */
+ char * app_func_name; /* Name of function where the HDF5 API routine was called */
+ unsigned app_line_num; /* Line # of source file where the HDF5 API routine was called */
+ uint64_t op_ins_count; /* Counter of operation's insertion into event set */
+ uint64_t op_ins_ts; /* Timestamp for when the operation was inserted into the event set */
+
+ /* Error info */
+ hid_t err_stack_id; /* ID for error stack from failed operation */
+} H5ES_err_info_t;
+
+/*
+H5ES_op_info_t:
+ const char *: API name (H5Dwrite_async, ...)
+ const char *: Arg string
+ const char *: Appl. source file name
+ const char *: Appl. source function
+ unsigned: Appl. source file line
+ uint64_t: Insert Time Timestamp
+ uint64_t: "event count" - n'th event inserted into event set
+ uint64_t: Execution Time timestamp (*)
+
+More Possible Info for H5ES_op_info_t:
+ Parent Operation's request token (*) -> "parent event count"? -- Could be
+ used to "prune" child operations from reported errors, with flag
+ to H5ESget_err_info?
+
+H5ES_err_info_t:
+ H5ES_op_info_t: (above)
+ hid_t: Error stack (*)
+
+Possible debugging routines: (Should also be configured from Env Var)
+ H5ESdebug_signal(hid_t es_id, signal_t sig, uint64_t <event count>);
+ H5ESdebug_err_trace_log(hid_t es_id, const char *filename);
+ H5ESdebug_err_trace_fh(hid_t es_id, FILE *fh);
+ H5ESdebug_err_signal(hid_t es_id, signal_t sig);
+[Possibly option to allow operations to be inserted into event set with error?]
+
+ Example usage:
+ es_id = H5EScreate();
+ H5ESdebug...(es_id, ...);
+ ...
+ H5Dwrite_async(..., es_id);
+
+How to Trace Async Operations?
+ <Example of stacking Logging VOL Connector w/Async VOL Connector>
+
+"Library / wrapper developer" version of API routines: (Auto-generated)
+ H5Dwrite_async_wrap(const char *app_file, const char *app_func,
+ unsigned app_line_num, dset_id, mem_type_id, mem_space_id, ..., es_id);
+
+ vs.
+
+ H5Dwrite_async(dset_id, mem_type_id, mem_space_id, ..., es_id);
+*/
+
/********************/
/* Public Variables */
/********************/
@@ -48,6 +119,16 @@ typedef enum H5ES_status_t {
extern "C" {
#endif
+H5_DLL hid_t H5EScreate(void);
+H5_DLL herr_t H5ESwait(hid_t es_id, uint64_t timeout, size_t *num_in_progress, hbool_t *err_occurred);
+H5_DLL herr_t H5ESget_count(hid_t es_id, size_t *count);
+H5_DLL herr_t H5ESget_op_counter(hid_t es_id, uint64_t *counter);
+H5_DLL herr_t H5ESget_err_status(hid_t es_id, hbool_t *err_occurred);
+H5_DLL herr_t H5ESget_err_count(hid_t es_id, size_t *num_errs);
+H5_DLL herr_t H5ESget_err_info(hid_t es_id, size_t num_err_info, H5ES_err_info_t err_info[],
+ size_t *err_cleared);
+H5_DLL herr_t H5ESclose(hid_t es_id);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/H5Epublic.h b/src/H5Epublic.h
index 8f9b473..2bb7996 100644
--- a/src/H5Epublic.h
+++ b/src/H5Epublic.h
@@ -159,6 +159,7 @@ H5_DLL herr_t H5Eclose_msg(hid_t err_id);
H5_DLL hid_t H5Ecreate_msg(hid_t cls, H5E_type_t msg_type, const char *msg);
H5_DLL hid_t H5Ecreate_stack(void);
H5_DLL hid_t H5Eget_current_stack(void);
+H5_DLL herr_t H5Eappend_stack(hid_t dst_stack_id, hid_t src_stack_id, hbool_t close_source_stack);
H5_DLL herr_t H5Eclose_stack(hid_t stack_id);
H5_DLL ssize_t H5Eget_class_name(hid_t class_id, char *name, size_t size);
H5_DLL herr_t H5Eset_current_stack(hid_t err_stack_id);
diff --git a/src/H5F.c b/src/H5F.c
index 3653677..365decf 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -24,6 +24,7 @@
#include "H5ACprivate.h" /* Metadata cache */
#include "H5CXprivate.h" /* API Contexts */
#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event Sets */
#include "H5Fpkg.h" /* File access */
#include "H5FLprivate.h" /* Free lists */
#include "H5Iprivate.h" /* IDs */
@@ -67,6 +68,15 @@ static int H5F__get_all_count_cb(void H5_ATTR_UNUSED *obj_ptr, hid_t H5_ATTR_UNU
/* Callback for getting IDs for open objects in a file */
static int H5F__get_all_ids_cb(void H5_ATTR_UNUSED *obj_ptr, hid_t obj_id, void *key);
+/* Helper routines for sync/async API calls */
+static herr_t H5F__post_open_api_common(H5VL_object_t *vol_obj, void **token_ptr);
+static hid_t H5F__create_api_common(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id,
+ void **token_ptr);
+static hid_t H5F__open_api_common(const char *filename, unsigned flags, hid_t fapl_id, void **token_ptr);
+static hid_t H5F__reopen_api_common(hid_t file_id, void **token_ptr);
+static herr_t H5F__flush_api_common(hid_t object_id, H5F_scope_t scope, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+
/*********************/
/* Package Variables */
/*********************/
@@ -447,40 +457,53 @@ done:
} /* end H5Fis_accessible() */
/*-------------------------------------------------------------------------
- * Function: H5Fcreate
+ * Function: H5F__post_open_api_common
*
- * Purpose: This is the primary function for creating HDF5 files . The
- * flags parameter determines whether an existing file will be
- * overwritten or not. All newly created files are opened for
- * both reading and writing. All flags may be combined with the
- * bit-wise OR operator (`|') to change the behavior of the file
- * create call.
+ * Purpose: This is the common function for 'post open' operations
*
- * The more complex behaviors of a file's creation and access
- * are controlled through the file-creation and file-access
- * property lists. The value of H5P_DEFAULT for a template
- * value indicates that the library should use the default
- * values for the appropriate template.
+ * Return: SUCCEED/FAIL
*
- * See also: H5Fpublic.h for the list of supported flags. H5Ppublic.h for
- * the list of file creation and file access properties.
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F__post_open_api_common(H5VL_object_t *vol_obj, void **token_ptr)
+{
+ uint64_t supported; /* Whether 'post open' operation is supported by VOL connector */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check for 'post open' callback */
+ supported = 0;
+ if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't check for 'post open' operation")
+ if (supported & H5VL_OPT_QUERY_SUPPORTED)
+ /* Make the 'post open' callback */
+ if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_POST_OPEN, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to make file 'post open' callback")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F__post_open_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F__create_api_common
+ *
+ * Purpose: This is the common function for creating new HDF5 files.
*
* Return: Success: A file ID
* Failure: H5I_INVALID_HID
*-------------------------------------------------------------------------
*/
-hid_t
-H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
+static hid_t
+H5F__create_api_common(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id, void **token_ptr)
{
void * new_file = NULL; /* File struct for new file */
- H5P_genplist_t * plist; /* Property list pointer */
- H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */
- H5VL_object_t * vol_obj = NULL; /* VOL object for file */
- uint64_t supported; /* Whether 'post open' operation is supported by VOL connector */
- hid_t ret_value; /* return value */
+ H5P_genplist_t * plist; /* Property list pointer */
+ H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
- FUNC_ENTER_API(H5I_INVALID_HID)
- H5TRACE4("i", "*sIuii", filename, flags, fcpl_id, fapl_id);
+ FUNC_ENTER_STATIC
/* Check/fix arguments */
if (!filename || !*filename)
@@ -528,40 +551,71 @@ H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
/* Create a new file or truncate an existing file through the VOL */
if (NULL == (new_file = H5VL_file_create(&connector_prop, filename, flags, fcpl_id, fapl_id,
- H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)))
+ H5P_DATASET_XFER_DEFAULT, token_ptr)))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to create file")
/* Get an ID for the file */
if ((ret_value = H5VL_register_using_vol_id(H5I_FILE, new_file, connector_prop.connector_id, TRUE)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register file handle")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F__create_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Fcreate
+ *
+ * Purpose: This is the primary function for creating HDF5 files . The
+ * flags parameter determines whether an existing file will be
+ * overwritten or not. All newly created files are opened for
+ * both reading and writing. All flags may be combined with the
+ * bit-wise OR operator (`|') to change the behavior of the file
+ * create call.
+ *
+ * The more complex behaviors of a file's creation and access
+ * are controlled through the file-creation and file-access
+ * property lists. The value of H5P_DEFAULT for a template
+ * value indicates that the library should use the default
+ * values for the appropriate template.
+ *
+ * See also: H5Fpublic.h for the list of supported flags. H5Ppublic.h for
+ * the list of file creation and file access properties.
+ *
+ * Return: Success: A file ID
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* File object */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE4("i", "*sIuii", filename, flags, fcpl_id, fapl_id);
+
+ /* Create the file synchronously */
+ if ((ret_value = H5F__create_api_common(filename, flags, fcpl_id, fapl_id, NULL)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously create file")
+
/* Get the file object */
if (NULL == (vol_obj = H5VL_vol_object(ret_value)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier")
+ HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier")
- /* Make the 'post open' callback */
- supported = 0;
- if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't check for 'post open' operation")
- if (supported & H5VL_OPT_QUERY_SUPPORTED)
- if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_POST_OPEN, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to make file 'post open' callback")
+ /* Perform 'post open' operation */
+ if (H5F__post_open_api_common(vol_obj, NULL) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed")
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Fcreate() */
/*-------------------------------------------------------------------------
- * Function: H5Fopen
+ * Function: H5Fcreate_async
*
- * Purpose: This is the primary function for accessing existing HDF5
- * files. The FLAGS argument determines whether writing to an
- * existing file will be allowed or not. All flags may be
- * combined with the bit-wise OR operator (`|') to change the
- * behavior of the file open call. The more complex behaviors
- * of a file's access are controlled through the file-access
- * property list.
+ * Purpose: Asynchronous version of H5Fcreate
*
* See Also: H5Fpublic.h for a list of possible values for FLAGS.
*
@@ -570,17 +624,78 @@ done:
*-------------------------------------------------------------------------
*/
hid_t
-H5Fopen(const char *filename, unsigned flags, hid_t fapl_id)
+H5Fcreate_async(const char *app_file, const char *app_func, unsigned app_line, const char *filename,
+ unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t es_id)
{
- void * new_file = NULL; /* File struct for new file */
- H5P_genplist_t * plist; /* Property list pointer */
- H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */
- H5VL_object_t * vol_obj = NULL; /* VOL object for file */
- uint64_t supported; /* Whether 'post open' operation is supported by VOL connector */
- hid_t ret_value; /* Return value */
+ H5VL_object_t *vol_obj = NULL; /* File object */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
FUNC_ENTER_API(H5I_INVALID_HID)
- H5TRACE3("i", "*sIui", filename, flags, fapl_id);
+ H5TRACE8("i", "*s*sIu*sIuiii", app_file, app_func, app_line, filename, flags, fcpl_id, fapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Create the file, possibly asynchronously */
+ if ((ret_value = H5F__create_api_common(filename, flags, fcpl_id, fapl_id, token_ptr)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously create file")
+
+ /* Get the file object */
+ if (NULL == (vol_obj = H5VL_vol_object(ret_value)))
+ HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE8(FUNC, "*s*sIu*sIuiii", app_file, app_func, app_line, filename, flags,
+ fcpl_id, fapl_id, es_id)) < 0) {
+ if (H5I_dec_app_ref(ret_value) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on file ID")
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
+
+ /* Reset token for 'post open' operation */
+ /* (Unnecessary if create operation didn't change it, but not worth checking -QAK) */
+ token = NULL;
+
+ /* Perform 'post open' operation */
+ if (H5F__post_open_api_common(vol_obj, token_ptr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE8(FUNC, "*s*sIu*sIuiii", app_file, app_func, app_line, filename, flags,
+ fcpl_id, fapl_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Fcreate_async() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F__open_api_common
+ *
+ * Purpose: This is the common function for accessing existing HDF5
+ * files.
+ *
+ * Return: Success: A file ID
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+H5F__open_api_common(const char *filename, unsigned flags, hid_t fapl_id, void **token_ptr)
+{
+ H5F_t * new_file = NULL; /* File struct for new file */
+ H5P_genplist_t * plist; /* Property list pointer */
+ H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_STATIC
/* Check arguments */
if (!filename || !*filename)
@@ -615,51 +730,146 @@ H5Fopen(const char *filename, unsigned flags, hid_t fapl_id)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set VOL connector info in API context")
/* Open the file through the VOL layer */
- if (NULL == (new_file = H5VL_file_open(&connector_prop, filename, flags, fapl_id,
- H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)))
+ if (NULL == (new_file = (H5F_t *)H5VL_file_open(&connector_prop, filename, flags, fapl_id,
+ H5P_DATASET_XFER_DEFAULT, token_ptr)))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to open file")
/* Get an ID for the file */
if ((ret_value = H5VL_register_using_vol_id(H5I_FILE, new_file, connector_prop.connector_id, TRUE)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register file handle")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F__open_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Fopen
+ *
+ * Purpose: This is the primary function for accessing existing HDF5
+ * files. The FLAGS argument determines whether writing to an
+ * existing file will be allowed or not. All flags may be
+ * combined with the bit-wise OR operator (`|') to change the
+ * behavior of the file open call. The more complex behaviors
+ * of a file's access are controlled through the file-access
+ * property list.
+ *
+ * See Also: H5Fpublic.h for a list of possible values for FLAGS.
+ *
+ * Return: Success: A file ID
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Fopen(const char *filename, unsigned flags, hid_t fapl_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* File object */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE3("i", "*sIui", filename, flags, fapl_id);
+
+ /* Open the file synchronously */
+ if ((ret_value = H5F__open_api_common(filename, flags, fapl_id, NULL)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to synchronously open file")
+
/* Get the file object */
if (NULL == (vol_obj = H5VL_vol_object(ret_value)))
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "invalid object identifier")
+ HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier")
- /* Make the 'post open' callback */
- supported = 0;
- if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't check for 'post open' operation")
- if (supported & H5VL_OPT_QUERY_SUPPORTED)
- if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_POST_OPEN, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to make file 'post open' callback")
+ /* Perform 'post open' operation */
+ if (H5F__post_open_api_common(vol_obj, NULL) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed")
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Fopen() */
/*-------------------------------------------------------------------------
- * Function: H5Fflush
+ * Function: H5Fopen_async
*
- * Purpose: Flushes all outstanding buffers of a file to disk but does
- * not remove them from the cache. The OBJECT_ID can be a file,
- * dataset, group, attribute, or named data type.
+ * Purpose: Asynchronous version of H5Fopen
+ *
+ * See Also: H5Fpublic.h for a list of possible values for FLAGS.
+ *
+ * Return: Success: A file ID
+ * Failure: H5I_INVALID_HID
*
- * Return: Success: Non-negative
- * Failure: Negative
*-------------------------------------------------------------------------
*/
-herr_t
-H5Fflush(hid_t object_id, H5F_scope_t scope)
+hid_t
+H5Fopen_async(const char *app_file, const char *app_func, unsigned app_line, const char *filename,
+ unsigned flags, hid_t fapl_id, hid_t es_id)
{
- H5VL_object_t *vol_obj = NULL; /* Object info */
- H5I_type_t obj_type; /* Type of object */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5VL_object_t *vol_obj = NULL; /* File object */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
- FUNC_ENTER_API(FAIL)
- H5TRACE2("e", "iFs", object_id, scope);
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE7("i", "*s*sIu*sIuii", app_file, app_func, app_line, filename, flags, fapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Open the file, possibly asynchronously */
+ if ((ret_value = H5F__open_api_common(filename, flags, fapl_id, token_ptr)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to asynchronously open file")
+
+ /* Get the file object */
+ if (NULL == (vol_obj = H5VL_vol_object(ret_value)))
+ HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE7(FUNC, "*s*sIu*sIuii", app_file, app_func, app_line, filename, flags,
+ fapl_id, es_id)) < 0) {
+ if (H5I_dec_app_ref(ret_value) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on file ID")
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
+
+ /* Reset token for 'post open' operation */
+ /* (Unnecessary if create operation didn't change it, but not worth checking -QAK) */
+ token = NULL;
+
+ /* Perform 'post open' operation */
+ if (H5F__post_open_api_common(vol_obj, token_ptr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE7(FUNC, "*s*sIu*sIuii", app_file, app_func, app_line, filename, flags,
+ fapl_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Fopen_async() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F__flush_api_common
+ *
+ * Purpose: This is the common function for flushing an HDF5 file.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F__flush_api_common(hid_t object_id, H5F_scope_t scope, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5I_type_t obj_type; /* Type of object to use */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
/* Get the type of object we're flushing + sanity check */
obj_type = H5I_get_type(object_id);
@@ -668,19 +878,87 @@ H5Fflush(hid_t object_id, H5F_scope_t scope)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
/* Get the file object */
- if (NULL == (vol_obj = H5VL_vol_object(object_id)))
+ if (NULL == (*vol_obj_ptr = H5VL_vol_object(object_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier")
/* Flush the object */
- if (H5VL_file_specific(vol_obj, H5VL_FILE_FLUSH, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (int)obj_type,
+ if (H5VL_file_specific(*vol_obj_ptr, H5VL_FILE_FLUSH, H5P_DATASET_XFER_DEFAULT, token_ptr, (int)obj_type,
(int)scope) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file")
done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F__flush_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Fflush
+ *
+ * Purpose: Flushes all outstanding buffers of a file to disk but does
+ * not remove them from the cache. The OBJECT_ID can be a file,
+ * dataset, group, attribute, or named data type.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Fflush(hid_t object_id, H5F_scope_t scope)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "iFs", object_id, scope);
+
+ /* Flush the file synchronously */
+ if (H5F__flush_api_common(object_id, scope, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to synchronously flush file")
+
+done:
FUNC_LEAVE_API(ret_value)
} /* end H5Fflush() */
/*-------------------------------------------------------------------------
+ * Function: H5Fflush_async
+ *
+ * Purpose: Asynchronous version of H5Fflush
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Fflush_async(const char *app_file, const char *app_func, unsigned app_line, hid_t object_id,
+ H5F_scope_t scope, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "*s*sIuiFsi", app_file, app_func, app_line, object_id, scope, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Flush the file asynchronously */
+ if (H5F__flush_api_common(object_id, scope, token_ptr, &vol_obj) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to asynchronously flush file")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(
+ es_id, vol_obj->connector, token,
+ H5ARG_TRACE6(FUNC, "*s*sIuiFsi", app_file, app_func, app_line, object_id, scope, es_id)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Fflush_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5Fclose
*
* Purpose: This function closes the file specified by FILE_ID by
@@ -717,6 +995,65 @@ done:
} /* end H5Fclose() */
/*-------------------------------------------------------------------------
+ * Function: H5Fclose_async
+ *
+ * Purpose: Asynchronous version of H5Fclose
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Fclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t file_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ H5VL_t * connector = NULL; /* VOL connector */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, file_id, es_id);
+
+ /* Check arguments */
+ if (H5I_FILE != H5I_get_type(file_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID")
+
+ /* Prepare for possible asynchronous operation */
+ if (H5ES_NONE != es_id) {
+ /* Get file object's connector */
+ if (NULL == (vol_obj = H5VL_vol_object(file_id)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get VOL object for file")
+
+ /* Increase connector's refcount, so it doesn't get closed if closing
+ * this file ID closes the file */
+ connector = vol_obj->connector;
+ H5VL_conn_inc_rc(connector);
+
+ /* Point at token for operation to set up */
+ token_ptr = &token;
+ } /* end if */
+
+ /* Asynchronously decrement reference count on ID.
+ * When it reaches zero the file will be closed.
+ */
+ if (H5I_dec_app_ref_async(file_id, token_ptr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, file_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ if (connector && H5VL_conn_dec_rc(connector) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't decrement ref count on connector")
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Fclose_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5Fdelete
*
* Purpose: Deletes an HDF5 file.
@@ -888,37 +1225,31 @@ done:
} /* end H5Funmount() */
/*-------------------------------------------------------------------------
- * Function: H5Freopen
- *
- * Purpose: Reopen a file. The new file handle which is returned points
- * to the same file as the specified file handle. Both handles
- * share caches and other information. The only difference
- * between the handles is that the new handle is not mounted
- * anywhere and no files are mounted on it.
+ * Function: H5F__reopen_api_common
*
- * Return: Success: New file ID
+ * Purpose: This is the common function for reopening an HDF5 file
+ * files.
*
+ * Return: Success: A file ID
* Failure: H5I_INVALID_HID
*
*-------------------------------------------------------------------------
*/
-hid_t
-H5Freopen(hid_t file_id)
+static hid_t
+H5F__reopen_api_common(hid_t file_id, void **token_ptr)
{
- void * file = NULL; /* File struct for new file */
- H5VL_object_t *vol_obj = NULL; /* VOL object for file */
- uint64_t supported; /* Whether 'post open' operation is supported by VOL connector */
+ void * file = NULL; /* File struct for new file */
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
hid_t ret_value = H5I_INVALID_HID; /* Return value */
- FUNC_ENTER_API(H5I_INVALID_HID)
- H5TRACE1("i", "i", file_id);
+ FUNC_ENTER_STATIC
/* Get the file object */
if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier")
/* Reopen the file */
- if (H5VL_file_specific(vol_obj, H5VL_FILE_REOPEN, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &file) < 0)
+ if (H5VL_file_specific(vol_obj, H5VL_FILE_REOPEN, H5P_DATASET_XFER_DEFAULT, token_ptr, &file) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to reopen file via the VOL connector")
/* Make sure that worked */
@@ -929,24 +1260,114 @@ H5Freopen(hid_t file_id)
if ((ret_value = H5VL_register(H5I_FILE, file, vol_obj->connector, TRUE)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register file handle")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F__reopen_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Freopen
+ *
+ * Purpose: Reopen a file. The new file handle which is returned points
+ * to the same file as the specified file handle. Both handles
+ * share caches and other information. The only difference
+ * between the handles is that the new handle is not mounted
+ * anywhere and no files are mounted on it.
+ *
+ * Return: Success: New file ID
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Freopen(hid_t file_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* File object */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE1("i", "i", file_id);
+
+ /* Reopen the file synchronously */
+ if ((ret_value = H5F__reopen_api_common(file_id, NULL)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to synchronously reopen file")
+
/* Get the file object */
if (NULL == (vol_obj = H5VL_vol_object(ret_value)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier")
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't get handle for re-opened file")
- /* Make the 'post open' callback */
- supported = 0;
- if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't check for 'post open' operation")
- if (supported & H5VL_OPT_QUERY_SUPPORTED)
- if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_POST_OPEN, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to make file 'post open' callback")
+ /* Perform 'post open' operation */
+ if (H5F__post_open_api_common(vol_obj, NULL) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed")
done:
+ /* XXX (VOL MERGE): If registration fails, file will not be closed */
FUNC_LEAVE_API(ret_value)
} /* end H5Freopen() */
/*-------------------------------------------------------------------------
+ * Function: H5Freopen_async
+ *
+ * Purpose: Asynchronous version of H5Freopen
+ *
+ * See Also: H5Fpublic.h for a list of possible values for FLAGS.
+ *
+ * Return: Success: A file ID
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Freopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t file_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE5("i", "*s*sIuii", app_file, app_func, app_line, file_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Reopen the file, possibly asynchronously */
+ if ((ret_value = H5F__reopen_api_common(file_id, token_ptr)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to asynchronously reopen file")
+
+ /* Get the file object */
+ if (NULL == (vol_obj = H5VL_vol_object(ret_value)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't get handle for re-opened file")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, file_id, es_id)) < 0) {
+ if (H5I_dec_app_ref(ret_value) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on file ID")
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
+
+ /* Reset token for 'post open' operation */
+ /* (Unnecessary if create operation didn't change it, but not worth checking -QAK) */
+ token = NULL;
+
+ /* Perform 'post open' operation */
+ if (H5F__post_open_api_common(vol_obj, token_ptr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, file_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Freopen_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5Fget_intent
*
* Purpose: Public API to retrieve the file's 'intent' flags passed
@@ -1990,3 +2411,40 @@ H5Fset_dset_no_attrs_hint(hid_t file_id, hbool_t minimize)
done:
FUNC_LEAVE_API(ret_value)
} /* H5Fset_dset_no_attrs_hint */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Fwait
+ *
+ * Purpose: Wait for all operations on a dataset.
+ * Tang: added for async
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Fwait(hid_t file_id)
+{
+ H5VL_object_t *vol_obj; /* File for this operation */
+ H5I_type_t obj_type; /* Type of object */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("e", "i", file_id);
+
+ /* Get the type of object we're flushing + sanity check */
+ obj_type = H5I_get_type(file_id);
+ if (H5I_FILE != obj_type && H5I_GROUP != obj_type && H5I_DATATYPE != obj_type &&
+ H5I_DATASET != obj_type && H5I_ATTR != obj_type)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
+
+ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "file_id parameter is not a valid file identifier")
+
+ if ((ret_value = H5VL_file_specific(vol_obj, H5VL_FILE_WAIT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL,
+ file_id)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPERATE, FAIL, "unable to wait file")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Fwait() */
diff --git a/src/H5FAtest.c b/src/H5FAtest.c
index 350530a..de9e6d7 100644
--- a/src/H5FAtest.c
+++ b/src/H5FAtest.c
@@ -200,7 +200,7 @@ BEGIN_FUNC(STATIC, NOERR, herr_t, SUCCEED, -,
#ifndef NDEBUG
H5FA__test_ctx_t *ctx = (H5FA__test_ctx_t *)_ctx; /* Callback context to destroy */
#endif /* NDEBUG */
- const uint64_t *elmt = (const uint64_t *)_elmt; /* Convenience pointer to native elements */
+ const uint64_t *elmt = (const uint64_t *)_elmt; /* Convenience pointer to native elements */
/* Sanity checks */
HDassert(raw);
@@ -241,9 +241,9 @@ BEGIN_FUNC(STATIC, NOERR, herr_t, SUCCEED, -,
/* Local variables */
#ifndef NDEBUG
H5FA__test_ctx_t *ctx = (H5FA__test_ctx_t *)_ctx; /* Callback context to destroy */
-#endif /* NDEBUG */
- uint64_t * elmt = (uint64_t *)_elmt; /* Convenience pointer to native elements */
- const uint8_t *raw = (const uint8_t *)_raw; /* Convenience pointer to raw elements */
+#endif /* NDEBUG */
+ uint64_t * elmt = (uint64_t *)_elmt; /* Convenience pointer to native elements */
+ const uint8_t *raw = (const uint8_t *)_raw; /* Convenience pointer to raw elements */
/* Sanity checks */
HDassert(raw);
diff --git a/src/H5FScache.c b/src/H5FScache.c
index fc61edd..3f8ce2b 100644
--- a/src/H5FScache.c
+++ b/src/H5FScache.c
@@ -1004,10 +1004,11 @@ H5FS__cache_sinfo_deserialize(const void *_image, size_t H5_ATTR_NDEBUG_UNUSED l
/* Check for any serialized sections */
if (fspace->serial_sect_count > 0) {
hsize_t old_tot_sect_count; /* Total section count from header */
- hsize_t H5_ATTR_NDEBUG_UNUSED old_serial_sect_count; /* Total serializable section count from header */
- hsize_t H5_ATTR_NDEBUG_UNUSED old_ghost_sect_count; /* Total ghost section count from header */
- hsize_t H5_ATTR_NDEBUG_UNUSED old_tot_space; /* Total space managed from header */
- unsigned sect_cnt_size; /* The size of the section size counts */
+ hsize_t H5_ATTR_NDEBUG_UNUSED
+ old_serial_sect_count; /* Total serializable section count from header */
+ hsize_t H5_ATTR_NDEBUG_UNUSED old_ghost_sect_count; /* Total ghost section count from header */
+ hsize_t H5_ATTR_NDEBUG_UNUSED old_tot_space; /* Total space managed from header */
+ unsigned sect_cnt_size; /* The size of the section size counts */
/* Compute the size of the section counts */
sect_cnt_size = H5VM_limit_enc_size((uint64_t)fspace->serial_sect_count);
diff --git a/src/H5Fint.c b/src/H5Fint.c
index 92b70ce..6ea2841 100644
--- a/src/H5Fint.c
+++ b/src/H5Fint.c
@@ -695,6 +695,7 @@ H5F__get_objects_cb(void *obj_ptr, hid_t obj_id, void *key)
case H5I_ERROR_MSG:
case H5I_ERROR_STACK:
case H5I_SPACE_SEL_ITER:
+ case H5I_EVENTSET:
case H5I_NTYPES:
default:
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5_ITER_ERROR, "unknown or invalid data object")
@@ -2621,8 +2622,8 @@ H5F__build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, const char *n
hid_t new_fapl_id = H5I_INVALID_HID; /* ID for duplicated FAPL */
#ifdef H5_HAVE_SYMLINK
/* This has to be declared here to avoid unfreed resources on errors */
- char *realname = NULL; /* Fully resolved path name of file */
-#endif /* H5_HAVE_SYMLINK */
+ char *realname = NULL; /* Fully resolved path name of file */
+#endif /* H5_HAVE_SYMLINK */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index f4268e5..7445d36 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -30,7 +30,7 @@ typedef struct H5F_t H5F_t;
/* Private headers needed by this file */
#include "H5MMprivate.h" /* Memory management */
#ifdef H5_HAVE_PARALLEL
-#include "H5Pprivate.h" /* Property lists */
+#include "H5Pprivate.h" /* Property lists */
#endif /* H5_HAVE_PARALLEL */
#include "H5VMprivate.h" /* Vectors and arrays */
#include "H5VLprivate.h" /* Virtual Object Layer */
@@ -532,33 +532,33 @@ typedef struct H5F_t H5F_t;
#define H5F_DEFAULT_CSET H5T_CSET_ASCII
/* ========= File Creation properties ============ */
-#define H5F_CRT_USER_BLOCK_NAME "block_size" /* Size of the file user block in bytes */
+#define H5F_CRT_USER_BLOCK_NAME "block_size" /* Size of the file user block in bytes */
#define H5F_CRT_SYM_LEAF_NAME "symbol_leaf" /* 1/2 rank for symbol table leaf nodes */
#define H5F_CRT_SYM_LEAF_DEF 4
-#define H5F_CRT_BTREE_RANK_NAME "btree_rank" /* 1/2 rank for btree internal nodes */
+#define H5F_CRT_BTREE_RANK_NAME "btree_rank" /* 1/2 rank for btree internal nodes */
#define H5F_CRT_ADDR_BYTE_NUM_NAME "addr_byte_num" /* Byte number in an address */
-#define H5F_CRT_OBJ_BYTE_NUM_NAME "obj_byte_num" /* Byte number for object size */
+#define H5F_CRT_OBJ_BYTE_NUM_NAME "obj_byte_num" /* Byte number for object size */
#define H5F_CRT_SUPER_VERS_NAME "super_version" /* Version number of the superblock */
/* Number of shared object header message indexes */
#define H5F_CRT_SHMSG_NINDEXES_NAME "num_shmsg_indexes"
#define H5F_CRT_SHMSG_INDEX_TYPES_NAME "shmsg_message_types" /* Types of message in each index */
/* Minimum size of messages in each index */
#define H5F_CRT_SHMSG_INDEX_MINSIZE_NAME "shmsg_message_minsize"
-#define H5F_CRT_SHMSG_LIST_MAX_NAME "shmsg_list_max" /* Shared message list maximum size */
-#define H5F_CRT_SHMSG_BTREE_MIN_NAME "shmsg_btree_min" /* Shared message B-tree minimum size */
-#define H5F_CRT_FILE_SPACE_STRATEGY_NAME "file_space_strategy" /* File space handling strategy */
-#define H5F_CRT_FREE_SPACE_PERSIST_NAME "free_space_persist" /* Free-space persisting status */
+#define H5F_CRT_SHMSG_LIST_MAX_NAME "shmsg_list_max" /* Shared message list maximum size */
+#define H5F_CRT_SHMSG_BTREE_MIN_NAME "shmsg_btree_min" /* Shared message B-tree minimum size */
+#define H5F_CRT_FILE_SPACE_STRATEGY_NAME "file_space_strategy" /* File space handling strategy */
+#define H5F_CRT_FREE_SPACE_PERSIST_NAME "free_space_persist" /* Free-space persisting status */
#define H5F_CRT_FREE_SPACE_THRESHOLD_NAME "free_space_threshold" /* Free space section threshold */
#define H5F_CRT_FILE_SPACE_PAGE_SIZE_NAME "file_space_page_size" /* File space page size */
/* ========= File Access properties ============ */
#define H5F_ACS_META_CACHE_INIT_CONFIG_NAME \
- "mdc_initCacheCfg" /* Initial metadata cache resize configuration */
+ "mdc_initCacheCfg" /* Initial metadata cache resize configuration */
#define H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME "rdcc_nslots" /* Size of raw data chunk cache(slots) */
#define H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME "rdcc_nbytes" /* Size of raw data chunk cache(bytes) */
-#define H5F_ACS_PREEMPT_READ_CHUNKS_NAME "rdcc_w0" /* Preemption read chunks first */
-#define H5F_ACS_ALIGN_THRHD_NAME "threshold" /* Threshold for alignment */
-#define H5F_ACS_ALIGN_NAME "align" /* Alignment */
+#define H5F_ACS_PREEMPT_READ_CHUNKS_NAME "rdcc_w0" /* Preemption read chunks first */
+#define H5F_ACS_ALIGN_THRHD_NAME "threshold" /* Threshold for alignment */
+#define H5F_ACS_ALIGN_NAME "align" /* Alignment */
#define H5F_ACS_META_BLOCK_SIZE_NAME \
"meta_block_size" /* Minimum metadata allocation block size (when aggregating metadata allocations) */
#define H5F_ACS_SIEVE_BUF_SIZE_NAME \
@@ -566,35 +566,35 @@ typedef struct H5F_t H5F_t;
#define H5F_ACS_SDATA_BLOCK_SIZE_NAME \
"sdata_block_size" /* Minimum "small data" allocation block size (when aggregating "small" raw data \
allocations) */
-#define H5F_ACS_GARBG_COLCT_REF_NAME "gc_ref" /* Garbage-collect references */
-#define H5F_ACS_FILE_DRV_NAME "vfd_info" /* File driver ID & info */
+#define H5F_ACS_GARBG_COLCT_REF_NAME "gc_ref" /* Garbage-collect references */
+#define H5F_ACS_FILE_DRV_NAME "vfd_info" /* File driver ID & info */
#define H5F_ACS_VOL_CONN_NAME "vol_connector_info" /* VOL connector ID & info */
-#define H5F_ACS_CLOSE_DEGREE_NAME "close_degree" /* File close degree */
-#define H5F_ACS_FAMILY_OFFSET_NAME "family_offset" /* Offset position in file for family file driver */
+#define H5F_ACS_CLOSE_DEGREE_NAME "close_degree" /* File close degree */
+#define H5F_ACS_FAMILY_OFFSET_NAME "family_offset" /* Offset position in file for family file driver */
#define H5F_ACS_FAMILY_NEWSIZE_NAME \
"family_newsize" /* New member size of family driver. (private property only used by h5repart) */
#define H5F_ACS_FAMILY_TO_SINGLE_NAME \
"family_to_single" /* Whether to convert family to a single-file driver. (private property only used by \
h5repart) */
-#define H5F_ACS_MULTI_TYPE_NAME "multi_type" /* Data type in multi file driver */
-#define H5F_ACS_LIBVER_LOW_BOUND_NAME "libver_low_bound" /* 'low' bound of library format versions */
+#define H5F_ACS_MULTI_TYPE_NAME "multi_type" /* Data type in multi file driver */
+#define H5F_ACS_LIBVER_LOW_BOUND_NAME "libver_low_bound" /* 'low' bound of library format versions */
#define H5F_ACS_LIBVER_HIGH_BOUND_NAME "libver_high_bound" /* 'high' bound of library format versions */
#define H5F_ACS_WANT_POSIX_FD_NAME \
"want_posix_fd" /* Internal: query the file descriptor from the core VFD, instead of the memory address \
*/
#define H5F_ACS_METADATA_READ_ATTEMPTS_NAME "metadata_read_attempts" /* # of metadata read attempts */
-#define H5F_ACS_OBJECT_FLUSH_CB_NAME "object_flush_cb" /* Object flush callback */
-#define H5F_ACS_EFC_SIZE_NAME "efc_size" /* Size of external file cache */
+#define H5F_ACS_OBJECT_FLUSH_CB_NAME "object_flush_cb" /* Object flush callback */
+#define H5F_ACS_EFC_SIZE_NAME "efc_size" /* Size of external file cache */
#define H5F_ACS_FILE_IMAGE_INFO_NAME \
"file_image_info" /* struct containing initial file image and callback info */
#define H5F_ACS_CLEAR_STATUS_FLAGS_NAME \
"clear_status_flags" /* Whether to clear superblock status_flags (private property only used by h5clear) \
*/
-#define H5F_ACS_NULL_FSM_ADDR_NAME "null_fsm_addr" /* Nullify addresses of free-space managers */
- /* Private property used only by h5clear */
-#define H5F_ACS_SKIP_EOF_CHECK_NAME "skip_eof_check" /* Skip EOF check */
- /* Private property used only by h5clear */
-#define H5F_ACS_USE_MDC_LOGGING_NAME "use_mdc_logging" /* Whether to use metadata cache logging */
+#define H5F_ACS_NULL_FSM_ADDR_NAME "null_fsm_addr" /* Nullify addresses of free-space managers */
+/* Private property used only by h5clear */
+#define H5F_ACS_SKIP_EOF_CHECK_NAME "skip_eof_check" /* Skip EOF check */
+/* Private property used only by h5clear */
+#define H5F_ACS_USE_MDC_LOGGING_NAME "use_mdc_logging" /* Whether to use metadata cache logging */
#define H5F_ACS_MDC_LOG_LOCATION_NAME "mdc_log_location" /* Name of metadata cache log location */
#define H5F_ACS_START_MDC_LOG_ON_ACCESS_NAME \
"start_mdc_log_on_access" /* Whether logging starts on file create/open */
@@ -640,7 +640,7 @@ typedef struct H5F_t H5F_t;
3 /* With file locking and consistency flags (at least this version for SWMR support) */
#define HDF5_SUPERBLOCK_VERSION_LATEST HDF5_SUPERBLOCK_VERSION_3 /* The maximum super block format */
#define HDF5_SUPERBLOCK_VERSION_V18_LATEST \
- HDF5_SUPERBLOCK_VERSION_2 /* The latest superblock version for v18 */
+ HDF5_SUPERBLOCK_VERSION_2 /* The latest superblock version for v18 */
#define HDF5_FREESPACE_VERSION 0 /* of the Free-Space Info */
#define HDF5_OBJECTDIR_VERSION 0 /* of the Object Directory format */
#define HDF5_SHAREDHEADER_VERSION 0 /* of the Shared-Header Info */
@@ -648,14 +648,15 @@ typedef struct H5F_t H5F_t;
/* B-tree internal 'K' values */
#define HDF5_BTREE_SNODE_IK_DEF 16
-#define HDF5_BTREE_CHUNK_IK_DEF 32 /* Note! this value is assumed \
- to be 32 for version 0 \
- of the superblock and \
- if it is changed, the code \
- must compensate. -QAK \
- */
+#define HDF5_BTREE_CHUNK_IK_DEF \
+ 32 /* Note! this value is assumed \
+ to be 32 for version 0 \
+ of the superblock and \
+ if it is changed, the code \
+ must compensate. -QAK \
+ */
#define HDF5_BTREE_IK_MAX_ENTRIES 65536 /* 2^16 - 2 bytes for storing entries (children) */
- /* See format specification on version 1 B-trees */
+/* See format specification on version 1 B-trees */
/* Default file space handling strategy */
#define H5F_FILE_SPACE_STRATEGY_DEF H5F_FSPACE_STRATEGY_FSM_AGGR
@@ -690,7 +691,7 @@ typedef struct H5F_t H5F_t;
#define H5F_PAGED_AGGR(F) (F->shared->fs_strategy == H5F_FSPACE_STRATEGY_PAGE && F->shared->fs_page_size)
/* Metadata read attempt values */
-#define H5F_METADATA_READ_ATTEMPTS 1 /* Default # of read attempts for non-SWMR access */
+#define H5F_METADATA_READ_ATTEMPTS 1 /* Default # of read attempts for non-SWMR access */
#define H5F_SWMR_METADATA_READ_ATTEMPTS 100 /* Default # of read attempts for SWMR access */
/* Macros to define signatures of all objects in the file */
@@ -806,7 +807,7 @@ typedef enum H5F_mem_page_t {
} H5F_mem_page_t;
/* Aliases for H5F_mem_page_t enum values */
-#define H5F_MEM_PAGE_META H5F_MEM_PAGE_SUPER /* Small-sized meta data */
+#define H5F_MEM_PAGE_META H5F_MEM_PAGE_SUPER /* Small-sized meta data */
#define H5F_MEM_PAGE_GENERIC H5F_MEM_PAGE_LARGE_SUPER /* Large-sized generic: meta and raw */
/* Type of prefix for opening prefixed files */
diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h
index 7981372..851d64d 100644
--- a/src/H5Fpublic.h
+++ b/src/H5Fpublic.h
@@ -84,8 +84,9 @@
#define H5F_OBJ_DATATYPE (0x0008u) /**< Named datatype objects */
#define H5F_OBJ_ATTR (0x0010u) /**< Attribute objects */
#define H5F_OBJ_ALL (H5F_OBJ_FILE | H5F_OBJ_DATASET | H5F_OBJ_GROUP | H5F_OBJ_DATATYPE | H5F_OBJ_ATTR)
-#define H5F_OBJ_LOCAL (0x0020u) /**< Restrict search to objects opened through current file ID
- (as opposed to objects opened through any file ID accessing this file) */
+#define H5F_OBJ_LOCAL \
+ (0x0020u) /**< Restrict search to objects opened through current file ID \
+ (as opposed to objects opened through any file ID accessing this file) */
#define H5F_FAMILY_DEFAULT (hsize_t)0
@@ -356,6 +357,8 @@ H5_DLL htri_t H5Fis_accessible(const char *container_name, hid_t fapl_id);
*
*/
H5_DLL hid_t H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id);
+H5_DLL hid_t H5Fcreate_async(const char *app_file, const char *app_func, unsigned app_line,
+ const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t es_id);
/**
* \ingroup H5F
*
@@ -446,6 +449,8 @@ H5_DLL hid_t H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_
*
*/
H5_DLL hid_t H5Fopen(const char *filename, unsigned flags, hid_t fapl_id);
+H5_DLL hid_t H5Fopen_async(const char *app_file, const char *app_func, unsigned app_line,
+ const char *filename, unsigned flags, hid_t access_plist, hid_t es_id);
/**
* \ingroup H5F
*
@@ -472,6 +477,8 @@ H5_DLL hid_t H5Fopen(const char *filename, unsigned flags, hid_t fapl_id);
*
*/
H5_DLL hid_t H5Freopen(hid_t file_id);
+H5_DLL hid_t H5Freopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t file_id,
+ hid_t es_id);
/**
* \ingroup H5F
*
@@ -502,6 +509,8 @@ H5_DLL hid_t H5Freopen(hid_t file_id);
*
*/
H5_DLL herr_t H5Fflush(hid_t object_id, H5F_scope_t scope);
+H5_DLL herr_t H5Fflush_async(const char *app_file, const char *app_func, unsigned app_line, hid_t object_id,
+ H5F_scope_t scope, hid_t es_id);
/**
* \example H5Fclose.c
* After creating an HDF5 file with H5Fcreate(), we close it with
@@ -551,6 +560,8 @@ H5_DLL herr_t H5Fflush(hid_t object_id, H5F_scope_t scope);
*
*/
H5_DLL herr_t H5Fclose(hid_t file_id);
+H5_DLL herr_t H5Fclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t file_id,
+ hid_t es_id);
/**
* \ingroup H5F
*
@@ -988,8 +999,8 @@ H5_DLL ssize_t H5Fget_file_image(hid_t file_id, void *buf_ptr, size_t buf_len);
* </tr>
* <tr>
* <td><em>hbool_t</em> <code>open_trace_file</code> </td>
- * <td>OUT: Boolean field indicating whether the <code>trace_file_name</code> field should be used to open
- * a trace file for the cache. This field will always be set to <code>0</code> in this context.</td>
+ * <td>OUT: Boolean field indicating whether the <code>trace_file_name</code> field should be used to
+ * open a trace file for the cache. This field will always be set to <code>0</code> in this context.</td>
* </tr>
* <tr>
* <td><em>hbool_t</em> <code>close_trace_file</code> </td>
@@ -997,9 +1008,8 @@ H5_DLL ssize_t H5Fget_file_image(hid_t file_id, void *buf_ptr, size_t buf_len);
* will always be set to <code>0</code> in this context.</td></tr>
* <tr>
* <td><em>char*</em><code>trace_file_name</code> </td>
- * <td>OUT: Full path name of the trace file to be opened if the <code>open_trace_file</code> field is set
- * to <code>1</code>. This field will always be set to the empty string in this context.</td></tr>
- * <tr>
+ * <td>OUT: Full path name of the trace file to be opened if the <code>open_trace_file</code> field is
+ * set to <code>1</code>. This field will always be set to the empty string in this context.</td></tr> <tr>
* <td><em>hbool_t</em> <code>evictions_enabled</code> </td>
* <td>OUT: Boolean flag indicating whether metadata cache entry evictions are
* enabled.</td>
@@ -1042,8 +1052,8 @@ H5_DLL ssize_t H5Fget_file_image(hid_t file_id, void *buf_ptr, size_t buf_len);
* <table>
* <tr>
* <td><em>enum H5C_cache_incr_mode</em> <code>incr_mode</code> </td>
- * <td>OUT: Enumerated value indicating the operational mode of the automatic cache size increase code. At
- * present, only the following values are legal:<p>\c H5C_incr__off: Automatic cache size increase is
+ * <td>OUT: Enumerated value indicating the operational mode of the automatic cache size increase code.
+ * At present, only the following values are legal:<p>\c H5C_incr__off: Automatic cache size increase is
* disabled.</p><p>\c H5C_incr__threshold: Automatic cache size increase is enabled using the hit rate
* threshold algorithm.</p></td>
* </tr>
@@ -1071,8 +1081,8 @@ H5_DLL ssize_t H5Fget_file_image(hid_t file_id, void *buf_ptr, size_t buf_len);
* <td><em>enum H5C_cache_flash_incr_mode</em> <code>flash_incr_mode</code> </td>
* <td>OUT: Enumerated value indicating the operational mode of the flash cache size increase code. At
* present, only the following values are legal:<p>\c H5C_flash_incr__off: Flash cache size increase is
- * disabled.</p><p>\c H5C_flash_incr__add_space: Flash cache size increase is enabled using the add space
- * algorithm.</p></td>
+ * disabled.</p><p>\c H5C_flash_incr__add_space: Flash cache size increase is enabled using the add
+ * space algorithm.</p></td>
* </tr>
* <tr>
* <td><em>double</em> <code>flash_threshold</code> </td>
@@ -1083,8 +1093,8 @@ H5_DLL ssize_t H5Fget_file_image(hid_t file_id, void *buf_ptr, size_t buf_len);
* <tr>
* <td><em>double</em> <code>flash_multiple</code> </td>
* <td>OUT: The factor by which the size of the triggering entry / entry size increase is multiplied to
- * obtain the initial cache size increment. This increment may be reduced to reflect existing free space
- * in the cache and the <code>max_size</code> field above.</td>
+ * obtain the initial cache size increment. This increment may be reduced to reflect existing free
+ * space in the cache and the <code>max_size</code> field above.</td>
* </tr>
* </table>
*
@@ -1095,13 +1105,12 @@ H5_DLL ssize_t H5Fget_file_image(hid_t file_id, void *buf_ptr, size_t buf_len);
* </tr>
* <tr>
* <td><em>enum H5C_cache_decr_mode</em> <code>decr_mode</code> </td>
- * <td>OUT: Enumerated value indicating the operational mode of the automatic cache size decrease code. At
- * present, the following values are legal:<p>H5C_decr__off: Automatic cache size decrease is disabled,
- * and the remaining decrement fields are ignored.</p><p>H5C_decr__threshold: Automatic cache size
- * decrease is enabled using the hit rate threshold algorithm.</p><p>H5C_decr__age_out: Automatic cache
- * size decrease is enabled using the ageout algorithm.</p><p>H5C_decr__age_out_with_threshold:
- * Automatic cache size decrease is enabled using the ageout with hit rate threshold
- * algorithm</p></td>
+ * <td>OUT: Enumerated value indicating the operational mode of the automatic cache size decrease code.
+ * At present, the following values are legal:<p>H5C_decr__off: Automatic cache size decrease is disabled, and
+ * the remaining decrement fields are ignored.</p><p>H5C_decr__threshold: Automatic cache size decrease is
+ * enabled using the hit rate threshold algorithm.</p><p>H5C_decr__age_out: Automatic cache size decrease is
+ * enabled using the ageout algorithm.</p><p>H5C_decr__age_out_with_threshold: Automatic cache size decrease
+ * is enabled using the ageout with hit rate threshold algorithm</p></td>
* </tr>
* <tr><td><em>double</em> <code>upper_hr_threshold</code> </td>
* <td>OUT: Upper hit rate threshold. This value is only used if the decr_mode is either
@@ -1144,7 +1153,8 @@ H5_DLL ssize_t H5Fget_file_image(hid_t file_id, void *buf_ptr, size_t buf_len);
* <tr><td><em>int</em> <code>dirty_bytes_threshold</code> </td>
* <td>OUT: Threshold number of bytes of dirty metadata generation for triggering synchronizations of the
* metadata caches serving the target file in the parallel case.<p>Synchronization occurs whenever the
- * number of bytes of dirty metadata created since the last synchronization exceeds this limit.</p></td>
+ * number of bytes of dirty metadata created since the last synchronization exceeds this
+ * limit.</p></td>
* </tr>
* </table>
*
@@ -1180,59 +1190,57 @@ H5_DLL herr_t H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr);
* <tr>
* <td><em>hbool_t</em> <code>rpt_fcn_enabled</code></td>
* <td>IN: Boolean flag indicating whether the adaptive cache resize report function is enabled. This
- * field should almost always be set to disabled (<code>0</code>). Since resize algorithm activity is reported
- * via stdout, it MUST be set to disabled (<code>0</code>) on Windows machines.<p>The report function is not
- * supported code, and can be expected to change between versions of the library. Use it at your own
+ * field should almost always be set to disabled (<code>0</code>). Since resize algorithm activity is
+ * reported via stdout, it MUST be set to disabled (<code>0</code>) on Windows machines.<p>The report function
+ * is not supported code, and can be expected to change between versions of the library. Use it at your own
* risk.</p></td>
* </tr>
* <tr>
* <td><em>hbool_t</em> <code>open_trace_File</code></td>
* <td>IN: Boolean field indicating whether the <code>trace_file_name</code> field should be used to open
- * a trace file for the cache.<p>The trace file is a debuging feature that allows the capture of top level
- * metadata cache requests for purposes of debugging and/or optimization. This field should normally be set
- * to <code>0</code>, as trace file collection imposes considerable overhead.</p><p>This field should only be
- * set to <code>1</code> when the <code>trace_file_name</code> contains the full path of the desired trace
- * file, and either there is no open trace file on the cache, or the <code>close_trace_file</code> field is
- * also <code>1</code>.</p><p>The trace file feature is unsupported unless used at the direction of The HDF
- * Group. It is intended to allow The HDF Group to collect a trace of cache activity in cases of occult
- * failures and/or poor performance seen in the field, so as to aid in reproduction in the lab. If you use it
- * absent the direction of The HDF Group, you are on your
- * own.</p></td>
+ * a trace file for the cache.<p>The trace file is a debuging feature that allows the capture of top
+ * level metadata cache requests for purposes of debugging and/or optimization. This field should normally be
+ * set to <code>0</code>, as trace file collection imposes considerable overhead.</p><p>This field should only
+ * be set to <code>1</code> when the <code>trace_file_name</code> contains the full path of the desired trace
+ * file, and either there is no open trace file on the cache, or the <code>close_trace_file</code>
+ * field is also <code>1</code>.</p><p>The trace file feature is unsupported unless used at the direction of
+ * The HDF Group. It is intended to allow The HDF Group to collect a trace of cache activity in cases of
+ * occult failures and/or poor performance seen in the field, so as to aid in reproduction in the lab. If you
+ * use it absent the direction of The HDF Group, you are on your own.</p></td>
* </tr>
* <tr><td><em>hbool_t</em> <code>close_trace_file</code></td>
* <td>IN: Boolean field indicating whether the current trace file (if any) should be closed.<p>See the
- * above comments on the <code>open_trace_file</code> field. This field should be set to <code>0</code> unless
- * there is an open trace file on the cache that you wish to close.</p><p>The trace file feature is
- * unsupported unless used at the direction of The HDF Group. It is intended to allow The HDF Group to collect
- * a trace of cache activity in cases of occult failures and/or poor performance seen in the field, so as to
- * aid in reproduction in the lab. If you use it absent the direction of The HDF Group, you are on your
- * own.</p></td>
+ * above comments on the <code>open_trace_file</code> field. This field should be set to
+ * <code>0</code> unless there is an open trace file on the cache that you wish to close.</p><p>The trace file
+ * feature is unsupported unless used at the direction of The HDF Group. It is intended to allow The HDF Group
+ * to collect a trace of cache activity in cases of occult failures and/or poor performance seen in the field,
+ * so as to aid in reproduction in the lab. If you use it absent the direction of The HDF Group, you are on
+ * your own.</p></td>
* </tr>
* <tr>
* <td><em>char</em> <code>trace_file_name[]</code></td>
* <td>IN: Full path of the trace file to be opened if the <code>open_trace_file</code> field is set
- * to <code>1</code>.<p>In the parallel case, an ascii representation of the mpi rank of the process will be
- * appended to the file name to yield a unique trace file name for each process.</p><p>The length of the path
- * must not exceed #H5AC__MAX_TRACE_FILE_NAME_LEN characters.</p><p>The trace file feature is
- * unsupported unless used at the direction of The HDF Group. It is intended to allow The HDF Group to collect
- * a trace of cache activity in cases of occult failures and/or poor performance seen in the field, so as to
- * aid in reproduction in the lab. If you use it absent the direction of The HDF Group, you are on your
- * own.</p></td>
+ * to <code>1</code>.<p>In the parallel case, an ascii representation of the mpi rank of the process
+ * will be appended to the file name to yield a unique trace file name for each process.</p><p>The length of
+ * the path must not exceed #H5AC__MAX_TRACE_FILE_NAME_LEN characters.</p><p>The trace file feature is
+ * unsupported unless used at the direction of The HDF Group. It is intended to allow The HDF Group
+ * to collect a trace of cache activity in cases of occult failures and/or poor performance seen in the field,
+ * so as to aid in reproduction in the lab. If you use it absent the direction of The HDF Group, you are on
+ * your own.</p></td>
* </tr>
* <tr>
* <td><em>hbool_t</em> <code>evictions_enabled</code></td>
* <td>IN: A boolean flag indicating whether evictions from the metadata cache are enabled. This flag is
- * initially set to enabled (<code>1</code>).<p>In rare circumstances, the raw data throughput requirements
- * may be so high that the user wishes to postpone metadata writes so as to reserve I/O throughput for raw
- * data. The <code>evictions_enabled</code> field exists to allow this. However, this is an extreme step, and
- * you have no business doing it unless you have read the User Guide section on metadata caching, and have
- * considered all other options carefully.</p><p>The <code>evictions_enabled</code> field may not be set to
- * disabled (<code>0</code>) unless all adaptive cache resizing code is disabled via
- * the <code>incr_mode</code>, <code>flash_incr_mode</code>, and <code>decr_mode</code> fields.</p><p>When
- * this flag is set to disabled (<code>0</code>), the metadata cache will not attempt to evict entries to make
- * space for new entries, and thus will grow without bound.</p><p>Evictions will be re-enabled when this field
- * is set back to <code>1</code>. This should be done as soon as
- * possible.</p></td>
+ * initially set to enabled (<code>1</code>).<p>In rare circumstances, the raw data throughput
+ * requirements may be so high that the user wishes to postpone metadata writes so as to reserve I/O
+ * throughput for raw data. The <code>evictions_enabled</code> field exists to allow this. However, this is an
+ * extreme step, and you have no business doing it unless you have read the User Guide section on metadata
+ * caching, and have considered all other options carefully.</p><p>The <code>evictions_enabled</code> field
+ * may not be set to disabled (<code>0</code>) unless all adaptive cache resizing code is disabled via the
+ * <code>incr_mode</code>, <code>flash_incr_mode</code>, and <code>decr_mode</code> fields.</p><p>When this
+ * flag is set to disabled (<code>0</code>), the metadata cache will not attempt to evict entries to make
+ * space for new entries, and thus will grow without bound.</p><p>Evictions will be re-enabled when
+ * this field is set back to <code>1</code>. This should be done as soon as possible.</p></td>
* </tr>
* <tr>
* <td><em>hbool_t</em> <code>set_initial_size</code></td>
@@ -1242,24 +1250,24 @@ H5_DLL herr_t H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr);
* <tr>
* <td><em>size_t</em> <code>initial_size</code></td>
* <td>IN: If <code>set_initial_size</code> is set to <code>1</code>, then <code>initial_size</code> must
- * contain the desired initial size in bytes. This value must lie in the closed interval <code>[min_size,
- * max_size]</code>. (see below)</td>
+ * contain the desired initial size in bytes. This value must lie in the closed interval
+ * <code>[min_size, max_size]</code>. (see below)</td>
* </tr>
* <tr><td><em>double</em> <code>min_clean_fraction</code></td>
* <td>IN: This field specifies the minimum fraction of the cache that must be kept either clean or
- * empty.<p>The value must lie in the interval [0.0, 1.0]. 0.01 is a good place to start in the serial case.
- * In the parallel case, a larger value is needed --
- * see <a href="/display/HDF5/Metadata+Caching+in+HDF5">Metadata Caching in HDF5</a> in the collection
- * "Advanced Topics in HDF5."</p></td>
+ * empty.<p>The value must lie in the interval [0.0, 1.0]. 0.01 is a good place to start in the serial
+ * case. In the parallel case, a larger value is needed -- see <a
+ * href="/display/HDF5/Metadata+Caching+in+HDF5">Metadata Caching in HDF5</a> in the collection "Advanced
+ * Topics in HDF5."</p></td>
* </tr>
* <tr><td><em>size_t</em> <code>max_size</code></td>
- * <td>IN: Upper bound (in bytes) on the range of values that the adaptive cache resize code can select as
- * the maximum cache size.</td>
+ * <td>IN: Upper bound (in bytes) on the range of values that the adaptive cache resize code can select
+ * as the maximum cache size.</td>
* </tr>
* <tr>
* <td><em>size_t</em> <code>min_size</code></td>
- * <td>IN: Lower bound (in bytes) on the range of values that the adaptive cache resize code can select as
- * the maximum cache size.</td>
+ * <td>IN: Lower bound (in bytes) on the range of values that the adaptive cache resize code can select
+ * as the maximum cache size.</td>
* </tr>
* <tr><td><em>long int</em> <code>epoch_length</code></td>
* <td>IN: Number of cache accesses between runs of the adaptive cache resize code. 50,000 is a good
@@ -1272,27 +1280,25 @@ H5_DLL herr_t H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr);
* <tr>
* <td><em>enum H5C_cache_incr_mode</em> <code>incr_mode</code></td>
* <td>IN: Enumerated value indicating the operational mode of the automatic cache size increase code. At
- * present, only two values are legal:<p>\c H5C_incr__off: Automatic cache size increase is disabled, and the
- * remaining increment fields are ignored.</p><p>\c H5C_incr__threshold: Automatic cache size increase is enabled
- * using the hit rate threshold
- * algorithm.</p></td>
+ * present, only two values are legal:<p>\c H5C_incr__off: Automatic cache size increase is disabled,
+ * and the remaining increment fields are ignored.</p><p>\c H5C_incr__threshold: Automatic cache size increase
+ * is enabled using the hit rate threshold algorithm.</p></td>
* </tr>
* <tr>
* <td><em>double</em> <code>lower_hr_threshold</code></td>
* <td>IN: Hit rate threshold used by the hit rate threshold cache size increment algorithm.<p>When the
- * hit rate over an epoch is below this threshold and the cache is full, the maximum size of the cache is
- * multiplied by increment (below), and then clipped as necessary to stay within max_size, and possibly
- * max_increment.</p><p>This field must lie in the interval [0.0, 1.0]. 0.8 or 0.9 is a good starting
+ * hit rate over an epoch is below this threshold and the cache is full, the maximum size of the
+ * cache is multiplied by increment (below), and then clipped as necessary to stay within max_size, and
+ * possibly max_increment.</p><p>This field must lie in the interval [0.0, 1.0]. 0.8 or 0.9 is a good starting
* point.</p></td>
* </tr>
* <tr>
* <td><em>double</em> <code>increment</code></td>
* <td>IN: Factor by which the hit rate threshold cache size increment algorithm multiplies the current
- * maximum cache size to obtain a tentative new cache size.<p>The actual cache size increase will be clipped
- * to satisfy the max_size specified in the general configuration, and possibly max_increment below.</p><p>The
- * parameter must be greater than or equal to 1.0 -- 2.0 is a reasonable value.</p><p>If you set it to 1.0,
- * you will effectively disable cache size
- * increases.</p></td>
+ * maximum cache size to obtain a tentative new cache size.<p>The actual cache size increase will be
+ * clipped to satisfy the max_size specified in the general configuration, and possibly max_increment
+ * below.</p><p>The parameter must be greater than or equal to 1.0 -- 2.0 is a reasonable value.</p><p>If you
+ * set it to 1.0, you will effectively disable cache size increases.</p></td>
* </tr>
* <tr>
* <td><em>hbool_t</em> <code>apply_max_increment</code></td>
@@ -1308,21 +1314,21 @@ H5_DLL herr_t H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr);
* <td><em>enum H5C_cache_flash_incr_mode</em> <code>flash_incr_mode</code></td>
* <td>IN: Enumerated value indicating the operational mode of the flash cache size increase code. At
* present, only the following values are legal:<p>\c H5C_flash_incr__off: Flash cache size increase is
- * disabled.</p><p>\c H5C_flash_incr__add_space: Flash cache size increase is enabled using the add space
- * algorithm.</p></td>
+ * disabled.</p><p>\c H5C_flash_incr__add_space: Flash cache size increase is enabled using the add
+ * space algorithm.</p></td>
* </tr>
* <tr>
* <td><em>double</em> <code>flash_threshold</code></td>
* <td>IN: The factor by which the current maximum cache size is multiplied to obtain the minimum size
- * entry / entry size increase which may trigger a flash cache size increase.<p>At present, this value must
- * lie in the range [0.1, 1.0].</p></td>
+ * entry / entry size increase which may trigger a flash cache size increase.<p>At present, this value
+ * must lie in the range [0.1, 1.0].</p></td>
* </tr>
* <tr>
* <td><em>double</em> <code>flash_multiple</code></td>
* <td>IN: The factor by which the size of the triggering entry / entry size increase is multiplied to
- * obtain the initial cache size increment. This increment may be reduced to reflect existing free space in
- * the cache and the <code>max_size</code> field above.<p>At present, this field must lie in the range [0.1,
- * 10.0].</p></td>
+ * obtain the initial cache size increment. This increment may be reduced to reflect existing free
+ * space in the cache and the <code>max_size</code> field above.<p>At present, this field must lie in the
+ * range [0.1, 10.0].</p></td>
* </tr>
* </table>
*
@@ -1332,31 +1338,29 @@ H5_DLL herr_t H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr);
* <td><em>enum H5C_cache_decr_mode</em> <code>decr_mode</code></td>
* <td>IN: Enumerated value indicating the operational mode of the automatic cache size decrease code. At
* present, the following values are legal:<p>\c H5C_decr__off: Automatic cache size decrease is
- * disabled.</p><p>\c H5C_decr__threshold: Automatic cache size decrease is enabled using the hit rate threshold
- * algorithm.</p><p>\c H5C_decr__age_out: Automatic cache size decrease is enabled using the ageout
- * algorithm.</p><p>\c H5C_decr__age_out_with_threshold: Automatic cache size decrease is enabled using the
- * ageout with hit rate threshold
- * algorithm</p></td>
+ * disabled.</p><p>\c H5C_decr__threshold: Automatic cache size decrease is enabled using the hit
+ * rate threshold algorithm.</p><p>\c H5C_decr__age_out: Automatic cache size decrease is enabled using the
+ * ageout algorithm.</p><p>\c H5C_decr__age_out_with_threshold: Automatic cache size decrease is enabled using
+ * the ageout with hit rate threshold algorithm</p></td>
* </tr>
* <tr>
* <td><em>double</em> <code>upper_hr_threshold</code></td>
* <td>IN: Hit rate threshold for the hit rate threshold and ageout with hit rate threshold cache size
- * decrement algorithms.<p>When \c decr_mode is \c H5C_decr__threshold, and the hit rate over a given epoch exceeds
- * the supplied threshold, the current maximum cache size is multiplied by decrement to obtain a tentative new
- * (and smaller) maximum cache size.</p><p>When \c decr_mode is \c H5C_decr__age_out_with_threshold, there is no
- * attempt to find and evict aged out entries unless the hit rate in the previous epoch exceeded the supplied
- * threshold.</p><p>This field must lie in the interval [0.0, 1.0].</p><p>For \c H5C_incr__threshold, .9995 or
- * .99995 is a good place to start.</p><p>For \c H5C_decr__age_out_with_threshold, .999 might be more
- * useful.</p></td>
+ * decrement algorithms.<p>When \c decr_mode is \c H5C_decr__threshold, and the hit rate over a given
+ * epoch exceeds the supplied threshold, the current maximum cache size is multiplied by decrement to obtain a
+ * tentative new (and smaller) maximum cache size.</p><p>When \c decr_mode is \c
+ * H5C_decr__age_out_with_threshold, there is no attempt to find and evict aged out entries unless the hit
+ * rate in the previous epoch exceeded the supplied threshold.</p><p>This field must lie in the interval
+ * [0.0, 1.0].</p><p>For \c H5C_incr__threshold, .9995 or .99995 is a good place to start.</p><p>For \c
+ * H5C_decr__age_out_with_threshold, .999 might be more useful.</p></td>
* </tr>
* <tr>
* <td><em>double</em> <code>decrement</code></td>
* <td>IN: In the hit rate threshold cache size decrease algorithm, this parameter contains the factor by
- * which the current max cache size is multiplied to produce a tentative new cache size.<p>The actual cache
- * size decrease will be clipped to satisfy the min_size specified in the general configuration, and possibly
- * max_decrement below.</p><p>The parameter must be be in the interval [0.0, 1.0].</p><p>If you set it to 1.0,
- * you will effectively disable cache size decreases. 0.9 is a reasonable starting
- * point.</p></td>
+ * which the current max cache size is multiplied to produce a tentative new cache size.<p>The actual
+ * cache size decrease will be clipped to satisfy the min_size specified in the general configuration, and
+ * possibly max_decrement below.</p><p>The parameter must be be in the interval [0.0, 1.0].</p><p>If you set
+ * it to 1.0, you will effectively disable cache size decreases. 0.9 is a reasonable starting point.</p></td>
* </tr>
* <tr>
* <td><em>hbool_t</em> <code>apply_max_decrement</code></td>
@@ -1371,8 +1375,8 @@ H5_DLL herr_t H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr);
* <tr>
* <td><em>int</em> <code>epochs_before_eviction</code></td>
* <td>IN: In the ageout based cache size reduction algorithms, this field contains the minimum number of
- * epochs an entry must remain unaccessed in cache before the cache size reduction algorithm tries to evict
- * it. 3 is a reasonable value.</td>
+ * epochs an entry must remain unaccessed in cache before the cache size reduction algorithm tries to
+ * evict it. 3 is a reasonable value.</td>
* </tr>
* <tr>
* <td><em>hbool_t</em> <code>apply_empty_reserve</code></td>
@@ -1381,9 +1385,9 @@ H5_DLL herr_t H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr);
* </tr>
* <tr>
* <td><em>double</em> <code>empty_reserve</code></td>
- * <td>IN: Empty reserve as a fraction of maximum cache size if applicable.<p>When so directed, the ageout
- * based algorithms will not decrease the maximum cache size unless the empty reserve can be met.</p><p>The
- * parameter must lie in the interval [0.0, 1.0]. 0.1 or 0.05 is a good place to
+ * <td>IN: Empty reserve as a fraction of maximum cache size if applicable.<p>When so directed, the
+ * ageout based algorithms will not decrease the maximum cache size unless the empty reserve can be
+ * met.</p><p>The parameter must lie in the interval [0.0, 1.0]. 0.1 or 0.05 is a good place to
* start.</p></td>
* </tr>
* </table>
@@ -1393,11 +1397,11 @@ H5_DLL herr_t H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr);
* <tr>
* <td><em>int</em> <code>dirty_bytes_threshold</code></td>
* <td>IN: Threshold number of bytes of dirty metadata generation for triggering synchronizations of the
- * metadata caches serving the target file in the parallel case.<p>Synchronization occurs whenever the number
- * of bytes of dirty metadata created since the last synchronization exceeds this limit.</p><p>This field only
- * applies to the parallel case. While it is ignored elsewhere, it can still draw a value out of bounds
- * error.</p><p>It must be consistant across all caches on any given file.</p><p>By default, this field is set
- * to 256 KB. It shouldn't be more than half the current maximum cache size times the minimum clean
+ * metadata caches serving the target file in the parallel case.<p>Synchronization occurs whenever the
+ * number of bytes of dirty metadata created since the last synchronization exceeds this limit.</p><p>This
+ * field only applies to the parallel case. While it is ignored elsewhere, it can still draw a value out of
+ * bounds error.</p><p>It must be consistant across all caches on any given file.</p><p>By default, this field
+ * is set to 256 KB. It shouldn't be more than half the current maximum cache size times the minimum clean
* fraction.</p></td>
* </tr>
* </table>
@@ -1640,7 +1644,8 @@ H5_DLL herr_t H5Fget_info2(hid_t obj_id, H5F_info2_t *file_info);
* <tr><td>18</td><td>Fixed array data block</td></tr>
* <tr><td>19</td><td>Fixed array data block page</td></tr>
* <tr><td>20</td><td>File's superblock (version 2)</td></tr>
- * <tr><td colspan=2><sup>*</sup> All entries are of version 0 (zero) unless indicated otherwise.</td></tr>
+ * <tr><td colspan=2><sup>*</sup> All entries are of version 0 (zero) unless indicated
+ * otherwise.</td></tr>
* </table>
*
* \note On a system that is not atomic, the library might possibly read inconsistent
@@ -1927,8 +1932,7 @@ H5_DLL herr_t H5Fstop_mdc_logging(hid_t file_id);
*
* \since 1.10.0
*/
-H5_DLL herr_t H5Fget_mdc_logging_status(hid_t file_id, hbool_t *is_enabled,
- hbool_t *is_currently_logging);
+H5_DLL herr_t H5Fget_mdc_logging_status(hid_t file_id, hbool_t *is_enabled, hbool_t *is_currently_logging);
/**
* \ingroup SWMR
*
@@ -2065,6 +2069,7 @@ H5_DLL herr_t H5Fget_dset_no_attrs_hint(hid_t file_id, hbool_t *minimize);
*
*/
H5_DLL herr_t H5Fset_dset_no_attrs_hint(hid_t file_id, hbool_t minimize);
+H5_DLL herr_t H5Fwait(hid_t file_id);
#ifdef H5_HAVE_PARALLEL
/**
@@ -2159,6 +2164,26 @@ H5_DLL herr_t H5Fset_mpi_atomicity(hid_t file_id, hbool_t flag);
H5_DLL herr_t H5Fget_mpi_atomicity(hid_t file_id, hbool_t *flag);
#endif /* H5_HAVE_PARALLEL */
+/* API Wrappers for async routines */
+/* (Must be defined _after_ the function prototype) */
+/* (And must only defined when included in application code, not the library) */
+#ifndef H5F_MODULE
+#define H5Fcreate_async(...) H5Fcreate_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Fopen_async(...) H5Fopen_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Freopen_async(...) H5Freopen_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Fflush_async(...) H5Fflush_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Fclose_async(...) H5Fclose_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+
+/* Define "wrapper" versions of function calls, to allow compile-time values to
+ * be passed in by language wrapper or library layer on top of HDF5.
+ */
+#define H5Fcreate_async_wrap H5_NO_EXPAND(H5Fcreate_async)
+#define H5Fopen_async_wrap H5_NO_EXPAND(H5Fopen_async)
+#define H5Freopen_async_wrap H5_NO_EXPAND(H5Freopen_async)
+#define H5Fflush_async_wrap H5_NO_EXPAND(H5Fflush_async)
+#define H5Fclose_async_wrap H5_NO_EXPAND(H5Fclose_async)
+#endif /* H5F_MODULE */
+
/* Symbols defined for compatibility with previous versions of the HDF5 API.
*
* Use of these symbols is deprecated.
diff --git a/src/H5G.c b/src/H5G.c
index 7d8ed39..c59194d 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -83,6 +83,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5CXprivate.h" /* API Contexts */
#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event Sets */
#include "H5Gpkg.h" /* Groups */
#include "H5Iprivate.h" /* IDs */
#include "H5Pprivate.h" /* Property lists */
@@ -104,6 +105,20 @@
/* Local Prototypes */
/********************/
+/* Helper routines for sync/async API calls */
+static hid_t H5G__create_api_common(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id,
+ hid_t gapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr);
+static hid_t H5G__open_api_common(hid_t loc_id, const char *name, hid_t gapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static herr_t H5G__get_info_api_common(hid_t loc_id, H5G_info_t *group_info /*out*/, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static herr_t H5G__get_info_by_name_api_common(hid_t loc_id, const char *name, H5G_info_t *group_info /*out*/,
+ hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr);
+static herr_t H5G__get_info_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t idx_type,
+ H5_iter_order_t order, hsize_t n,
+ H5G_info_t *group_info /*out*/, hid_t lapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+
/*********************/
/* Package Variables */
/*********************/
@@ -117,38 +132,27 @@
/*******************/
/*-------------------------------------------------------------------------
- * Function: H5Gcreate2
- *
- * Purpose: Creates a new group relative to LOC_ID, giving it the
- * specified creation property list GCPL_ID and access
- * property list GAPL_ID. The link to the new group is
- * created with the LCPL_ID.
- *
- * Usage: H5Gcreate2(loc_id, char *name, lcpl_id, gcpl_id, gapl_id)
- * hid_t loc_id; IN: File or group identifier
- * const char *name; IN: Absolute or relative name of the new group
- * hid_t lcpl_id; IN: Property list for link creation
- * hid_t gcpl_id; IN: Property list for group creation
- * hid_t gapl_id; IN: Property list for group access
+ * Function: H5G__create_api_common
*
- * Return: Success: The object ID of a new, empty group open for
- * writing. Call H5Gclose() when finished with
- * the group.
+ * Purpose: This is the common function for creating HDF5 groups.
*
+ * Return: Success: A group ID
* Failure: H5I_INVALID_HID
*
*-------------------------------------------------------------------------
*/
-hid_t
-H5Gcreate2(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id)
+static hid_t
+H5G__create_api_common(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id,
+ void **token_ptr, H5VL_object_t **_vol_obj_ptr)
{
- void * grp = NULL; /* Structure for new group */
- H5VL_object_t * vol_obj = NULL; /* object of loc_id */
- H5VL_loc_params_t loc_params;
- hid_t ret_value = H5I_INVALID_HID; /* Return value */
+ void * grp = NULL; /* Structure for new group */
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
- FUNC_ENTER_API(H5I_INVALID_HID)
- H5TRACE5("i", "i*siii", loc_id, name, lcpl_id, gcpl_id, gapl_id);
+ FUNC_ENTER_STATIC
/* Check arguments */
if (!name)
@@ -156,6 +160,10 @@ H5Gcreate2(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t g
if (!*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string")
+ /* Set up object access arguments */
+ if (H5VL_setup_acc_args(loc_id, H5P_CLS_GACC, TRUE, &gapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")
+
/* Check link creation property list */
if (H5P_DEFAULT == lcpl_id)
lcpl_id = H5P_LINK_CREATE_DEFAULT;
@@ -171,36 +179,109 @@ H5Gcreate2(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t g
/* Set the LCPL for the API context */
H5CX_set_lcpl(lcpl_id);
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&gapl_id, H5P_CLS_GACC, loc_id, TRUE) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
-
- /* Get the location object */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
-
- /* Set the location parameters */
- loc_params.type = H5VL_OBJECT_BY_SELF;
- loc_params.obj_type = H5I_get_type(loc_id);
-
/* Create the group */
- if (NULL == (grp = H5VL_group_create(vol_obj, &loc_params, name, lcpl_id, gcpl_id, gapl_id,
- H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)))
+ if (NULL == (grp = H5VL_group_create(*vol_obj_ptr, &loc_params, name, lcpl_id, gcpl_id, gapl_id,
+ H5P_DATASET_XFER_DEFAULT, token_ptr)))
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5I_INVALID_HID, "unable to create group")
/* Get an ID for the group */
- if ((ret_value = H5VL_register(H5I_GROUP, grp, vol_obj->connector, TRUE)) < 0)
+ if ((ret_value = H5VL_register(H5I_GROUP, grp, (*vol_obj_ptr)->connector, TRUE)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to get ID for group handle")
done:
if (H5I_INVALID_HID == ret_value)
- if (grp && H5VL_group_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
+ if (grp && H5VL_group_close(*vol_obj_ptr, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release group")
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G__create_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Gcreate2
+ *
+ * Purpose: Creates a new group relative to LOC_ID, giving it the
+ * specified creation property list GCPL_ID and access
+ * property list GAPL_ID. The link to the new group is
+ * created with the LCPL_ID.
+ *
+ * Usage: H5Gcreate2(loc_id, char *name, lcpl_id, gcpl_id, gapl_id)
+ * hid_t loc_id; IN: File or group identifier
+ * const char *name; IN: Absolute or relative name of the new group
+ * hid_t lcpl_id; IN: Property list for link creation
+ * hid_t gcpl_id; IN: Property list for group creation
+ * hid_t gapl_id; IN: Property list for group access
+ *
+ * Return: Success: The object ID of a new, empty group open for
+ * writing. Call H5Gclose() when finished with
+ * the group.
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Gcreate2(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id)
+{
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE5("i", "i*siii", loc_id, name, lcpl_id, gcpl_id, gapl_id);
+
+ /* Create the group synchronously */
+ if ((ret_value = H5G__create_api_common(loc_id, name, lcpl_id, gcpl_id, gapl_id, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously create group")
+
+done:
FUNC_LEAVE_API(ret_value)
} /* end H5Gcreate2() */
/*-------------------------------------------------------------------------
+ * Function: H5Gcreate_async
+ *
+ * Purpose: Asynchronous version of H5Gcreate
+ *
+ * Return: Success: A group ID
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Gcreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name,
+ hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE9("i", "*s*sIui*siiii", app_file, app_func, app_line, loc_id, name, lcpl_id, gcpl_id, gapl_id,
+ es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Create the group asynchronously */
+ if ((ret_value = H5G__create_api_common(loc_id, name, lcpl_id, gcpl_id, gapl_id, token_ptr, &vol_obj)) <
+ 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously create group")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE9(FUNC, "*s*sIui*siiii", app_file, app_func, app_line, loc_id, name,
+ lcpl_id, gcpl_id, gapl_id, es_id)) < 0) {
+ if (H5I_dec_app_ref_always_close(ret_value) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on group ID")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gcreate_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5Gcreate_anon
*
* Purpose: Creates a new group relative to LOC_ID, giving it the
@@ -280,30 +361,27 @@ done:
} /* end H5Gcreate_anon() */
/*-------------------------------------------------------------------------
- * Function: H5Gopen2
+ * Function: H5G__open_api_common
*
- * Purpose: Opens an existing group for modification. When finished,
- * call H5Gclose() to close it and release resources.
- *
- * This function allows the user the pass in a Group Access
- * Property List, which H5Gopen1() does not.
- *
- * Return: Success: Object ID of the group
+ * Purpose: This is the common function for opening HDF5 groups.
*
+ * Return: Success: A group ID
* Failure: H5I_INVALID_HID
*
*-------------------------------------------------------------------------
*/
-hid_t
-H5Gopen2(hid_t loc_id, const char *name, hid_t gapl_id)
+static hid_t
+H5G__open_api_common(hid_t loc_id, const char *name, hid_t gapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
{
- void * grp = NULL; /* Group opened */
- H5VL_object_t * vol_obj = NULL; /* object of loc_id */
- H5VL_loc_params_t loc_params;
- hid_t ret_value = H5I_INVALID_HID; /* Return value */
+ void * grp = NULL; /* Group opened */
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
- FUNC_ENTER_API(H5I_INVALID_HID)
- H5TRACE3("i", "i*si", loc_id, name, gapl_id);
+ FUNC_ENTER_STATIC
/* Check args */
if (!name)
@@ -311,35 +389,102 @@ H5Gopen2(hid_t loc_id, const char *name, hid_t gapl_id)
if (!*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string")
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&gapl_id, H5P_CLS_GACC, loc_id, FALSE) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
-
- /* Get the location object */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
+ /* Set up object access arguments */
+ if (H5VL_setup_acc_args(loc_id, H5P_CLS_GACC, FALSE, &gapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")
- /* Open the group */
- loc_params.type = H5VL_OBJECT_BY_SELF;
- loc_params.obj_type = H5I_get_type(loc_id);
-
- if (NULL == (grp = H5VL_group_open(vol_obj, &loc_params, name, gapl_id, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL)))
+ if (NULL == (grp = H5VL_group_open(*vol_obj_ptr, &loc_params, name, gapl_id, H5P_DATASET_XFER_DEFAULT,
+ token_ptr)))
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open group")
/* Register an ID for the group */
- if ((ret_value = H5VL_register(H5I_GROUP, grp, vol_obj->connector, TRUE)) < 0)
+ if ((ret_value = H5VL_register(H5I_GROUP, grp, (*vol_obj_ptr)->connector, TRUE)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register group")
done:
if (H5I_INVALID_HID == ret_value)
- if (grp && H5VL_group_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
+ if (grp && H5VL_group_close(*vol_obj_ptr, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release group")
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5G__open_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Gopen2
+ *
+ * Purpose: Opens an existing group for modification. When finished,
+ * call H5Gclose() to close it and release resources.
+ *
+ * This function allows the user the pass in a Group Access
+ * Property List, which H5Gopen1() does not.
+ *
+ * Return: Success: Object ID of the group
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Gopen2(hid_t loc_id, const char *name, hid_t gapl_id)
+{
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE3("i", "i*si", loc_id, name, gapl_id);
+
+ /* Open the group synchronously */
+ if ((ret_value = H5G__open_api_common(loc_id, name, gapl_id, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously open group")
+
+done:
FUNC_LEAVE_API(ret_value)
} /* end H5Gopen2() */
/*-------------------------------------------------------------------------
+ * Function: H5Gopen_async
+ *
+ * Purpose: Asynchronous version of H5Gopen2
+ *
+ * Return: Success: A group ID
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Gopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name,
+ hid_t gapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE7("i", "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, gapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Open the group asynchronously */
+ if ((ret_value = H5G__open_api_common(loc_id, name, gapl_id, token_ptr, &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously open group")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE7(FUNC, "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, gapl_id,
+ es_id)) < 0) {
+ if (H5I_dec_app_ref_always_close(ret_value) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on group ID")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gopen_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5Gget_create_plist
*
* Purpose: Returns a copy of the group creation property list.
@@ -375,6 +520,49 @@ done:
} /* end H5Gget_create_plist() */
/*-------------------------------------------------------------------------
+ * Function: H5G__get_info_api_common
+ *
+ * Purpose: This is the common function for retrieving information
+ * about a group.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G__get_info_api_common(hid_t loc_id, H5G_info_t *group_info /*out*/, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ H5I_type_t id_type; /* Type of ID */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check args */
+ id_type = H5I_get_type(loc_id);
+ if (!(H5I_GROUP == id_type || H5I_FILE == id_type))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid group (or file) ID")
+ if (!group_info)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_info parameter cannot be NULL")
+
+ /* Set up object access arguments */
+ if (H5VL_setup_self_args(loc_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set object access arguments")
+
+ /* Retrieve group information */
+ if (H5VL_group_get(*vol_obj_ptr, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params,
+ group_info) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get group info")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5G__get_info_api_common() */
+
+/*-------------------------------------------------------------------------
* Function: H5Gget_info
*
* Purpose: Retrieve information about a group.
@@ -386,35 +574,97 @@ done:
herr_t
H5Gget_info(hid_t loc_id, H5G_info_t *group_info /*out*/)
{
- H5VL_object_t * vol_obj;
- H5I_type_t id_type; /* Type of ID */
- H5VL_loc_params_t loc_params;
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE2("e", "ix", loc_id, group_info);
+ /* Retrieve group information synchronously */
+ if (H5G__get_info_api_common(loc_id, group_info, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to synchronously get group info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gget_info() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Gget_info_async
+ *
+ * Purpose: Asynchronous version of H5Gget_info
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Gget_info_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ H5G_info_t *group_info /*out*/, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "*s*sIuixi", app_file, app_func, app_line, loc_id, group_info, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Retrieve group information asynchronously */
+ if (H5G__get_info_api_common(loc_id, group_info, token_ptr, &vol_obj) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to asynchronously get group info")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(
+ es_id, vol_obj->connector, token,
+ H5ARG_TRACE6(FUNC, "*s*sIuixi", app_file, app_func, app_line, loc_id, group_info, es_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Gget_info_async() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5G__get_info_by_name_api_common
+ *
+ * Purpose: This is the common function for retrieving information
+ * about a group.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G__get_info_by_name_api_common(hid_t loc_id, const char *name, H5G_info_t *group_info /*out*/,
+ hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
/* Check args */
- id_type = H5I_get_type(loc_id);
- if (!(H5I_GROUP == id_type || H5I_FILE == id_type))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid group (or file) ID")
if (!group_info)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_info parameter cannot be NULL")
- /* Get group location */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+ /* Set up object access arguments */
+ if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set object access arguments")
- /* Retrieve the group's information */
- loc_params.type = H5VL_OBJECT_BY_SELF;
- loc_params.obj_type = id_type;
- if (H5VL_group_get(vol_obj, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params,
+ /* Retrieve group information */
+ if (H5VL_group_get(*vol_obj_ptr, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params,
group_info) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get group info")
done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Gget_info() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5G__get_info_by_name_api_common() */
/*-------------------------------------------------------------------------
* Function: H5Gget_info_by_name
@@ -429,43 +679,99 @@ done:
herr_t
H5Gget_info_by_name(hid_t loc_id, const char *name, H5G_info_t *group_info /*out*/, hid_t lapl_id)
{
- H5VL_object_t * vol_obj;
- H5VL_loc_params_t loc_params;
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE4("e", "i*sxi", loc_id, name, group_info, lapl_id);
+ /* Retrieve group information synchronously */
+ if (H5G__get_info_by_name_api_common(loc_id, name, group_info, lapl_id, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't synchronously retrieve group info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gget_info_by_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Gget_info_by_name_async
+ *
+ * Purpose: Asynchronous version of H5Gget_info_by_name
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Gget_info_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *name, H5G_info_t *group_info /*out*/, hid_t lapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE8("e", "*s*sIui*sxii", app_file, app_func, app_line, loc_id, name, group_info, lapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Retrieve group information asynchronously */
+ if (H5G__get_info_by_name_api_common(loc_id, name, group_info, lapl_id, token_ptr, &vol_obj) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't asynchronously retrieve group info")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE8(FUNC, "*s*sIui*sxii", app_file, app_func, app_line, loc_id, name,
+ group_info, lapl_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Gget_info_by_name_async() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5G__get_info_by_idx_api_common
+ *
+ * Purpose: This is the common function for retrieving information
+ * about a group.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G__get_info_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t idx_type,
+ H5_iter_order_t order, hsize_t n, H5G_info_t *group_info /*out*/,
+ hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
/* Check args */
- if (!name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be NULL")
- if (!*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be an empty string")
if (!group_info)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_info parameter cannot be NULL")
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set access property list info")
-
- /* Get the location object */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
-
- /* Set up location parameters */
- loc_params.type = H5VL_OBJECT_BY_NAME;
- loc_params.loc_data.loc_by_name.name = name;
- loc_params.loc_data.loc_by_name.lapl_id = lapl_id;
- loc_params.obj_type = H5I_get_type(loc_id);
+ /* Set up object access arguments */
+ if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr,
+ &loc_params) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set object access arguments")
- /* Retrieve the group's information */
- if (H5VL_group_get(vol_obj, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params,
+ /* Retrieve group information */
+ if (H5VL_group_get(*vol_obj_ptr, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params,
group_info) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get group info")
done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Gget_info_by_name() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5G__get_info_by_idx_api_common() */
/*-------------------------------------------------------------------------
* Function: H5Gget_info_by_idx
@@ -481,50 +787,62 @@ herr_t
H5Gget_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order,
hsize_t n, H5G_info_t *group_info /*out*/, hid_t lapl_id)
{
- H5VL_object_t * vol_obj;
- H5VL_loc_params_t loc_params;
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE7("e", "i*sIiIohxi", loc_id, group_name, idx_type, order, n, group_info, lapl_id);
- /* Check args */
- if (!group_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_name parameter cannot be NULL")
- if (!*group_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_name parameter cannot be an empty string")
- if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
- if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
- if (!group_info)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_info parameter cannot be NULL")
+ /* Retrieve group information synchronously */
+ if (H5G__get_info_by_idx_api_common(loc_id, group_name, idx_type, order, n, group_info, lapl_id, NULL,
+ NULL) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't synchronously retrieve group info")
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set access property list info")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gget_info_by_idx() */
- /* Get the location object */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
-
- /* Set location parameters */
- loc_params.type = H5VL_OBJECT_BY_IDX;
- loc_params.loc_data.loc_by_idx.name = group_name;
- loc_params.loc_data.loc_by_idx.idx_type = idx_type;
- loc_params.loc_data.loc_by_idx.order = order;
- loc_params.loc_data.loc_by_idx.n = n;
- loc_params.loc_data.loc_by_idx.lapl_id = lapl_id;
- loc_params.obj_type = H5I_get_type(loc_id);
-
- /* Retrieve the group's information */
- if (H5VL_group_get(vol_obj, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params,
- group_info) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info")
+/*-------------------------------------------------------------------------
+ * Function: H5Gget_info_by_idx_async
+ *
+ * Purpose: Asynchronous version of H5Gget_info_by_idx
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Gget_info_by_idx_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
+ H5G_info_t *group_info /*out*/, hid_t lapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE11("e", "*s*sIui*sIiIohxii", app_file, app_func, app_line, loc_id, group_name, idx_type, order, n,
+ group_info, lapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Retrieve group information asynchronously */
+ if (H5G__get_info_by_idx_api_common(loc_id, group_name, idx_type, order, n, group_info, lapl_id,
+ token_ptr, &vol_obj) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't asynchronously retrieve group info")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE11(FUNC, "*s*sIui*sIiIohxii", app_file, app_func, app_line, loc_id,
+ group_name, idx_type, order, n, group_info, lapl_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert token into event set")
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Gget_info_by_idx() */
+} /* H5Gget_info_by_idx_async() */
/*-------------------------------------------------------------------------
* Function: H5Gclose
@@ -559,6 +877,65 @@ done:
} /* end H5Gclose() */
/*-------------------------------------------------------------------------
+ * Function: H5Gclose_async
+ *
+ * Purpose: Asynchronous version of H5Gclose
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Gclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t group_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ H5VL_t * connector = NULL; /* VOL connector */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, group_id, es_id);
+
+ /* Check arguments */
+ if (H5I_GROUP != H5I_get_type(group_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group ID")
+
+ /* Prepare for possible asynchronous operation */
+ if (H5ES_NONE != es_id) {
+ /* Get group object's connector */
+ if (NULL == (vol_obj = H5VL_vol_object(group_id)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get VOL object for group")
+
+ /* Increase connector's refcount, so it doesn't get closed if closing
+ * the group closes the file */
+ connector = vol_obj->connector;
+ H5VL_conn_inc_rc(connector);
+
+ /* Point at token for operation to set up */
+ token_ptr = &token;
+ } /* end if */
+
+ /* Decrement the counter on the group ID. It will be freed if the count
+ * reaches zero.
+ */
+ if (H5I_dec_app_ref_async(group_id, token_ptr) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "decrementing group ID failed")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, group_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ if (connector && H5VL_conn_dec_rc(connector) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "can't decrement ref count on connector")
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gclose_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5Gflush
*
* Purpose: Flushes all buffers associated with a group to disk.
diff --git a/src/H5Gcompact.c b/src/H5Gcompact.c
index c2bbd7c..bca6477 100644
--- a/src/H5Gcompact.c
+++ b/src/H5Gcompact.c
@@ -52,7 +52,7 @@ typedef struct {
/* upward */
H5O_link_t *lnk; /* Link struct to fill in */
- hbool_t found; /* Flag to indicate that the object was found */
+ hbool_t * found; /* Pointer to flag to indicate that the object was found */
} H5G_iter_lkp_t;
/* Private macros */
@@ -450,7 +450,7 @@ H5G__compact_lookup_cb(const void *_mesg, unsigned H5_ATTR_UNUSED idx, void *_ud
} /* end if */
/* Indicate that the correct link was found */
- udata->found = TRUE;
+ *udata->found = TRUE;
/* Stop iteration now */
HGOTO_DONE(H5_ITER_STOP)
@@ -472,23 +472,24 @@ done:
*
*-------------------------------------------------------------------------
*/
-htri_t
-H5G__compact_lookup(const H5O_loc_t *oloc, const char *name, H5O_link_t *lnk)
+herr_t
+H5G__compact_lookup(const H5O_loc_t *oloc, const char *name, hbool_t *found, H5O_link_t *lnk)
{
- H5G_iter_lkp_t udata; /* User data for iteration callback */
- H5O_mesg_operator_t op; /* Message operator */
- htri_t ret_value = FAIL; /* Return value */
+ H5G_iter_lkp_t udata; /* User data for iteration callback */
+ H5O_mesg_operator_t op; /* Message operator */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
/* check arguments */
- HDassert(lnk && oloc->file);
HDassert(name && *name);
+ HDassert(found);
+ HDassert(lnk && oloc->file);
/* Set up user data for iteration */
udata.name = name;
udata.lnk = lnk;
- udata.found = FALSE;
+ udata.found = found;
/* Iterate through the link messages, adding them to the table */
op.op_type = H5O_MESG_OP_APP;
@@ -496,9 +497,6 @@ H5G__compact_lookup(const H5O_loc_t *oloc, const char *name, H5O_link_t *lnk)
if (H5O_msg_iterate(oloc, H5O_LINK_ID, &op, &udata) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over link messages")
- /* Determine if we found the link we were looking for */
- ret_value = (htri_t)udata.found;
-
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G__compact_lookup() */
diff --git a/src/H5Gdense.c b/src/H5Gdense.c
index ddc9720..ce9c107 100644
--- a/src/H5Gdense.c
+++ b/src/H5Gdense.c
@@ -479,20 +479,20 @@ done:
*
* Purpose: Look up a link within a group that uses dense link storage
*
- * Return: Non-negative (TRUE/FALSE) on success/Negative on failure
+ * Return: SUCCEED/FAIL
*
* Programmer: Quincey Koziol
* Sep 11 2006
*
*-------------------------------------------------------------------------
*/
-htri_t
-H5G__dense_lookup(H5F_t *f, const H5O_linfo_t *linfo, const char *name, H5O_link_t *lnk)
+herr_t
+H5G__dense_lookup(H5F_t *f, const H5O_linfo_t *linfo, const char *name, hbool_t *found, H5O_link_t *lnk)
{
- H5G_bt2_ud_common_t udata; /* User data for v2 B-tree link lookup */
- H5HF_t * fheap = NULL; /* Fractal heap handle */
- H5B2_t * bt2_name = NULL; /* v2 B-tree handle for name index */
- htri_t ret_value = FAIL; /* Return value */
+ H5G_bt2_ud_common_t udata; /* User data for v2 B-tree link lookup */
+ H5HF_t * fheap = NULL; /* Fractal heap handle */
+ H5B2_t * bt2_name = NULL; /* v2 B-tree handle for name index */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
@@ -502,6 +502,7 @@ H5G__dense_lookup(H5F_t *f, const H5O_linfo_t *linfo, const char *name, H5O_link
HDassert(f);
HDassert(linfo);
HDassert(name && *name);
+ HDassert(found);
HDassert(lnk);
/* Open the fractal heap */
@@ -521,7 +522,7 @@ H5G__dense_lookup(H5F_t *f, const H5O_linfo_t *linfo, const char *name, H5O_link
udata.found_op_data = lnk;
/* Find & copy the named link in the 'name' index */
- if ((ret_value = H5B2_find(bt2_name, &udata, NULL, NULL)) < 0)
+ if (H5B2_find(bt2_name, &udata, found, NULL, NULL) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to locate link in name index")
done:
diff --git a/src/H5Gloc.c b/src/H5Gloc.c
index 267c762..73991c5 100644
--- a/src/H5Gloc.c
+++ b/src/H5Gloc.c
@@ -235,6 +235,9 @@ H5G_loc_real(void *obj, H5I_type_t type, H5G_loc_t *loc)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
"unable to get group location of a dataspace selection iterator")
+ case H5I_EVENTSET:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get group location of a event set")
+
case H5I_UNINIT:
case H5I_BADID:
case H5I_NTYPES:
diff --git a/src/H5Gname.c b/src/H5Gname.c
index 218b8d4..bf1d573 100644
--- a/src/H5Gname.c
+++ b/src/H5Gname.c
@@ -729,6 +729,7 @@ H5G__name_replace_cb(void *obj_ptr, hid_t obj_id, void *key)
case H5I_ERROR_MSG:
case H5I_ERROR_STACK:
case H5I_SPACE_SEL_ITER:
+ case H5I_EVENTSET:
case H5I_NTYPES:
default:
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unknown data object")
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index c66a174..150a3bf 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -75,7 +75,7 @@ static herr_t H5G__node_create(H5F_t *f, H5B_ins_t op, void *_lt_key, void *_
haddr_t *addr_p /*out*/);
static int H5G__node_cmp2(void *_lt_key, void *_udata, void *_rt_key);
static int H5G__node_cmp3(void *_lt_key, void *_udata, void *_rt_key);
-static htri_t H5G__node_found(H5F_t *f, haddr_t addr, const void *_lt_key, void *_udata);
+static herr_t H5G__node_found(H5F_t *f, haddr_t addr, const void *_lt_key, hbool_t *found, void *_udata);
static H5B_ins_t H5G__node_insert(H5F_t *f, haddr_t addr, void *_lt_key, hbool_t *lt_key_changed,
void *_md_key, void *_udata, void *_rt_key, hbool_t *rt_key_changed,
haddr_t *new_node_p /*out*/);
@@ -463,8 +463,7 @@ done:
* UDATA entry field to the symbol table.
*
* Return: Success: Non-negative (TRUE/FALSE) if found and data
- * returned through the UDATA pointer.
- *
+ * returned through the UDATA pointer, if *FOUND is true.
* Failure: Negative if not found.
*
* Programmer: Robb Matzke
@@ -472,15 +471,15 @@ done:
*
*-------------------------------------------------------------------------
*/
-static htri_t
-H5G__node_found(H5F_t *f, haddr_t addr, const void H5_ATTR_UNUSED *_lt_key, void *_udata)
+static herr_t
+H5G__node_found(H5F_t *f, haddr_t addr, const void H5_ATTR_UNUSED *_lt_key, hbool_t *found, void *_udata)
{
H5G_bt_lkp_t *udata = (H5G_bt_lkp_t *)_udata;
H5G_node_t * sn = NULL;
unsigned lt = 0, idx = 0, rt;
int cmp = 1;
const char * s;
- htri_t ret_value = TRUE; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
@@ -489,6 +488,7 @@ H5G__node_found(H5F_t *f, haddr_t addr, const void H5_ATTR_UNUSED *_lt_key, void
*/
HDassert(f);
HDassert(H5F_addr_defined(addr));
+ HDassert(found);
HDassert(udata && udata->common.heap);
/*
@@ -515,11 +515,15 @@ H5G__node_found(H5F_t *f, haddr_t addr, const void H5_ATTR_UNUSED *_lt_key, void
} /* end while */
if (cmp)
- HGOTO_DONE(FALSE)
+ *found = FALSE;
+ else {
+ /* Set the 'found it' flag */
+ *found = TRUE;
- /* Call user's callback operator */
- if ((udata->op)(&sn->entry[idx], udata->op_data) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "iterator callback failed")
+ /* Call user's callback operator */
+ if ((udata->op)(&sn->entry[idx], udata->op_data) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "iterator callback failed")
+ } /* end else */
done:
if (sn && H5AC_unprotect(f, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) < 0)
diff --git a/src/H5Gobj.c b/src/H5Gobj.c
index 40ed72c..13af429 100644
--- a/src/H5Gobj.c
+++ b/src/H5Gobj.c
@@ -1079,12 +1079,12 @@ done:
*
*-------------------------------------------------------------------------
*/
-htri_t
-H5G__obj_lookup(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk)
+herr_t
+H5G__obj_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found, H5O_link_t *lnk)
{
- H5O_linfo_t linfo; /* Link info message */
- htri_t linfo_exists; /* Whether the link info message exists */
- htri_t ret_value = FALSE; /* Return value */
+ H5O_linfo_t linfo; /* Link info message */
+ htri_t linfo_exists; /* Whether the link info message exists */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE_TAG(grp_oloc->addr)
@@ -1099,18 +1099,18 @@ H5G__obj_lookup(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk)
/* Check for dense link storage */
if (H5F_addr_defined(linfo.fheap_addr)) {
/* Get the object's info from the dense link storage */
- if ((ret_value = H5G__dense_lookup(grp_oloc->file, &linfo, name, lnk)) < 0)
+ if (H5G__dense_lookup(grp_oloc->file, &linfo, name, found, lnk) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object")
} /* end if */
else {
/* Get the object's info from the link messages */
- if ((ret_value = H5G__compact_lookup(grp_oloc, name, lnk)) < 0)
+ if (H5G__compact_lookup(grp_oloc, name, found, lnk) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object")
} /* end else */
} /* end if */
else
/* Get the object's info from the symbol table */
- if ((ret_value = H5G__stab_lookup(grp_oloc, name, lnk)) < 0)
+ if (H5G__stab_lookup(grp_oloc, name, found, lnk) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object")
done:
diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h
index e93e2da..174d72d 100644
--- a/src/H5Gpkg.h
+++ b/src/H5Gpkg.h
@@ -364,7 +364,7 @@ H5_DLL ssize_t H5G__stab_get_name_by_idx(const H5O_loc_t *oloc, H5_iter_order_t
H5_DLL herr_t H5G__stab_remove(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name);
H5_DLL herr_t H5G__stab_remove_by_idx(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r,
H5_iter_order_t order, hsize_t n);
-H5_DLL herr_t H5G__stab_lookup(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk);
+H5_DLL herr_t H5G__stab_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found, H5O_link_t *lnk);
H5_DLL herr_t H5G__stab_lookup_by_idx(const H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n,
H5O_link_t *lnk);
#ifndef H5_STRICT_FORMAT_CHECKS
@@ -417,7 +417,8 @@ H5_DLL herr_t H5G__compact_remove_by_idx(const H5O_loc_t *oloc, const H5O_linfo
H5_DLL herr_t H5G__compact_iterate(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type,
H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk,
H5G_lib_iterate_t op, void *op_data);
-H5_DLL htri_t H5G__compact_lookup(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk);
+H5_DLL herr_t H5G__compact_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found,
+ H5O_link_t *lnk);
H5_DLL herr_t H5G__compact_lookup_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, H5O_link_t *lnk);
@@ -426,7 +427,8 @@ H5_DLL herr_t H5G__dense_build_table(H5F_t *f, const H5O_linfo_t *linfo, H5_ind
H5_iter_order_t order, H5G_link_table_t *ltable);
H5_DLL herr_t H5G__dense_create(H5F_t *f, H5O_linfo_t *linfo, const H5O_pline_t *pline);
H5_DLL herr_t H5G__dense_insert(H5F_t *f, const H5O_linfo_t *linfo, const H5O_link_t *lnk);
-H5_DLL htri_t H5G__dense_lookup(H5F_t *f, const H5O_linfo_t *linfo, const char *name, H5O_link_t *lnk);
+H5_DLL herr_t H5G__dense_lookup(H5F_t *f, const H5O_linfo_t *linfo, const char *name, hbool_t *found,
+ H5O_link_t *lnk);
H5_DLL herr_t H5G__dense_lookup_by_idx(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, H5O_link_t *lnk);
H5_DLL herr_t H5G__dense_iterate(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type,
@@ -449,7 +451,7 @@ H5_DLL htri_t H5G__obj_get_linfo(const H5O_loc_t *grp_oloc, H5O_linfo_t *linfo);
H5_DLL herr_t H5G__obj_iterate(const H5O_loc_t *grp_oloc, H5_index_t idx_type, H5_iter_order_t order,
hsize_t skip, hsize_t *last_lnk, H5G_lib_iterate_t op, void *op_data);
H5_DLL herr_t H5G__obj_info(const H5O_loc_t *oloc, H5G_info_t *grp_info);
-H5_DLL htri_t H5G__obj_lookup(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk);
+H5_DLL herr_t H5G__obj_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found, H5O_link_t *lnk);
#ifndef H5_NO_DEPRECATED_SYMBOLS
H5_DLL herr_t H5G__get_objinfo(const H5G_loc_t *loc, const char *name, hbool_t follow_link,
H5G_stat_t *statbuf /*out*/);
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index a9a2903..a037e54 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -168,14 +168,14 @@ typedef enum H5G_link_iterate_op_type_t {
#ifndef H5_NO_DEPRECATED_SYMBOLS
H5G_LINK_OP_OLD, /* "Old" application callback */
#endif /* H5_NO_DEPRECATED_SYMBOLS */
- H5G_LINK_OP_NEW /* "New" application callback */
+ H5G_LINK_OP_NEW /* "New" application callback */
} H5G_link_iterate_op_type_t;
typedef struct {
H5G_link_iterate_op_type_t op_type;
union {
#ifndef H5_NO_DEPRECATED_SYMBOLS
- H5G_iterate_t op_old; /* "Old" application callback for each link */
+ H5G_iterate_t op_old; /* "Old" application callback for each link */
#endif /* H5_NO_DEPRECATED_SYMBOLS */
H5L_iterate2_t op_new; /* "New" application callback for each link */
} op_func;
diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h
index fd0106b..f209c3d 100644
--- a/src/H5Gpublic.h
+++ b/src/H5Gpublic.h
@@ -70,16 +70,53 @@ extern "C" {
#endif
H5_DLL hid_t H5Gcreate2(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id);
+H5_DLL hid_t H5Gcreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t es_id);
H5_DLL hid_t H5Gcreate_anon(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id);
H5_DLL hid_t H5Gopen2(hid_t loc_id, const char *name, hid_t gapl_id);
+H5_DLL hid_t H5Gopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *name, hid_t gapl_id, hid_t es_id);
H5_DLL hid_t H5Gget_create_plist(hid_t group_id);
H5_DLL herr_t H5Gget_info(hid_t loc_id, H5G_info_t *ginfo);
+H5_DLL herr_t H5Gget_info_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ H5G_info_t *group_info /*out*/, hid_t es_id);
H5_DLL herr_t H5Gget_info_by_name(hid_t loc_id, const char *name, H5G_info_t *ginfo, hid_t lapl_id);
+H5_DLL herr_t H5Gget_info_by_name_async(const char *app_file, const char *app_func, unsigned app_line,
+ hid_t loc_id, const char *name, H5G_info_t *group_info /*out*/,
+ hid_t lapl_id, hid_t es_id);
H5_DLL herr_t H5Gget_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, H5G_info_t *ginfo, hid_t lapl_id);
-H5_DLL herr_t H5Gclose(hid_t group_id);
+H5_DLL herr_t H5Gget_info_by_idx_async(const char *app_file, const char *app_func, unsigned app_line,
+ hid_t loc_id, const char *group_name, H5_index_t idx_type,
+ H5_iter_order_t order, hsize_t n, H5G_info_t *group_info /*out*/,
+ hid_t lapl_id, hid_t es_id);
H5_DLL herr_t H5Gflush(hid_t group_id);
H5_DLL herr_t H5Grefresh(hid_t group_id);
+H5_DLL herr_t H5Gclose(hid_t group_id);
+H5_DLL herr_t H5Gclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t group_id,
+ hid_t es_id);
+
+/* API Wrappers for async routines */
+/* (Must be defined _after_ the function prototype) */
+/* (And must only defined when included in application code, not the library) */
+#ifndef H5G_MODULE
+#define H5Gcreate_async(...) H5Gcreate_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Gopen_async(...) H5Gopen_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Gget_info_async(...) H5Gget_info_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Gget_info_by_name_async(...) H5Gget_info_by_name_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Gget_info_by_idx_async(...) H5Gget_info_by_idx_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Gclose_async(...) H5Gclose_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+
+/* Define "wrapper" versions of function calls, to allow compile-time values to
+ * be passed in by language wrapper or library layer on top of HDF5.
+ */
+#define H5Gcreate_async_wrap H5_NO_EXPAND(H5Gcreate_async)
+#define H5Gopen_async_wrap H5_NO_EXPAND(H5Gopen_async)
+#define H5Gget_info_async_wrap H5_NO_EXPAND(H5Gget_info_async)
+#define H5Gget_info_by_name_async_wrap H5_NO_EXPAND(H5Gget_info_by_name_async)
+#define H5Gget_info_by_idx_async_wrap H5_NO_EXPAND(H5Gget_info_by_idx_async)
+#define H5Gclose_async_wrap H5_NO_EXPAND(H5Gclose_async)
+#endif /* H5G_MODULE */
/* Symbols defined for compatibility with previous versions of the HDF5 API.
*
@@ -98,7 +135,7 @@ H5_DLL herr_t H5Grefresh(hid_t group_id);
/* Macros for types of objects in a group (see H5G_obj_t definition) */
#define H5G_NTYPES 256 /* Max possible number of types */
-#define H5G_NLIBTYPES 8 /* Number of internal types */
+#define H5G_NLIBTYPES 8 /* Number of internal types */
#define H5G_NUSERTYPES (H5G_NTYPES - H5G_NLIBTYPES)
#define H5G_USERTYPE(X) (8 + (X)) /* User defined types */
diff --git a/src/H5Gstab.c b/src/H5Gstab.c
index c93fae6..0f8d43b 100644
--- a/src/H5Gstab.c
+++ b/src/H5Gstab.c
@@ -833,20 +833,21 @@ done:
*
*-------------------------------------------------------------------------
*/
-htri_t
-H5G__stab_lookup(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk)
+herr_t
+H5G__stab_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found, H5O_link_t *lnk)
{
- H5HL_t * heap = NULL; /* Pointer to local heap */
- H5G_bt_lkp_t bt_udata; /* Data to pass through B-tree */
- H5G_stab_fnd_ud_t udata; /* 'User data' to give to callback */
- H5O_stab_t stab; /* Symbol table message */
- htri_t ret_value = FAIL; /* Return value */
+ H5HL_t * heap = NULL; /* Pointer to local heap */
+ H5G_bt_lkp_t bt_udata; /* Data to pass through B-tree */
+ H5G_stab_fnd_ud_t udata; /* 'User data' to give to callback */
+ H5O_stab_t stab; /* Symbol table message */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
/* check arguments */
HDassert(grp_oloc && grp_oloc->file);
HDassert(name && *name);
+ HDassert(found);
HDassert(lnk);
/* Retrieve the symbol table message for the group */
@@ -869,7 +870,7 @@ H5G__stab_lookup(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk)
bt_udata.op_data = &udata;
/* Search the B-tree */
- if ((ret_value = H5B_find(grp_oloc->file, H5B_SNODE, stab.btree_addr, &bt_udata)) < 0)
+ if (H5B_find(grp_oloc->file, H5B_SNODE, stab.btree_addr, found, &bt_udata) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found")
done:
diff --git a/src/H5Gtest.c b/src/H5Gtest.c
index 0cdb380..92a0e4d 100644
--- a/src/H5Gtest.c
+++ b/src/H5Gtest.c
@@ -607,6 +607,7 @@ H5G__user_path_test(hid_t obj_id, char *user_path, size_t *user_path_len, unsign
case H5I_ERROR_MSG:
case H5I_ERROR_STACK:
case H5I_SPACE_SEL_ITER:
+ case H5I_EVENTSET:
case H5I_NTYPES:
default:
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unknown data object type")
diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c
index 3de8cfa..2204209 100644
--- a/src/H5Gtraverse.c
+++ b/src/H5Gtraverse.c
@@ -535,7 +535,7 @@ H5G__traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, H5G
/* Traverse the path */
while ((name = H5G__component(name, &nchars)) && *name) {
const char *s; /* Temporary string pointer */
- htri_t lookup_status; /* Status from object lookup */
+ hbool_t lookup_status; /* Status from object lookup */
hbool_t obj_exists; /* Whether the object exists */
/*
@@ -564,7 +564,8 @@ H5G__traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, H5G
} /* end if */
/* Get information for object in current group */
- if ((lookup_status = H5G__obj_lookup(grp_loc.oloc, comp, &lnk /*out*/)) < 0)
+ lookup_status = FALSE;
+ if (H5G__obj_lookup(grp_loc.oloc, comp, &lookup_status, &lnk /*out*/) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't look up component")
obj_exists = FALSE;
diff --git a/src/H5HFcache.c b/src/H5HFcache.c
index a9f89e0..ef2c4b2 100644
--- a/src/H5HFcache.c
+++ b/src/H5HFcache.c
@@ -1302,9 +1302,9 @@ H5HF__cache_iblock_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_NDEBUG
H5HF_indirect_t *iblock = (H5HF_indirect_t *)_thing; /* Indirect block info */
uint8_t * image = (uint8_t *)_image; /* Pointer into raw data buffer */
#ifndef NDEBUG
- unsigned nchildren = 0; /* Track # of children */
- size_t max_child = 0; /* Track max. child entry used */
-#endif /* NDEBUG */
+ unsigned nchildren = 0; /* Track # of children */
+ size_t max_child = 0; /* Track max. child entry used */
+#endif /* NDEBUG */
uint32_t metadata_chksum; /* Computed metadata checksum value */
size_t u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
diff --git a/src/H5HFhuge.c b/src/H5HFhuge.c
index b981797..b6b3d47 100644
--- a/src/H5HFhuge.c
+++ b/src/H5HFhuge.c
@@ -508,6 +508,8 @@ H5HF__huge_get_obj_len(H5HF_hdr_t *hdr, const uint8_t *id, size_t *obj_len_p)
} /* end else */
} /* end if */
else {
+ hbool_t found = FALSE; /* Whether entry was found */
+
/* Check if v2 B-tree is open yet */
if (NULL == hdr->huge_bt2) {
/* Open existing v2 B-tree */
@@ -524,7 +526,10 @@ H5HF__huge_get_obj_len(H5HF_hdr_t *hdr, const uint8_t *id, size_t *obj_len_p)
UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
/* Look up object in v2 B-tree */
- if (H5B2_find(hdr->huge_bt2, &search_rec, H5HF__huge_bt2_filt_indir_found, &found_rec) != TRUE)
+ if (H5B2_find(hdr->huge_bt2, &search_rec, &found, H5HF__huge_bt2_filt_indir_found, &found_rec) <
+ 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFIND, FAIL, "can't check for object in v2 B-tree")
+ if (!found)
HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree")
/* Retrieve the object's length */
@@ -538,7 +543,9 @@ H5HF__huge_get_obj_len(H5HF_hdr_t *hdr, const uint8_t *id, size_t *obj_len_p)
UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
/* Look up object in v2 B-tree */
- if (H5B2_find(hdr->huge_bt2, &search_rec, H5HF__huge_bt2_indir_found, &found_rec) != TRUE)
+ if (H5B2_find(hdr->huge_bt2, &search_rec, &found, H5HF__huge_bt2_indir_found, &found_rec) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFIND, FAIL, "can't check for object in v2 B-tree")
+ if (!found)
HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree")
/* Retrieve the object's length */
@@ -587,6 +594,8 @@ H5HF__huge_get_obj_off(H5HF_hdr_t *hdr, const uint8_t *id, hsize_t *obj_off_p)
H5F_addr_decode(hdr->f, &id, &obj_addr);
} /* end if */
else {
+ hbool_t found = FALSE; /* Whether entry was found */
+
/* Sanity check */
HDassert(H5F_addr_defined(hdr->huge_bt2_addr));
@@ -606,7 +615,10 @@ H5HF__huge_get_obj_off(H5HF_hdr_t *hdr, const uint8_t *id, hsize_t *obj_off_p)
UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
/* Look up object in v2 B-tree */
- if (H5B2_find(hdr->huge_bt2, &search_rec, H5HF__huge_bt2_filt_indir_found, &found_rec) != TRUE)
+ if (H5B2_find(hdr->huge_bt2, &search_rec, &found, H5HF__huge_bt2_filt_indir_found, &found_rec) <
+ 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFIND, FAIL, "can't check for object in v2 B-tree")
+ if (!found)
HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree")
/* Retrieve the object's address & length */
@@ -620,7 +632,9 @@ H5HF__huge_get_obj_off(H5HF_hdr_t *hdr, const uint8_t *id, hsize_t *obj_off_p)
UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
/* Look up object in v2 B-tree */
- if (H5B2_find(hdr->huge_bt2, &search_rec, H5HF__huge_bt2_indir_found, &found_rec) != TRUE)
+ if (H5B2_find(hdr->huge_bt2, &search_rec, &found, H5HF__huge_bt2_indir_found, &found_rec) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFIND, FAIL, "can't check for object in v2 B-tree")
+ if (!found)
HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree")
/* Retrieve the object's address & length */
@@ -679,6 +693,8 @@ H5HF__huge_op_real(H5HF_hdr_t *hdr, const uint8_t *id, hbool_t is_read, H5HF_ope
UINT32DECODE(id, filter_mask);
} /* end if */
else {
+ hbool_t found = FALSE; /* Whether entry was found */
+
/* Sanity check */
HDassert(H5F_addr_defined(hdr->huge_bt2_addr));
@@ -698,7 +714,10 @@ H5HF__huge_op_real(H5HF_hdr_t *hdr, const uint8_t *id, hbool_t is_read, H5HF_ope
UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
/* Look up object in v2 B-tree */
- if (H5B2_find(hdr->huge_bt2, &search_rec, H5HF__huge_bt2_filt_indir_found, &found_rec) != TRUE)
+ if (H5B2_find(hdr->huge_bt2, &search_rec, &found, H5HF__huge_bt2_filt_indir_found, &found_rec) <
+ 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFIND, FAIL, "can't check for object in v2 B-tree")
+ if (!found)
HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree")
/* Retrieve the object's address & length */
@@ -714,7 +733,9 @@ H5HF__huge_op_real(H5HF_hdr_t *hdr, const uint8_t *id, hbool_t is_read, H5HF_ope
UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
/* Look up object in v2 B-tree */
- if (H5B2_find(hdr->huge_bt2, &search_rec, H5HF__huge_bt2_indir_found, &found_rec) != TRUE)
+ if (H5B2_find(hdr->huge_bt2, &search_rec, &found, H5HF__huge_bt2_indir_found, &found_rec) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFIND, FAIL, "can't check for object in v2 B-tree")
+ if (!found)
HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree")
/* Retrieve the object's address & length */
@@ -827,8 +848,9 @@ H5HF__huge_write(H5HF_hdr_t *hdr, const uint8_t *id, const void *obj)
H5F_DECODE_LENGTH(hdr->f, id, obj_size);
} /* end if */
else {
- H5HF_huge_bt2_indir_rec_t found_rec; /* Record found from tracking object */
- H5HF_huge_bt2_indir_rec_t search_rec; /* Record for searching for object */
+ H5HF_huge_bt2_indir_rec_t found_rec; /* Record found from tracking object */
+ H5HF_huge_bt2_indir_rec_t search_rec; /* Record for searching for object */
+ hbool_t found = FALSE; /* Whether entry was found */
/* Sanity check */
HDassert(H5F_addr_defined(hdr->huge_bt2_addr));
@@ -845,7 +867,9 @@ H5HF__huge_write(H5HF_hdr_t *hdr, const uint8_t *id, const void *obj)
UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size)
/* Look up object in v2 B-tree */
- if (H5B2_find(hdr->huge_bt2, &search_rec, H5HF__huge_bt2_indir_found, &found_rec) != TRUE)
+ if (H5B2_find(hdr->huge_bt2, &search_rec, &found, H5HF__huge_bt2_indir_found, &found_rec) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFIND, FAIL, "can't check for object in v2 B-tree")
+ if (!found)
HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree")
/* Retrieve the object's address & length */
diff --git a/src/H5I.c b/src/H5I.c
index 623a2f7..313fcd2 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -319,13 +319,47 @@ H5Iregister(H5I_type_t type, const void *object)
HGOTO_ERROR(H5E_ID, H5E_BADGROUP, H5I_INVALID_HID, "cannot call public function on library type")
/* Register the object */
- ret_value = H5I_register(type, object, TRUE);
+ if ((ret_value = H5I__register(type, object, TRUE, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object")
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Iregister() */
/*-------------------------------------------------------------------------
+ * Function: H5Iregister_future
+ *
+ * Purpose: Register a "future" object.
+ *
+ * Return: Success: New future object ID
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Iregister_future(H5I_type_t type, const void *object, H5I_future_realize_func_t realize_cb,
+ H5I_future_discard_func_t discard_cb)
+{
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE4("i", "It*xIRID", type, object, realize_cb, discard_cb);
+
+ /* Check arguments */
+ if (NULL == realize_cb)
+ HGOTO_ERROR(H5E_ID, H5E_BADVALUE, H5I_INVALID_HID, "NULL pointer for realize_cb not allowed")
+ if (NULL == discard_cb)
+ HGOTO_ERROR(H5E_ID, H5E_BADVALUE, H5I_INVALID_HID, "NULL pointer for realize_cb not allowed")
+
+ /* Register the future object */
+ if ((ret_value = H5I__register(type, object, TRUE, realize_cb, discard_cb)) < 0)
+ HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Iregister_future() */
+
+/*-------------------------------------------------------------------------
* Function: H5Iobject_verify
*
* Purpose: Find an object pointer for the specified ID, verifying that
diff --git a/src/H5Idbg.c b/src/H5Idbg.c
index 80be9d0..fbcf23d 100644
--- a/src/H5Idbg.c
+++ b/src/H5Idbg.c
@@ -136,6 +136,7 @@ H5I__id_dump_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata)
case H5I_ERROR_MSG:
case H5I_ERROR_STACK:
case H5I_SPACE_SEL_ITER:
+ case H5I_EVENTSET:
case H5I_NTYPES:
default:
break; /* Other types of IDs are not stored in files */
diff --git a/src/H5Iint.c b/src/H5Iint.c
index b511cb5..4d7c076 100644
--- a/src/H5Iint.c
+++ b/src/H5Iint.c
@@ -367,27 +367,52 @@ H5I__clear_type_cb(void *_info, void H5_ATTR_UNUSED *key, void *_udata)
* one and forcing is off.
*/
if (udata->force || (info->count - (!udata->app_ref * info->app_count)) <= 1) {
- /* Check for a 'free' function and call it, if it exists */
+ /* Check if this is an un-realized future object */
H5_GCC_DIAG_OFF("cast-qual")
- if (udata->type_info->cls->free_func &&
- (udata->type_info->cls->free_func)((void *)info->object, H5_REQUEST_NULL) < 0) { /* (Casting away const OK -QAK) */
- if (udata->force) {
+ if (info->is_future) {
+ /* Discard the future object */
+ if ((info->discard_cb)((void *)info->object) < 0) {
+ if (udata->force) {
#ifdef H5I_DEBUG
- if (H5DEBUG(I)) {
- HDfprintf(H5DEBUG(I),
- "H5I: free type=%d obj=0x%08lx "
- "failure ignored\n",
- (int)udata->type_info->cls->type, (unsigned long)(info->object));
- }
+ if (H5DEBUG(I)) {
+ HDfprintf(H5DEBUG(I),
+ "H5I: discard type=%d obj=0x%08lx "
+ "failure ignored\n",
+ (int)udata->type_info->cls->type, (unsigned long)(info->object));
+ }
#endif /* H5I_DEBUG */
+ /* Indicate node should be removed from list */
+ ret_value = TRUE;
+ }
+ }
+ else {
/* Indicate node should be removed from list */
ret_value = TRUE;
}
}
else {
- /* Indicate node should be removed from list */
- ret_value = TRUE;
+ /* Check for a 'free' function and call it, if it exists */
+ if (udata->type_info->cls->free_func &&
+ (udata->type_info->cls->free_func)((void *)info->object, H5_REQUEST_NULL) < 0) {
+ if (udata->force) {
+#ifdef H5I_DEBUG
+ if (H5DEBUG(I)) {
+ HDfprintf(H5DEBUG(I),
+ "H5I: free type=%d obj=0x%08lx "
+ "failure ignored\n",
+ (int)udata->type_info->cls->type, (unsigned long)(info->object));
+ }
+#endif /* H5I_DEBUG */
+
+ /* Indicate node should be removed from list */
+ ret_value = TRUE;
+ }
+ }
+ else {
+ /* Indicate node should be removed from list */
+ ret_value = TRUE;
+ }
}
H5_GCC_DIAG_ON("cast-qual")
@@ -435,10 +460,9 @@ H5I__destroy_type(H5I_type_t type)
if (type_info == NULL || type_info->init_count <= 0)
HGOTO_ERROR(H5E_ID, H5E_BADGROUP, FAIL, "invalid type")
- /* Close/clear/destroy all IDs for this type */
- H5E_BEGIN_TRY {
- H5I_clear_type(type, TRUE, FALSE);
- } H5E_END_TRY /* don't care about errors */
+ /* Close/clear/destroy all IDs for this type */
+ H5E_BEGIN_TRY { H5I_clear_type(type, TRUE, FALSE); }
+ H5E_END_TRY /* don't care about errors */
/* Check if we should release the ID class */
if (type_info->cls->flags & H5I_CLASS_IS_APPLICATION)
@@ -457,30 +481,34 @@ done:
} /* end H5I__destroy_type() */
/*-------------------------------------------------------------------------
- * Function: H5I_register
+ * Function: H5I__register
*
* Purpose: Registers an OBJECT in a TYPE and returns an ID for it.
* This routine does _not_ check for unique-ness of the objects,
* if you register an object twice, you will get two different
* IDs for it. This routine does make certain that each ID in a
* type is unique. IDs are created by getting a unique number
- * for the type the ID is in and incorporating the type into
+ * for the type the ID is in and incorporating the TYPE into
* the ID which is returned to the user.
*
+ * IDs are marked as "future" if the realize_cb and discard_cb
+ * parameters are non-NULL.
+ *
* Return: Success: New object ID
* Failure: H5I_INVALID_HID
*
*-------------------------------------------------------------------------
*/
hid_t
-H5I_register(H5I_type_t type, const void *object, hbool_t app_ref)
+H5I__register(H5I_type_t type, const void *object, hbool_t app_ref, H5I_future_realize_func_t realize_cb,
+ H5I_future_discard_func_t discard_cb)
{
H5I_type_info_t *type_info = NULL; /* Pointer to the type */
H5I_id_info_t * info = NULL; /* Pointer to the new ID information */
hid_t new_id = H5I_INVALID_HID; /* New ID */
hid_t ret_value = H5I_INVALID_HID; /* Return value */
- FUNC_ENTER_NOAPI(H5I_INVALID_HID)
+ FUNC_ENTER_PACKAGE
/* Check arguments */
if (type <= H5I_BADID || (int)type >= H5I_next_type_g)
@@ -488,15 +516,18 @@ H5I_register(H5I_type_t type, const void *object, hbool_t app_ref)
type_info = H5I_type_info_array_g[type];
if ((NULL == type_info) || (type_info->init_count <= 0))
HGOTO_ERROR(H5E_ID, H5E_BADGROUP, H5I_INVALID_HID, "invalid type")
- if (NULL == (info = H5FL_MALLOC(H5I_id_info_t)))
+ if (NULL == (info = H5FL_CALLOC(H5I_id_info_t)))
HGOTO_ERROR(H5E_ID, H5E_NOSPACE, H5I_INVALID_HID, "memory allocation failed")
/* Create the struct & its ID */
- new_id = H5I_MAKE(type, type_info->nextid);
- info->id = new_id;
- info->count = 1; /* initial reference count */
- info->app_count = !!app_ref;
- info->object = object;
+ new_id = H5I_MAKE(type, type_info->nextid);
+ info->id = new_id;
+ info->count = 1; /* initial reference count */
+ info->app_count = !!app_ref;
+ info->object = object;
+ info->is_future = (NULL != realize_cb);
+ info->realize_cb = realize_cb;
+ info->discard_cb = discard_cb;
/* Insert into the type */
if (H5SL_insert(type_info->ids, info, &info->id) < 0)
@@ -515,6 +546,35 @@ H5I_register(H5I_type_t type, const void *object, hbool_t app_ref)
done:
FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I__register() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5I_register
+ *
+ * Purpose: Library-private wrapper for H5I__register.
+ *
+ * Return: Success: New object ID
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5I_register(H5I_type_t type, const void *object, hbool_t app_ref)
+{
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5I_INVALID_HID)
+
+ /* Sanity checks */
+ HDassert(type >= H5I_FILE && type < H5I_NTYPES);
+ HDassert(object);
+
+ /* Retrieve ID for object */
+ if (H5I_INVALID_HID == (ret_value = H5I__register(type, object, app_ref, NULL, NULL)))
+ HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5I_register() */
/*-------------------------------------------------------------------------
@@ -566,7 +626,7 @@ H5I_register_using_existing_id(H5I_type_t type, void *object, hbool_t app_ref, h
HGOTO_ERROR(H5E_ID, H5E_BADRANGE, FAIL, "invalid type for provided ID")
/* Allocate new structure to house this ID */
- if (NULL == (info = H5FL_MALLOC(H5I_id_info_t)))
+ if (NULL == (info = H5FL_CALLOC(H5I_id_info_t)))
HGOTO_ERROR(H5E_ID, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Create the struct & insert requested ID */
@@ -574,6 +634,12 @@ H5I_register_using_existing_id(H5I_type_t type, void *object, hbool_t app_ref, h
info->count = 1; /* initial reference count*/
info->app_count = !!app_ref;
info->object = object;
+ /* This API call is only used by the native VOL connector, which is
+ * not asynchronous.
+ */
+ info->is_future = FALSE;
+ info->realize_cb = NULL;
+ info->discard_cb = NULL;
/* Insert into the type */
if (H5SL_insert(type_info->ids, info, &info->id) < 0)
@@ -892,8 +958,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5I__dec_ref
*
- * Purpose: Decrements the number of references outstanding for an ID.
- * This will fail if the type is not a reference counted type.
+ * Purpose: This will fail if the type is not a reference counted type.
* The ID type's 'free' function will be called for the ID
* if the reference count for the ID reaches 0 and a free
* function has been defined at type creation time.
@@ -1071,6 +1136,41 @@ done:
} /* end H5I_dec_app_ref() */
/*-------------------------------------------------------------------------
+ * Function: H5I_dec_app_ref_async
+ *
+ * Purpose: Asynchronous wrapper for case of modifying the application ref.
+ * count for an ID as well as normal reference count.
+ *
+ * Note: Allows for asynchronous 'close' operation on object, with
+ * token != H5_REQUEST_NULL.
+ *
+ * Return: Success: New app. reference count
+ * Failure: -1
+ *
+ * Programmer: Houjun Tang
+ * Oct 21, 2019
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5I_dec_app_ref_async(hid_t id, void **token)
+{
+ int ret_value = 0; /* Return value */
+
+ FUNC_ENTER_NOAPI((-1))
+
+ /* Sanity check */
+ HDassert(id >= 0);
+
+ /* [Possibly] aynchronously decrement refcount on ID */
+ if ((ret_value = H5I__dec_app_ref(id, token)) < 0)
+ HGOTO_ERROR(H5E_ID, H5E_CANTDEC, (-1), "can't asynchronously decrement ID ref count")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_dec_app_ref_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5I__dec_app_ref_always_close
*
* Purpose: Wrapper for case of always closing the ID, even when the free
@@ -1144,6 +1244,38 @@ done:
} /* end H5I_dec_app_ref_always_close() */
/*-------------------------------------------------------------------------
+ * Function: H5I_dec_app_ref_always_close_async
+ *
+ * Purpose: Asynchronous wrapper for case of always closing the ID, even
+ * when the free routine fails
+ *
+ * Note: Allows for asynchronous 'close' operation on object, with
+ * token != H5_REQUEST_NULL.
+ *
+ * Return: Success: New app. reference count
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5I_dec_app_ref_always_close_async(hid_t id, void **token)
+{
+ int ret_value = 0; /* Return value */
+
+ FUNC_ENTER_NOAPI((-1))
+
+ /* Sanity check */
+ HDassert(id >= 0);
+
+ /* [Possibly] aynchronously decrement refcount on ID */
+ if ((ret_value = H5I__dec_app_ref_always_close(id, token)) < 0)
+ HGOTO_ERROR(H5E_ID, H5E_CANTDEC, (-1), "can't asynchronously decrement ID ref count")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_dec_app_ref_always_close_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5I_inc_ref
*
* Purpose: Increment the reference count for an object.
@@ -1455,6 +1587,7 @@ H5I__find_id(hid_t id)
{
H5I_type_t type; /* ID's type */
H5I_type_info_t *type_info = NULL; /* Pointer to the type */
+ H5I_id_info_t * id_info = NULL; /* ID's info */
H5I_id_info_t * ret_value = NULL; /* Return value */
FUNC_ENTER_PACKAGE_NOERR
@@ -1469,15 +1602,53 @@ H5I__find_id(hid_t id)
/* Check for same ID as we have looked up last time */
if (type_info->last_id_info && type_info->last_id_info->id == id)
- ret_value = type_info->last_id_info;
+ id_info = type_info->last_id_info;
else {
/* Locate the ID node for the ID */
- ret_value = (H5I_id_info_t *)H5SL_search(type_info->ids, &id);
+ id_info = (H5I_id_info_t *)H5SL_search(type_info->ids, &id);
/* Remember this ID */
- type_info->last_id_info = ret_value;
+ type_info->last_id_info = id_info;
}
+ /* Check if this is a future ID */
+ H5_GCC_DIAG_OFF("cast-qual")
+ if (id_info && id_info->is_future) {
+ hid_t actual_id = H5I_INVALID_HID; /* ID for actual object */
+ void *future_object; /* Pointer to the future object */
+ void *actual_object; /* Pointer to the actual object */
+
+ /* Invoke the realize callback, to get the actual object */
+ if ((id_info->realize_cb)((void *)id_info->object, &actual_id) < 0)
+ HGOTO_DONE(NULL)
+
+ /* Verify that we received a valid ID, of the same type */
+ if (H5I_INVALID_HID == actual_id)
+ HGOTO_DONE(NULL)
+ if (H5I_TYPE(id) != H5I_TYPE(actual_id))
+ HGOTO_DONE(NULL)
+
+ /* Swap the actual object in for the future object */
+ future_object = (void *)id_info->object;
+ actual_object = H5I__remove_common(type_info, actual_id);
+ HDassert(actual_object);
+ id_info->object = actual_object;
+
+ /* Discard the future object */
+ if ((id_info->discard_cb)(future_object) < 0)
+ HGOTO_DONE(NULL)
+ future_object = NULL;
+
+ /* Change the ID from 'future' to 'actual' */
+ id_info->is_future = FALSE;
+ id_info->realize_cb = NULL;
+ id_info->discard_cb = NULL;
+ }
+ H5_GCC_DIAG_ON("cast-qual")
+
+ /* Set return value */
+ ret_value = id_info;
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5I__find_id() */
diff --git a/src/H5Ipkg.h b/src/H5Ipkg.h
index 5d9af13..b6e3da3 100644
--- a/src/H5Ipkg.h
+++ b/src/H5Ipkg.h
@@ -67,6 +67,11 @@ typedef struct H5I_id_info_t {
unsigned count; /* Ref. count for this ID */
unsigned app_count; /* Ref. count of application visible IDs */
const void *object; /* Pointer associated with the ID */
+
+ /* Future ID info */
+ hbool_t is_future; /* Whether this ID represents a future object */
+ H5I_future_realize_func_t realize_cb; /* 'realize' callback for future object */
+ H5I_future_discard_func_t discard_cb; /* 'discard' callback for future object */
} H5I_id_info_t;
/* Type information structure used */
@@ -98,10 +103,12 @@ H5_DLLVAR int H5I_next_type_g;
/* Package Private Prototypes */
/******************************/
-H5_DLL int H5I__destroy_type(H5I_type_t type);
-H5_DLL void * H5I__remove_verify(hid_t id, H5I_type_t type);
-H5_DLL int H5I__inc_type_ref(H5I_type_t type);
-H5_DLL int H5I__get_type_ref(H5I_type_t type);
+H5_DLL hid_t H5I__register(H5I_type_t type, const void *object, hbool_t app_ref,
+ H5I_future_realize_func_t realize_cb, H5I_future_discard_func_t discard_cb);
+H5_DLL int H5I__destroy_type(H5I_type_t type);
+H5_DLL void *H5I__remove_verify(hid_t id, H5I_type_t type);
+H5_DLL int H5I__inc_type_ref(H5I_type_t type);
+H5_DLL int H5I__get_type_ref(H5I_type_t type);
H5_DLL H5I_id_info_t *H5I__find_id(hid_t id);
/* Testing functions */
diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h
index d8d80f9..6395275 100644
--- a/src/H5Iprivate.h
+++ b/src/H5Iprivate.h
@@ -70,7 +70,9 @@ H5_DLL int H5I_get_ref(hid_t id, hbool_t app_ref);
H5_DLL int H5I_inc_ref(hid_t id, hbool_t app_ref);
H5_DLL int H5I_dec_ref(hid_t id);
H5_DLL int H5I_dec_app_ref(hid_t id);
+H5_DLL int H5I_dec_app_ref_async(hid_t id, void **token);
H5_DLL int H5I_dec_app_ref_always_close(hid_t id);
+H5_DLL int H5I_dec_app_ref_always_close_async(hid_t id, void **token);
H5_DLL int H5I_dec_type_ref(H5I_type_t type);
H5_DLL herr_t H5I_find_id(const void *object, H5I_type_t type, hid_t *id /*out*/);
diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h
index 3912252..0075018 100644
--- a/src/H5Ipublic.h
+++ b/src/H5Ipublic.h
@@ -50,6 +50,7 @@ typedef enum H5I_type_t {
H5I_ERROR_MSG, /**< type ID for error messages */
H5I_ERROR_STACK, /**< type ID for error stacks */
H5I_SPACE_SEL_ITER, /**< type ID for dataspace selection iterator */
+ H5I_EVENTSET, /**< type ID for event sets */
H5I_NTYPES /**< number of library types, MUST BE LAST! */
} H5I_type_t;
@@ -96,6 +97,20 @@ typedef int (*H5I_search_func_t)(void *obj, hid_t id, void *key);
typedef herr_t (*H5I_iterate_func_t)(hid_t id, void *udata);
//! [H5I_iterate_func_t_snip]
+/**
+ * The type of the realize_cb callback for H5Iregister_future
+ */
+//! [H5I_future_realize_func_t_snip]
+typedef herr_t (*H5I_future_realize_func_t)(void *future_object, hid_t *actual_object_id);
+//! [H5I_future_realize_func_t_snip]
+
+/**
+ * The type of the discard_cb callback for H5Iregister_future
+ */
+//! [H5I_future_discard_func_t_snip]
+typedef herr_t (*H5I_future_discard_func_t)(void *future_object);
+//! [H5I_future_discard_func_t_snip]
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -112,7 +127,7 @@ extern "C" {
*
* \return \hid_t{object}
*
- * \details H5Iregister() allocates and returns a new ID for an object.
+ * \details H5Iregister() creates and returns a new ID for an object.
*
* \details The \p type parameter is the identifier for the ID type to which
* this new ID will belong. This identifier must have been created by
@@ -127,6 +142,82 @@ H5_DLL hid_t H5Iregister(H5I_type_t type, const void *object);
/**
* \ingroup H5I
*
+ * \brief Registers a "future" object under a type and returns an ID for it
+ *
+ * \param[in] type The identifier of the type of the new ID
+ * \param[in] object Pointer to "future" object for which a new ID is created
+ * \param[in] realize_cb Function pointer to realize a future object
+ * \param[in] discard_cb Function pointer to destroy a future object
+ *
+ * \return \hid_t{object}
+ *
+ * \details H5Iregister_future() creates and returns a new ID for a "future" object.
+ * Future objects are a special kind of object and represent a
+ * placeholder for an object that has not yet been created or opened.
+ * The \p realize_cb will be invoked by the HDF5 library to 'realize'
+ * the future object as an actual object. A call to H5Iobject_verify()
+ * will invoke the \p realize_cb callback and if it successfully
+ * returns, will return the actual object, not the future object.
+ *
+ * \details The \p type parameter is the identifier for the ID type to which
+ * this new future ID will belong. This identifier may have been created
+ * by a call to H5Iregister_type() or may be one of the HDF5 pre-defined
+ * ID classes (e.g. H5I_FILE, H5I_GROUP, H5I_DATASPACE, etc).
+ *
+ * \details The \p object parameter is a pointer to the memory which the new ID
+ * will be a reference to. This pointer will be stored by the library,
+ * but will not be returned to a call to H5Iobject_verify() until the
+ * \p realize_cb callback has returned the actual pointer for the object.
+ *
+ * A NULL value for \p object is allowed.
+ *
+ * \details The \p realize_cb parameter is a function pointer that will be
+ * invoked by the HDF5 library to convert a future object into an
+ * actual object. The \realize_cb function may be invoked by
+ * H5Iobject_verify() to return the actual object for a user-defined
+ * ID class (i.e. an ID class registered with H5Iregister_type()) or
+ * internally by the HDF5 library in order to use or get information
+ * from an HDF5 pre-defined ID type. For example, the \p realize_cb
+ * for a future dataspace object will be called during the process
+ * of returning information from H5Sget_simple_extent_dims().
+ *
+ * Note that although the \p realize_cb routine returns
+ * an ID (as a parameter) for the actual object, the HDF5 library
+ * will swap the actual object in that ID for the future object in
+ * the future ID. This ensures that the ID value for the object
+ * doesn't change for the user when the object is realized.
+ *
+ * Note that the \p realize_cb callback could receive a NULL value
+ * for a future object pointer, if one was used when H5Iregister_future()
+ * was initially called. This is permitted as a means of allowing
+ * the \p realize_cb to act as a generator of new objects, without
+ * requiring creation of unnecessary future objects.
+ *
+ * It is an error to pass NULL for \p realize_cb.
+ *
+ * \details The \p discard_cb parameter is a function pointer that will be
+ * invoked by the HDF5 library to destroy a future object. This
+ * callback will always be invoked for _every_ future object, whether
+ * the \p realize_cb is invoked on it or not. It's possible that
+ * the \p discard_cb is invoked on a future object without the
+ * \p realize_cb being invoked, e.g. when a future ID is closed without
+ * requiring the future object to be realized into an actual one.
+ *
+ * Note that the \p discard_cb callback could receive a NULL value
+ * for a future object pointer, if one was used when H5Iregister_future()
+ * was initially called.
+ *
+ * It is an error to pass NULL for \p discard_cb.
+ *
+ * \note The H5Iregister_future() function is primarily targeted at VOL connector
+ * authors and is _not_ designed for general-purpose application use.
+ *
+ */
+H5_DLL hid_t H5Iregister_future(H5I_type_t type, const void *object, H5I_future_realize_func_t realize_cb,
+ H5I_future_discard_func_t discard_cb);
+/**
+ * \ingroup H5I
+ *
* \brief Returns the object referenced by an ID
*
* \param[in] id ID to be dereferenced
diff --git a/src/H5L.c b/src/H5L.c
index fbf5b1f..44fdeff 100644
--- a/src/H5L.c
+++ b/src/H5L.c
@@ -25,6 +25,7 @@
#include "H5CXprivate.h" /* API Contexts */
#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event Sets */
#include "H5Fprivate.h" /* File access */
#include "H5Gprivate.h" /* Groups */
#include "H5Iprivate.h" /* IDs */
@@ -82,7 +83,7 @@ typedef struct {
char *sep; /* Pointer to next separator in the string */
/* Up */
- hbool_t exists; /* Whether the link exists or not */
+ hbool_t *exists; /* Whether the link exists or not */
} H5L_trav_le_t;
/* User data for path traversal routine for getting link value */
@@ -129,6 +130,22 @@ static herr_t H5L__get_info_by_idx_cb(H5G_loc_t *grp_loc /*in*/, const char *nam
static herr_t H5L__get_name_by_idx_cb(H5G_loc_t *grp_loc /*in*/, const char *name, const H5O_link_t *lnk,
H5G_loc_t *obj_loc, void *_udata /*in,out*/,
H5G_own_loc_t *own_loc /*out*/);
+static herr_t H5L__create_soft_api_common(const char *link_target, hid_t link_loc_id, const char *link_name,
+ hid_t lcpl_id, hid_t lapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static herr_t H5L__create_hard_api_common(hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id,
+ const char *new_name, hid_t lcpl_id, hid_t lapl_id,
+ void **token_ptr, H5VL_object_t **_vol_obj_ptr);
+static herr_t H5L__delete_api_common(hid_t loc_id, const char *name, hid_t lapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static herr_t H5L__delete_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t idx_type,
+ H5_iter_order_t order, hsize_t n, hid_t lapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static herr_t H5L__exists_api_common(hid_t loc_id, const char *name, hbool_t *exists, hid_t lapl_id,
+ void **token_ptr, H5VL_object_t **_vol_obj_ptr);
+static herr_t H5L__iterate_api_common(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order,
+ hsize_t *idx_p, H5L_iterate2_t op, void *op_data, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
/*********************/
/* Package Variables */
@@ -422,33 +439,25 @@ done:
} /* end H5Lcopy() */
/*-------------------------------------------------------------------------
- * Function: H5Lcreate_soft
+ * Function: H5L__create_soft_api_common
*
- * Purpose: Creates a soft link from LINK_NAME to LINK_TARGET.
- *
- * LINK_TARGET can be anything and is interpreted at lookup
- * time relative to the group which contains the final component
- * of LINK_NAME. For instance, if LINK_TARGET is `./foo' and
- * LINK_NAME is `./x/y/bar' and a request is made for `./x/y/bar'
- * then the actual object looked up is `./x/y/./foo'.
+ * Purpose: This is the common function for creating a soft link
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Robb Matzke
- * Monday, April 6, 1998
- *
*-------------------------------------------------------------------------
*/
-herr_t
-H5Lcreate_soft(const char *link_target, hid_t link_loc_id, const char *link_name, hid_t lcpl_id,
- hid_t lapl_id)
+static herr_t
+H5L__create_soft_api_common(const char *link_target, hid_t link_loc_id, const char *link_name, hid_t lcpl_id,
+ hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
{
- H5VL_object_t * vol_obj = NULL; /* object of loc_id */
- H5VL_loc_params_t loc_params;
- herr_t ret_value = SUCCEED; /* Return value */
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_API(FAIL)
- H5TRACE5("e", "*si*sii", link_target, link_loc_id, link_name, lcpl_id, lapl_id);
+ FUNC_ENTER_STATIC
/* Check arguments */
if (link_loc_id == H5L_SAME_LOC)
@@ -457,10 +466,6 @@ H5Lcreate_soft(const char *link_target, hid_t link_loc_id, const char *link_name
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link_target parameter cannot be NULL")
if (!*link_target)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link_target parameter cannot be an empty string")
- if (!link_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link_name parameter cannot be NULL")
- if (!*link_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link_name parameter cannot be an empty string")
if (lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list")
@@ -471,37 +476,31 @@ H5Lcreate_soft(const char *link_target, hid_t link_loc_id, const char *link_name
/* Set the LCPL for the API context */
H5CX_set_lcpl(lcpl_id);
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, link_loc_id, TRUE) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
-
- /* Set location fields */
- loc_params.type = H5VL_OBJECT_BY_NAME;
- loc_params.loc_data.loc_by_name.name = link_name;
- loc_params.loc_data.loc_by_name.lapl_id = lapl_id;
- loc_params.obj_type = H5I_get_type(link_loc_id);
-
- /* get the location object */
- if (NULL == (vol_obj = (H5VL_object_t *)H5VL_vol_object(link_loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+ /* link_name is verified in H5VL_setup_name_args() */
+ /* Set up object access arguments */
+ if (H5VL_setup_name_args(link_loc_id, link_name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) <
+ 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments")
/* Create the link */
- if (H5VL_link_create(H5VL_LINK_CREATE_SOFT, vol_obj, &loc_params, lcpl_id, lapl_id,
- H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, link_target) < 0)
+ if (H5VL_link_create(H5VL_LINK_CREATE_SOFT, *vol_obj_ptr, &loc_params, lcpl_id, lapl_id,
+ H5P_DATASET_XFER_DEFAULT, token_ptr, link_target) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to create soft link")
done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Lcreate_soft() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5L__create_soft_api_common() */
/*-------------------------------------------------------------------------
- * Function: H5Lcreate_hard
+ * Function: H5Lcreate_soft
*
- * Purpose: Creates a hard link from NEW_NAME to CUR_NAME.
+ * Purpose: Creates a soft link from LINK_NAME to LINK_TARGET.
*
- * CUR_NAME must name an existing object. CUR_NAME and
- * NEW_NAME are interpreted relative to CUR_LOC_ID and
- * NEW_LOC_ID, which are either file IDs or group IDs.
+ * LINK_TARGET can be anything and is interpreted at lookup
+ * time relative to the group which contains the final component
+ * of LINK_NAME. For instance, if LINK_TARGET is `./foo' and
+ * LINK_NAME is `./x/y/bar' and a request is made for `./x/y/bar'
+ * then the actual object looked up is `./x/y/./foo'.
*
* Return: Non-negative on success/Negative on failure
*
@@ -511,18 +510,88 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Lcreate_hard(hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id, const char *new_name, hid_t lcpl_id,
+H5Lcreate_soft(const char *link_target, hid_t link_loc_id, const char *link_name, hid_t lcpl_id,
hid_t lapl_id)
{
- H5VL_object_t * vol_obj1 = NULL; /* Object of cur_loc_id */
- H5VL_object_t * vol_obj2 = NULL; /* Object of new_loc_id */
- H5VL_object_t tmp_vol_obj; /* Temporary object */
- H5VL_loc_params_t loc_params1;
- H5VL_loc_params_t loc_params2;
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
- H5TRACE6("e", "i*si*sii", cur_loc_id, cur_name, new_loc_id, new_name, lcpl_id, lapl_id);
+ H5TRACE5("e", "*si*sii", link_target, link_loc_id, link_name, lcpl_id, lapl_id);
+
+ /* Creates a soft link synchronously */
+ if (H5L__create_soft_api_common(link_target, link_loc_id, link_name, lcpl_id, lapl_id, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to synchronously create soft link")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Lcreate_soft() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Lcreate_soft_async
+ *
+ * Purpose: Asynchronous version of H5Lcreate_soft
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lcreate_soft_async(const char *app_file, const char *app_func, unsigned app_line, const char *link_target,
+ hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE9("e", "*s*sIu*si*siii", app_file, app_func, app_line, link_target, link_loc_id, link_name,
+ lcpl_id, lapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Creates a soft link asynchronously */
+ if (H5L__create_soft_api_common(link_target, link_loc_id, link_name, lcpl_id, lapl_id, token_ptr,
+ &vol_obj) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to asynchronously create soft link")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE9(FUNC, "*s*sIu*si*siii", app_file, app_func, app_line, link_target,
+ link_loc_id, link_name, lcpl_id, lapl_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Lcreate_soft_async() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5L__create_hard_api_common
+ *
+ * Purpose: This is the common function for creating a hard link
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5L__create_hard_api_common(hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id, const char *new_name,
+ hid_t lcpl_id, hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * vol_obj1 = NULL; /* Object of cur_loc_id */
+ H5VL_object_t * vol_obj2 = NULL; /* Object of new_loc_id */
+ H5VL_object_t tmp_vol_obj; /* Temporary object */
+ H5VL_object_t * tmp_vol_obj_ptr = &tmp_vol_obj; /* Ptr to temporary object */
+ H5VL_object_t **tmp_vol_obj_ptr_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj_ptr); /* Ptr to ptr to temporary object */
+ H5VL_loc_params_t loc_params1; /* Location parameters for cur_loc_id object access */
+ H5VL_loc_params_t loc_params2; /* Location parameters for new_loc_id object access */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
/* Check arguments */
if (cur_loc_id == H5L_SAME_LOC && new_loc_id == H5L_SAME_LOC)
@@ -576,20 +645,97 @@ H5Lcreate_hard(hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id, const c
"Objects are accessed through different VOL connectors and can't be linked")
/* Construct a temporary VOL object */
- tmp_vol_obj.data = (vol_obj2 ? (vol_obj2->data) : NULL);
- tmp_vol_obj.connector = (vol_obj1 != NULL ? vol_obj1->connector : vol_obj2->connector);
+ (*tmp_vol_obj_ptr_ptr)->data = (vol_obj2 ? (vol_obj2->data) : NULL);
+ (*tmp_vol_obj_ptr_ptr)->connector = (vol_obj1 != NULL ? vol_obj1->connector : vol_obj2->connector);
/* Create the link */
- if (H5VL_link_create(H5VL_LINK_CREATE_HARD, &tmp_vol_obj, &loc_params2, lcpl_id, lapl_id,
- H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (vol_obj1 ? vol_obj1->data : NULL),
+ if (H5VL_link_create(H5VL_LINK_CREATE_HARD, *tmp_vol_obj_ptr_ptr, &loc_params2, lcpl_id, lapl_id,
+ H5P_DATASET_XFER_DEFAULT, token_ptr, (vol_obj1 ? vol_obj1->data : NULL),
&loc_params1) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to create hard link")
done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5L__create_hard_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Lcreate_hard
+ *
+ * Purpose: Creates a hard link from NEW_NAME to CUR_NAME.
+ *
+ * CUR_NAME must name an existing object. CUR_NAME and
+ * NEW_NAME are interpreted relative to CUR_LOC_ID and
+ * NEW_LOC_ID, which are either file IDs or group IDs.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Monday, April 6, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lcreate_hard(hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id, const char *new_name, hid_t lcpl_id,
+ hid_t lapl_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "i*si*sii", cur_loc_id, cur_name, new_loc_id, new_name, lcpl_id, lapl_id);
+
+ /* Creates a hard link synchronously */
+ if (H5L__create_hard_api_common(cur_loc_id, cur_name, new_loc_id, new_name, lcpl_id, lapl_id, NULL,
+ NULL) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to synchronously create hard link")
+
+done:
FUNC_LEAVE_API(ret_value)
} /* end H5Lcreate_hard() */
/*-------------------------------------------------------------------------
+ * Function: H5Lcreate_hard_async
+ *
+ * Purpose: Asynchronous version of H5Lcreate_hard
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Lcreate_hard_async(const char *app_file, const char *app_func, unsigned app_line, hid_t cur_loc_id,
+ const char *cur_name, hid_t new_loc_id, const char *new_name, hid_t lcpl_id,
+ hid_t lapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE10("e", "*s*sIui*si*siii", app_file, app_func, app_line, cur_loc_id, cur_name, new_loc_id,
+ new_name, lcpl_id, lapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Creates a hard link asynchronously */
+ if (H5L__create_hard_api_common(cur_loc_id, cur_name, new_loc_id, new_name, lcpl_id, lapl_id, token_ptr,
+ &vol_obj) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to asynchronously create hard link")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE10(FUNC, "*s*sIui*si*siii", app_file, app_func, app_line, cur_loc_id,
+ cur_name, new_loc_id, new_name, lcpl_id, lapl_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Lcreate_hard_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5Lcreate_external
*
* Purpose: Creates an external link from LINK_NAME to OBJ_NAME.
@@ -759,6 +905,43 @@ done:
} /* end H5Lcreate_ud() */
/*-------------------------------------------------------------------------
+ * Function: H5L__delete_api_common
+ *
+ * Purpose: This is the common function for deleting a link
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5L__delete_api_common(hid_t loc_id, const char *name, hid_t lapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check arguments */
+ /* name is verified in H5VL_setup_name_args() */
+
+ /* Set up object access arguments */
+ if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments")
+
+ /* Unlink */
+ if (H5VL_link_specific(*vol_obj_ptr, &loc_params, H5VL_LINK_DELETE, H5P_DATASET_XFER_DEFAULT, token_ptr) <
+ 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5L__delete_api_common() */
+
+/*-------------------------------------------------------------------------
* Function: H5Ldelete
*
* Purpose: Removes the specified NAME from the group graph and
@@ -778,39 +961,103 @@ done:
herr_t
H5Ldelete(hid_t loc_id, const char *name, hid_t lapl_id)
{
- H5VL_object_t * vol_obj = NULL; /* Object of loc_id */
- H5VL_loc_params_t loc_params;
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE3("e", "i*si", loc_id, name, lapl_id);
- /* Check arguments */
- if (!name || !*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+ /* Delete a link synchronously */
+ if (H5L__delete_api_common(loc_id, name, lapl_id, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to synchronously delete link")
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Ldelete() */
- /* Fill in the location struct fields */
- loc_params.type = H5VL_OBJECT_BY_NAME;
- loc_params.obj_type = H5I_get_type(loc_id);
- loc_params.loc_data.loc_by_name.name = name;
- loc_params.loc_data.loc_by_name.lapl_id = lapl_id;
+/*-------------------------------------------------------------------------
+ * Function: H5Ldelete_async
+ *
+ * Purpose: Asynchronous version of H5Ldelete
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Ldelete_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name,
+ hid_t lapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* get the location object */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+ FUNC_ENTER_API(FAIL)
+ H5TRACE7("e", "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, lapl_id, es_id);
- /* Unlink */
- if (H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_DELETE, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link")
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Delete a link asynchronously */
+ if (H5L__delete_api_common(loc_id, name, lapl_id, token_ptr, &vol_obj) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to asynchronously delete link")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE7(FUNC, "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, lapl_id,
+ es_id)) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINSERT, FAIL, "can't insert token into event set")
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Ldelete() */
+} /* H5Ldelete_async() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5L__delete_by_idx_api_common
+ *
+ * Purpose: This is the common function for deleting a link
+ * according to the order within an index.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5L__delete_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t idx_type,
+ H5_iter_order_t order, hsize_t n, hid_t lapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check arguments */
+ if (!group_name || !*group_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
+ if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
+ if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
+
+ /* Set up object access arguments */
+ if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr,
+ &loc_params) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments")
+
+ /* Delete the link */
+ if (H5VL_link_specific(*vol_obj_ptr, &loc_params, H5VL_LINK_DELETE, H5P_DATASET_XFER_DEFAULT, token_ptr) <
+ 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5L__delete_by_idx_api_common() */
/*-------------------------------------------------------------------------
* Function: H5Ldelete_by_idx
@@ -835,45 +1082,61 @@ herr_t
H5Ldelete_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
hid_t lapl_id)
{
- H5VL_object_t * vol_obj = NULL; /* object of loc_id */
- H5VL_loc_params_t loc_params;
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE6("e", "i*sIiIohi", loc_id, group_name, idx_type, order, n, lapl_id);
- /* Check arguments */
- if (!group_name || !*group_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
- if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
- if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
+ /* Delete a link synchronously */
+ if (H5L__delete_by_idx_api_common(loc_id, group_name, idx_type, order, n, lapl_id, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to synchronously delete link")
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Ldelete_by_idx() */
- loc_params.type = H5VL_OBJECT_BY_IDX;
- loc_params.loc_data.loc_by_idx.name = group_name;
- loc_params.loc_data.loc_by_idx.idx_type = idx_type;
- loc_params.loc_data.loc_by_idx.order = order;
- loc_params.loc_data.loc_by_idx.n = n;
- loc_params.loc_data.loc_by_idx.lapl_id = lapl_id;
- loc_params.obj_type = H5I_get_type(loc_id);
+/*-------------------------------------------------------------------------
+ * Function: H5Ldelete_by_idx_async
+ *
+ * Purpose: Asynchronous version of H5Ldelete_by_idx
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Ldelete_by_idx_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
+ hid_t lapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Get the location object */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+ FUNC_ENTER_API(FAIL)
+ H5TRACE10("e", "*s*sIui*sIiIohii", app_file, app_func, app_line, loc_id, group_name, idx_type, order, n,
+ lapl_id, es_id);
- /* Delete the link */
- if (H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_DELETE, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link")
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Delete a link asynchronously */
+ if (H5L__delete_by_idx_api_common(loc_id, group_name, idx_type, order, n, lapl_id, token_ptr, &vol_obj) <
+ 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to asynchronously delete link")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE10(FUNC, "*s*sIui*sIiIohii", app_file, app_func, app_line, loc_id,
+ group_name, idx_type, order, n, lapl_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINSERT, FAIL, "can't insert token into event set")
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Ldelete_by_idx() */
+} /* H5Ldelete_by_idx_async() */
/*-------------------------------------------------------------------------
* Function: H5Lget_val
@@ -992,6 +1255,45 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Lget_val_by_idx() */
+/*--------------------------------------------------------------------------
+ * NAME
+ * H5L__exists_api_common
+ * PURPOSE
+ * Common helper routine for sync/async check if an attribute exists
+ * RETURNS
+ * Non-negative on success/Negative on failure
+ *
+ *--------------------------------------------------------------------------*/
+static herr_t
+H5L__exists_api_common(hid_t loc_id, const char *name, hbool_t *exists, hid_t lapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check arguments */
+ /* name is verified in H5VL_setup_name_args() */
+ if (NULL == exists)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer for link existence")
+
+ /* Set up object access arguments */
+ if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments")
+
+ /* Check for the existence of the link */
+ if (H5VL_link_specific(*vol_obj_ptr, &loc_params, H5VL_LINK_EXISTS, H5P_DATASET_XFER_DEFAULT, token_ptr,
+ exists) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5L__exists_api_common() */
+
/*-------------------------------------------------------------------------
* Function: H5Lexists
*
@@ -1007,41 +1309,62 @@ done:
htri_t
H5Lexists(hid_t loc_id, const char *name, hid_t lapl_id)
{
- H5VL_object_t * vol_obj = NULL; /* object of loc_id */
- H5VL_loc_params_t loc_params;
- htri_t ret_value = FAIL; /* Return value */
+ hbool_t exists; /* Flag to indicate if link exists */
+ htri_t ret_value = FAIL; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE3("t", "i*si", loc_id, name, lapl_id);
- /* Check arguments */
- if (!name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be NULL")
- if (!*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be an empty string")
+ /* Synchronously check if a link exists */
+ exists = FALSE;
+ if (H5L__exists_api_common(loc_id, name, &exists, lapl_id, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to synchronously check link existence")
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
+ /* Set return value */
+ ret_value = (htri_t)exists;
- /* Set location struct fields */
- loc_params.type = H5VL_OBJECT_BY_NAME;
- loc_params.obj_type = H5I_get_type(loc_id);
- loc_params.loc_data.loc_by_name.name = name;
- loc_params.loc_data.loc_by_name.lapl_id = lapl_id;
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Lexists() */
- /* Get the location object */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+/*--------------------------------------------------------------------------
+ * Function: H5Lexists_async
+ *
+ * Purpose: Asynchronous version of H5Lexists
+ *
+ * Return: Success: TRUE/FALSE/FAIL
+ *
+ *--------------------------------------------------------------------------*/
+herr_t
+H5Lexists_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name,
+ hbool_t *exists, hid_t lapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Check for the existence of the link */
- if (H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_EXISTS, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL,
- &ret_value) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info")
+ FUNC_ENTER_API(FAIL)
+ H5TRACE8("e", "*s*sIui*s*bii", app_file, app_func, app_line, loc_id, name, exists, lapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Asynchronously check if a link exists */
+ if (H5L__exists_api_common(loc_id, name, exists, lapl_id, token_ptr, &vol_obj) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to asynchronously check link existence")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE8(FUNC, "*s*sIui*s*bii", app_file, app_func, app_line, loc_id, name,
+ exists, lapl_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINSERT, FAIL, "can't insert token into event set")
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Lexists() */
+} /* H5Lexists_async() */
/*-------------------------------------------------------------------------
* Function: H5Lget_info2
@@ -1349,6 +1672,53 @@ done:
} /* end H5Lget_name_by_idx() */
/*-------------------------------------------------------------------------
+ * Function: H5L__iterate_api_common
+ *
+ * Purpose: This is the common function for iterating over links
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5L__iterate_api_common(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p,
+ H5L_iterate2_t op, void *op_data, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ H5I_type_t id_type; /* Type of ID */
+ herr_t ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check arguments */
+ id_type = H5I_get_type(group_id);
+ if (!(H5I_GROUP == id_type || H5I_FILE == id_type))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument")
+ if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
+ if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
+ if (!op)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified")
+
+ /* Set up object access arguments */
+ if (H5VL_setup_self_args(group_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments")
+
+ /* Iterate over the links */
+ if ((ret_value = H5VL_link_specific(*vol_obj_ptr, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT,
+ token_ptr, (unsigned)FALSE, (int)idx_type, (int)order, idx_p, op,
+ op_data)) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5L__iterate_api_common() */
+
+/*-------------------------------------------------------------------------
* Function: H5Literate2
*
* Purpose: Iterates over links in a group, with user callback routine,
@@ -1370,42 +1740,68 @@ herr_t
H5Literate2(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, H5L_iterate2_t op,
void *op_data)
{
- H5VL_object_t * vol_obj = NULL; /* Object of loc_id */
- H5VL_loc_params_t loc_params;
- H5I_type_t id_type; /* Type of ID */
- herr_t ret_value; /* Return value */
+ herr_t ret_value; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE6("e", "iIiIo*hLI*x", group_id, idx_type, order, idx_p, op, op_data);
- /* Check arguments */
- id_type = H5I_get_type(group_id);
- if (!(H5I_GROUP == id_type || H5I_FILE == id_type))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument")
- if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
- if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
- if (!op)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified")
+ /* Iterate over links synchronously */
+ if ((ret_value = H5L__iterate_api_common(group_id, idx_type, order, idx_p, op, op_data, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "asynchronous link iteration failed")
- /* Get the location object */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(group_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Literate2() */
- /* Set location struct fields */
- loc_params.type = H5VL_OBJECT_BY_SELF;
- loc_params.obj_type = H5I_get_type(group_id);
+/*-------------------------------------------------------------------------
+ * Function: H5Literate_async
+ *
+ * Purpose: Asynchronous version of H5Literate2
+ *
+ * Return: Success: The return value of the first operator that
+ * returns non-zero, or zero if all members were
+ * processed with no operator returning non-zero.
+ *
+ * Failure: Negative if something goes wrong within the
+ * library, or the negative value returned by one
+ * of the operators.
+ *
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Literate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t group_id,
+ H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, H5L_iterate2_t op, void *op_data,
+ hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value; /* Return value */
- /* Iterate over the links */
- if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL, (unsigned)FALSE, (int)idx_type, (int)order, idx_p,
- op, op_data)) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed")
+ FUNC_ENTER_API(FAIL)
+ H5TRACE10("e", "*s*sIuiIiIo*hLI*xi", app_file, app_func, app_line, group_id, idx_type, order, idx_p, op,
+ op_data, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Iterate over links asynchronously */
+ if ((ret_value =
+ H5L__iterate_api_common(group_id, idx_type, order, idx_p, op, op_data, token_ptr, &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "asynchronous link iteration failed")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE10(FUNC, "*s*sIuiIiIo*hLI*xi", app_file, app_func, app_line, group_id,
+ idx_type, order, idx_p, op, op_data, es_id)) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINSERT, FAIL, "can't insert token into event set")
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Literate2() */
+} /* H5Literate_async() */
/*-------------------------------------------------------------------------
* Function: H5Literate_by_name2
@@ -3094,7 +3490,7 @@ H5L__exists_final_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc /*in*/, const char H5_ATT
FUNC_ENTER_STATIC_NOERR
/* Check if the name in this group resolved to a valid link */
- udata->exists = (hbool_t)(lnk != NULL);
+ *udata->exists = (hbool_t)(lnk != NULL);
/* Indicate that this callback didn't take ownership of the group *
* location for the object */
@@ -3149,10 +3545,10 @@ H5L__exists_inter_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc /*in*/, const char H5_ATT
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't determine if link exists")
} /* end if */
else
- udata->exists = TRUE;
+ *udata->exists = TRUE;
} /* end if */
else
- udata->exists = FALSE;
+ *udata->exists = FALSE;
/* Indicate that this callback didn't take ownership of the group *
* location for the object */
@@ -3177,20 +3573,21 @@ done:
*
*-------------------------------------------------------------------------
*/
-htri_t
-H5L_exists_tolerant(const H5G_loc_t *loc, const char *name)
+herr_t
+H5L_exists_tolerant(const H5G_loc_t *loc, const char *name, hbool_t *exists)
{
- H5L_trav_le_t udata; /* User data for traversal */
- H5G_traverse_t cb_func; /* Callback function for tranversal */
- char * name_copy = NULL; /* Duplicate of name */
- char * name_trav; /* Name to traverse */
- htri_t ret_value = FAIL; /* Return value */
+ H5L_trav_le_t udata; /* User data for traversal */
+ H5G_traverse_t cb_func; /* Callback function for tranversal */
+ char * name_copy = NULL; /* Duplicate of name */
+ char * name_trav; /* Name to traverse */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* Sanity checks */
HDassert(loc);
HDassert(name);
+ HDassert(exists);
/* Copy the name and skip leading '/'s */
name_trav = name_copy = H5MM_strdup(name);
@@ -3199,27 +3596,25 @@ H5L_exists_tolerant(const H5G_loc_t *loc, const char *name)
/* A path of "/" will always exist in a file */
if ('\0' == *name_trav)
- HGOTO_DONE(TRUE)
-
- /* Set up user data & correct callback */
- udata.exists = FALSE;
- if (NULL == (udata.sep = HDstrchr(name_trav, '/')))
- cb_func = H5L__exists_final_cb;
+ *exists = TRUE;
else {
- /* Chew through adjacent separators, if present */
- do {
- *udata.sep = '\0';
- udata.sep++;
- } while ('/' == *udata.sep);
- cb_func = H5L__exists_inter_cb;
- } /* end else */
-
- /* Traverse the group hierarchy to locate the link to check */
- if (H5G_traverse(loc, name_trav, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, cb_func, &udata) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't determine if link exists")
+ /* Set up user data & correct callback */
+ udata.exists = exists;
+ if (NULL == (udata.sep = HDstrchr(name_trav, '/')))
+ cb_func = H5L__exists_final_cb;
+ else {
+ /* Chew through adjacent separators, if present */
+ do {
+ *udata.sep = '\0';
+ udata.sep++;
+ } while ('/' == *udata.sep);
+ cb_func = H5L__exists_inter_cb;
+ } /* end else */
- /* Set return value */
- ret_value = (htri_t)udata.exists;
+ /* Traverse the group hierarchy to locate the link to check */
+ if (H5G_traverse(loc, name_trav, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, cb_func, &udata) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't determine if link exists")
+ }
done:
/* Release duplicated string */
@@ -3236,36 +3631,35 @@ done:
* Note: Same as H5L_exists_tolerant, except that missing links are reported
* as failures
*
- * Return: Non-negative (TRUE/FALSE) on success/Negative on failure
+ * Return: Non-negative on success, with *exists set/Negative on failure
*
* Programmer: Quincey Koziol
* Friday, March 16 2007
*
*-------------------------------------------------------------------------
*/
-htri_t
-H5L__exists(const H5G_loc_t *loc, const char *name)
+herr_t
+H5L__exists(const H5G_loc_t *loc, const char *name, hbool_t *exists)
{
- H5L_trav_le_t udata; /* User data for traversal */
- htri_t ret_value = FAIL; /* Return value */
+ H5L_trav_le_t udata; /* User data for traversal */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
/* Sanity checks */
HDassert(loc);
HDassert(name);
+ HDassert(exists);
/* A path of "/" will always exist in a file */
if (0 == HDstrcmp(name, "/"))
- HGOTO_DONE(TRUE)
-
- /* Traverse the group hierarchy to locate the object to get info about */
- udata.exists = FALSE;
- if (H5G_traverse(loc, name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L__exists_final_cb, &udata) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_EXISTS, FAIL, "path doesn't exist")
-
- /* Set return value */
- ret_value = (htri_t)udata.exists;
+ *exists = TRUE;
+ else {
+ /* Traverse the group hierarchy to locate the object to get info about */
+ udata.exists = exists;
+ if (H5G_traverse(loc, name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L__exists_final_cb, &udata) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_EXISTS, FAIL, "link doesn't exist")
+ }
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c
index 1081c85..d60f996 100644
--- a/src/H5Lexternal.c
+++ b/src/H5Lexternal.c
@@ -251,8 +251,7 @@ done:
if (ret_value < 0) {
/* Close object if it's open and something failed */
if (ext_obj_id >= 0 && H5I_dec_ref(ext_obj_id) < 0)
- HDONE_ERROR(H5E_ID, H5E_CANTRELEASE, H5I_INVALID_HID,
- "unable to close ID for external object")
+ HDONE_ERROR(H5E_ID, H5E_CANTRELEASE, H5I_INVALID_HID, "unable to close ID for external object")
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Lpkg.h b/src/H5Lpkg.h
index fe08ea4..6cbe087 100644
--- a/src/H5Lpkg.h
+++ b/src/H5Lpkg.h
@@ -59,7 +59,7 @@ H5_DLL herr_t H5L__create_soft(const char *target_path, const H5G_loc_t *cur_lo
hid_t lcpl_id);
H5_DLL herr_t H5L__create_ud(const H5G_loc_t *link_loc, const char *link_name, const void *ud_data,
size_t ud_data_size, H5L_type_t type, hid_t lcpl_id);
-H5_DLL htri_t H5L__exists(const H5G_loc_t *loc, const char *name);
+H5_DLL herr_t H5L__exists(const H5G_loc_t *loc, const char *name, hbool_t *exists);
H5_DLL herr_t H5L__get_info_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, H5L_info2_t *linfo /*out*/);
H5_DLL ssize_t H5L__get_name_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx_type,
diff --git a/src/H5Lprivate.h b/src/H5Lprivate.h
index 5bc8d35..ed7ef4b 100644
--- a/src/H5Lprivate.h
+++ b/src/H5Lprivate.h
@@ -114,7 +114,7 @@ H5_DLL herr_t H5L_init(void);
H5_DLL herr_t H5L_link(const H5G_loc_t *new_loc, const char *new_name, H5G_loc_t *obj_loc, hid_t lcpl_id);
H5_DLL herr_t H5L_link_object(const H5G_loc_t *new_loc, const char *new_name, H5O_obj_create_t *ocrt_info,
hid_t lcpl_id);
-H5_DLL htri_t H5L_exists_tolerant(const H5G_loc_t *loc, const char *name);
+H5_DLL herr_t H5L_exists_tolerant(const H5G_loc_t *loc, const char *name, hbool_t *exists);
H5_DLL herr_t H5L_get_info(const H5G_loc_t *loc, const char *name, H5L_info2_t *linkbuf /*out*/);
H5_DLL herr_t H5L_register_external(void);
H5_DLL herr_t H5L_iterate(H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, H5_iter_order_t order,
diff --git a/src/H5Lpublic.h b/src/H5Lpublic.h
index e930a15..4154518 100644
--- a/src/H5Lpublic.h
+++ b/src/H5Lpublic.h
@@ -357,6 +357,9 @@ H5_DLL herr_t H5Lcopy(hid_t src_loc, const char *src_name, hid_t dst_loc, const
*/
H5_DLL herr_t H5Lcreate_hard(hid_t cur_loc, const char *cur_name, hid_t dst_loc, const char *dst_name,
hid_t lcpl_id, hid_t lapl_id);
+H5_DLL herr_t H5Lcreate_hard_async(const char *app_file, const char *app_func, unsigned app_line,
+ hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id,
+ const char *new_name, hid_t lcpl_id, hid_t lapl_id, hid_t es_id);
/**
* \ingroup H5L
*
@@ -423,6 +426,9 @@ H5_DLL herr_t H5Lcreate_hard(hid_t cur_loc, const char *cur_name, hid_t dst_loc,
*/
H5_DLL herr_t H5Lcreate_soft(const char *link_target, hid_t link_loc_id, const char *link_name, hid_t lcpl_id,
hid_t lapl_id);
+H5_DLL herr_t H5Lcreate_soft_async(const char *app_file, const char *app_func, unsigned app_line,
+ const char *link_target, hid_t link_loc_id, const char *link_name,
+ hid_t lcpl_id, hid_t lapl_id, hid_t es_id);
/**
* \ingroup H5L
*
@@ -462,6 +468,8 @@ H5_DLL herr_t H5Lcreate_soft(const char *link_target, hid_t link_loc_id, const c
*
*/
H5_DLL herr_t H5Ldelete(hid_t loc_id, const char *name, hid_t lapl_id);
+H5_DLL herr_t H5Ldelete_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *name, hid_t lapl_id, hid_t es_id);
/**
* \ingroup H5L
*
@@ -492,6 +500,9 @@ H5_DLL herr_t H5Ldelete(hid_t loc_id, const char *name, hid_t lapl_id);
*/
H5_DLL herr_t H5Ldelete_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, hid_t lapl_id);
+H5_DLL herr_t H5Ldelete_by_idx_async(const char *app_file, const char *app_func, unsigned app_line,
+ hid_t loc_id, const char *group_name, H5_index_t idx_type,
+ H5_iter_order_t order, hsize_t n, hid_t lapl_id, hid_t es_id);
/**
* \ingroup H5L
*
@@ -696,6 +707,8 @@ H5_DLL herr_t H5Lget_val_by_idx(hid_t loc_id, const char *group_name, H5_index_t
*
*/
H5_DLL htri_t H5Lexists(hid_t loc_id, const char *name, hid_t lapl_id);
+H5_DLL herr_t H5Lexists_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *name, hbool_t *exists, hid_t lapl_id, hid_t es_id);
/**
* \ingroup H5L
*
@@ -944,6 +957,9 @@ H5_DLL ssize_t H5Lget_name_by_idx(hid_t loc_id, const char *group_name, H5_index
*/
H5_DLL herr_t H5Literate2(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx,
H5L_iterate2_t op, void *op_data);
+H5_DLL herr_t H5Literate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t group_id,
+ H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, H5L_iterate2_t op,
+ void *op_data, hid_t es_id);
/**
* \ingroup TRAV
*
@@ -1591,6 +1607,28 @@ H5_DLL herr_t H5Lunpack_elink_val(const void *ext_linkval /*in*/, size_t link_si
H5_DLL herr_t H5Lcreate_external(const char *file_name, const char *obj_name, hid_t link_loc_id,
const char *link_name, hid_t lcpl_id, hid_t lapl_id);
+/* API Wrappers for async routines */
+/* (Must be defined _after_ the function prototype) */
+/* (And must only defined when included in application code, not the library) */
+#ifndef H5L_MODULE
+#define H5Lcreate_hard_async(...) H5Lcreate_hard_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Lcreate_soft_async(...) H5Lcreate_soft_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Ldelete_async(...) H5Ldelete_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Ldelete_by_idx_async(...) H5Ldelete_by_idx_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Lexists_async(...) H5Lexists_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Literate_async(...) H5Literate_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+
+/* Define "wrapper" versions of function calls, to allow compile-time values to
+ * be passed in by language wrapper or library layer on top of HDF5.
+ */
+#define H5Lcreate_hard_async_wrap H5_NO_EXPAND(H5Lcreate_hard_async)
+#define H5Lcreate_soft_async_wrap H5_NO_EXPAND(H5Lcreate_soft_async)
+#define H5Ldelete_async_wrap H5_NO_EXPAND(H5Ldelete_async)
+#define H5Ldelete_by_idx_async_wrap H5_NO_EXPAND(H5Ldelete_by_idx_async)
+#define H5Lexists_async_wrap H5_NO_EXPAND(H5Lexists_async)
+#define H5Literate_async_wrap H5_NO_EXPAND(H5Literate_async)
+#endif /* H5L_MODULE */
+
/* Symbols defined for compatibility with previous versions of the HDF5 API.
*
* Use of these symbols is deprecated.
diff --git a/src/H5M.c b/src/H5M.c
index 4cb5d3a..cb8ed13 100644
--- a/src/H5M.c
+++ b/src/H5M.c
@@ -24,6 +24,7 @@
#include "H5CXprivate.h" /* API Contexts */
#include "H5Mpkg.h" /* Maps */
#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event Sets */
#include "H5Iprivate.h" /* IDs */
#include "H5VLprivate.h" /* Virtual Object Layer */
@@ -40,6 +41,19 @@
/********************/
static herr_t H5M__close_cb(H5VL_object_t *map_vol_obj, void **request);
+#ifdef H5_HAVE_MAP_API
+static hid_t H5M__create_api_common(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id,
+ hid_t lcpl_id, hid_t mcpl_id, hid_t mapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static hid_t H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static herr_t H5M__put_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id,
+ const void *value, hid_t dxpl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static herr_t H5M__get_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id,
+ void *value, hid_t dxpl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr);
+#endif /* H5_HAVE_MAP_API */
+
/*********************/
/* Package Variables */
/*********************/
@@ -219,15 +233,9 @@ done:
#ifdef H5_HAVE_MAP_API
/*-------------------------------------------------------------------------
- * Function: H5Mcreate
+ * Function: H5M__create_api_common
*
- * Purpose: Creates a new map object for storing key-value pairs. The
- * in-file datatype for keys is defined by KEY_TYPE_ID and
- * the in-file datatype for values is defined by VAL_TYPE_ID.
- * LOC_ID specifies the location to create the map object and
- * NAME specifies the name of the link to the object
- * (relative to LOC_ID). Other options can be specified
- * through the property lists LCPL_ID, MCPL_ID, and MAPL_ID.
+ * Purpose: This is the common function for creating the HDF5 map.
*
* Return: Success: The object ID of the new map.
*
@@ -235,17 +243,18 @@ done:
*
*-------------------------------------------------------------------------
*/
-hid_t
-H5Mcreate(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id, hid_t mcpl_id,
- hid_t mapl_id)
+static hid_t
+H5M__create_api_common(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id,
+ hid_t mcpl_id, hid_t mapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
{
- void * map = NULL; /* New map's info */
- H5VL_object_t * vol_obj = NULL; /* object of loc_id */
- H5VL_loc_params_t loc_params;
- hid_t ret_value = H5I_INVALID_HID; /* Return value */
+ void * map = NULL; /* New map's info */
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
- FUNC_ENTER_API(H5I_INVALID_HID)
- H5TRACE7("i", "i*siiiii", loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id);
+ FUNC_ENTER_STATIC
/* Check arguments */
if (!name)
@@ -265,37 +274,112 @@ H5Mcreate(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id,
else if (TRUE != H5P_isa_class(mcpl_id, H5P_MAP_CREATE))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "mcpl_id is not a map create property list ID")
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&mapl_id, H5P_CLS_MACC, loc_id, TRUE) < 0)
- HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
-
- /* Get the location object */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
-
- /* Set location parameters */
- loc_params.type = H5VL_OBJECT_BY_SELF;
- loc_params.obj_type = H5I_get_type(loc_id);
+ /* Set up object access arguments */
+ if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, TRUE, &mapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")
/* Create the map */
- if (H5VL_optional(vol_obj, H5VL_MAP_CREATE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, name,
+ if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_CREATE, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, name,
lcpl_id, key_type_id, val_type_id, mcpl_id, mapl_id, &map) < 0)
HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, H5I_INVALID_HID, "unable to create map")
/* Get an ID for the map */
- if ((ret_value = H5VL_register(H5I_MAP, map, vol_obj->connector, TRUE)) < 0)
+ if ((ret_value = H5VL_register(H5I_MAP, map, (*vol_obj_ptr)->connector, TRUE)) < 0)
HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register map handle")
done:
/* Cleanup on failure */
if (H5I_INVALID_HID == ret_value)
- if (map && H5VL_optional(vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
+ if (map && H5VL_optional(*vol_obj_ptr, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map")
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5M__create_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mcreate
+ *
+ * Purpose: Creates a new map object for storing key-value pairs. The
+ * in-file datatype for keys is defined by KEY_TYPE_ID and
+ * the in-file datatype for values is defined by VAL_TYPE_ID.
+ * LOC_ID specifies the location to create the map object and
+ * NAME specifies the name of the link to the object
+ * (relative to LOC_ID). Other options can be specified
+ * through the property lists LCPL_ID, MCPL_ID, and MAPL_ID.
+ *
+ * Return: Success: The object ID of the new map.
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Mcreate(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id, hid_t mcpl_id,
+ hid_t mapl_id)
+{
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE7("i", "i*siiiii", loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id);
+
+ /* Create the map synchronously */
+ if ((ret_value = H5M__create_api_common(loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id,
+ NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create map synchronously")
+
+done:
FUNC_LEAVE_API(ret_value)
} /* end H5Mcreate() */
/*-------------------------------------------------------------------------
+ * Function: H5Mcreate_async
+ *
+ * Purpose: Asynchronous version of H5Mcreate
+ *
+ * Return: Success: The object ID of the new map.
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Mcreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name,
+ hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id, hid_t mcpl_id, hid_t mapl_id,
+ hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE11("i", "*s*sIui*siiiiii", app_file, app_func, app_line, loc_id, name, key_type_id, val_type_id,
+ lcpl_id, mcpl_id, mapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token;
+
+ /* Create the map asynchronously */
+ if ((ret_value = H5M__create_api_common(loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id,
+ token_ptr, &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create map asynchronously")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE11(FUNC, "*s*sIui*siiiiii", app_file, app_func, app_line, loc_id, name,
+ key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id, es_id)) < 0) {
+ if (H5I_dec_app_ref_always_close(ret_value) < 0)
+ HDONE_ERROR(H5E_MAP, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on map ID")
+ HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mcreate_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5Mcreate_anon
*
* Purpose: Creates a new map object for storing key-value pairs. The
@@ -367,13 +451,9 @@ done:
} /* end H5Mcreate_anon() */
/*------------------------------------------------------------------------
- * Function: H5Mopen
- *
- * Purpose: Finds a map named NAME at LOC_ID, opens it, and returns
- * its ID. The map should be close when the caller is no
- * longer interested in it.
+ * Function: H5M__open_api_common
*
- * Takes a map access property list
+ * Purpose: This is the common function for opening the HDF5 map.
*
* Return: Success: Object ID of the map
*
@@ -381,16 +461,18 @@ done:
*
*-------------------------------------------------------------------------
*/
-hid_t
-H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id)
+static hid_t
+H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
{
- void * map = NULL; /* map object from VOL connector */
- H5VL_object_t * vol_obj = NULL; /* object of loc_id */
- H5VL_loc_params_t loc_params;
- hid_t ret_value = H5I_INVALID_HID; /* Return value */
+ void * map = NULL; /* map object from VOL connector */
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
- FUNC_ENTER_API(H5I_INVALID_HID)
- H5TRACE3("i", "i*si", loc_id, name, mapl_id);
+ FUNC_ENTER_STATIC
/* Check args */
if (!name)
@@ -398,36 +480,111 @@ H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id)
if (!*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string")
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&mapl_id, H5P_CLS_MACC, loc_id, FALSE) < 0)
- HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
-
- /* get the location object */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
-
- /* Set the location parameters */
- loc_params.type = H5VL_OBJECT_BY_SELF;
- loc_params.obj_type = H5I_get_type(loc_id);
+ /* Set up object access arguments */
+ if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, FALSE, &mapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")
/* Open the map */
- if (H5VL_optional(vol_obj, H5VL_MAP_OPEN, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, name,
+ if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_OPEN, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, name,
mapl_id, &map) < 0)
HGOTO_ERROR(H5E_MAP, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open map")
/* Register an ID for the map */
- if ((ret_value = H5VL_register(H5I_MAP, map, vol_obj->connector, TRUE)) < 0)
+ if ((ret_value = H5VL_register(H5I_MAP, map, (*vol_obj_ptr)->connector, TRUE)) < 0)
HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register map ID")
done:
/* Cleanup on failure */
if (H5I_INVALID_HID == ret_value)
+ if (map && H5VL_optional(*vol_obj_ptr, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5M__open_api_common() */
+
+/*------------------------------------------------------------------------
+ * Function: H5Mopen
+ *
+ * Purpose: Finds a map named NAME at LOC_ID, opens it, and returns
+ * its ID. The map should be close when the caller is no
+ * longer interested in it.
+ *
+ * Takes a map access property list
+ *
+ * Return: Success: Object ID of the map
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id)
+{
+ void * map = NULL; /* map object from VOL connector */
+ H5VL_object_t *vol_obj = NULL; /* object of loc_id */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE3("i", "i*si", loc_id, name, mapl_id);
+
+ /* Open the map synchronously */
+ if ((ret_value = H5M__open_api_common(loc_id, name, mapl_id, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to open map synchronously")
+
+done:
+ /* Cleanup on failure */
+ if (H5I_INVALID_HID == ret_value)
if (map && H5VL_optional(vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map")
FUNC_LEAVE_API(ret_value)
} /* end H5Mopen() */
+/*------------------------------------------------------------------------
+ * Function: H5Mopen_async
+ *
+ * Purpose: Asynchronous version of H5Mopen
+ *
+ * Return: Success: Object ID of the map
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Mopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name,
+ hid_t mapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE7("i", "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, mapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token;
+
+ /* Open the map asynchronously */
+ if ((ret_value = H5M__open_api_common(loc_id, name, mapl_id, token_ptr, &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to open map asynchronously")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE7(FUNC, "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, mapl_id,
+ es_id)) < 0) {
+ if (H5I_dec_app_ref_always_close(ret_value) < 0)
+ HDONE_ERROR(H5E_MAP, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on map ID")
+ HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mopen_async() */
+
/*-------------------------------------------------------------------------
* Function: H5Mclose
*
@@ -462,6 +619,65 @@ done:
} /* end H5Mclose() */
/*-------------------------------------------------------------------------
+ * Function: H5Mclose_async
+ *
+ * Purpose: Asynchronous version of H5Mclose
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Mclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id, hid_t es_id)
+{
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ H5VL_object_t *vol_obj = NULL; /* VOL object of dset_id */
+ H5VL_t * connector = NULL; /* VOL connector */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, map_id, es_id);
+
+ /* Check args */
+ if (H5I_MAP != H5I_get_type(map_id))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a map ID")
+
+ /* Get dataset object's connector */
+ if (NULL == (vol_obj = H5VL_vol_object(map_id)))
+ HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "can't get VOL object for dataset")
+
+ /* Prepare for possible asynchronous operation */
+ if (H5ES_NONE != es_id) {
+ /* Increase connector's refcount, so it doesn't get closed if closing
+ * the dataset closes the file */
+ connector = vol_obj->connector;
+ H5VL_conn_inc_rc(connector);
+
+ /* Point at token for operation to set up */
+ token_ptr = &token;
+ } /* end if */
+
+ /* Decrement the counter on the map. It will be freed if the count
+ * reaches zero.
+ */
+ if (H5I_dec_app_ref_always_close_async(map_id, token_ptr) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, map_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ if (connector && H5VL_conn_dec_rc(connector) < 0)
+ HDONE_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "can't decrement ref count on connector")
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mclose_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5Mget_key_type
*
* Purpose: Returns a copy of the key datatype for a map.
@@ -647,6 +863,54 @@ done:
} /* end H5Mget_count() */
/*-------------------------------------------------------------------------
+ * Function: H5M__put_api_common
+ *
+ * Purpose: This is the common function for putting value to map.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5M__put_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id,
+ const void *value, hid_t dxpl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check arguments */
+ if (key_mem_type_id < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID")
+ if (val_mem_type_id < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid value memory datatype ID")
+
+ /* Get map pointer */
+ if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID")
+
+ /* Get the default dataset transfer property list if the user didn't provide one */
+ if (H5P_DEFAULT == dxpl_id)
+ dxpl_id = H5P_DATASET_XFER_DEFAULT;
+ else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
+
+ /* Set DXPL for operation */
+ H5CX_set_dxpl(dxpl_id);
+
+ /* Set the key/value pair */
+ if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_PUT, dxpl_id, token_ptr, key_mem_type_id, key, val_mem_type_id,
+ value) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTSET, FAIL, "unable to put key/value pair")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5M__put_api_common() */
+
+/*-------------------------------------------------------------------------
* Function: H5Mput
*
* Purpose: H5Mput adds a key-value pair to the Map specified by
@@ -666,12 +930,83 @@ herr_t
H5Mput(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, const void *value,
hid_t dxpl_id)
{
- H5VL_object_t *vol_obj = NULL;
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE6("e", "ii*xi*xi", map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id);
+ /* Add key-value pair to the map synchronously */
+ if ((ret_value = H5M__put_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, NULL,
+ NULL)) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTPUT, FAIL, "unable to put value to map synchronously")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mput() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mput_async
+ *
+ * Purpose: Asynchronous version of H5Mput
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Mput_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id,
+ hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, const void *value, hid_t dxpl_id,
+ hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE10("e", "*s*sIuii*xi*xii", app_file, app_func, app_line, map_id, key_mem_type_id, key,
+ val_mem_type_id, value, dxpl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token;
+
+ /* Add key-value pair to the map asynchronously */
+ if ((ret_value = H5M__put_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id,
+ token_ptr, &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTPUT, FAIL, "unable to put value to map asynchronously")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE10(FUNC, "*s*sIuii*xi*xii", app_file, app_func, app_line, map_id,
+ key_mem_type_id, key, val_mem_type_id, value, dxpl_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mput_async() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5M__get_api_common
+ *
+ * Purpose: This is common function for getting value from the map.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5M__get_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value,
+ hid_t dxpl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
/* Check arguments */
if (key_mem_type_id < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID")
@@ -679,7 +1014,7 @@ H5Mput(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid value memory datatype ID")
/* Get map pointer */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
+ if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID")
/* Get the default dataset transfer property list if the user didn't provide one */
@@ -691,14 +1026,14 @@ H5Mput(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_
/* Set DXPL for operation */
H5CX_set_dxpl(dxpl_id);
- /* Set the key/value pair */
- if (H5VL_optional(vol_obj, H5VL_MAP_PUT, dxpl_id, H5_REQUEST_NULL, key_mem_type_id, key, val_mem_type_id,
- value) < 0)
- HGOTO_ERROR(H5E_MAP, H5E_CANTSET, FAIL, "unable to put key/value pair")
+ /* Get the value for the key */
+ if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_GET_VAL, dxpl_id, token_ptr, key_mem_type_id, key,
+ val_mem_type_id, value) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map")
done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Mput() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5M__get_api_common() */
/*-------------------------------------------------------------------------
* Function: H5Mget
@@ -723,39 +1058,62 @@ herr_t
H5Mget(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value,
hid_t dxpl_id)
{
- H5VL_object_t *vol_obj = NULL;
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE6("e", "ii*xi*xi", map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id);
- /* Check arguments */
- if (key_mem_type_id < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID")
- if (val_mem_type_id < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid value memory datatype ID")
+ /* Get key-value pair from the map synchronously */
+ if ((ret_value = H5M__get_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, NULL,
+ NULL)) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map synchronously")
- /* Get map pointer */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mget() */
- /* Get the default dataset transfer property list if the user didn't provide one */
- if (H5P_DEFAULT == dxpl_id)
- dxpl_id = H5P_DATASET_XFER_DEFAULT;
- else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
+/*-------------------------------------------------------------------------
+ * Function: H5Mget_async
+ *
+ * Purpose: Asynchronous version of H5Mget
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Mget_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id,
+ hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value, hid_t dxpl_id,
+ hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Set DXPL for operation */
- H5CX_set_dxpl(dxpl_id);
+ FUNC_ENTER_API(FAIL)
+ H5TRACE10("e", "*s*sIuii*xi*xii", app_file, app_func, app_line, map_id, key_mem_type_id, key,
+ val_mem_type_id, value, dxpl_id, es_id);
- /* Get the value for the key */
- if (H5VL_optional(vol_obj, H5VL_MAP_GET_VAL, dxpl_id, H5_REQUEST_NULL, key_mem_type_id, key,
- val_mem_type_id, value) < 0)
- HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map")
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token;
+
+ /* Get key-value pair from the map asynchronously */
+ if ((ret_value = H5M__get_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id,
+ token_ptr, &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map asynchronously")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE10(FUNC, "*s*sIuii*xi*xii", app_file, app_func, app_line, map_id,
+ key_mem_type_id, key, val_mem_type_id, value, dxpl_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, FAIL, "can't insert token into event set")
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Mget() */
+} /* end H5Mget_async() */
/*-------------------------------------------------------------------------
* Function: H5Mexists
diff --git a/src/H5MM.c b/src/H5MM.c
index ca358bf..1effd6a 100644
--- a/src/H5MM.c
+++ b/src/H5MM.c
@@ -52,7 +52,8 @@
/* Memory allocation "block", wrapped around each allocation */
struct H5MM_block_t; /* Forward declaration for typedef */
typedef struct H5MM_block_t {
- unsigned char sig[H5MM_SIG_SIZE]; /* Signature for the block, to indicate it was allocated with H5MM* interface */
+ unsigned char
+ sig[H5MM_SIG_SIZE]; /* Signature for the block, to indicate it was allocated with H5MM* interface */
struct H5MM_block_t *next; /* Pointer to next block in the list of allocated blocks */
struct H5MM_block_t *prev; /* Pointer to previous block in the list of allocated blocks */
union {
diff --git a/src/H5MMprivate.h b/src/H5MMprivate.h
index 7c34a98..b4a59ba 100644
--- a/src/H5MMprivate.h
+++ b/src/H5MMprivate.h
@@ -48,9 +48,9 @@ H5_DLL void * H5MM_xfree(void *mem);
H5_DLL void * H5MM_xfree_const(const void *mem);
H5_DLL void * H5MM_memcpy(void *dest, const void *src, size_t n);
H5_DLL herr_t H5MM_get_alloc_stats(H5_alloc_stats_t *stats);
-#if defined H5_MEMORY_ALLOC_SANITY_CHECK
-H5_DLL void H5MM_sanity_check_all(void);
-H5_DLL void H5MM_final_sanity_check(void);
+#if defined H5_MEMORY_ALLOC_SANITY_CHECK
+H5_DLL void H5MM_sanity_check_all(void);
+H5_DLL void H5MM_final_sanity_check(void);
#endif /* H5_MEMORY_ALLOC_SANITY_CHECK */
#endif /* _H5MMprivate_H */
diff --git a/src/H5Mpublic.h b/src/H5Mpublic.h
index 643a1e6..5c8ba23 100644
--- a/src/H5Mpublic.h
+++ b/src/H5Mpublic.h
@@ -83,9 +83,16 @@ extern "C" {
H5_DLL hid_t H5Mcreate(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id,
hid_t mcpl_id, hid_t mapl_id);
+H5_DLL hid_t H5Mcreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *name, hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id,
+ hid_t mcpl_id, hid_t mapl_id, hid_t es_id);
H5_DLL hid_t H5Mcreate_anon(hid_t loc_id, hid_t key_type_id, hid_t val_type_id, hid_t mcpl_id, hid_t mapl_id);
H5_DLL hid_t H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id);
+H5_DLL hid_t H5Mopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *name, hid_t mapl_id, hid_t es_id);
H5_DLL herr_t H5Mclose(hid_t map_id);
+H5_DLL herr_t H5Mclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id,
+ hid_t es_id);
H5_DLL hid_t H5Mget_key_type(hid_t map_id);
H5_DLL hid_t H5Mget_val_type(hid_t map_id);
H5_DLL hid_t H5Mget_create_plist(hid_t map_id);
@@ -93,8 +100,14 @@ H5_DLL hid_t H5Mget_access_plist(hid_t map_id);
H5_DLL herr_t H5Mget_count(hid_t map_id, hsize_t *count, hid_t dxpl_id);
H5_DLL herr_t H5Mput(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id,
const void *value, hid_t dxpl_id);
+H5_DLL herr_t H5Mput_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id,
+ hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, const void *value,
+ hid_t dxpl_id, hid_t es_id);
H5_DLL herr_t H5Mget(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value,
hid_t dxpl_id);
+H5_DLL herr_t H5Mget_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id,
+ hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value,
+ hid_t dxpl_id, hid_t es_id);
H5_DLL herr_t H5Mexists(hid_t map_id, hid_t key_mem_type_id, const void *key, hbool_t *exists, hid_t dxpl_id);
H5_DLL herr_t H5Miterate(hid_t map_id, hsize_t *idx, hid_t key_mem_type_id, H5M_iterate_t op, void *op_data,
hid_t dxpl_id);
@@ -102,6 +115,25 @@ H5_DLL herr_t H5Miterate_by_name(hid_t loc_id, const char *map_name, hsize_t *id
H5M_iterate_t op, void *op_data, hid_t dxpl_id, hid_t lapl_id);
H5_DLL herr_t H5Mdelete(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t dxpl_id);
+/* API Wrappers for async routines */
+/* (Must be defined _after_ the function prototype) */
+/* (And must only defined when included in application code, not the library) */
+#ifndef H5M_MODULE
+#define H5Mcreate_async(...) H5Mcreate_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Mopen_async(...) H5Mopen_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Mclose_async(...) H5Mclose_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Mput_async(...) H5Mput_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Mget_async(...) H5Mget_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+
+/* Define "wrapper" versions of function calls, to allow compile-time values to
+ * be passed in by language wrapper or library layer on top of HDF5. */
+#define H5Mcreate_async_wrap H5_NO_EXPAND(H5Mcreate_async)
+#define H5Mopen_async_wrap H5_NO_EXPAND(H5Mopen_async)
+#define H5Mclose_async_wrap H5_NO_EXPAND(H5Mclose_async)
+#define H5Mput_async_wrap H5_NO_EXPAND(H5Mput_async)
+#define H5Mget_async_wrap H5_NO_EXPAND(H5Mget_async)
+#endif /* H5M_MODULE */
+
/* Symbols defined for compatibility with previous versions of the HDF5 API.
*
* Use of these symbols is deprecated.
diff --git a/src/H5O.c b/src/H5O.c
index 9da011b..c0a295d 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -32,6 +32,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5CXprivate.h" /* API Contexts */
#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event Sets */
#include "H5Fprivate.h" /* File access */
#include "H5Iprivate.h" /* IDs */
#include "H5Lprivate.h" /* Links */
@@ -55,6 +56,22 @@
/* Local Prototypes */
/********************/
+/* Helper routines for sync/async API calls */
+static hid_t H5O__open_api_common(hid_t loc_id, const char *name, hid_t lapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static hid_t H5O__open_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t idx_type,
+ H5_iter_order_t order, hsize_t n, hid_t lapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static herr_t H5O__get_info_by_name_api_common(hid_t loc_id, const char *name, H5O_info2_t *oinfo /*out*/,
+ unsigned fields, hid_t lapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static herr_t H5O__copy_api_common(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
+ const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static herr_t H5O__flush_api_common(hid_t obj_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr);
+static herr_t H5O__refresh_api_common(hid_t oid, void **token_ptr, H5VL_object_t **_vol_obj_ptr);
+static htri_t H5O__close_check_common(hid_t object_id);
+
/*********************/
/* Package Variables */
/*********************/
@@ -68,6 +85,50 @@
/*******************/
/*-------------------------------------------------------------------------
+ * Function: H5O__open_api_common
+ *
+ * Purpose: This is the common function for opening an object
+ *
+ * Return: Success: An open object identifier
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+H5O__open_api_common(hid_t loc_id, const char *name, hid_t lapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5I_type_t opened_type;
+ void * opened_obj = NULL;
+ H5VL_loc_params_t loc_params;
+ hid_t ret_value = H5I_INVALID_HID;
+
+ FUNC_ENTER_STATIC
+
+ /* Check args */
+
+ /* name is checked in this H5VL_setup_name_args() */
+ /* Set up object access arguments */
+ if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")
+
+ /* Open the object */
+ if (NULL == (opened_obj = H5VL_object_open(*vol_obj_ptr, &loc_params, &opened_type,
+ H5P_DATASET_XFER_DEFAULT, token_ptr)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object")
+
+ /* Get an atom for the object */
+ if ((ret_value = H5VL_register(opened_type, opened_obj, (*vol_obj_ptr)->connector, TRUE)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize object handle")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O__open_api_common() */
+
+/*-------------------------------------------------------------------------
* Function: H5Oopen
*
* Purpose: Opens an object within an HDF5 file.
@@ -93,47 +154,106 @@
hid_t
H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id)
{
- H5VL_object_t * vol_obj; /* Object of loc_id */
- H5I_type_t opened_type;
- void * opened_obj = NULL;
- H5VL_loc_params_t loc_params;
- hid_t ret_value = H5I_INVALID_HID;
+ hid_t ret_value = H5I_INVALID_HID;
FUNC_ENTER_API(H5I_INVALID_HID)
H5TRACE3("i", "i*si", loc_id, name, lapl_id);
- /* Check args */
- if (!name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL")
- if (!*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string")
+ /* Open the object synchronously */
+ if ((ret_value = H5O__open_api_common(loc_id, name, lapl_id, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to synchronously open object")
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Oopen() */
- /* Get the location object */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
+/*-------------------------------------------------------------------------
+ * Function: H5Oopen_async
+ *
+ * Purpose: Asynchronous version of H5Oopen
+ *
+ * Return: Success: An open object identifier
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Oopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name,
+ hid_t lapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
- /* Set location struct fields */
- loc_params.type = H5VL_OBJECT_BY_NAME;
- loc_params.loc_data.loc_by_name.name = name;
- loc_params.loc_data.loc_by_name.lapl_id = lapl_id;
- loc_params.obj_type = H5I_get_type(loc_id);
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE7("i", "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, lapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Open the object asynchronously */
+ if ((ret_value = H5O__open_api_common(loc_id, name, lapl_id, token_ptr, &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to asynchronously open object")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE7(FUNC, "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, lapl_id,
+ es_id)) < 0) {
+ if (H5I_dec_app_ref_always_close(ret_value) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on object ID")
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Oopen_async() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5O__open_by_idx_api_common
+ *
+ * Purpose: This is the common function for opening an object within an index
+ *
+ * Return: Success: An open object identifier
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+H5O__open_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order,
+ hsize_t n, hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5I_type_t opened_type;
+ void * opened_obj = NULL;
+ H5VL_loc_params_t loc_params;
+ hid_t ret_value = H5I_INVALID_HID;
+
+ FUNC_ENTER_STATIC
+
+ /* Check args */
+ /* group_name, idx_type, order are checked in H5VL_setup_idx-args() */
+ /* Set up object access arguments */
+ if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr,
+ &loc_params) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")
/* Open the object */
- if (NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL)))
+ if (NULL == (opened_obj = H5VL_object_open(*vol_obj_ptr, &loc_params, &opened_type,
+ H5P_DATASET_XFER_DEFAULT, token_ptr)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object")
/* Get an ID for the object */
- if ((ret_value = H5VL_register(opened_type, opened_obj, vol_obj->connector, TRUE)) < 0)
+ if ((ret_value = H5VL_register(opened_type, opened_obj, (*vol_obj_ptr)->connector, TRUE)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle")
done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Oopen() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O__open_by_idx_api_common() */
/*-------------------------------------------------------------------------
* Function: H5Oopen_by_idx
@@ -162,50 +282,66 @@ hid_t
H5Oopen_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
hid_t lapl_id)
{
- H5VL_object_t * vol_obj; /* Object of loc_id */
- H5I_type_t opened_type;
- void * opened_obj = NULL;
- H5VL_loc_params_t loc_params;
- hid_t ret_value = H5I_INVALID_HID;
+ hid_t ret_value = H5I_INVALID_HID;
FUNC_ENTER_API(H5I_INVALID_HID)
H5TRACE6("i", "i*sIiIohi", loc_id, group_name, idx_type, order, n, lapl_id);
- /* Check args */
- if (!group_name || !*group_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no name specified")
- if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid index type specified")
- if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid iteration order specified")
-
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
+ /* Open the object synchronously */
+ if ((ret_value =
+ H5O__open_by_idx_api_common(loc_id, group_name, idx_type, order, n, lapl_id, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to synchronously open object")
- loc_params.type = H5VL_OBJECT_BY_IDX;
- loc_params.loc_data.loc_by_idx.name = group_name;
- loc_params.loc_data.loc_by_idx.idx_type = idx_type;
- loc_params.loc_data.loc_by_idx.order = order;
- loc_params.loc_data.loc_by_idx.n = n;
- loc_params.loc_data.loc_by_idx.lapl_id = lapl_id;
- loc_params.obj_type = H5I_get_type(loc_id);
-
- /* get the location object */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Oopen_by_idx() */
- /* Open the object */
- if (NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object")
+/*-------------------------------------------------------------------------
+ * Function: H5Oopen_by_idx_async
+ *
+ * Purpose: Asynchronous version of H5Oopen_by_idx
+ *
+ * Return: Success: An open object identifier
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Oopen_by_idx_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
+ hid_t lapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
- if ((ret_value = H5VL_register(opened_type, opened_obj, vol_obj->connector, TRUE)) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle")
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE10("i", "*s*sIui*sIiIohii", app_file, app_func, app_line, loc_id, group_name, idx_type, order, n,
+ lapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Open the object asynchronously */
+ if ((ret_value = H5O__open_by_idx_api_common(loc_id, group_name, idx_type, order, n, lapl_id, token_ptr,
+ &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to asynchronously open object")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE10(FUNC, "*s*sIui*sIiIohii", app_file, app_func, app_line, loc_id,
+ group_name, idx_type, order, n, lapl_id, es_id)) < 0) {
+ if (H5I_dec_app_ref_always_close(ret_value) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on object ID")
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ }
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Oopen_by_idx() */
+} /* end H5Oopen_by_idx_async() */
/*-------------------------------------------------------------------------
* Function: H5Oopen_by_token
@@ -263,6 +399,72 @@ done:
} /* end H5Oopen_by_token() */
/*-------------------------------------------------------------------------
+ * Function: H5O__copy_api_common
+ *
+ * Purpose: This is the common function for copying an object.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O__copy_api_common(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name,
+ hid_t ocpypl_id, hid_t lcpl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ /* dst_id */
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params2;
+
+ /* src_id */
+ H5VL_object_t * vol_obj1 = NULL; /* object of src_id */
+ H5VL_loc_params_t loc_params1;
+
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check arguments */
+ if (!src_name || !*src_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no source name specified")
+ if (!dst_name || !*dst_name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination name specified")
+
+ /* Get correct property lists */
+ if (H5P_DEFAULT == lcpl_id)
+ lcpl_id = H5P_LINK_CREATE_DEFAULT;
+ else if (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link creation property list")
+
+ /* Get object copy property list */
+ if (H5P_DEFAULT == ocpypl_id)
+ ocpypl_id = H5P_OBJECT_COPY_DEFAULT;
+ else if (TRUE != H5P_isa_class(ocpypl_id, H5P_OBJECT_COPY))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not object copy property list")
+
+ /* Set the LCPL for the API context */
+ H5CX_set_lcpl(lcpl_id);
+
+ if (H5VL_setup_loc_args(src_loc_id, &vol_obj1, &loc_params1) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set object access arguments")
+
+ /* get the object */
+ if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object(dst_loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+ loc_params2.type = H5VL_OBJECT_BY_SELF;
+ loc_params2.obj_type = H5I_get_type(dst_loc_id);
+
+ /* Copy the object */
+ if (H5VL_object_copy(vol_obj1, &loc_params1, src_name, *vol_obj_ptr, &loc_params2, dst_name, ocpypl_id,
+ lcpl_id, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O__copy_api_common() */
+
+/*-------------------------------------------------------------------------
* Function: H5Ocopy
*
* Purpose: Copy an object (group or dataset) to destination location
@@ -340,60 +542,95 @@ herr_t
H5Ocopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name, hid_t ocpypl_id,
hid_t lcpl_id)
{
- H5VL_object_t * vol_obj1 = NULL; /* object of src_id */
- H5VL_loc_params_t loc_params1;
- H5VL_object_t * vol_obj2 = NULL; /* object of dst_id */
- H5VL_loc_params_t loc_params2;
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE6("e", "i*si*sii", src_loc_id, src_name, dst_loc_id, dst_name, ocpypl_id, lcpl_id);
- /* Check arguments */
- if (!src_name || !*src_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no source name specified")
- if (!dst_name || !*dst_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination name specified")
-
- /* Get correct property lists */
- if (H5P_DEFAULT == lcpl_id)
- lcpl_id = H5P_LINK_CREATE_DEFAULT;
- else if (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link creation property list")
+ /* To copy an object synchronously */
+ if (H5O__copy_api_common(src_loc_id, src_name, dst_loc_id, dst_name, ocpypl_id, lcpl_id, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to synchronously copy object")
- /* Get object copy property list */
- if (H5P_DEFAULT == ocpypl_id)
- ocpypl_id = H5P_OBJECT_COPY_DEFAULT;
- else if (TRUE != H5P_isa_class(ocpypl_id, H5P_OBJECT_COPY))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not object copy property list")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Ocopy() */
- /* Set the LCPL for the API context */
- H5CX_set_lcpl(lcpl_id);
+/*-------------------------------------------------------------------------
+ * Function: H5Ocopy_async
+ *
+ * Purpose: Asynchronous version of H5Ocopy
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Ocopy_async(const char *app_file, const char *app_func, unsigned app_line, hid_t src_loc_id,
+ const char *src_name, hid_t dst_loc_id, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id,
+ hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Set up collective metadata if appropriate */
- if (H5CX_set_loc(src_loc_id) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set collective metadata read info")
+ FUNC_ENTER_API(FAIL)
+ H5TRACE10("e", "*s*sIui*si*siii", app_file, app_func, app_line, src_loc_id, src_name, dst_loc_id,
+ dst_name, ocpypl_id, lcpl_id, es_id);
- /* get the object */
- if (NULL == (vol_obj1 = (H5VL_object_t *)H5I_object(src_loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
- loc_params1.type = H5VL_OBJECT_BY_SELF;
- loc_params1.obj_type = H5I_get_type(src_loc_id);
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
- /* get the object */
- if (NULL == (vol_obj2 = (H5VL_object_t *)H5I_object(dst_loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
- loc_params2.type = H5VL_OBJECT_BY_SELF;
- loc_params2.obj_type = H5I_get_type(dst_loc_id);
+ /* To copy an object asynchronously */
+ if (H5O__copy_api_common(src_loc_id, src_name, dst_loc_id, dst_name, ocpypl_id, lcpl_id, token_ptr,
+ &vol_obj) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to asynchronously copy object")
- /* Copy the object */
- if (H5VL_object_copy(vol_obj1, &loc_params1, src_name, vol_obj2, &loc_params2, dst_name, ocpypl_id,
- lcpl_id, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE10(FUNC, "*s*sIui*si*siii", app_file, app_func, app_line, src_loc_id,
+ src_name, dst_loc_id, dst_name, ocpypl_id, lcpl_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert token into event set")
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Ocopy() */
+} /* H5Ocopy_async() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5O__flush_api_common
+ *
+ * Purpose: This is the common function for flushing an object.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O__flush_api_common(hid_t obj_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check args */
+
+ if (H5VL_setup_loc_args(obj_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set object access arguments")
+
+ /* Flush the object */
+ if (H5VL_object_specific(*vol_obj_ptr, &loc_params, H5VL_OBJECT_FLUSH, H5P_DATASET_XFER_DEFAULT,
+ token_ptr, obj_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O__flush_api_common() */
/*-------------------------------------------------------------------------
* Function: H5Oflush
@@ -410,33 +647,90 @@ done:
herr_t
H5Oflush(hid_t obj_id)
{
- H5VL_object_t * vol_obj = NULL; /* Object of obj_id */
- H5VL_loc_params_t loc_params;
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE1("e", "i", obj_id);
- /* Check args */
- if (NULL == (vol_obj = H5VL_vol_object(obj_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier")
+ /* To flush an object synchronously */
+ if (H5O__flush_api_common(obj_id, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to synchronously flush object")
- /* Set up collective metadata if appropriate */
- if (H5CX_set_loc(obj_id) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Oflush() */
- /* Set location parameters */
- loc_params.type = H5VL_OBJECT_BY_SELF;
- loc_params.obj_type = H5I_get_type(obj_id);
+/*-------------------------------------------------------------------------
+ * Function: H5Oflush_async
+ *
+ * Purpose: Asynchronous version of H5Oflush
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Oflush_async(const char *app_file, const char *app_func, unsigned app_line, hid_t obj_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Flush the object */
- if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_FLUSH, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL, obj_id) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object")
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, obj_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Flush an object asynchronously */
+ if (H5O__flush_api_common(obj_id, token_ptr, &vol_obj) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to asynchronously flush object")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, obj_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert token into event set")
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Oflush() */
+} /* H5Oflush_async() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5O__refresh_api_common
+ *
+ * Purpose: This is the common function for refreshing an object.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O__refresh_api_common(hid_t oid, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check args */
+
+ if (H5VL_setup_loc_args(oid, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set object access arguments")
+
+ /* Refresh the object */
+ if (H5VL_object_specific(*vol_obj_ptr, &loc_params, H5VL_OBJECT_REFRESH, H5P_DATASET_XFER_DEFAULT,
+ token_ptr, oid) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O__refresh_api_common() */
/*-------------------------------------------------------------------------
* Function: H5Orefresh
@@ -453,33 +747,56 @@ done:
herr_t
H5Orefresh(hid_t oid)
{
- H5VL_object_t * vol_obj = NULL; /* Object of oid */
- H5VL_loc_params_t loc_params;
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE1("e", "i", oid);
- /* Check args */
- if (NULL == (vol_obj = H5VL_vol_object(oid)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier")
+ /* To refresh an object synchronously */
+ if (H5O__refresh_api_common(oid, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to synchronously refresh object")
- /* Set up collective metadata if appropriate */
- if (H5CX_set_loc(oid) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Orefresh() */
- /* Set location parameters */
- loc_params.type = H5VL_OBJECT_BY_SELF;
- loc_params.obj_type = H5I_get_type(oid);
+/*-------------------------------------------------------------------------
+ * Function: H5Orefresh_async
+ *
+ * Purpose: Asynchronous version of H5Orefresh
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Orefresh_async(const char *app_file, const char *app_func, unsigned app_line, hid_t oid, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Refresh the object */
- if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_REFRESH, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL, oid) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object")
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, oid, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Refresh an object asynchronously */
+ if (H5O__refresh_api_common(oid, token_ptr, &vol_obj) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to asynchronously refresh object")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, oid, es_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert token into event set")
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Orefresh() */
+} /* H5Orefresh_async() */
/*-------------------------------------------------------------------------
* Function: H5Olink
@@ -774,6 +1091,48 @@ done:
} /* end H5Oget_info3() */
/*-------------------------------------------------------------------------
+ * Function: H5O__get_info_by_name_api_common
+ *
+ * Purpose: This is the common function for retrieving information
+ * about an object.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O__get_info_by_name_api_common(hid_t loc_id, const char *name, H5O_info2_t *oinfo /*out*/, unsigned fields,
+ hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
+{
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters for object access */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check args */
+ if (!oinfo)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "oinfo parameter cannot be NULL")
+ if (fields & ~H5O_INFO_ALL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid fields")
+
+ /* "name" is checked in H5VL_setup_name_args() */
+ /* Set up object access arguments */
+ if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set object access arguments")
+
+ /* Retrieve the object's information */
+ if (H5VL_object_get(*vol_obj_ptr, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, token_ptr,
+ oinfo, fields) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get data model info for object")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O__get_info_by_name_api_common() */
+
+/*-------------------------------------------------------------------------
* Function: H5Oget_info_by_name3
*
* Purpose: Retrieve information about an object
@@ -789,45 +1148,60 @@ herr_t
H5Oget_info_by_name3(hid_t loc_id, const char *name, H5O_info2_t *oinfo /*out*/, unsigned fields,
hid_t lapl_id)
{
- H5VL_object_t * vol_obj; /* Object of loc_id */
- H5VL_loc_params_t loc_params;
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE5("e", "i*sxIui", loc_id, name, oinfo, fields, lapl_id);
- /* Check args */
- if (!name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be NULL")
- if (!*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be an empty string")
- if (!oinfo)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "oinfo parameter cannot be NULL")
- if (fields & ~H5O_INFO_ALL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid fields")
+ /* Retrieve object information synchronously */
+ if (H5O__get_info_by_name_api_common(loc_id, name, oinfo, fields, lapl_id, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't synchronously retrieve object info")
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info")
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Oget_info_by_name3() */
- /* Fill out location struct */
- loc_params.type = H5VL_OBJECT_BY_NAME;
- loc_params.loc_data.loc_by_name.name = name;
- loc_params.loc_data.loc_by_name.lapl_id = lapl_id;
- loc_params.obj_type = H5I_get_type(loc_id);
+/*-------------------------------------------------------------------------
+ * Function: H5Oget_info_by_name_async
+ *
+ * Purpose: Asynchronous version of H5Oget_info_by_name3
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Oget_info_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *name, H5O_info2_t *oinfo /*out*/, unsigned fields, hid_t lapl_id,
+ hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Get the location object */
- if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+ FUNC_ENTER_API(FAIL)
+ H5TRACE9("e", "*s*sIui*sxIuii", app_file, app_func, app_line, loc_id, name, oinfo, fields, lapl_id,
+ es_id);
- /* Retrieve the object's information */
- if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL,
- oinfo, fields) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get data model info for object")
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Retrieve group information asynchronously */
+ if (H5O__get_info_by_name_api_common(loc_id, name, oinfo, fields, lapl_id, token_ptr, &vol_obj) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't asynchronously retrieve object info")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE9(FUNC, "*s*sIui*sxIuii", app_file, app_func, app_line, loc_id, name,
+ oinfo, fields, lapl_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert token into event set")
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Oget_info_by_name3() */
+} /* H5Oget_info_by_name_async() */
/*-------------------------------------------------------------------------
* Function: H5Oget_info_by_idx3
@@ -1411,29 +1785,21 @@ done:
} /* end H5Ovisit_by_name3() */
/*-------------------------------------------------------------------------
- * Function: H5Oclose
- *
- * Purpose: Close an open file object.
- *
- * This is the companion to H5Oopen. It is used to close any
- * open object in an HDF5 file (but not IDs are that not file
- * objects, such as property lists and dataspaces). It has
- * the same effect as calling H5Gclose, H5Dclose, or H5Tclose.
+ * Function: H5O__close_check_common
*
- * Return: SUCCEED/FAIL
+ * Purpose: This is the common function to validate an object
+ * when closing it.
*
- * Programmer: James Laird
- * July 14 2006
+ * Return: TRUE/FALSE/FAIL
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5Oclose(hid_t object_id)
+static htri_t
+H5O__close_check_common(hid_t object_id)
{
- herr_t ret_value = SUCCEED;
+ htri_t ret_value = TRUE; /* Return value */
- FUNC_ENTER_API(FAIL)
- H5TRACE1("e", "i", object_id);
+ FUNC_ENTER_STATIC
/* Get the type of the object and close it in the correct way */
switch (H5I_get_type(object_id)) {
@@ -1443,8 +1809,6 @@ H5Oclose(hid_t object_id)
case H5I_MAP:
if (H5I_object(object_id) == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object")
- if (H5I_dec_app_ref(object_id) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object")
break;
case H5I_UNINIT:
@@ -1460,18 +1824,114 @@ H5Oclose(hid_t object_id)
case H5I_ERROR_MSG:
case H5I_ERROR_STACK:
case H5I_SPACE_SEL_ITER:
+ case H5I_EVENTSET:
case H5I_NTYPES:
default:
- HGOTO_ERROR(H5E_ARGS, H5E_CANTRELEASE, FAIL,
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTRELEASE, FALSE,
"not a valid file object ID (dataset, group, or datatype)")
break;
} /* end switch */
done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O__close_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oclose
+ *
+ * Purpose: Close an open file object.
+ *
+ * This is the companion to H5Oopen. It is used to close any
+ * open object in an HDF5 file (but not IDs are that not file
+ * objects, such as property lists and dataspaces). It has
+ * the same effect as calling H5Gclose, H5Dclose, or H5Tclose.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: James Laird
+ * July 14 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Oclose(hid_t object_id)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("e", "i", object_id);
+
+ /* Validate the object type before closing */
+ if (H5O__close_check_common(object_id) <= 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "not a valid object")
+
+ if (H5I_dec_app_ref(object_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object")
+
+done:
FUNC_LEAVE_API(ret_value)
} /* end H5Oclose() */
/*-------------------------------------------------------------------------
+ * Function: H5Oclose_async
+ *
+ * Purpose: Asynchronous version of H5Oclose
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Oclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t object_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ H5VL_t * connector = NULL; /* VOL connector */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, object_id, es_id);
+
+ /* Validate the object type before closing */
+ if (H5O__close_check_common(object_id) <= 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "not a valid object")
+
+ /* Prepare for possible asynchronous operation */
+ if (H5ES_NONE != es_id) {
+ /* Get file object's connector */
+ if (NULL == (vol_obj = H5VL_vol_object(object_id)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get VOL object for object")
+
+ /* Increase connector's refcount, so it doesn't get closed if closing
+ * this object ID closes the file */
+ connector = vol_obj->connector;
+ H5VL_conn_inc_rc(connector);
+
+ /* Point at token for operation to set up */
+ token_ptr = &token;
+ } /* end if */
+
+ /* Asynchronously decrement reference count on ID.
+ * When it reaches zero the object will be closed.
+ */
+ if (H5I_dec_app_ref_async(object_id, token_ptr) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCLOSEFILE, FAIL, "decrementing object ID failed")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, object_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ if (connector && H5VL_conn_dec_rc(connector) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "can't decrement ref count on connector")
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Oclose_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5O_disable_mdc_flushes
*
* Purpose: Private version of the metadata cache cork function.
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index bf75634..6749459 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -93,6 +93,15 @@ typedef struct {
hbool_t found; /* Found attribute to delete */
} H5O_iter_rm_t;
+/* User data for iteration when checking if an attribute exists */
+typedef struct {
+ /* down */
+ const char *name; /* Name of attribute to open */
+
+ /* up */
+ hbool_t *exists; /* Pointer to flag to indicate attribute exists */
+} H5O_iter_xst_t;
+
/********************/
/* Package Typedefs */
/********************/
@@ -1723,19 +1732,19 @@ static herr_t
H5O__attr_exists_cb(H5O_t H5_ATTR_UNUSED *oh, H5O_mesg_t *mesg /*in,out*/, unsigned H5_ATTR_UNUSED sequence,
unsigned H5_ATTR_UNUSED *oh_modified, void *_udata /*in,out*/)
{
- H5O_iter_rm_t *udata = (H5O_iter_rm_t *)_udata; /* Operator user data */
- herr_t ret_value = H5_ITER_CONT; /* Return value */
+ H5O_iter_xst_t *udata = (H5O_iter_xst_t *)_udata; /* Operator user data */
+ herr_t ret_value = H5_ITER_CONT; /* Return value */
FUNC_ENTER_STATIC_NOERR
/* check args */
HDassert(mesg);
- HDassert(!udata->found);
+ HDassert(udata->exists && !*udata->exists);
/* Check for correct attribute message */
if (HDstrcmp(((H5A_t *)mesg->native)->shared->name, udata->name) == 0) {
/* Indicate that this message is the attribute sought */
- udata->found = TRUE;
+ *udata->exists = TRUE;
/* Stop iterating */
ret_value = H5_ITER_STOP;
@@ -1756,18 +1765,19 @@ H5O__attr_exists_cb(H5O_t H5_ATTR_UNUSED *oh, H5O_mesg_t *mesg /*in,out*/, unsig
*
*-------------------------------------------------------------------------
*/
-htri_t
-H5O__attr_exists(const H5O_loc_t *loc, const char *name)
+herr_t
+H5O__attr_exists(const H5O_loc_t *loc, const char *name, hbool_t *attr_exists)
{
- H5O_t * oh = NULL; /* Pointer to actual object header */
- H5O_ainfo_t ainfo; /* Attribute information for object */
- htri_t ret_value = FAIL; /* Return value */
+ H5O_t * oh = NULL; /* Pointer to actual object header */
+ H5O_ainfo_t ainfo; /* Attribute information for object */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE_TAG(loc->addr)
/* Check arguments */
HDassert(loc);
HDassert(name);
+ HDassert(attr_exists);
/* Protect the object header to iterate over */
if (NULL == (oh = H5O_protect(loc, H5AC__READ_ONLY_FLAG, FALSE)))
@@ -1784,26 +1794,22 @@ H5O__attr_exists(const H5O_loc_t *loc, const char *name)
/* Check for attributes stored densely */
if (H5F_addr_defined(ainfo.fheap_addr)) {
/* Check if attribute exists in dense storage */
- if ((ret_value = H5A__dense_exists(loc->file, &ainfo, name)) < 0)
+ if (H5A__dense_exists(loc->file, &ainfo, name, attr_exists) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "error checking for existence of attribute")
} /* end if */
else {
- H5O_iter_rm_t udata; /* User data for callback */
+ H5O_iter_xst_t udata; /* User data for callback */
H5O_mesg_operator_t op; /* Wrapper for operator */
/* Set up user data for callback */
- udata.f = loc->file;
- udata.name = name;
- udata.found = FALSE;
+ udata.name = name;
+ udata.exists = attr_exists;
/* Iterate over existing attributes, checking for attribute with same name */
op.op_type = H5O_MESG_OP_LIB;
op.u.lib_op = H5O__attr_exists_cb;
if (H5O__msg_iterate_real(loc->file, oh, H5O_MSG_ATTR, &op, &udata) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "error checking for existence of attribute")
-
- /* Check that we found the attribute */
- ret_value = (htri_t)udata.found;
} /* end else */
done:
diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c
index c6f54d7..e0e47e3 100644
--- a/src/H5Ocopy.c
+++ b/src/H5Ocopy.c
@@ -33,6 +33,7 @@
#include "H5Aprivate.h" /* Attributes */
#include "H5CXprivate.h" /* API Contexts */
#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event Sets */
#include "H5FLprivate.h" /* Free lists */
#include "H5Iprivate.h" /* IDs */
#include "H5HGprivate.h" /* Global Heaps */
@@ -129,7 +130,7 @@ H5O__copy(const H5G_loc_t *loc, const char *src_name, H5G_loc_t *dst_loc, const
H5G_loc_t src_loc; /* Source object group location */
H5G_name_t src_path; /* Opened source object hier. path */
H5O_loc_t src_oloc; /* Opened source object object location */
- htri_t dst_exists; /* Does destination name exist already? */
+ hbool_t dst_exists; /* Does destination name exist already? */
hbool_t loc_found = FALSE; /* Location at 'name' found */
hbool_t obj_open = FALSE; /* Entry at 'name' found */
herr_t ret_value = SUCCEED; /* Return value */
@@ -143,9 +144,10 @@ H5O__copy(const H5G_loc_t *loc, const char *src_name, H5G_loc_t *dst_loc, const
HDassert(dst_name && *dst_name);
/* Check if destination name already exists */
- if ((dst_exists = H5L_exists_tolerant(dst_loc, dst_name)) < 0)
+ dst_exists = FALSE;
+ if (H5L_exists_tolerant(dst_loc, dst_name, &dst_exists) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to check if destination name exists")
- if (TRUE == dst_exists)
+ if (dst_exists)
HGOTO_ERROR(H5E_OHDR, H5E_EXISTS, FAIL, "destination object already exists")
/* Set up opened group location to fill in */
diff --git a/src/H5Oflush.c b/src/H5Oflush.c
index adbe4fa..c4a33d6 100644
--- a/src/H5Oflush.c
+++ b/src/H5Oflush.c
@@ -37,6 +37,7 @@
#include "H5CXprivate.h" /* API Contexts */
#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Errors */
+#include "H5ESprivate.h" /* Event Sets */
#include "H5Fprivate.h" /* Files */
#include "H5Gprivate.h" /* Groups */
#include "H5Iprivate.h" /* IDs */
@@ -400,6 +401,7 @@ H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, H5VL_t *vol_connector
case H5I_ERROR_MSG:
case H5I_ERROR_STACK:
case H5I_SPACE_SEL_ITER:
+ case H5I_EVENTSET:
case H5I_NTYPES:
default:
HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, FAIL,
diff --git a/src/H5Oint.c b/src/H5Oint.c
index b966b45..3b8193c 100644
--- a/src/H5Oint.c
+++ b/src/H5Oint.c
@@ -1827,6 +1827,7 @@ H5O_get_loc(hid_t object_id)
case H5I_ERROR_MSG:
case H5I_ERROR_STACK:
case H5I_SPACE_SEL_ITER:
+ case H5I_EVENTSET:
case H5I_NTYPES:
default:
HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, NULL, "invalid object type")
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 8e338cc..d2aed18 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -29,22 +29,22 @@ typedef struct H5O_t H5O_t;
typedef struct H5O_fill_t H5O_fill_t;
/* Include the public header file for this API */
-#include "H5Opublic.h" /* Object header functions */
+#include "H5Opublic.h" /* Object header functions */
/* Public headers needed by this file */
-#include "H5Dpublic.h" /* Dataset functions */
-#include "H5Lpublic.h" /* Link functions */
-#include "H5Spublic.h" /* Dataspace functions */
+#include "H5Dpublic.h" /* Dataset functions */
+#include "H5Lpublic.h" /* Link functions */
+#include "H5Spublic.h" /* Dataspace functions */
/* Private headers needed by this file */
-#include "H5private.h" /* Generic Functions */
+#include "H5private.h" /* Generic Functions */
#include "H5ACprivate.h" /* Metadata cache */
-#include "H5Fprivate.h" /* File access */
+#include "H5Fprivate.h" /* File access */
#include "H5HGprivate.h" /* Global Heaps */
#include "H5SLprivate.h" /* Skip lists */
-#include "H5Tprivate.h" /* Datatype functions */
+#include "H5Tprivate.h" /* Datatype functions */
#include "H5VLprivate.h" /* Virtual Object Layer */
-#include "H5Zprivate.h" /* I/O pipeline filters */
+#include "H5Zprivate.h" /* I/O pipeline filters */
/* Forward references of package typedefs */
typedef struct H5O_msg_class_t H5O_msg_class_t;
@@ -67,8 +67,8 @@ typedef struct H5O_mesg_t H5O_mesg_t;
/* Object header macros */
#define H5O_MESG_MAX_SIZE 65536 /*max obj header message size */
-#define H5O_ALL (-1) /* Operate on all messages of type */
-#define H5O_FIRST (-2) /* Operate on first message of type */
+#define H5O_ALL (-1) /* Operate on all messages of type */
+#define H5O_FIRST (-2) /* Operate on first message of type */
/* Flags needed when encoding messages */
#define H5O_MSG_NO_FLAGS_SET 0x00u
@@ -96,10 +96,10 @@ typedef struct H5O_mesg_t H5O_mesg_t;
/* #define H5O_ENABLE_BOGUS */
/* ========= Object Creation properties ============ */
-#define H5O_CRT_ATTR_MAX_COMPACT_NAME "max compact attr" /* Max. # of attributes to store compactly */
-#define H5O_CRT_ATTR_MIN_DENSE_NAME "min dense attr" /* Min. # of attributes to store densely */
+#define H5O_CRT_ATTR_MAX_COMPACT_NAME "max compact attr" /* Max. # of attributes to store compactly */
+#define H5O_CRT_ATTR_MIN_DENSE_NAME "min dense attr" /* Min. # of attributes to store densely */
#define H5O_CRT_OHDR_FLAGS_NAME "object header flags" /* Object header flags */
-#define H5O_CRT_PIPELINE_NAME "pline" /* Filter pipeline */
+#define H5O_CRT_PIPELINE_NAME "pline" /* Filter pipeline */
#define H5O_CRT_PIPELINE_DEF \
{ \
{0, NULL, H5O_NULL_ID, {{0, HADDR_UNDEF}}}, H5O_PLINE_VERSION_1, 0, 0, NULL \
@@ -232,7 +232,7 @@ typedef struct H5O_copy_t {
#define H5O_FSINFO_ID 0x0017 /* File space info message. */
#define H5O_MDCI_MSG_ID 0x0018 /* Metadata Cache Image Message */
#define H5O_UNKNOWN_ID 0x0019 /* Placeholder message ID for unknown message. */
- /* (this should never exist in a file) */
+/* (this should never exist in a file) */
/*
* Note: Must increment H5O_MSG_TYPES in H5Opkg.h and update H5O_msg_class_g
* in H5O.c when creating a new message type. Also bump the value of
@@ -376,7 +376,7 @@ typedef struct H5O_link_t {
* External File List Message
* (Data structure in memory)
*/
-#define H5O_EFL_ALLOC 16 /*number of slots to alloc at once */
+#define H5O_EFL_ALLOC 16 /*number of slots to alloc at once */
#define H5O_EFL_UNLIMITED H5F_UNLIMITED /*max possible file size */
typedef struct H5O_efl_entry_t {
diff --git a/src/H5Opublic.h b/src/H5Opublic.h
index 64408a0..2d2abdf 100644
--- a/src/H5Opublic.h
+++ b/src/H5Opublic.h
@@ -182,30 +182,41 @@ typedef H5O_mcdt_search_ret_t (*H5O_mcdt_search_cb_t)(void *op_data);
extern "C" {
#endif
-H5_DLL hid_t H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id);
-H5_DLL hid_t H5Oopen_by_token(hid_t loc_id, H5O_token_t token);
-H5_DLL hid_t H5Oopen_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order,
- hsize_t n, hid_t lapl_id);
-H5_DLL htri_t H5Oexists_by_name(hid_t loc_id, const char *name, hid_t lapl_id);
-H5_DLL herr_t H5Oget_info3(hid_t loc_id, H5O_info2_t *oinfo, unsigned fields);
-H5_DLL herr_t H5Oget_info_by_name3(hid_t loc_id, const char *name, H5O_info2_t *oinfo, unsigned fields,
+H5_DLL hid_t H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id);
+H5_DLL hid_t H5Oopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *name, hid_t lapl_id, hid_t es_id);
+H5_DLL hid_t H5Oopen_by_token(hid_t loc_id, H5O_token_t token);
+H5_DLL hid_t H5Oopen_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order,
+ hsize_t n, hid_t lapl_id);
+H5_DLL hid_t H5Oopen_by_idx_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *group_name, H5_index_t idx_type, H5_iter_order_t order,
+ hsize_t n, hid_t lapl_id, hid_t es_id);
+H5_DLL htri_t H5Oexists_by_name(hid_t loc_id, const char *name, hid_t lapl_id);
+H5_DLL herr_t H5Oget_info3(hid_t loc_id, H5O_info2_t *oinfo, unsigned fields);
+H5_DLL herr_t H5Oget_info_by_name3(hid_t loc_id, const char *name, H5O_info2_t *oinfo, unsigned fields,
+ hid_t lapl_id);
+H5_DLL herr_t H5Oget_info_by_name_async(const char *app_file, const char *app_func, unsigned app_line,
+ hid_t loc_id, const char *name, H5O_info2_t *oinfo /*out*/,
+ unsigned fields, hid_t lapl_id, hid_t es_id);
+H5_DLL herr_t H5Oget_info_by_idx3(hid_t loc_id, const char *group_name, H5_index_t idx_type,
+ H5_iter_order_t order, hsize_t n, H5O_info2_t *oinfo, unsigned fields,
hid_t lapl_id);
-H5_DLL herr_t H5Oget_info_by_idx3(hid_t loc_id, const char *group_name, H5_index_t idx_type,
- H5_iter_order_t order, hsize_t n, H5O_info2_t *oinfo, unsigned fields,
- hid_t lapl_id);
-H5_DLL herr_t H5Oget_native_info(hid_t loc_id, H5O_native_info_t *oinfo, unsigned fields);
-H5_DLL herr_t H5Oget_native_info_by_name(hid_t loc_id, const char *name, H5O_native_info_t *oinfo,
+H5_DLL herr_t H5Oget_native_info(hid_t loc_id, H5O_native_info_t *oinfo, unsigned fields);
+H5_DLL herr_t H5Oget_native_info_by_name(hid_t loc_id, const char *name, H5O_native_info_t *oinfo,
+ unsigned fields, hid_t lapl_id);
+H5_DLL herr_t H5Oget_native_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type,
+ H5_iter_order_t order, hsize_t n, H5O_native_info_t *oinfo,
unsigned fields, hid_t lapl_id);
-H5_DLL herr_t H5Oget_native_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type,
- H5_iter_order_t order, hsize_t n, H5O_native_info_t *oinfo,
- unsigned fields, hid_t lapl_id);
-H5_DLL herr_t H5Olink(hid_t obj_id, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, hid_t lapl_id);
-H5_DLL herr_t H5Oincr_refcount(hid_t object_id);
-H5_DLL herr_t H5Odecr_refcount(hid_t object_id);
-H5_DLL herr_t H5Ocopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name,
- hid_t ocpypl_id, hid_t lcpl_id);
-H5_DLL herr_t H5Oset_comment(hid_t obj_id, const char *comment);
-H5_DLL herr_t H5Oset_comment_by_name(hid_t loc_id, const char *name, const char *comment, hid_t lapl_id);
+H5_DLL herr_t H5Olink(hid_t obj_id, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, hid_t lapl_id);
+H5_DLL herr_t H5Oincr_refcount(hid_t object_id);
+H5_DLL herr_t H5Odecr_refcount(hid_t object_id);
+H5_DLL herr_t H5Ocopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name,
+ hid_t ocpypl_id, hid_t lcpl_id);
+H5_DLL herr_t H5Ocopy_async(const char *app_file, const char *app_func, unsigned app_line, hid_t src_loc_id,
+ const char *src_name, hid_t dst_loc_id, const char *dst_name, hid_t ocpypl_id,
+ hid_t lcpl_id, hid_t es_id);
+H5_DLL herr_t H5Oset_comment(hid_t obj_id, const char *comment);
+H5_DLL herr_t H5Oset_comment_by_name(hid_t loc_id, const char *name, const char *comment, hid_t lapl_id);
H5_DLL ssize_t H5Oget_comment(hid_t obj_id, char *comment, size_t bufsize);
H5_DLL ssize_t H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comment, size_t bufsize,
hid_t lapl_id);
@@ -215,8 +226,14 @@ H5_DLL herr_t H5Ovisit_by_name3(hid_t loc_id, const char *obj_name, H5_index_t
H5_iter_order_t order, H5O_iterate2_t op, void *op_data, unsigned fields,
hid_t lapl_id);
H5_DLL herr_t H5Oclose(hid_t object_id);
+H5_DLL herr_t H5Oclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t object_id,
+ hid_t es_id);
H5_DLL herr_t H5Oflush(hid_t obj_id);
+H5_DLL herr_t H5Oflush_async(const char *app_file, const char *app_func, unsigned app_line, hid_t obj_id,
+ hid_t es_id);
H5_DLL herr_t H5Orefresh(hid_t oid);
+H5_DLL herr_t H5Orefresh_async(const char *app_file, const char *app_func, unsigned app_line, hid_t oid,
+ hid_t es_id);
H5_DLL herr_t H5Odisable_mdc_flushes(hid_t object_id);
H5_DLL herr_t H5Oenable_mdc_flushes(hid_t object_id);
H5_DLL herr_t H5Oare_mdc_flushes_disabled(hid_t object_id, hbool_t *are_disabled);
@@ -225,6 +242,30 @@ H5_DLL herr_t H5Otoken_cmp(hid_t loc_id, const H5O_token_t *token1, const H5O_t
H5_DLL herr_t H5Otoken_to_str(hid_t loc_id, const H5O_token_t *token, char **token_str);
H5_DLL herr_t H5Otoken_from_str(hid_t loc_id, const char *token_str, H5O_token_t *token);
+/* API Wrappers for async routines */
+/* (Must be defined _after_ the function prototype) */
+/* (And must only defined when included in application code, not the library) */
+#ifndef H5O_MODULE
+#define H5Oopen_async(...) H5Oopen_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Oopen_by_idx_async(...) H5Oopen_by_idx_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Oget_info_by_name_async(...) H5Oget_info_by_name_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Oclose_async(...) H5Oclose_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Oflush_async(...) H5Oflush_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Orefresh_async(...) H5Orefresh_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Ocopy_async(...) H5Ocopy_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+
+/* Define "wrapper" versions of function calls, to allow compile-time values to
+ * be passed in by language wrapper or library layer on top of HDF5.
+ */
+#define H5Oopen_async_wrap H5_NO_EXPAND(H5Oopen_async)
+#define H5Oopen_by_idx_async_wrap H5_NO_EXPAND(H5Oopen_by_idx_async)
+#define H5Oget_info_by_name_async_wrap H5_NO_EXPAND(H5Oget_info_by_name_async)
+#define H5Oclose_async_wrap H5_NO_EXPAND(H5Oclose_async)
+#define H5Oflush_async_wrap H5_NO_EXPAND(H5Oflush_async)
+#define H5Orefresh_async_wrap H5_NO_EXPAND(H5Orefresh_async)
+#define H5Ocopy_async_wrap H5_NO_EXPAND(H5Ocopy_async)
+#endif
+
/* The canonical 'undefined' token value */
#define H5O_TOKEN_UNDEF (H5OPEN H5O_TOKEN_UNDEF_g)
H5_DLLVAR const H5O_token_t H5O_TOKEN_UNDEF_g;
diff --git a/src/H5PLpublic.h b/src/H5PLpublic.h
index a08c78d..f61ad48 100644
--- a/src/H5PLpublic.h
+++ b/src/H5PLpublic.h
@@ -99,10 +99,8 @@ H5_DLL herr_t H5PLset_loading_state(unsigned int plugin_control_mask);
* disabled.\n
* A plugin bit set to 1 (one) indicates that that the dynamic plugin type is
* enabled.\n
- * If the value of \p plugin_control_mask is negative, all dynamic plugin types
- * are enabled.\n
- * If the value of \p plugin_control_mask is 0 (zero), all dynamic plugins
- * are disabled.
+ * If the value of \p plugin_control_mask is negative, all dynamic plugin
+ * types are enabled.\n If the value of \p plugin_control_mask is 0 (zero), all dynamic plugins are disabled.
* \return \herr_t
*
* \details H5PLget_loading_state() retrieves the bitmask that controls whether a certain type of plugins
diff --git a/src/H5Ppkg.h b/src/H5Ppkg.h
index 157e34a..4013c0a 100644
--- a/src/H5Ppkg.h
+++ b/src/H5Ppkg.h
@@ -86,7 +86,8 @@ struct H5P_genclass_t {
char * name; /* Name of property list class */
H5P_plist_type_t type; /* Type of property */
size_t nprops; /* Number of properties in class */
- unsigned plists; /* Number of property lists that have been created since the last modification to the class */
+ unsigned
+ plists; /* Number of property lists that have been created since the last modification to the class */
unsigned classes; /* Number of classes that have been derived since the last modification to the class */
unsigned ref_count; /* Number of outstanding ID's open on this class object */
hbool_t deleted; /* Whether this class has been deleted and is waiting for dependent classes & proplists
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index a978895..6493895 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -374,7 +374,7 @@ H5_DLL herr_t H5Pclose(hid_t plist_id);
* \since 1.0.0
*
*/
-H5_DLL hid_t H5Pcreate(hid_t cls_id);
+H5_DLL hid_t H5Pcreate(hid_t cls_id);
H5_DLL hid_t H5Pcreate_class(hid_t parent, const char *name, H5P_cls_create_func_t cls_create,
void *create_data, H5P_cls_copy_func_t cls_copy, void *copy_data,
H5P_cls_close_func_t cls_close, void *close_data);
@@ -472,30 +472,27 @@ H5_DLL hid_t H5Pcopy(hid_t plist_id);
* \since 1.8.0
*
*/
-H5_DLL H5Z_filter_t H5Pget_filter2(hid_t plist_id, unsigned idx,
- unsigned int *flags/*out*/,
- size_t *cd_nelmts/*out*/,
- unsigned cd_values[]/*out*/,
- size_t namelen, char name[],
- unsigned *filter_config /*out*/);
-H5_DLL herr_t H5Pset_attr_phase_change(hid_t plist_id, unsigned max_compact, unsigned min_dense);
-H5_DLL herr_t H5Pget_attr_phase_change(hid_t plist_id, unsigned *max_compact, unsigned *min_dense);
-H5_DLL herr_t H5Pset_attr_creation_order(hid_t plist_id, unsigned crt_order_flags);
-H5_DLL herr_t H5Pget_attr_creation_order(hid_t plist_id, unsigned *crt_order_flags);
-H5_DLL herr_t H5Pset_obj_track_times(hid_t plist_id, hbool_t track_times);
-H5_DLL herr_t H5Pget_obj_track_times(hid_t plist_id, hbool_t *track_times);
+H5_DLL H5Z_filter_t H5Pget_filter2(hid_t plist_id, unsigned idx, unsigned int *flags /*out*/,
+ size_t *cd_nelmts /*out*/, unsigned cd_values[] /*out*/, size_t namelen,
+ char name[], unsigned *filter_config /*out*/);
+H5_DLL herr_t H5Pset_attr_phase_change(hid_t plist_id, unsigned max_compact, unsigned min_dense);
+H5_DLL herr_t H5Pget_attr_phase_change(hid_t plist_id, unsigned *max_compact, unsigned *min_dense);
+H5_DLL herr_t H5Pset_attr_creation_order(hid_t plist_id, unsigned crt_order_flags);
+H5_DLL herr_t H5Pget_attr_creation_order(hid_t plist_id, unsigned *crt_order_flags);
+H5_DLL herr_t H5Pset_obj_track_times(hid_t plist_id, hbool_t track_times);
+H5_DLL herr_t H5Pget_obj_track_times(hid_t plist_id, hbool_t *track_times);
H5_DLL herr_t H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, size_t cd_nelmts,
const unsigned int cd_values[/*cd_nelmts*/]);
H5_DLL herr_t H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, size_t cd_nelmts,
const unsigned int c_values[]);
H5_DLL int H5Pget_nfilters(hid_t plist_id);
-H5_DLL herr_t H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id, unsigned int *flags /*out*/,
- size_t *cd_nelmts /*out*/, unsigned cd_values[] /*out*/, size_t namelen,
- char name[] /*out*/, unsigned *filter_config /*out*/);
-H5_DLL htri_t H5Pall_filters_avail(hid_t plist_id);
-H5_DLL herr_t H5Premove_filter(hid_t plist_id, H5Z_filter_t filter);
-H5_DLL herr_t H5Pset_deflate(hid_t plist_id, unsigned aggression);
-H5_DLL herr_t H5Pset_fletcher32(hid_t plist_id);
+H5_DLL herr_t H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id, unsigned int *flags /*out*/,
+ size_t *cd_nelmts /*out*/, unsigned cd_values[] /*out*/, size_t namelen,
+ char name[] /*out*/, unsigned *filter_config /*out*/);
+H5_DLL htri_t H5Pall_filters_avail(hid_t plist_id);
+H5_DLL herr_t H5Premove_filter(hid_t plist_id, H5Z_filter_t filter);
+H5_DLL herr_t H5Pset_deflate(hid_t plist_id, unsigned aggression);
+H5_DLL herr_t H5Pset_fletcher32(hid_t plist_id);
/* File creation property list (FCPL) routines */
H5_DLL herr_t H5Pset_userblock(hid_t plist_id, hsize_t size);
@@ -610,7 +607,7 @@ H5_DLL herr_t H5Pget_page_buffer_size(hid_t plist_id, size_t *buf_size, unsigned
* \since 1.0.0
*
*/
-H5_DLL int H5Pget_chunk(hid_t plist_id, int max_ndims, hsize_t dim[]/*out*/);
+H5_DLL int H5Pget_chunk(hid_t plist_id, int max_ndims, hsize_t dim[] /*out*/);
/**
*-------------------------------------------------------------------------
*
@@ -683,8 +680,7 @@ H5_DLL herr_t H5Pget_chunk_opts(hid_t plist_id, unsigned *opts);
* \since 1.6.0
*
*/
-H5_DLL herr_t H5Pget_fill_time(hid_t plist_id, H5D_fill_time_t
- *fill_time/*out*/);
+H5_DLL herr_t H5Pget_fill_time(hid_t plist_id, H5D_fill_time_t *fill_time /*out*/);
/**
*-------------------------------------------------------------------------
*
@@ -723,8 +719,7 @@ H5_DLL herr_t H5Pget_fill_time(hid_t plist_id, H5D_fill_time_t
* \since 1.0.0
*
*/
-H5_DLL herr_t H5Pget_fill_value(hid_t plist_id, hid_t type_id,
- void *value/*out*/);
+H5_DLL herr_t H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value /*out*/);
/**
*-------------------------------------------------------------------------
* \ingroup DCPL
@@ -941,8 +936,7 @@ H5_DLL herr_t H5Pset_fill_time(hid_t plist_id, H5D_fill_time_t fill_time);
* \since 1.0.0
*
*/
-H5_DLL herr_t H5Pset_fill_value(hid_t plist_id, hid_t type_id,
- const void *value);
+H5_DLL herr_t H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value);
/**
*-------------------------------------------------------------------------
*
@@ -1173,25 +1167,25 @@ H5_DLL herr_t H5Pset_layout(hid_t plist_id, H5D_layout_t layout);
*
*--------------------------------------------------------------------------
*/
-H5_DLL herr_t H5Pset_szip(hid_t plist_id, unsigned options_mask, unsigned pixels_per_block);
-H5_DLL herr_t H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name,
- const char *src_dset_name, hid_t src_space_id);
-H5_DLL herr_t H5Pget_virtual_count(hid_t dcpl_id, size_t *count /*out*/);
-H5_DLL hid_t H5Pget_virtual_vspace(hid_t dcpl_id, size_t index);
-H5_DLL hid_t H5Pget_virtual_srcspace(hid_t dcpl_id, size_t index);
-H5_DLL ssize_t H5Pget_virtual_filename(hid_t dcpl_id, size_t index, char *name /*out*/, size_t size);
-H5_DLL ssize_t H5Pget_virtual_dsetname(hid_t dcpl_id, size_t index, char *name /*out*/, size_t size);
-H5_DLL herr_t H5Pset_external(hid_t plist_id, const char *name, off_t offset, hsize_t size);
-H5_DLL int H5Pget_external_count(hid_t plist_id);
-H5_DLL herr_t H5Pget_external(hid_t plist_id, unsigned idx, size_t name_size, char *name /*out*/,
- off_t *offset /*out*/, hsize_t *size /*out*/);
-H5_DLL herr_t H5Pset_nbit(hid_t plist_id);
-H5_DLL herr_t H5Pset_scaleoffset(hid_t plist_id, H5Z_SO_scale_type_t scale_type, int scale_factor);
-H5_DLL herr_t H5Pfill_value_defined(hid_t plist, H5D_fill_value_t *status);
-H5_DLL herr_t H5Pset_alloc_time(hid_t plist_id, H5D_alloc_time_t alloc_time);
-H5_DLL herr_t H5Pget_alloc_time(hid_t plist_id, H5D_alloc_time_t *alloc_time /*out*/);
-H5_DLL herr_t H5Pget_dset_no_attrs_hint(hid_t dcpl_id, hbool_t *minimize);
-H5_DLL herr_t H5Pset_dset_no_attrs_hint(hid_t dcpl_id, hbool_t minimize);
+H5_DLL herr_t H5Pset_szip(hid_t plist_id, unsigned options_mask, unsigned pixels_per_block);
+H5_DLL herr_t H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name,
+ const char *src_dset_name, hid_t src_space_id);
+H5_DLL herr_t H5Pget_virtual_count(hid_t dcpl_id, size_t *count /*out*/);
+H5_DLL hid_t H5Pget_virtual_vspace(hid_t dcpl_id, size_t index);
+H5_DLL hid_t H5Pget_virtual_srcspace(hid_t dcpl_id, size_t index);
+H5_DLL ssize_t H5Pget_virtual_filename(hid_t dcpl_id, size_t index, char *name /*out*/, size_t size);
+H5_DLL ssize_t H5Pget_virtual_dsetname(hid_t dcpl_id, size_t index, char *name /*out*/, size_t size);
+H5_DLL herr_t H5Pset_external(hid_t plist_id, const char *name, off_t offset, hsize_t size);
+H5_DLL int H5Pget_external_count(hid_t plist_id);
+H5_DLL herr_t H5Pget_external(hid_t plist_id, unsigned idx, size_t name_size, char *name /*out*/,
+ off_t *offset /*out*/, hsize_t *size /*out*/);
+H5_DLL herr_t H5Pset_nbit(hid_t plist_id);
+H5_DLL herr_t H5Pset_scaleoffset(hid_t plist_id, H5Z_SO_scale_type_t scale_type, int scale_factor);
+H5_DLL herr_t H5Pfill_value_defined(hid_t plist, H5D_fill_value_t *status);
+H5_DLL herr_t H5Pset_alloc_time(hid_t plist_id, H5D_alloc_time_t alloc_time);
+H5_DLL herr_t H5Pget_alloc_time(hid_t plist_id, H5D_alloc_time_t *alloc_time /*out*/);
+H5_DLL herr_t H5Pget_dset_no_attrs_hint(hid_t dcpl_id, hbool_t *minimize);
+H5_DLL herr_t H5Pset_dset_no_attrs_hint(hid_t dcpl_id, hbool_t minimize);
/* Dataset access property list (DAPL) routines */
H5_DLL herr_t H5Pset_chunk_cache(hid_t dapl_id, size_t rdcc_nslots, size_t rdcc_nbytes, double rdcc_w0);
@@ -1300,15 +1294,15 @@ H5_DLL herr_t H5Pget_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t *func,
/* Typedefs */
/* Function prototypes */
-H5_DLL herr_t H5Pregister1(hid_t cls_id, const char *name, size_t size, void *def_value,
- H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set,
- H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_del,
- H5P_prp_copy_func_t prp_copy, H5P_prp_close_func_t prp_close);
-H5_DLL herr_t H5Pinsert1(hid_t plist_id, const char *name, size_t size, void *value,
- H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,
- H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy,
- H5P_prp_close_func_t prp_close);
-H5_DLL herr_t H5Pencode1(hid_t plist_id, void *buf, size_t *nalloc);
+H5_DLL herr_t H5Pregister1(hid_t cls_id, const char *name, size_t size, void *def_value,
+ H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set,
+ H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_del,
+ H5P_prp_copy_func_t prp_copy, H5P_prp_close_func_t prp_close);
+H5_DLL herr_t H5Pinsert1(hid_t plist_id, const char *name, size_t size, void *value,
+ H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,
+ H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy,
+ H5P_prp_close_func_t prp_close);
+H5_DLL herr_t H5Pencode1(hid_t plist_id, void *buf, size_t *nalloc);
/**
*-------------------------------------------------------------------------
* \ingroup OCPL
diff --git a/src/H5R.c b/src/H5R.c
index b961a16..efada16 100644
--- a/src/H5R.c
+++ b/src/H5R.c
@@ -27,10 +27,12 @@
#include "H5private.h" /* Generic Functions */
#include "H5CXprivate.h" /* API Contexts */
#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event Sets */
#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Rpkg.h" /* References */
#include "H5Sprivate.h" /* Dataspaces */
+#include "H5VLprivate.h" /* Virtual Object Layer */
/****************/
/* Local Macros */
@@ -44,6 +46,14 @@
/* Local Prototypes */
/********************/
+/* Helper routines for sync/async API calls */
+static hid_t H5R__open_object_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static hid_t H5R__open_region_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static hid_t H5R__open_attr_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+
/*********************/
/* Package Variables */
/*********************/
@@ -448,28 +458,29 @@ done:
} /* end H5Rcopy() */
/*-------------------------------------------------------------------------
- * Function: H5Ropen_object
+ * Function: H5R__open_object_api_common
*
- * Purpose: Given a reference to some object, open that object and
- * return an ID for that object.
+ * Purpose: This is the common function for opening an object via a reference.
*
* Return: Valid ID on success / H5I_INVALID_HID on failure
*
*-------------------------------------------------------------------------
*/
-hid_t
-H5Ropen_object(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id)
+static hid_t
+H5R__open_object_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
{
- hid_t loc_id; /* Reference location ID */
- H5VL_object_t * vol_obj = NULL; /* Object of loc_id */
- H5VL_loc_params_t loc_params; /* Location parameters */
- H5O_token_t obj_token = {0}; /* Object token */
- H5I_type_t opened_type; /* Opened object type */
- void * opened_obj = NULL; /* Opened object */
- hid_t ret_value = H5I_INVALID_HID; /* Return value */
-
- FUNC_ENTER_API(H5I_INVALID_HID)
- H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, oapl_id);
+ hid_t loc_id; /* Reference location ID */
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters */
+ H5O_token_t obj_token = {0}; /* Object token */
+ H5I_type_t opened_type; /* Opened object type */
+ void * opened_obj = NULL; /* Opened object */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_STATIC
/* Check args */
if (ref_ptr == NULL)
@@ -489,52 +500,117 @@ H5Ropen_object(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id)
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENFILE, H5I_INVALID_HID, "cannot re-open referenced file")
}
- /* Get object token */
- if (H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get object token")
-
/* Verify access property list and set up collective metadata if appropriate */
if (H5CX_set_apl(&oapl_id, H5P_CLS_DACC, loc_id, FALSE) < 0)
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
- /* Get the VOL object */
- if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
+ /* Get object token */
+ if (H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get object token")
- /* Set location parameters */
- loc_params.type = H5VL_OBJECT_BY_TOKEN;
- loc_params.loc_data.loc_by_token.token = &obj_token;
- loc_params.obj_type = H5I_get_type(loc_id);
+ /* Set up arguments for object access by token */
+ if (H5VL_setup_token_args(loc_id, &obj_token, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")
/* Open object by token */
- if (NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL)))
+ if (NULL == (opened_obj = H5VL_object_open(*vol_obj_ptr, &loc_params, &opened_type,
+ H5P_DATASET_XFER_DEFAULT, token_ptr)))
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object by token")
/* Register object */
- if ((ret_value = H5VL_register(opened_type, opened_obj, vol_obj->connector, TRUE)) < 0)
+ if ((ret_value = H5VL_register(opened_type, opened_obj, (*vol_obj_ptr)->connector, TRUE)) < 0)
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle")
done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__open_object_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Ropen_object
+ *
+ * Purpose: Given a reference to some object, open that object and
+ * return an ID for that object.
+ *
+ * Return: Valid ID on success / H5I_INVALID_HID on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Ropen_object(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id)
+{
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, oapl_id);
+
+ /* Open the dataset synchronously */
+ if ((ret_value = H5R__open_object_api_common(ref_ptr, rapl_id, oapl_id, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object synchronously")
+
+done:
FUNC_LEAVE_API(ret_value)
} /* end H5Ropen_object() */
/*-------------------------------------------------------------------------
- * Function: H5Ropen_region
+ * Function: H5Ropen_object_async
*
- * Purpose: Given a reference to some object, creates a copy of the dataset
- * pointed to's dataspace and defines a selection in the copy
- * which is the region pointed to.
+ * Purpose: Asynchronous version of H5Ropen_object
*
* Return: Valid ID on success / H5I_INVALID_HID on failure
*
*-------------------------------------------------------------------------
*/
hid_t
-H5Ropen_region(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id)
+H5Ropen_object_async(const char *app_file, const char *app_func, unsigned app_line, H5R_ref_t *ref_ptr,
+ hid_t rapl_id, hid_t oapl_id, hid_t es_id)
{
- hid_t loc_id; /* Reference location ID */
- H5VL_object_t * vol_obj = NULL; /* Object of loc_id */
+ H5VL_object_t *vol_obj = NULL; /* Object of loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE7("i", "*s*sIu*Rriii", app_file, app_func, app_line, ref_ptr, rapl_id, oapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Open the object asynchronously */
+ if ((ret_value = H5R__open_object_api_common(ref_ptr, rapl_id, oapl_id, token_ptr, &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object asynchronously")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE7(FUNC, "*s*sIu*Rriii", app_file, app_func, app_line, ref_ptr, rapl_id,
+ oapl_id, es_id)) < 0) {
+ if (H5I_dec_app_ref_always_close(ret_value) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on object ID")
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Ropen_object_async() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__open_region_api_common
+ *
+ * Purpose: This is the common function for opening a region.
+ *
+ * Return: Valid ID on success / H5I_INVALID_HID on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+H5R__open_region_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
+{
+ hid_t loc_id; /* Reference location ID */
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
H5VL_loc_params_t loc_params; /* Location parameters */
H5O_token_t obj_token = {0}; /* Object token */
H5I_type_t opened_type; /* Opened object type */
@@ -544,8 +620,7 @@ H5Ropen_region(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id)
hid_t space_id = H5I_INVALID_HID; /* Dataspace ID */
hid_t ret_value = H5I_INVALID_HID; /* Return value */
- FUNC_ENTER_API(H5I_INVALID_HID)
- H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, oapl_id);
+ FUNC_ENTER_STATIC
/* Check args */
if (ref_ptr == NULL)
@@ -569,22 +644,17 @@ H5Ropen_region(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id)
if (H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0)
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get object token")
- /* Get the VOL object */
- if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
-
- /* Set location parameters */
- loc_params.type = H5VL_OBJECT_BY_TOKEN;
- loc_params.loc_data.loc_by_token.token = &obj_token;
- loc_params.obj_type = H5I_get_type(loc_id);
+ /* Set up arguments for object access by token */
+ if (H5VL_setup_token_args(loc_id, &obj_token, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")
/* Open object by token */
- if (NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL)))
+ if (NULL == (opened_obj = H5VL_object_open(*vol_obj_ptr, &loc_params, &opened_type,
+ H5P_DATASET_XFER_DEFAULT, token_ptr)))
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object by token")
/* Register object */
- if ((opened_obj_id = H5VL_register(opened_type, opened_obj, vol_obj->connector, FALSE)) < 0)
+ if ((opened_obj_id = H5VL_register(opened_type, opened_obj, (*vol_obj_ptr)->connector, FALSE)) < 0)
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle")
/* Get VOL object object */
@@ -612,24 +682,96 @@ done:
if ((space_id != H5I_INVALID_HID) && (H5I_dec_ref(space_id) < 0))
HDONE_ERROR(H5E_REFERENCE, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close dataspace")
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__open_region_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Ropen_region
+ *
+ * Purpose: Given a reference to some object, creates a copy of the dataset
+ * pointed to's dataspace and defines a selection in the copy
+ * which is the region pointed to.
+ *
+ * Return: Valid ID on success / H5I_INVALID_HID on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Ropen_region(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id)
+{
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, oapl_id);
+
+ /* Open the region synchronously */
+ if ((ret_value = H5R__open_region_api_common(ref_ptr, rapl_id, oapl_id, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open region synchronously")
+
+done:
FUNC_LEAVE_API(ret_value)
} /* end H5Ropen_region() */
/*-------------------------------------------------------------------------
- * Function: H5Ropen_attr
+ * Function: H5Ropen_region_async
*
- * Purpose: Given a reference to some attribute, open that attribute and
- * return an ID for that attribute.
+ * Purpose: Asynchronous version of H5Ropen_region
*
* Return: Valid ID on success / H5I_INVALID_HID on failure
*
*-------------------------------------------------------------------------
*/
hid_t
-H5Ropen_attr(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id)
+H5Ropen_region_async(const char *app_file, const char *app_func, unsigned app_line, H5R_ref_t *ref_ptr,
+ hid_t rapl_id, hid_t oapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object of loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE7("i", "*s*sIu*Rriii", app_file, app_func, app_line, ref_ptr, rapl_id, oapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Open the region asynchronously */
+ if ((ret_value = H5R__open_region_api_common(ref_ptr, rapl_id, oapl_id, token_ptr, &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open region asynchronously")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE7(FUNC, "*s*sIu*Rriii", app_file, app_func, app_line, ref_ptr, rapl_id,
+ oapl_id, es_id)) < 0) {
+ if (H5I_dec_app_ref_always_close(ret_value) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on region ID")
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Ropen_region_async() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__open_attr_api_common
+ *
+ * Purpose: This is the common function for opening an attribute via a reference.
+ *
+ * Return: Valid ID on success / H5I_INVALID_HID on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+H5R__open_attr_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
{
- hid_t loc_id; /* Reference location ID */
- H5VL_object_t * vol_obj = NULL; /* Object of loc_id */
+ hid_t loc_id; /* Reference location ID */
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
H5VL_loc_params_t loc_params; /* Location parameters */
H5O_token_t obj_token = {0}; /* Object token */
H5I_type_t opened_type; /* Opened object type */
@@ -638,9 +780,9 @@ H5Ropen_attr(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id)
void * opened_attr = NULL; /* Opened attribute */
hid_t ret_value = H5I_INVALID_HID; /* Return value */
- FUNC_ENTER_API(H5I_INVALID_HID)
- H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, aapl_id);
+ FUNC_ENTER_STATIC
+ fprintf(stderr, "H5R__open_attr_api_common is here\n");
/* Check args */
if (ref_ptr == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid reference pointer")
@@ -663,7 +805,7 @@ H5Ropen_attr(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id)
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get object token")
/* Get the VOL object */
- if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
+ if (NULL == (*vol_obj_ptr = H5VL_vol_object(loc_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier")
/* Set location parameters */
@@ -672,12 +814,12 @@ H5Ropen_attr(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id)
loc_params.obj_type = H5I_get_type(loc_id);
/* Open object by token */
- if (NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL)))
+ if (NULL == (opened_obj = H5VL_object_open(*vol_obj_ptr, &loc_params, &opened_type,
+ H5P_DATASET_XFER_DEFAULT, token_ptr)))
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object by token")
/* Register object */
- if ((opened_obj_id = H5VL_register(opened_type, opened_obj, vol_obj->connector, FALSE)) < 0)
+ if ((opened_obj_id = H5VL_register(opened_type, opened_obj, (*vol_obj_ptr)->connector, FALSE)) < 0)
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle")
/* Verify access property list and set up collective metadata if appropriate */
@@ -700,19 +842,89 @@ H5Ropen_attr(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id)
H5R_REF_ATTRNAME((const H5R_ref_priv_t *)ref_ptr))
/* Register the attribute and get an ID for it */
- if ((ret_value = H5VL_register(H5I_ATTR, opened_attr, vol_obj->connector, TRUE)) < 0)
+ if ((ret_value = H5VL_register(H5I_ATTR, opened_attr, (*vol_obj_ptr)->connector, TRUE)) < 0)
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register attribute handle")
done:
if ((opened_obj_id != H5I_INVALID_HID) && (H5I_dec_ref(opened_obj_id) < 0))
HDONE_ERROR(H5E_REFERENCE, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close object")
if (H5I_INVALID_HID == ret_value) /* Cleanup on failure */
- if (opened_attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
+ if (opened_attr && H5VL_attr_close(*vol_obj_ptr, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
HDONE_ERROR(H5E_REFERENCE, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute")
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__open_attr_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Ropen_attr
+ *
+ * Purpose: Given a reference to some attribute, open that attribute and
+ * return an ID for that attribute.
+ *
+ * Return: Valid ID on success / H5I_INVALID_HID on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Ropen_attr(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id)
+{
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, aapl_id);
+
+ /* Open the attribute synchronously */
+ if ((ret_value = H5R__open_attr_api_common(ref_ptr, rapl_id, aapl_id, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_OPENERROR, H5I_INVALID_HID, "unable to open attribute synchronously")
+
+done:
FUNC_LEAVE_API(ret_value)
} /* end H5Ropen_attr() */
+/*--------------------------------------------------------------------------
+ * Function: H5Ropen_attr_async
+ *
+ * Purpose: Asynchronous version of H5Ropen_attr
+ *
+ * Return: An attribute ID on success / H5I_INVALID_HID on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Ropen_attr_async(const char *app_file, const char *app_func, unsigned app_line, H5R_ref_t *ref_ptr,
+ hid_t rapl_id, hid_t aapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE7("i", "*s*sIu*Rriii", app_file, app_func, app_line, ref_ptr, rapl_id, aapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Open the attribute asynchronously */
+ if ((ret_value = H5R__open_attr_api_common(ref_ptr, rapl_id, aapl_id, token_ptr, &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_OPENERROR, H5I_INVALID_HID, "unable to open attribute asynchronously")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE7(FUNC, "*s*sIu*Rriii", app_file, app_func, app_line, ref_ptr, rapl_id,
+ aapl_id, es_id)) < 0) {
+ if (H5I_dec_app_ref_always_close(ret_value) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDEC, H5I_INVALID_HID,
+ "can't decrement count on attribute ID")
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Ropen_attr_async() */
+
/*-------------------------------------------------------------------------
* Function: H5Rget_obj_type3
*
diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h
index 6b30b85..b2803de 100644
--- a/src/H5Rpublic.h
+++ b/src/H5Rpublic.h
@@ -113,8 +113,14 @@ H5_DLL herr_t H5Rcopy(const H5R_ref_t *src_ref_ptr, H5R_ref_t *dst_ref_ptr);
/* Dereference */
H5_DLL hid_t H5Ropen_object(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id);
+H5_DLL hid_t H5Ropen_object_async(const char *app_file, const char *app_func, unsigned app_line,
+ H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, hid_t es_id);
H5_DLL hid_t H5Ropen_region(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id);
+H5_DLL hid_t H5Ropen_region_async(const char *app_file, const char *app_func, unsigned app_line,
+ H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, hid_t es_id);
H5_DLL hid_t H5Ropen_attr(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id);
+H5_DLL hid_t H5Ropen_attr_async(const char *app_file, const char *app_func, unsigned app_line,
+ H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id, hid_t es_id);
/* Get type */
H5_DLL herr_t H5Rget_obj_type3(H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type);
@@ -124,6 +130,21 @@ H5_DLL ssize_t H5Rget_file_name(const H5R_ref_t *ref_ptr, char *buf, size_t size
H5_DLL ssize_t H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf, size_t size);
H5_DLL ssize_t H5Rget_attr_name(const H5R_ref_t *ref_ptr, char *buf, size_t size);
+/* API Wrappers for async routines */
+/* (Must be defined _after_ the function prototype) */
+/* (And must only defined when included in application code, not the library) */
+#ifndef H5R_MODULE
+#define H5Ropen_object_async(...) H5Ropen_object_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Ropen_region_async(...) H5Ropen_region_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Ropen_attr_async(...) H5Ropen_attr_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+
+/* Define "wrapper" versions of function calls, to allow compile-time values to
+ * be passed in by language wrapper or library layer on top of HDF5. */
+#define H5Ropen_object_async_wrap H5_NO_EXPAND(H5Ropen_object_async)
+#define H5Ropen_region_async_wrap H5_NO_EXPAND(H5Ropen_region_async)
+#define H5Ropen_attr_async_wrap H5_NO_EXPAND(H5Ropen_attr_async)
+#endif /* H5R_MODULE */
+
/* Symbols defined for compatibility with previous versions of the HDF5 API.
*
* Use of these symbols is or will be deprecated.
diff --git a/src/H5S.c b/src/H5S.c
index a03b58a..56c3f28 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -99,6 +99,27 @@ static const H5I_class_t H5I_SPACE_SEL_ITER_CLS[1] = {{
/* Flag indicating "top" of interface has been initialized */
static hbool_t H5S_top_package_initialize_s = FALSE;
+/*-------------------------------------------------------------------------
+ * Function: H5S_init
+ *
+ * Purpose: Initialize the interface from some other layer.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *-------------------------------------------------------------------------
+ */
+herr_t
+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
diff --git a/src/H5SM.c b/src/H5SM.c
index 31f0e10..6af4173 100644
--- a/src/H5SM.c
+++ b/src/H5SM.c
@@ -1364,16 +1364,13 @@ H5SM__write_mesg(H5F_t *f, H5O_t *open_oh, H5SM_index_header_t *header, hbool_t
HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index")
if (defer) {
- htri_t bt2_find; /* Result from searching in the v2 B-tree */
-
/* If this returns 0, it means that the message wasn't found. */
/* If it return 1, set the heap_id in the shared struct. It will
* return a heap ID, since a message with a reference count greater
* than 1 is always shared in the heap.
*/
- if ((bt2_find = H5B2_find(bt2, &key, NULL, NULL)) < 0)
+ if (H5B2_find(bt2, &key, &found, NULL, NULL) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "can't search for message in index")
- found = (hbool_t)bt2_find;
} /* end if */
else {
H5SM_incr_ref_opdata op_data;
@@ -2231,7 +2228,7 @@ H5SM_get_refcount(H5F_t *f, unsigned type_id, const H5O_shared_t *sh_mesg, hsize
message = list->messages[list_pos];
} /* end if */
else {
- htri_t msg_exists; /* Whether the message exists in the v2 B-tree */
+ hbool_t msg_exists; /* Whether the message exists in the v2 B-tree */
/* Index is a B-tree */
HDassert(header->index_type == H5SM_BTREE);
@@ -2241,7 +2238,8 @@ H5SM_get_refcount(H5F_t *f, unsigned type_id, const H5O_shared_t *sh_mesg, hsize
HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index")
/* Look up the message in the v2 B-tree */
- if ((msg_exists = H5B2_find(bt2, &key, H5SM__get_refcount_bt2_cb, &message)) < 0)
+ msg_exists = FALSE;
+ if (H5B2_find(bt2, &key, &msg_exists, H5SM__get_refcount_bt2_cb, &message) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "error finding message in index")
if (!msg_exists)
HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "message not in index")
diff --git a/src/H5Spkg.h b/src/H5Spkg.h
index b744a6a..8b1922b 100644
--- a/src/H5Spkg.h
+++ b/src/H5Spkg.h
@@ -280,23 +280,28 @@ typedef struct {
H5S_sel_copy_func_t copy; /* Method to make a copy of a selection */
H5S_sel_release_func_t release; /* Method to release current selection */
H5S_sel_is_valid_func_t is_valid; /* Method to determine if current selection is valid for dataspace */
- H5S_sel_serial_size_func_t serial_size; /* Method to determine number of bytes required to store current selection */
+ H5S_sel_serial_size_func_t
+ serial_size; /* Method to determine number of bytes required to store current selection */
H5S_sel_serialize_func_t serialize; /* Method to store current selection in "serialized" form (a byte
sequence suitable for storing on disk) */
H5S_sel_deserialize_func_t deserialize; /* Method to store create selection from "serialized" form (a byte
sequence suitable for storing on disk) */
- H5S_sel_bounds_func_t bounds; /* Method to determine to smallest n-D bounding box containing the current selection */
- H5S_sel_offset_func_t offset; /* Method to determine linear offset of initial element in selection within dataspace */
+ H5S_sel_bounds_func_t
+ bounds; /* Method to determine to smallest n-D bounding box containing the current selection */
+ H5S_sel_offset_func_t
+ offset; /* Method to determine linear offset of initial element in selection within dataspace */
H5S_sel_unlim_dim_func_t unlim_dim; /* Method to get unlimited dimension of selection (or -1 for none) */
H5S_sel_num_elem_non_unlim_func_t num_elem_non_unlim; /* Method to get the number of elements in a slice
through the unlimited dimension */
H5S_sel_is_contiguous_func_t is_contiguous; /* Method to determine if current selection is contiguous */
H5S_sel_is_single_func_t is_single; /* Method to determine if current selection is a single block */
H5S_sel_is_regular_func_t is_regular; /* Method to determine if current selection is "regular" */
- H5S_sel_shape_same_func_t shape_same; /* Method to determine if two dataspaces' selections are the same shape */
- H5S_sel_intersect_block_func_t intersect_block; /* Method to determine if a dataspaces' selection intersects a block */
- H5S_sel_adjust_u_func_t adjust_u; /* Method to adjust a selection by an offset */
- H5S_sel_adjust_s_func_t adjust_s; /* Method to adjust a selection by an offset (signed) */
+ H5S_sel_shape_same_func_t
+ shape_same; /* Method to determine if two dataspaces' selections are the same shape */
+ H5S_sel_intersect_block_func_t
+ intersect_block; /* Method to determine if a dataspaces' selection intersects a block */
+ H5S_sel_adjust_u_func_t adjust_u; /* Method to adjust a selection by an offset */
+ H5S_sel_adjust_s_func_t adjust_s; /* Method to adjust a selection by an offset (signed) */
H5S_sel_project_scalar project_scalar; /* Method to construct scalar dataspace projection */
H5S_sel_project_simple project_simple; /* Method to construct simple dataspace projection */
H5S_sel_iter_init_func_t iter_init; /* Method to initialize iterator for current selection */
@@ -347,13 +352,20 @@ typedef struct H5S_sel_iter_class_t {
H5S_sel_type type; /* Type of selection (all, none, points or hyperslab) */
/* Methods on selections */
- H5S_sel_iter_coords_func_t iter_coords; /* Method to retrieve the current coordinates of iterator for current selection */
- H5S_sel_iter_block_func_t iter_block; /* Method to retrieve the current block of iterator for current selection */
- H5S_sel_iter_nelmts_func_t iter_nelmts; /* Method to determine number of elements left in iterator for current selection */
- H5S_sel_iter_has_next_block_func_t iter_has_next_block; /* Method to query if there is another block left in the selection */
- H5S_sel_iter_next_func_t iter_next; /* Method to move selection iterator to the next element in the selection */
- H5S_sel_iter_next_block_func_t iter_next_block; /* Method to move selection iterator to the next block in the selection */
- H5S_sel_iter_get_seq_list_func_t iter_get_seq_list; /* Method to retrieve a list of offset/length sequences for selection iterator */
+ H5S_sel_iter_coords_func_t
+ iter_coords; /* Method to retrieve the current coordinates of iterator for current selection */
+ H5S_sel_iter_block_func_t
+ iter_block; /* Method to retrieve the current block of iterator for current selection */
+ H5S_sel_iter_nelmts_func_t
+ iter_nelmts; /* Method to determine number of elements left in iterator for current selection */
+ H5S_sel_iter_has_next_block_func_t
+ iter_has_next_block; /* Method to query if there is another block left in the selection */
+ H5S_sel_iter_next_func_t
+ iter_next; /* Method to move selection iterator to the next element in the selection */
+ H5S_sel_iter_next_block_func_t
+ iter_next_block; /* Method to move selection iterator to the next block in the selection */
+ H5S_sel_iter_get_seq_list_func_t
+ iter_get_seq_list; /* Method to retrieve a list of offset/length sequences for selection iterator */
H5S_sel_iter_release_func_t iter_release; /* Method to release iterator for current selection */
} H5S_sel_iter_class_t;
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index 3389e1f..4598a41 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -201,6 +201,7 @@ struct H5O_loc_t;
typedef struct H5S_t H5S_t;
/* Operations on dataspaces */
+H5_DLL herr_t H5S_init(void);
H5_DLL H5S_t * H5S_copy(const H5S_t *src, hbool_t share_selection, hbool_t copy_max);
H5_DLL herr_t H5S_close(H5S_t *ds);
H5_DLL H5S_class_t H5S_get_simple_extent_type(const H5S_t *ds);
diff --git a/src/H5Spublic.h b/src/H5Spublic.h
index c16af93..62e2128 100644
--- a/src/H5Spublic.h
+++ b/src/H5Spublic.h
@@ -171,7 +171,7 @@ H5_DLL herr_t H5Sclose(hid_t space_id);
* \since 1.0.0
*
*/
-H5_DLL hid_t H5Screate(H5S_class_t type);
+H5_DLL hid_t H5Screate(H5S_class_t type);
/**
* \ingroup H5S
* \brief Creates a new simple dataspace and opens it for access
@@ -222,7 +222,7 @@ H5_DLL hid_t H5Screate(H5S_class_t type);
* \since 1.0.0
*
*/
-H5_DLL hid_t H5Screate_simple(int rank, const hsize_t dims[], const hsize_t maxdims[]);
+H5_DLL hid_t H5Screate_simple(int rank, const hsize_t dims[], const hsize_t maxdims[]);
/*--------------------------------------------------------------------------*/
/**\ingroup H5S
*
@@ -269,8 +269,7 @@ H5_DLL hssize_t H5Sget_select_npoints(hid_t spaceid);
* \since 1.0.0
*
*/
-H5_DLL int H5Sget_simple_extent_dims(hid_t space_id, hsize_t dims[],
- hsize_t maxdims[]);
+H5_DLL int H5Sget_simple_extent_dims(hid_t space_id, hsize_t dims[], hsize_t maxdims[]);
/*-------------------------------------------------------------------------*/
/**\ingroup H5S
*
@@ -394,9 +393,8 @@ H5_DLL int H5Sget_simple_extent_ndims(hid_t space_id);
* \since 1.0.0
*
*/
-H5_DLL herr_t H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op,
- const hsize_t start[], const hsize_t stride[], const hsize_t count[],
- const hsize_t block[]);
+H5_DLL herr_t H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_t start[],
+ const hsize_t stride[], const hsize_t count[], const hsize_t block[]);
H5_DLL herr_t H5Sset_extent_simple(hid_t space_id, int rank, const hsize_t dims[], const hsize_t max[]);
H5_DLL hid_t H5Scopy(hid_t space_id);
H5_DLL herr_t H5Sencode2(hid_t obj_id, void *buf, size_t *nalloc, hid_t fapl);
diff --git a/src/H5T.c b/src/H5T.c
index 6c2c6b9..59f0224 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -32,6 +32,7 @@
#include "H5CXprivate.h" /* API Contexts */
#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event Sets */
#include "H5Fprivate.h" /* Files */
#include "H5FLprivate.h" /* Free Lists */
#include "H5FOprivate.h" /* File objects */
@@ -325,7 +326,7 @@
/* Adjust information for this type */ \
H5_GLUE3(H5T_INIT_TYPE_, GUTS, _CORE) \
\
- /* Register result */ \
+ /* Register result */ \
if ((GLOBAL = H5I_register(H5I_DATATYPE, dt, FALSE)) < 0) \
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype atom") \
}
@@ -1923,6 +1924,7 @@ H5Tcopy(hid_t obj_id)
case H5I_ERROR_MSG:
case H5I_ERROR_STACK:
case H5I_SPACE_SEL_ITER:
+ case H5I_EVENTSET:
case H5I_NTYPES:
default:
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a datatype or dataset")
@@ -1954,12 +1956,12 @@ done:
/*-------------------------------------------------------------------------
* Function: H5Tclose
*
- * Purpose: Frees a datatype and all associated memory.
+ * Purpose: Frees a datatype and all associated memory.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Non-negative on success/Negative on failure
*
- * Programmer: Robb Matzke
- * Tuesday, December 9, 1997
+ * Programmer: Robb Matzke
+ * Tuesday, December 9, 1997
*-------------------------------------------------------------------------
*/
herr_t
@@ -1986,6 +1988,66 @@ done:
} /* end H5Tclose() */
/*-------------------------------------------------------------------------
+ * Function: H5Tclose_async
+ *
+ * Purpose: Asynchronous version of H5Tclose.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t type_id, hid_t es_id)
+{
+ H5T_t * dt; /* Pointer to datatype to close */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ H5VL_object_t *vol_obj = NULL; /* VOL object of dset_id */
+ H5VL_t * connector = NULL; /* VOL connector */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, type_id, es_id);
+
+ /* Check args */
+ if (NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+ if (H5T_STATE_IMMUTABLE == dt->shared->state)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "immutable datatype")
+
+ /* Get dataset object's connector */
+ if (NULL == (vol_obj = H5VL_vol_object(type_id)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get VOL object for dataset")
+
+ /* Prepare for possible asynchronous operation */
+ if (H5ES_NONE != es_id) {
+ /* Increase connector's refcount, so it doesn't get closed if closing
+ * the dataset closes the file */
+ connector = vol_obj->connector;
+ H5VL_conn_inc_rc(connector);
+
+ /* Point at token for operation to set up */
+ token_ptr = &token;
+ } /* end if */
+
+ /* When the reference count reaches zero the resources are freed */
+ if (H5I_dec_app_ref_async(type_id, token_ptr) < 0)
+ HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "problem freeing id")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, type_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ if (connector && H5VL_conn_dec_rc(connector) < 0)
+ HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement ref count on connector")
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Tclose_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5Tequal
*
* Purpose: Determines if two datatypes are equal.
diff --git a/src/H5TS.c b/src/H5TS.c
index aa53943..09caf51 100644
--- a/src/H5TS.c
+++ b/src/H5TS.c
@@ -56,6 +56,8 @@ typedef void *(*H5TS_thread_cb_t)(void *);
/* Local Prototypes */
/********************/
static void H5TS__key_destructor(void *key_val);
+static herr_t H5TS__mutex_acquire(H5TS_mutex_t *mutex, unsigned int lock_count, hbool_t *acquired);
+static herr_t H5TS__mutex_unlock(H5TS_mutex_t *mutex, unsigned int *lock_count);
/*********************/
/* Package Variables */
@@ -303,6 +305,9 @@ H5TS_pthread_first_thread_init(void)
HDpthread_cond_init(&H5_g.init_lock.cond_var, NULL);
H5_g.init_lock.lock_count = 0;
+ HDpthread_mutex_init(&H5_g.init_lock.atomic_lock2, NULL);
+ H5_g.init_lock.attempt_lock_count = 0;
+
/* Initialize integer thread identifiers. */
H5TS_tid_init();
@@ -325,6 +330,90 @@ H5TS_pthread_first_thread_init(void)
#endif /* H5_HAVE_WIN_THREADS */
/*--------------------------------------------------------------------------
+ * Function: H5TS__mutex_acquire
+ *
+ * Purpose: Attempts to acquire a mutex lock, without blocking
+ *
+ * Note: On success, the 'acquired' flag indicates if the HDF5 library
+ * global lock was acquired.
+ *
+ * Note: The Windows threads code is very likely bogus.
+ *
+ * Return: Non-negative on success / Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Februrary 27, 2019
+ *
+ *--------------------------------------------------------------------------
+ */
+static herr_t
+H5TS__mutex_acquire(H5TS_mutex_t *mutex, unsigned int lock_count, hbool_t *acquired)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC_NAMECHECK_ONLY
+
+#ifdef H5_HAVE_WIN_THREADS
+ EnterCriticalSection(&mutex->CriticalSection);
+ *acquired = TRUE;
+#else /* H5_HAVE_WIN_THREADS */
+ /* Attempt to acquire the mutex lock */
+ if (0 == HDpthread_mutex_lock(&mutex->atomic_lock)) {
+ pthread_t my_thread_id = HDpthread_self();
+
+ /* Check if locked already */
+ if (mutex->lock_count) {
+ /* Check for this thread already owning the lock */
+ if (HDpthread_equal(my_thread_id, mutex->owner_thread)) {
+ /* Already owned by self - increment count */
+ mutex->lock_count += lock_count;
+ *acquired = TRUE;
+ } /* end if */
+ else
+ *acquired = FALSE;
+ } /* end if */
+ else {
+ /* Take ownership of the mutex */
+ mutex->owner_thread = my_thread_id;
+ mutex->lock_count = lock_count;
+ *acquired = TRUE;
+ } /* end else */
+
+ if (0 != HDpthread_mutex_unlock(&mutex->atomic_lock))
+ ret_value = -1;
+ } /* end if */
+ else
+ ret_value = -1;
+#endif /* H5_HAVE_WIN_THREADS */
+
+ FUNC_LEAVE_NOAPI_NAMECHECK_ONLY(ret_value)
+} /* end H5TS__mutex_acquire() */
+
+/*--------------------------------------------------------------------------
+ * Function: H5TSmutex_acquire
+ *
+ * Purpose: Attempts to acquire the HDF5 library global lock
+ *
+ * Note: On success, the 'acquired' flag indicates if the HDF5 library
+ * global lock was acquired.
+ *
+ * Return: Non-negative on success / Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Februrary 27, 2019
+ *
+ *--------------------------------------------------------------------------
+ */
+herr_t
+H5TSmutex_acquire(unsigned int lock_count, hbool_t *acquired){
+ FUNC_ENTER_API_NAMECHECK_ONLY
+
+ /*NO TRACE*/
+
+ FUNC_LEAVE_API_NAMECHECK_ONLY(H5TS__mutex_acquire(&H5_g.init_lock, lock_count, acquired))}
+/* end H5TSmutex_acquire() */
+
+/*--------------------------------------------------------------------------
* NAME
* H5TS_mutex_lock
*
@@ -344,8 +433,7 @@ H5TS_pthread_first_thread_init(void)
*
*--------------------------------------------------------------------------
*/
-herr_t
-H5TS_mutex_lock(H5TS_mutex_t *mutex)
+herr_t H5TS_mutex_lock(H5TS_mutex_t *mutex)
{
herr_t ret_value = SUCCEED;
@@ -354,6 +442,15 @@ H5TS_mutex_lock(H5TS_mutex_t *mutex)
#ifdef H5_HAVE_WIN_THREADS
EnterCriticalSection(&mutex->CriticalSection);
#else /* H5_HAVE_WIN_THREADS */
+ /* Acquire the "attempt" lock, increment the attempt lock count, release the lock */
+ ret_value = HDpthread_mutex_lock(&mutex->atomic_lock2);
+ if (ret_value)
+ HGOTO_DONE(ret_value);
+ mutex->attempt_lock_count++;
+ ret_value = HDpthread_mutex_unlock(&mutex->atomic_lock2);
+ if (ret_value)
+ HGOTO_DONE(ret_value);
+
/* Acquire the library lock */
ret_value = HDpthread_mutex_lock(&mutex->atomic_lock);
if (ret_value)
@@ -383,6 +480,61 @@ done:
/*--------------------------------------------------------------------------
* NAME
+ * H5TS__mutex_unlock
+ *
+ * USAGE
+ * H5TS__mutex_unlock(&mutex_var, &lock_count)
+ *
+ * RETURNS
+ * Non-negative on success / Negative on failure
+ *
+ * DESCRIPTION
+ * Recursive lock semantics for HDF5 (unlocking) -
+ * Reset the lock and return the current lock count
+ *
+ * PROGRAMMER: Houjun Tang
+ * Nov 3, 2020
+ *
+ *--------------------------------------------------------------------------
+ */
+static herr_t
+H5TS__mutex_unlock(H5TS_mutex_t *mutex, unsigned int *lock_count)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NAMECHECK_ONLY
+
+#ifdef H5_HAVE_WIN_THREADS
+ /* Releases ownership of the specified critical section object. */
+ LeaveCriticalSection(&mutex->CriticalSection);
+#else /* H5_HAVE_WIN_THREADS */
+
+ /* Reset the lock count for this thread */
+ ret_value = HDpthread_mutex_lock(&mutex->atomic_lock);
+ if (ret_value)
+ HGOTO_DONE(ret_value);
+ *lock_count = mutex->lock_count;
+ mutex->lock_count = 0;
+ ret_value = HDpthread_mutex_unlock(&mutex->atomic_lock);
+
+ /* If the lock count drops to zero, signal the condition variable, to
+ * wake another thread.
+ */
+ if (mutex->lock_count == 0) {
+ int err;
+
+ err = HDpthread_cond_signal(&mutex->cond_var);
+ if (err != 0)
+ ret_value = err;
+ } /* end if */
+#endif /* H5_HAVE_WIN_THREADS */
+
+done:
+ FUNC_LEAVE_NOAPI_NAMECHECK_ONLY(ret_value)
+} /* H5TS__mutex_unlock */
+
+/*--------------------------------------------------------------------------
+ * NAME
* H5TS_mutex_unlock
*
* USAGE
@@ -437,6 +589,67 @@ done:
} /* H5TS_mutex_unlock */
/*--------------------------------------------------------------------------
+ * Function: H5TSmutex_get_attempt_count
+ *
+ * Purpose: Get the current count of the global lock attempt
+ *
+ * Return: Non-negative on success / Negative on failure
+ *
+ * Programmer: Houjun Tang
+ * June 24, 2019
+ *
+ *--------------------------------------------------------------------------
+ */
+herr_t
+H5TSmutex_get_attempt_count(unsigned int *count)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API_NAMECHECK_ONLY
+ /*NO TRACE*/
+
+ ret_value = HDpthread_mutex_lock(&H5_g.init_lock.atomic_lock2);
+ if (ret_value)
+ HGOTO_DONE(ret_value);
+
+ *count = H5_g.init_lock.attempt_lock_count;
+
+ ret_value = HDpthread_mutex_unlock(&H5_g.init_lock.atomic_lock2);
+ if (ret_value)
+ HGOTO_DONE(ret_value);
+
+done:
+ FUNC_LEAVE_API_NAMECHECK_ONLY(ret_value)
+} /* end H5TSmutex_get_attempt_count() */
+
+/*--------------------------------------------------------------------------
+ * Function: H5TSmutex_release
+ *
+ * Purpose: Releases the HDF5 library global lock
+ *
+ * Return: Non-negative on success / Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Februrary 27, 2019
+ *
+ *--------------------------------------------------------------------------
+ */
+herr_t
+H5TSmutex_release(unsigned int *lock_count)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API_NAMECHECK_ONLY
+ /*NO TRACE*/
+
+ *lock_count = 0;
+ if (0 != H5TS__mutex_unlock(&H5_g.init_lock, lock_count))
+ ret_value = -1;
+
+ FUNC_LEAVE_API_NAMECHECK_ONLY(ret_value)
+} /* end H5TSmutex_release() */
+
+/*--------------------------------------------------------------------------
* NAME
* H5TS_cancel_count_inc
*
@@ -495,7 +708,7 @@ H5TS_cancel_count_inc(void)
HDfree(cancel_counter);
HGOTO_DONE(FAIL);
} /* end if */
- } /* end if */
+ } /* end if */
/* Check if thread entering library */
if (cancel_counter->cancel_count == 0)
diff --git a/src/H5TSprivate.h b/src/H5TSprivate.h
index dc85145..ccc7910 100644
--- a/src/H5TSprivate.h
+++ b/src/H5TSprivate.h
@@ -26,9 +26,7 @@
#ifdef H5_HAVE_THREADSAFE
/* Public headers needed by this file */
-#ifdef LATER
#include "H5TSpublic.h" /* Public API prototypes */
-#endif /* LATER */
#ifdef H5_HAVE_WIN_THREADS
@@ -81,6 +79,9 @@ typedef struct H5TS_mutex_struct {
pthread_mutex_t atomic_lock; /* lock for atomicity of new mechanism */
pthread_cond_t cond_var; /* condition variable */
unsigned int lock_count;
+
+ pthread_mutex_t atomic_lock2; /* lock for attempt_lock_count */
+ unsigned int attempt_lock_count;
} H5TS_mutex_t;
/* Portability wrappers around pthread types */
diff --git a/src/H5TSpublic.h b/src/H5TSpublic.h
new file mode 100644
index 0000000..d246093
--- /dev/null
+++ b/src/H5TSpublic.h
@@ -0,0 +1,52 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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://support.hdfgroup.org/ftp/HDF5/releases. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * This file contains public declarations for the H5TS (threadsafety) module.
+ */
+
+#ifndef _H5TSpublic_H
+#define _H5TSpublic_H
+
+/* Public headers needed by this file */
+#include "H5public.h" /* Generic Functions */
+
+/*****************/
+/* Public Macros */
+/*****************/
+
+/*******************/
+/* Public Typedefs */
+/*******************/
+
+/********************/
+/* Public Variables */
+/********************/
+
+/*********************/
+/* Public Prototypes */
+/*********************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* HDF5 global library lock routines */
+H5_DLL herr_t H5TSmutex_acquire(unsigned int lock_count, hbool_t *acquired);
+H5_DLL herr_t H5TSmutex_release(unsigned int *lock_count);
+H5_DLL herr_t H5TSmutex_get_attempt_count(unsigned int *count);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _H5TSpublic_H */
diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c
index 3eecfb3..1298909 100644
--- a/src/H5Tcommit.c
+++ b/src/H5Tcommit.c
@@ -29,6 +29,7 @@
#include "H5ACprivate.h" /* Metadata cache */
#include "H5CXprivate.h" /* API Contexts */
#include "H5Eprivate.h" /* Error handling */
+#include "H5ESprivate.h" /* Event Sets */
#include "H5FLprivate.h" /* Free lists */
#include "H5FOprivate.h" /* File objects */
#include "H5Iprivate.h" /* IDs */
@@ -54,6 +55,11 @@
/********************/
/* Local Prototypes */
/********************/
+static herr_t H5T__commit_api_common(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id,
+ hid_t tcpl_id, hid_t tapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
+static hid_t H5T__open_api_common(hid_t loc_id, const char *name, hid_t tapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr);
static H5T_t *H5T__open_oid(const H5G_loc_t *loc);
/*********************/
@@ -79,30 +85,28 @@ H5FL_EXTERN(H5VL_t);
H5FL_EXTERN(H5VL_object_t);
/*-------------------------------------------------------------------------
- * Function: H5Tcommit2
+ * Function: H5T__commit_api_common
*
- * Purpose: Save a transient datatype to a file and turn the type handle
- * into a "named", immutable type.
+ * Purpose: This is the common function for committing a datytype.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * April 5, 2007
- *
*-------------------------------------------------------------------------
*/
-herr_t
-H5Tcommit2(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id)
+static herr_t
+H5T__commit_api_common(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id,
+ hid_t tapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
{
- void * data = NULL; /* VOL-managed datatype data */
- H5VL_object_t * new_obj = NULL; /* VOL object that holds the datatype object and the VOL info */
- H5T_t * dt = NULL; /* High level datatype object that wraps the VOL object */
- H5VL_object_t * vol_obj = NULL; /* object of loc_id */
- H5VL_loc_params_t loc_params;
- herr_t ret_value = SUCCEED; /* Return value */
+ void * data = NULL; /* VOL-managed datatype data */
+ H5VL_object_t * new_obj = NULL; /* VOL object that holds the datatype object and the VOL info */
+ H5T_t * dt = NULL; /* High level datatype object that wraps the VOL object */
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
+ H5VL_loc_params_t loc_params; /* Location parameters */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_API(FAIL)
- H5TRACE6("e", "i*siiii", loc_id, name, type_id, lcpl_id, tcpl_id, tapl_id);
+ FUNC_ENTER_STATIC
/* Check arguments */
if (!name)
@@ -129,27 +133,19 @@ H5Tcommit2(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id, hid_t t
/* Set the LCPL for the API context */
H5CX_set_lcpl(lcpl_id);
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&tapl_id, H5P_CLS_TACC, loc_id, TRUE) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set access property list info")
-
- /* Fill in location struct fields */
- loc_params.type = H5VL_OBJECT_BY_SELF;
- loc_params.obj_type = H5I_get_type(loc_id);
-
- /* Get the object from the loc_id */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier")
+ /* Set up object access arguments */
+ if (H5VL_setup_acc_args(loc_id, H5P_CLS_TACC, TRUE, &tapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set object access arguments")
/* Commit the type */
- if (NULL == (data = H5VL_datatype_commit(vol_obj, &loc_params, name, type_id, lcpl_id, tcpl_id, tapl_id,
- H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)))
+ if (NULL == (data = H5VL_datatype_commit(*vol_obj_ptr, &loc_params, name, type_id, lcpl_id, tcpl_id,
+ tapl_id, H5P_DATASET_XFER_DEFAULT, token_ptr)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit datatype")
/* Set up VOL object */
if (NULL == (new_obj = H5FL_CALLOC(H5VL_object_t)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "can't allocate top object structure")
- new_obj->connector = vol_obj->connector;
+ new_obj->connector = (*vol_obj_ptr)->connector;
new_obj->connector->nrefs++;
new_obj->data = data;
@@ -157,10 +153,82 @@ H5Tcommit2(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id, hid_t t
dt->vol_obj = new_obj;
done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T__commit_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Tcommit2
+ *
+ * Purpose: Save a transient datatype to a file and turn the type handle
+ * into a "named", immutable type.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * April 5, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tcommit2(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "i*siiii", loc_id, name, type_id, lcpl_id, tcpl_id, tapl_id);
+
+ /* Commit the dataset synchronously */
+ if ((ret_value = H5T__commit_api_common(loc_id, name, type_id, lcpl_id, tcpl_id, tapl_id, NULL, NULL)) <
+ 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to commit datatype synchronously")
+
+done:
FUNC_LEAVE_API(ret_value)
} /* end H5Tcommit2() */
/*-------------------------------------------------------------------------
+ * Function: H5Tcommit_async
+ *
+ * Purpose: Asynchronous version of H5Tcommit2
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tcommit_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name,
+ hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE10("e", "*s*sIui*siiiii", app_file, app_func, app_line, loc_id, name, type_id, lcpl_id, tcpl_id,
+ tapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token;
+
+ /* Commit the datatype asynchronously */
+ if ((ret_value = H5T__commit_api_common(loc_id, name, type_id, lcpl_id, tcpl_id, tapl_id, token_ptr,
+ &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to commit datatype asynchronously")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE10(FUNC, "*s*sIui*siiiii", app_file, app_func, app_line, loc_id, name,
+ type_id, lcpl_id, tcpl_id, tapl_id, es_id)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "can't insert token into event set")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Tcommit_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5T__commit_named
*
* Purpose: Internal routine to save a transient datatype to a file and
@@ -545,30 +613,28 @@ done:
} /* end H5T_link() */
/*-------------------------------------------------------------------------
- * Function: H5Topen2
+ * Function: H5T__open_api_common
*
- * Purpose: Opens a named datatype using a Datatype Access Property
- * List.
+ * Purpose: This is the common function for opening a datatype.
*
* Return: Success: Object ID of the named datatype
*
* Failure: H5I_INVALID_HID
*
- * Programmer: James Laird
- * Thursday July 27, 2006
- *
*-------------------------------------------------------------------------
*/
-hid_t
-H5Topen2(hid_t loc_id, const char *name, hid_t tapl_id)
+static hid_t
+H5T__open_api_common(hid_t loc_id, const char *name, hid_t tapl_id, void **token_ptr,
+ H5VL_object_t **_vol_obj_ptr)
{
- void * dt = NULL; /* datatype object created by VOL connector */
- H5VL_object_t * vol_obj = NULL; /* object of loc_id */
+ void * dt = NULL; /* datatype object created by VOL connector */
+ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */
+ H5VL_object_t **vol_obj_ptr =
+ (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
H5VL_loc_params_t loc_params;
hid_t ret_value = H5I_INVALID_HID; /* Return value */
- FUNC_ENTER_API(H5I_INVALID_HID)
- H5TRACE3("i", "i*si", loc_id, name, tapl_id);
+ FUNC_ENTER_STATIC
/* Check args */
if (!name)
@@ -576,37 +642,107 @@ H5Topen2(hid_t loc_id, const char *name, hid_t tapl_id)
if (!*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string")
- /* Verify access property list and set up collective metadata if appropriate */
- if (H5CX_set_apl(&tapl_id, H5P_CLS_TACC, loc_id, FALSE) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set access property list info")
-
- /* Fill in location struct fields */
- loc_params.type = H5VL_OBJECT_BY_SELF;
- loc_params.obj_type = H5I_get_type(loc_id);
-
- /* get the location object */
- if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier")
+ /* Set up object access arguments */
+ if (H5VL_setup_acc_args(loc_id, H5P_CLS_TACC, FALSE, &tapl_id, vol_obj_ptr, &loc_params) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments")
/* Open the datatype */
- if (NULL == (dt = H5VL_datatype_open(vol_obj, &loc_params, name, tapl_id, H5P_DATASET_XFER_DEFAULT,
- H5_REQUEST_NULL)))
+ if (NULL == (dt = H5VL_datatype_open(*vol_obj_ptr, &loc_params, name, tapl_id, H5P_DATASET_XFER_DEFAULT,
+ token_ptr)))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open named datatype")
/* Register the type and return the ID */
- if ((ret_value = H5VL_register(H5I_DATATYPE, dt, vol_obj->connector, TRUE)) < 0)
+ if ((ret_value = H5VL_register(H5I_DATATYPE, dt, (*vol_obj_ptr)->connector, TRUE)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register named datatype")
done:
/* Cleanup on error */
if (H5I_INVALID_HID == ret_value)
- if (dt && H5VL_datatype_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
+ if (dt && H5VL_datatype_close(*vol_obj_ptr, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
HDONE_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release datatype")
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T__open_api_common() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Topen2
+ *
+ * Purpose: Opens a named datatype using a Datatype Access Property
+ * List.
+ *
+ * Return: Success: Object ID of the named datatype
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ * Programmer: James Laird
+ * Thursday July 27, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Topen2(hid_t loc_id, const char *name, hid_t tapl_id)
+{
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE3("i", "i*si", loc_id, name, tapl_id);
+
+ /* Open the datatype synchronously */
+ if ((ret_value = H5T__open_api_common(loc_id, name, tapl_id, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, H5I_INVALID_HID,
+ "unable to open named datatype synchronously")
+done:
FUNC_LEAVE_API(ret_value)
} /* end H5Topen2() */
/*-------------------------------------------------------------------------
+ * Function: H5Topen_async
+ *
+ * Purpose: Asynchronous version of H5Topen2.
+ *
+ * Return: Success: Object ID of the named datatype
+ *
+ * Failure: H5I_INVALID_HID
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Topen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name,
+ hid_t tapl_id, hid_t es_id)
+{
+ H5VL_object_t *vol_obj = NULL; /* Object for loc_id */
+ void * token = NULL; /* Request token for async operation */
+ void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */
+ hid_t ret_value = H5I_INVALID_HID; /* Return value */
+
+ FUNC_ENTER_API(H5I_INVALID_HID)
+ H5TRACE7("i", "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, tapl_id, es_id);
+
+ /* Set up request token pointer for asynchronous operation */
+ if (H5ES_NONE != es_id)
+ token_ptr = &token; /* Point at token for VOL connector to set up */
+
+ /* Open the datatype asynchronously */
+ if ((ret_value = H5T__open_api_common(loc_id, name, tapl_id, token_ptr, &vol_obj)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, H5I_INVALID_HID,
+ "unable to open named datatype asynchronously")
+
+ /* If a token was created, add the token to the event set */
+ if (NULL != token)
+ if (H5ES_insert(es_id, vol_obj->connector, token,
+ H5ARG_TRACE7(FUNC, "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, tapl_id,
+ es_id)) < 0) {
+ if (H5I_dec_app_ref_always_close(ret_value) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDEC, H5I_INVALID_HID,
+ "can't decrement count on datatype ID")
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Topen_async() */
+
+/*-------------------------------------------------------------------------
* Function: H5Tget_create_plist
*
* Purpose: Returns a copy of the datatype creation property list.
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index 4f3d89d..e96921f 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -338,7 +338,8 @@ typedef struct H5T_shared_t {
H5T_class_t type; /*which class of type is this? */
size_t size; /*total size of an instance of this type */
unsigned version; /* Version of object header message to encode this object with */
- hbool_t force_conv; /* Set if this type always needs to be converted and H5T__conv_noop cannot be called */
+ hbool_t
+ force_conv; /* Set if this type always needs to be converted and H5T__conv_noop cannot be called */
struct H5T_t * parent; /*parent type for derived datatypes */
H5VL_object_t *owned_vol_obj; /* Vol object owned by this type (free on close) */
union {
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index b3dc064..52f1c14 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -24,12 +24,12 @@ typedef struct H5T_t H5T_t;
#include "H5Tpublic.h"
/* Other public headers needed by this file */
-#include "H5MMpublic.h" /* Memory management */
+#include "H5MMpublic.h" /* Memory management */
/* Private headers needed by this file */
-#include "H5private.h" /* Generic Functions */
-#include "H5Gprivate.h" /* Groups */
-#include "H5Rprivate.h" /* References */
+#include "H5private.h" /* Generic Functions */
+#include "H5Gprivate.h" /* Groups */
+#include "H5Rprivate.h" /* References */
#include "H5VLprivate.h" /* VOL Drivers */
/* Macro for size of temporary buffers to contain a single element */
diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h
index 68a1d79..4006ceb 100644
--- a/src/H5Tpublic.h
+++ b/src/H5Tpublic.h
@@ -30,20 +30,20 @@
*/
//! [H5T_class_t_snip]
typedef enum H5T_class_t {
- H5T_NO_CLASS = -1, /**< error */
- H5T_INTEGER = 0, /**< integer types */
- H5T_FLOAT = 1, /**< floating-point types */
- H5T_TIME = 2, /**< date and time types */
- H5T_STRING = 3, /**< character string types */
- H5T_BITFIELD = 4, /**< bit field types */
- H5T_OPAQUE = 5, /**< opaque types */
- H5T_COMPOUND = 6, /**< compound types */
- H5T_REFERENCE = 7, /**< reference types */
- H5T_ENUM = 8, /**< enumeration types */
- H5T_VLEN = 9, /**< variable-Length types */
- H5T_ARRAY = 10, /**< array types */
+ H5T_NO_CLASS = -1, /**< error */
+ H5T_INTEGER = 0, /**< integer types */
+ H5T_FLOAT = 1, /**< floating-point types */
+ H5T_TIME = 2, /**< date and time types */
+ H5T_STRING = 3, /**< character string types */
+ H5T_BITFIELD = 4, /**< bit field types */
+ H5T_OPAQUE = 5, /**< opaque types */
+ H5T_COMPOUND = 6, /**< compound types */
+ H5T_REFERENCE = 7, /**< reference types */
+ H5T_ENUM = 8, /**< enumeration types */
+ H5T_VLEN = 9, /**< variable-Length types */
+ H5T_ARRAY = 10, /**< array types */
- H5T_NCLASSES /**< sentinel: this must be last */
+ H5T_NCLASSES /**< sentinel: this must be last */
} H5T_class_t;
//! [H5T_class_t_snip]
@@ -52,12 +52,12 @@ typedef enum H5T_class_t {
*/
//! [H5T_order_t_snip]
typedef enum H5T_order_t {
- H5T_ORDER_ERROR = -1, /**< error */
- H5T_ORDER_LE = 0, /**< little endian */
- H5T_ORDER_BE = 1, /**< bit endian */
- H5T_ORDER_VAX = 2, /**< VAX mixed endian */
- H5T_ORDER_MIXED = 3, /**< Compound type with mixed member orders */
- H5T_ORDER_NONE = 4 /**< no particular order (strings, bits,..) */
+ H5T_ORDER_ERROR = -1, /**< error */
+ H5T_ORDER_LE = 0, /**< little endian */
+ H5T_ORDER_BE = 1, /**< bit endian */
+ H5T_ORDER_VAX = 2, /**< VAX mixed endian */
+ H5T_ORDER_MIXED = 3, /**< Compound type with mixed member orders */
+ H5T_ORDER_NONE = 4 /**< no particular order (strings, bits,..) */
/*H5T_ORDER_NONE must be last */
} H5T_order_t;
//! [H5T_order_t_snip]
@@ -67,11 +67,11 @@ typedef enum H5T_order_t {
*/
//! [H5T_sign_t_snip]
typedef enum H5T_sign_t {
- H5T_SGN_ERROR = -1, /**< error */
- H5T_SGN_NONE = 0, /**< this is an unsigned type */
- H5T_SGN_2 = 1, /**< two's complement */
+ H5T_SGN_ERROR = -1, /**< error */
+ H5T_SGN_NONE = 0, /**< this is an unsigned type */
+ H5T_SGN_2 = 1, /**< two's complement */
- H5T_NSGN = 2 /** sentinel: this must be last! */
+ H5T_NSGN = 2 /** sentinel: this must be last! */
} H5T_sign_t;
//! [H5T_sign_t_snip]
@@ -80,10 +80,10 @@ typedef enum H5T_sign_t {
*/
//! [H5T_norm_t_snip]
typedef enum H5T_norm_t {
- H5T_NORM_ERROR = -1, /**< error */
- H5T_NORM_IMPLIED = 0, /**< msb of mantissa isn't stored, always 1 */
- H5T_NORM_MSBSET = 1, /**< msb of mantissa is always 1 */
- H5T_NORM_NONE = 2 /**< not normalized */
+ H5T_NORM_ERROR = -1, /**< error */
+ H5T_NORM_IMPLIED = 0, /**< msb of mantissa isn't stored, always 1 */
+ H5T_NORM_MSBSET = 1, /**< msb of mantissa is always 1 */
+ H5T_NORM_NONE = 2 /**< not normalized */
/*H5T_NORM_NONE must be last */
} H5T_norm_t;
//! [H5T_norm_t_snip]
@@ -93,62 +93,62 @@ typedef enum H5T_norm_t {
* \internal Do not change these values since they appear in HDF5 files!
*/
typedef enum H5T_cset_t {
- H5T_CSET_ERROR = -1, /**< error */
- H5T_CSET_ASCII = 0, /**< US ASCII */
- H5T_CSET_UTF8 = 1, /**< UTF-8 Unicode encoding */
- H5T_CSET_RESERVED_2 = 2, /**< reserved for later use */
- H5T_CSET_RESERVED_3 = 3, /**< reserved for later use */
- H5T_CSET_RESERVED_4 = 4, /**< reserved for later use */
- H5T_CSET_RESERVED_5 = 5, /**< reserved for later use */
- H5T_CSET_RESERVED_6 = 6, /**< reserved for later use */
- H5T_CSET_RESERVED_7 = 7, /**< reserved for later use */
- H5T_CSET_RESERVED_8 = 8, /**< reserved for later use */
- H5T_CSET_RESERVED_9 = 9, /**< reserved for later use */
- H5T_CSET_RESERVED_10 = 10, /**< reserved for later use */
- H5T_CSET_RESERVED_11 = 11, /**< reserved for later use */
- H5T_CSET_RESERVED_12 = 12, /**< reserved for later use */
- H5T_CSET_RESERVED_13 = 13, /**< reserved for later use */
- H5T_CSET_RESERVED_14 = 14, /**< reserved for later use */
- H5T_CSET_RESERVED_15 = 15 /**< reserved for later use */
+ H5T_CSET_ERROR = -1, /**< error */
+ H5T_CSET_ASCII = 0, /**< US ASCII */
+ H5T_CSET_UTF8 = 1, /**< UTF-8 Unicode encoding */
+ H5T_CSET_RESERVED_2 = 2, /**< reserved for later use */
+ H5T_CSET_RESERVED_3 = 3, /**< reserved for later use */
+ H5T_CSET_RESERVED_4 = 4, /**< reserved for later use */
+ H5T_CSET_RESERVED_5 = 5, /**< reserved for later use */
+ H5T_CSET_RESERVED_6 = 6, /**< reserved for later use */
+ H5T_CSET_RESERVED_7 = 7, /**< reserved for later use */
+ H5T_CSET_RESERVED_8 = 8, /**< reserved for later use */
+ H5T_CSET_RESERVED_9 = 9, /**< reserved for later use */
+ H5T_CSET_RESERVED_10 = 10, /**< reserved for later use */
+ H5T_CSET_RESERVED_11 = 11, /**< reserved for later use */
+ H5T_CSET_RESERVED_12 = 12, /**< reserved for later use */
+ H5T_CSET_RESERVED_13 = 13, /**< reserved for later use */
+ H5T_CSET_RESERVED_14 = 14, /**< reserved for later use */
+ H5T_CSET_RESERVED_15 = 15 /**< reserved for later use */
} H5T_cset_t;
-#define H5T_NCSET H5T_CSET_RESERVED_2 /*Number of character sets actually defined */
+#define H5T_NCSET H5T_CSET_RESERVED_2 /*Number of character sets actually defined */
/**
* Type of padding to use in character strings.
* \internal Do not change these values since they appear in HDF5 files!
*/
typedef enum H5T_str_t {
- H5T_STR_ERROR = -1, /**< error */
- H5T_STR_NULLTERM = 0, /**< null terminate like in C */
- H5T_STR_NULLPAD = 1, /**< pad with nulls */
- H5T_STR_SPACEPAD = 2, /**< pad with spaces like in Fortran */
- H5T_STR_RESERVED_3 = 3, /**< reserved for later use */
- H5T_STR_RESERVED_4 = 4, /**< reserved for later use */
- H5T_STR_RESERVED_5 = 5, /**< reserved for later use */
- H5T_STR_RESERVED_6 = 6, /**< reserved for later use */
- H5T_STR_RESERVED_7 = 7, /**< reserved for later use */
- H5T_STR_RESERVED_8 = 8, /**< reserved for later use */
- H5T_STR_RESERVED_9 = 9, /**< reserved for later use */
- H5T_STR_RESERVED_10 = 10, /**< reserved for later use */
- H5T_STR_RESERVED_11 = 11, /**< reserved for later use */
- H5T_STR_RESERVED_12 = 12, /**< reserved for later use */
- H5T_STR_RESERVED_13 = 13, /**< reserved for later use */
- H5T_STR_RESERVED_14 = 14, /**< reserved for later use */
- H5T_STR_RESERVED_15 = 15 /**< reserved for later use */
+ H5T_STR_ERROR = -1, /**< error */
+ H5T_STR_NULLTERM = 0, /**< null terminate like in C */
+ H5T_STR_NULLPAD = 1, /**< pad with nulls */
+ H5T_STR_SPACEPAD = 2, /**< pad with spaces like in Fortran */
+ H5T_STR_RESERVED_3 = 3, /**< reserved for later use */
+ H5T_STR_RESERVED_4 = 4, /**< reserved for later use */
+ H5T_STR_RESERVED_5 = 5, /**< reserved for later use */
+ H5T_STR_RESERVED_6 = 6, /**< reserved for later use */
+ H5T_STR_RESERVED_7 = 7, /**< reserved for later use */
+ H5T_STR_RESERVED_8 = 8, /**< reserved for later use */
+ H5T_STR_RESERVED_9 = 9, /**< reserved for later use */
+ H5T_STR_RESERVED_10 = 10, /**< reserved for later use */
+ H5T_STR_RESERVED_11 = 11, /**< reserved for later use */
+ H5T_STR_RESERVED_12 = 12, /**< reserved for later use */
+ H5T_STR_RESERVED_13 = 13, /**< reserved for later use */
+ H5T_STR_RESERVED_14 = 14, /**< reserved for later use */
+ H5T_STR_RESERVED_15 = 15 /**< reserved for later use */
} H5T_str_t;
-#define H5T_NSTR H5T_STR_RESERVED_3 /*num H5T_str_t types actually defined */
+#define H5T_NSTR H5T_STR_RESERVED_3 /*num H5T_str_t types actually defined */
/**
* Type of padding to use in other atomic types
*/
//! [H5T_pad_t_snip]
typedef enum H5T_pad_t {
- H5T_PAD_ERROR = -1, /**< error */
- H5T_PAD_ZERO = 0, /**< always set to zero */
- H5T_PAD_ONE = 1, /**< always set to one */
- H5T_PAD_BACKGROUND = 2, /**< set to background value */
+ H5T_PAD_ERROR = -1, /**< error */
+ H5T_PAD_ZERO = 0, /**< always set to zero */
+ H5T_PAD_ONE = 1, /**< always set to one */
+ H5T_PAD_BACKGROUND = 2, /**< set to background value */
- H5T_NPAD = 3 /**< sentinal: THIS MUST BE LAST */
+ H5T_NPAD = 3 /**< sentinal: THIS MUST BE LAST */
} H5T_pad_t;
//! [H5T_pad_t_snip]
@@ -156,18 +156,18 @@ typedef enum H5T_pad_t {
* Commands sent to conversion functions
*/
typedef enum H5T_cmd_t {
- H5T_CONV_INIT = 0, /**< query and/or initialize private data */
- H5T_CONV_CONV = 1, /**< convert data from source to dest datatype */
- H5T_CONV_FREE = 2 /**< function is being removed from path */
+ H5T_CONV_INIT = 0, /**< query and/or initialize private data */
+ H5T_CONV_CONV = 1, /**< convert data from source to dest datatype */
+ H5T_CONV_FREE = 2 /**< function is being removed from path */
} H5T_cmd_t;
/**
* How is the `bkg' buffer used by the conversion function?
*/
typedef enum H5T_bkg_t {
- H5T_BKG_NO = 0, /**< background buffer is not needed, send NULL */
- H5T_BKG_TEMP = 1, /**< bkg buffer used as temp storage only */
- H5T_BKG_YES = 2 /**< init bkg buf with data before conversion */
+ H5T_BKG_NO = 0, /**< background buffer is not needed, send NULL */
+ H5T_BKG_TEMP = 1, /**< bkg buffer used as temp storage only */
+ H5T_BKG_YES = 2 /**< init bkg buf with data before conversion */
} H5T_bkg_t;
/**
@@ -175,10 +175,10 @@ typedef enum H5T_bkg_t {
*/
//! [H5T_cdata_t_snip]
typedef struct H5T_cdata_t {
- H5T_cmd_t command;/**< what should the conversion function do? */
- H5T_bkg_t need_bkg;/**< is the background buffer needed? */
- hbool_t recalc; /**< recalculate private data */
- void *priv; /**< private data */
+ H5T_cmd_t command; /**< what should the conversion function do? */
+ H5T_bkg_t need_bkg; /**< is the background buffer needed? */
+ hbool_t recalc; /**< recalculate private data */
+ void * priv; /**< private data */
} H5T_cdata_t;
//! [H5T_cdata_t_snip]
@@ -186,9 +186,9 @@ typedef struct H5T_cdata_t {
* Conversion function persistence
*/
typedef enum H5T_pers_t {
- H5T_PERS_DONTCARE = -1, /**< wild card */
- H5T_PERS_HARD = 0, /**< hard conversion function */
- H5T_PERS_SOFT = 1 /**< soft conversion function */
+ H5T_PERS_DONTCARE = -1, /**< wild card */
+ H5T_PERS_HARD = 0, /**< hard conversion function */
+ H5T_PERS_SOFT = 1 /**< soft conversion function */
} H5T_pers_t;
/**
@@ -196,9 +196,9 @@ typedef enum H5T_pers_t {
*/
//! [H5T_direction_t_snip]
typedef enum H5T_direction_t {
- H5T_DIR_DEFAULT = 0, /**< default direction is inscendent */
- H5T_DIR_ASCEND = 1, /**< in inscendent order */
- H5T_DIR_DESCEND = 2 /**< in descendent order */
+ H5T_DIR_DEFAULT = 0, /**< default direction is inscendent */
+ H5T_DIR_ASCEND = 1, /**< in inscendent order */
+ H5T_DIR_DESCEND = 2 /**< in descendent order */
} H5T_direction_t;
//! [H5T_direction_t_snip]
@@ -206,22 +206,22 @@ typedef enum H5T_direction_t {
* The exception type passed into the conversion callback function
*/
typedef enum H5T_conv_except_t {
- H5T_CONV_EXCEPT_RANGE_HI = 0, /**< source value is greater than destination's range */
- H5T_CONV_EXCEPT_RANGE_LOW = 1, /**< source value is less than destination's range */
- H5T_CONV_EXCEPT_PRECISION = 2, /**< source value loses precision in destination */
- H5T_CONV_EXCEPT_TRUNCATE = 3, /**< source value is truncated in destination */
- H5T_CONV_EXCEPT_PINF = 4, /**< source value is positive infinity(floating number) */
- H5T_CONV_EXCEPT_NINF = 5, /**< source value is negative infinity(floating number) */
- H5T_CONV_EXCEPT_NAN = 6 /**< source value is NaN(floating number) */
+ H5T_CONV_EXCEPT_RANGE_HI = 0, /**< source value is greater than destination's range */
+ H5T_CONV_EXCEPT_RANGE_LOW = 1, /**< source value is less than destination's range */
+ H5T_CONV_EXCEPT_PRECISION = 2, /**< source value loses precision in destination */
+ H5T_CONV_EXCEPT_TRUNCATE = 3, /**< source value is truncated in destination */
+ H5T_CONV_EXCEPT_PINF = 4, /**< source value is positive infinity(floating number) */
+ H5T_CONV_EXCEPT_NINF = 5, /**< source value is negative infinity(floating number) */
+ H5T_CONV_EXCEPT_NAN = 6 /**< source value is NaN(floating number) */
} H5T_conv_except_t;
/**
* The return value from conversion callback function H5T_conv_except_func_t()
*/
typedef enum H5T_conv_ret_t {
- H5T_CONV_ABORT = -1, /**< abort conversion */
- H5T_CONV_UNHANDLED = 0, /**< callback function failed to handle the exception */
- H5T_CONV_HANDLED = 1 /**< callback function handled the exception successfully */
+ H5T_CONV_ABORT = -1, /**< abort conversion */
+ H5T_CONV_UNHANDLED = 0, /**< callback function failed to handle the exception */
+ H5T_CONV_HANDLED = 1 /**< callback function handled the exception successfully */
} H5T_conv_ret_t;
/**
@@ -1128,6 +1128,16 @@ H5_DLL herr_t H5Tclose(hid_t type_id);
/**
* \ingroup H5T
*
+ * \brief Asynchronous version of H5Tclose().
+ *
+ * \todo Create an example for H5Tclose_async().
+ *
+ */
+H5_DLL herr_t H5Tclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t type_id,
+ hid_t es_id);
+/**
+ * \ingroup H5T
+ *
* \brief Determines whether two datatype identifiers refer to the same datatype
*
* \type_id{type1_id}
@@ -1208,6 +1218,17 @@ H5_DLL herr_t H5Tlock(hid_t type_id);
H5_DLL herr_t H5Tcommit2(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id,
hid_t tapl_id);
/**
+ * \ingroup H5T
+ *
+ * \brief Asynchronous version of H5Tcommit2().
+ *
+ * \todo Create an example for H5Tcommit_async().
+ *
+ */
+H5_DLL herr_t H5Tcommit_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id,
+ hid_t es_id);
+/**
* --------------------------------------------------------------------------
* \ingroup H5T
*
@@ -1234,6 +1255,16 @@ H5_DLL hid_t H5Topen2(hid_t loc_id, const char *name, hid_t tapl_id);
/**
* \ingroup H5T
*
+ * \brief Asynchronous version of H5Topen2().
+ *
+ * \todo Create an example for H5Topen_async().
+ *
+ */
+H5_DLL hid_t H5Topen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id,
+ const char *name, hid_t tapl_id, hid_t es_id);
+/**
+ * \ingroup H5T
+ *
* \brief Commits a transient datatype to a file, creating a new named
* datatype, but does not link it into the file structure
*
@@ -2875,6 +2906,22 @@ H5_DLL herr_t H5Treclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *bu
*
* Use of these symbols is deprecated.
*/
+
+/* API Wrappers for async routines */
+/* (Must be defined _after_ the function prototype) */
+/* (And must only defined when included in application code, not the library) */
+#ifndef H5T_MODULE
+#define H5Tcommit_async(...) H5Tcommit_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Topen_async(...) H5Topen_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+#define H5Tclose_async(...) H5Tclose_async(__FILE__, __func__, __LINE__, __VA_ARGS__)
+
+/* Define "wrapper" versions of function calls, to allow compile-time values to
+ * be passed in by language wrapper or library layer on top of HDF5. */
+#define H5Tcommit_async_wrap H5_NO_EXPAND(H5Tcommit_async)
+#define H5Topen_async_wrap H5_NO_EXPAND(H5Topen_async)
+#define H5Tclose_async_wrap H5_NO_EXPAND(H5Tclose_async)
+#endif /* H5T_MODULE */
+
#ifndef H5_NO_DEPRECATED_SYMBOLS
/* Macros */
diff --git a/src/H5VL.c b/src/H5VL.c
index d73c95e..55779d7 100644
--- a/src/H5VL.c
+++ b/src/H5VL.c
@@ -92,8 +92,7 @@ H5VLregister_connector(const H5VL_class_t *cls, hid_t vipl_id)
HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID,
"VOL connector class pointer cannot be NULL")
if (H5VL_VERSION != cls->version)
- HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID,
- "VOL connector has incompatible version")
+ HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "VOL connector has incompatible version")
if (!cls->name)
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID,
"VOL connector class name cannot be the NULL pointer")
@@ -631,6 +630,7 @@ H5VLwrap_register(void *obj, H5I_type_t type)
case H5I_ERROR_MSG:
case H5I_ERROR_STACK:
case H5I_SPACE_SEL_ITER:
+ case H5I_EVENTSET:
case H5I_NTYPES:
default:
HGOTO_ERROR(H5E_VOL, H5E_BADRANGE, H5I_INVALID_HID, "invalid type number")
diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c
index 427e447..4ab398f 100644
--- a/src/H5VLcallback.c
+++ b/src/H5VLcallback.c
@@ -153,9 +153,10 @@ static herr_t H5VL__introspect_get_conn_cls(void *obj, const H5VL_class_t *cls,
const H5VL_class_t **conn_cls);
static herr_t H5VL__introspect_opt_query(void *obj, const H5VL_class_t *cls, H5VL_subclass_t subcls,
int opt_type, uint64_t *flags);
-static herr_t H5VL__request_wait(void *req, const H5VL_class_t *cls, uint64_t timeout, H5ES_status_t *status);
+static herr_t H5VL__request_wait(void *req, const H5VL_class_t *cls, uint64_t timeout,
+ H5VL_request_status_t *status);
static herr_t H5VL__request_notify(void *req, const H5VL_class_t *cls, H5VL_request_notify_t cb, void *ctx);
-static herr_t H5VL__request_cancel(void *req, const H5VL_class_t *cls);
+static herr_t H5VL__request_cancel(void *req, const H5VL_class_t *cls, H5VL_request_status_t *status);
static herr_t H5VL__request_specific(void *req, const H5VL_class_t *cls,
H5VL_request_specific_t specific_type, va_list arguments);
static herr_t H5VL__request_optional(void *req, const H5VL_class_t *cls, H5VL_request_optional_t opt_type,
@@ -5941,16 +5942,13 @@ done:
*
* Purpose: Waits on an asychronous request through the VOL
*
- * Note: Releases the request if the operation has completed and the
- * connector callback succeeds
- *
* Return: Success: Non-negative
* Failure: Negative
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5VL__request_wait(void *req, const H5VL_class_t *cls, uint64_t timeout, H5ES_status_t *status)
+H5VL__request_wait(void *req, const H5VL_class_t *cls, uint64_t timeout, H5VL_request_status_t *status)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -5978,16 +5976,13 @@ done:
*
* Purpose: Waits on an asychronous request through the VOL
*
- * Note: Releases the request if the operation has completed and the
- * connector callback succeeds
- *
* Return: Success: Non-negative
* Failure: Negative
*
*-------------------------------------------------------------------------
*/
herr_t
-H5VL_request_wait(const H5VL_object_t *vol_obj, uint64_t timeout, H5ES_status_t *status)
+H5VL_request_wait(const H5VL_object_t *vol_obj, uint64_t timeout, H5VL_request_status_t *status)
{
hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */
herr_t ret_value = SUCCEED; /* Return value */
@@ -6019,16 +6014,13 @@ done:
*
* Purpose: Waits on a request
*
- * Note: Releases the request if the operation has completed and the
- * connector callback succeeds
- *
* Return: Success: Non-negative
* Failure: Negative
*
*-------------------------------------------------------------------------
*/
herr_t
-H5VLrequest_wait(void *req, hid_t connector_id, uint64_t timeout, H5ES_status_t *status /*out*/)
+H5VLrequest_wait(void *req, hid_t connector_id, uint64_t timeout, H5VL_request_status_t *status /*out*/)
{
H5VL_class_t *cls; /* VOL connector's class struct */
herr_t ret_value = SUCCEED; /* Return value */
@@ -6054,8 +6046,6 @@ done:
* Purpose: Registers a user callback to be invoked when an asynchronous
* operation completes
*
- * Note: Releases the request, if connector callback succeeds
- *
* Return: Success: Non-negative
* Failure: Negative
*
@@ -6090,8 +6080,6 @@ done:
* Purpose: Registers a user callback to be invoked when an asynchronous
* operation completes
*
- * Note: Releases the request, if connector callback succeeds
- *
* Return: Success: Non-negative
* Failure: Negative
*
@@ -6131,8 +6119,6 @@ done:
* Purpose: Registers a user callback to be invoked when an asynchronous
* operation completes
*
- * Note: Releases the request, if connector callback succeeds
- *
* Return: Success: Non-negative
* Failure: Negative
*
@@ -6164,15 +6150,13 @@ done:
*
* Purpose: Cancels an asynchronous request through the VOL
*
- * Note: Releases the request, if connector callback succeeds
- *
* Return: Success: Non-negative
* Failure: Negative
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5VL__request_cancel(void *req, const H5VL_class_t *cls)
+H5VL__request_cancel(void *req, const H5VL_class_t *cls, H5VL_request_status_t *status)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -6187,7 +6171,7 @@ H5VL__request_cancel(void *req, const H5VL_class_t *cls)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'async cancel' method")
/* Call the corresponding VOL callback */
- if ((cls->request_cls.cancel)(req) < 0)
+ if ((cls->request_cls.cancel)(req, status) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request cancel failed")
done:
@@ -6199,15 +6183,13 @@ done:
*
* Purpose: Cancels an asynchronous request through the VOL
*
- * Note: Releases the request, if connector callback succeeds
- *
* Return: Success: Non-negative
* Failure: Negative
*
*-------------------------------------------------------------------------
*/
herr_t
-H5VL_request_cancel(const H5VL_object_t *vol_obj)
+H5VL_request_cancel(const H5VL_object_t *vol_obj, H5VL_request_status_t *status)
{
hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */
herr_t ret_value = SUCCEED; /* Return value */
@@ -6223,7 +6205,7 @@ H5VL_request_cancel(const H5VL_object_t *vol_obj)
vol_wrapper_set = TRUE;
/* Call the corresponding internal VOL routine */
- if (H5VL__request_cancel(vol_obj->data, vol_obj->connector->cls) < 0)
+ if (H5VL__request_cancel(vol_obj->data, vol_obj->connector->cls, status) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request cancel failed")
done:
@@ -6239,28 +6221,26 @@ done:
*
* Purpose: Cancels a request
*
- * Note: Releases the request, if connector callback succeeds
- *
* Return: Success: Non-negative
* Failure: Negative
*
*-------------------------------------------------------------------------
*/
herr_t
-H5VLrequest_cancel(void *req, hid_t connector_id)
+H5VLrequest_cancel(void *req, hid_t connector_id, H5VL_request_status_t *status)
{
H5VL_class_t *cls; /* VOL connector's class struct */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API_NOINIT
- H5TRACE2("e", "*xi", req, connector_id);
+ H5TRACE3("e", "*xi*#", req, connector_id, status);
/* Get class pointer */
if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID")
/* Call the corresponding internal VOL routine */
- if (H5VL__request_cancel(req, cls) < 0)
+ if (H5VL__request_cancel(req, cls, status) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to cancel request")
done:
diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h
index d873019..442a15c 100644
--- a/src/H5VLconnector.h
+++ b/src/H5VLconnector.h
@@ -81,7 +81,8 @@ typedef enum H5VL_dataset_get_t {
typedef enum H5VL_dataset_specific_t {
H5VL_DATASET_SET_EXTENT, /* H5Dset_extent */
H5VL_DATASET_FLUSH, /* H5Dflush */
- H5VL_DATASET_REFRESH /* H5Drefresh */
+ H5VL_DATASET_REFRESH, /* H5Drefresh */
+ H5VL_DATASET_WAIT /* H5Dwait */
} H5VL_dataset_specific_t;
/* Typedef for VOL connector dataset optional VOL operations */
@@ -120,7 +121,8 @@ typedef enum H5VL_file_specific_t {
H5VL_FILE_UNMOUNT, /* Unmount a file */
H5VL_FILE_IS_ACCESSIBLE, /* Check if a file is accessible */
H5VL_FILE_DELETE, /* Delete a file */
- H5VL_FILE_IS_EQUAL /* Check if two files are the same */
+ H5VL_FILE_IS_EQUAL, /* Check if two files are the same */
+ H5VL_FILE_WAIT /* Wait for async operations to complete */
} H5VL_file_specific_t;
/* Typedef for VOL connector file optional VOL operations */
@@ -184,11 +186,25 @@ typedef enum H5VL_object_specific_t {
/* Typedef for VOL connector object optional VOL operations */
typedef int H5VL_object_optional_t;
+/* Status values for async request operations */
+typedef enum H5VL_request_status_t {
+ H5VL_REQUEST_STATUS_IN_PROGRESS, /* Operation has not yet completed */
+ H5VL_REQUEST_STATUS_SUCCEED, /* Operation has completed, successfully */
+ H5VL_REQUEST_STATUS_FAIL, /* Operation has completed, but failed */
+ H5VL_REQUEST_STATUS_CANT_CANCEL, /* An attempt to cancel this operation was made, but it */
+ /* can't be canceled immediately. The operation has */
+ /* not completed successfully or failed, and is not yet */
+ /* in progress. Another attempt to cancel it may be */
+ /* attempted and may (or may not) succeed. */
+ H5VL_REQUEST_STATUS_CANCELED /* Operation has not completed and was canceled */
+} H5VL_request_status_t;
+
/* types for async request SPECIFIC callback */
typedef enum H5VL_request_specific_t {
- H5VL_REQUEST_WAITANY, /* Wait until any request completes */
- H5VL_REQUEST_WAITSOME, /* Wait until at least one requesst completes */
- H5VL_REQUEST_WAITALL /* Wait until all requests complete */
+ H5VL_REQUEST_WAITANY, /* Wait until any request completes */
+ H5VL_REQUEST_WAITSOME, /* Wait until at least one requesst completes */
+ H5VL_REQUEST_WAITALL, /* Wait until all requests complete */
+ H5VL_REQUEST_GET_ERR_STACK /* Retrieve error stack for failed operation */
} H5VL_request_specific_t;
/* Typedef and values for native VOL connector request optional VOL operations */
@@ -394,7 +410,7 @@ typedef struct H5VL_object_class_t {
} H5VL_object_class_t;
/* Asynchronous request 'notify' callback */
-typedef herr_t (*H5VL_request_notify_t)(void *ctx, H5ES_status_t status);
+typedef herr_t (*H5VL_request_notify_t)(void *ctx, H5VL_request_status_t status);
/* "Levels" for 'get connector class' introspection callback */
typedef enum H5VL_get_conn_lvl_t {
@@ -415,9 +431,9 @@ typedef struct H5VL_introspect_class_t {
/* Async request operation routines */
typedef struct H5VL_request_class_t {
- herr_t (*wait)(void *req, uint64_t timeout, H5ES_status_t *status);
+ herr_t (*wait)(void *req, uint64_t timeout, H5VL_request_status_t *status);
herr_t (*notify)(void *req, H5VL_request_notify_t cb, void *ctx);
- herr_t (*cancel)(void *req);
+ herr_t (*cancel)(void *req, H5VL_request_status_t *status);
herr_t (*specific)(void *req, H5VL_request_specific_t specific_type, va_list arguments);
herr_t (*optional)(void *req, H5VL_request_optional_t opt_type, va_list arguments);
herr_t (*free)(void *req);
diff --git a/src/H5VLconnector_passthru.h b/src/H5VLconnector_passthru.h
index 053d912..54864b7 100644
--- a/src/H5VLconnector_passthru.h
+++ b/src/H5VLconnector_passthru.h
@@ -198,9 +198,10 @@ H5_DLL herr_t H5VLintrospect_opt_query(void *obj, hid_t connector_id, H5VL_subcl
uint64_t *flags);
/* Public wrappers for asynchronous request callbacks */
-H5_DLL herr_t H5VLrequest_wait(void *req, hid_t connector_id, uint64_t timeout, H5ES_status_t *status);
+H5_DLL herr_t H5VLrequest_wait(void *req, hid_t connector_id, uint64_t timeout,
+ H5VL_request_status_t *status);
H5_DLL herr_t H5VLrequest_notify(void *req, hid_t connector_id, H5VL_request_notify_t cb, void *ctx);
-H5_DLL herr_t H5VLrequest_cancel(void *req, hid_t connector_id);
+H5_DLL herr_t H5VLrequest_cancel(void *req, hid_t connector_id, H5VL_request_status_t *status);
H5_DLL herr_t H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_specific_t specific_type,
va_list arguments);
H5_DLL herr_t H5VLrequest_optional(void *req, hid_t connector_id, H5VL_request_optional_t opt_type,
diff --git a/src/H5VLint.c b/src/H5VLint.c
index cdd8139..bc06361 100644
--- a/src/H5VLint.c
+++ b/src/H5VLint.c
@@ -92,8 +92,6 @@ static herr_t H5VL__set_def_conn(void);
static void * H5VL__wrap_obj(void *obj, H5I_type_t obj_type);
static H5VL_object_t *H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector,
hbool_t wrap_obj);
-static int64_t H5VL__conn_inc_rc(H5VL_t *connector);
-static int64_t H5VL__conn_dec_rc(H5VL_t *connector);
static void * H5VL__object(hid_t id, H5I_type_t obj_type);
static herr_t H5VL__free_vol_wrapper(H5VL_wrap_ctx_t *vol_wrap_ctx);
@@ -572,7 +570,7 @@ H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t
new_vol_obj->data = object;
/* Bump the reference count on the VOL connector */
- H5VL__conn_inc_rc(vol_connector);
+ H5VL_conn_inc_rc(vol_connector);
conn_rc_incr = TRUE;
/* If this is a datatype, we have to hide the VOL object under the H5T_t pointer */
@@ -586,7 +584,7 @@ H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t
done:
/* Cleanup on error */
if (NULL == ret_value) {
- if (conn_rc_incr && H5VL__conn_dec_rc(vol_connector) < 0)
+ if (conn_rc_incr && H5VL_conn_dec_rc(vol_connector) < 0)
HDONE_ERROR(H5E_VOL, H5E_CANTDEC, NULL, "unable to decrement ref count on VOL connector")
} /* end if */
@@ -816,6 +814,45 @@ done:
} /* end H5VL_register_using_vol_id() */
/*-------------------------------------------------------------------------
+ * Function: H5VL_create_object
+ *
+ * Purpose: Similar to H5VL_register but does not create an ID.
+ * Creates a new VOL object for the provided generic object
+ * using the provided vol connector. Should only be used for
+ * internal objects returned from the connector such as
+ * requests.
+ *
+ * Return: Success: A valid VOL object
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+H5VL_object_t *
+H5VL_create_object(void *object, H5VL_t *vol_connector)
+{
+ H5VL_object_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI(NULL)
+
+ /* Check arguments */
+ HDassert(object);
+ HDassert(vol_connector);
+
+ /* Set up VOL object for the passed-in data */
+ /* (Does not wrap object, since it's from a VOL callback) */
+ if (NULL == (ret_value = H5FL_CALLOC(H5VL_object_t)))
+ HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, NULL, "can't allocate memory for VOL object")
+ ret_value->connector = vol_connector;
+ ret_value->data = object;
+
+ /* Bump the reference count on the VOL connector */
+ H5VL_conn_inc_rc(vol_connector);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_create_object() */
+
+/*-------------------------------------------------------------------------
* Function: H5VL_create_object_using_vol_id
*
* Purpose: Similar to H5VL_register_using_vol_id but does not create
@@ -871,7 +908,7 @@ done:
} /* end H5VL_create_object_using_vol_id() */
/*-------------------------------------------------------------------------
- * Function: H5VL__conn_inc_rc
+ * Function: H5VL_conn_inc_rc
*
* Purpose: Wrapper to increment the ref. count on a connector.
*
@@ -882,10 +919,12 @@ done:
*
*-------------------------------------------------------------------------
*/
-static int64_t
-H5VL__conn_inc_rc(H5VL_t *connector)
+int64_t
+H5VL_conn_inc_rc(H5VL_t *connector)
{
- FUNC_ENTER_STATIC_NOERR
+ int64_t ret_value = -1;
+
+ FUNC_ENTER_NOAPI(-1)
/* Check arguments */
HDassert(connector);
@@ -893,11 +932,14 @@ H5VL__conn_inc_rc(H5VL_t *connector)
/* Increment refcount for connector */
connector->nrefs++;
- FUNC_LEAVE_NOAPI(connector->nrefs)
-} /* end H5VL__conn_inc_rc() */
+ ret_value = connector->nrefs;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_conn_inc_rc() */
/*-------------------------------------------------------------------------
- * Function: H5VL__conn_dec_rc
+ * Function: H5VL_conn_dec_rc
*
* Purpose: Wrapper to decrement the ref. count on a connector.
*
@@ -908,12 +950,12 @@ H5VL__conn_inc_rc(H5VL_t *connector)
*
*-------------------------------------------------------------------------
*/
-static int64_t
-H5VL__conn_dec_rc(H5VL_t *connector)
+int64_t
+H5VL_conn_dec_rc(H5VL_t *connector)
{
int64_t ret_value = -1; /* Return value */
- FUNC_ENTER_STATIC
+ FUNC_ENTER_NOAPI(-1)
/* Check arguments */
HDassert(connector);
@@ -936,7 +978,7 @@ H5VL__conn_dec_rc(H5VL_t *connector)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5VL__conn_dec_rc() */
+} /* end H5VL_conn_dec_rc() */
/*-------------------------------------------------------------------------
* Function: H5VL_free_object
@@ -959,7 +1001,7 @@ H5VL_free_object(H5VL_object_t *vol_obj)
HDassert(vol_obj);
/* Decrement refcount on connector */
- if (H5VL__conn_dec_rc(vol_obj->connector) < 0)
+ if (H5VL_conn_dec_rc(vol_obj->connector) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement ref count on VOL connector")
vol_obj = H5FL_FREE(H5VL_object_t, vol_obj);
@@ -1776,6 +1818,7 @@ H5VL__object(hid_t id, H5I_type_t obj_type)
case H5I_ERROR_MSG:
case H5I_ERROR_STACK:
case H5I_SPACE_SEL_ITER:
+ case H5I_EVENTSET:
case H5I_NTYPES:
default:
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unknown data object type")
@@ -2095,7 +2138,7 @@ H5VL__free_vol_wrapper(H5VL_wrap_ctx_t *vol_wrap_ctx)
"unable to release connector's object wrapping context")
/* Decrement refcount on connector */
- if (H5VL__conn_dec_rc(vol_wrap_ctx->connector) < 0)
+ if (H5VL_conn_dec_rc(vol_wrap_ctx->connector) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement ref count on VOL connector")
/* Release object wrapping context */
@@ -2152,7 +2195,7 @@ H5VL_set_vol_wrapper(const H5VL_object_t *vol_obj)
HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "can't allocate VOL wrap context")
/* Increment the outstanding objects that are using the connector */
- H5VL__conn_inc_rc(vol_obj->connector);
+ H5VL_conn_inc_rc(vol_obj->connector);
/* Set up VOL object wrapper context */
vol_wrap_ctx->rc = 1;
@@ -2362,7 +2405,7 @@ done:
herr_t
H5VL_check_plugin_load(const H5VL_class_t *cls, const H5PL_key_t *key, hbool_t *success)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
@@ -2375,16 +2418,16 @@ H5VL_check_plugin_load(const H5VL_class_t *cls, const H5PL_key_t *key, hbool_t *
if (key->vol.kind == H5VL_GET_CONNECTOR_BY_NAME) {
/* Check if plugin name matches VOL connector class name */
if (cls->name && !HDstrcmp(cls->name, key->vol.u.name))
- *success = TRUE;
- } /* end if */
+ *success = TRUE;
+ } /* end if */
else {
/* Sanity check */
HDassert(key->vol.kind == H5VL_GET_CONNECTOR_BY_VALUE);
/* Check if plugin value matches VOL connector class value */
if (cls->value == key->vol.u.value)
- *success = TRUE;
- } /* end else */
+ *success = TRUE;
+ } /* end else */
/* Connector is a match, but might not be a compatible version */
if (*success && cls->version != H5VL_VERSION)
@@ -2393,3 +2436,273 @@ H5VL_check_plugin_load(const H5VL_class_t *cls, const H5PL_key_t *key, hbool_t *
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_check_plugin_load() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_setup_args
+ *
+ * Purpose: Set up arguments to access an object
+ *
+ * Return: SUCCEED / FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_setup_args(hid_t loc_id, H5I_type_t id_type, H5VL_object_t **vol_obj)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity check */
+ HDassert(vol_obj);
+
+ /* Get attribute pointer */
+ if (NULL == (*vol_obj = (H5VL_object_t *)H5I_object_verify(loc_id, id_type)))
+ HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not the correct type of ID")
+
+ /* Set up collective metadata (if appropriate */
+ if (H5CX_set_loc(loc_id) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set collective metadata read")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_setup_args() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_setup_loc_args
+ *
+ * Purpose: Set up arguments to access an object
+ *
+ * Return: SUCCEED / FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_setup_loc_args(hid_t loc_id, H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity check */
+ HDassert(vol_obj);
+ HDassert(loc_params);
+
+ /* Get the location object */
+ if (NULL == (*vol_obj = (H5VL_object_t *)H5VL_vol_object(loc_id)))
+ HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not the correct type of ID")
+
+ /* Set up collective metadata (if appropriate */
+ if (H5CX_set_loc(loc_id) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set collective metadata read")
+
+ /* Set location parameters */
+ loc_params->type = H5VL_OBJECT_BY_SELF;
+ loc_params->obj_type = H5I_get_type(loc_id);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_setup_loc_args() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_setup_acc_args
+ *
+ * Purpose: Set up arguments to access an object
+ *
+ * Return: SUCCEED / FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_setup_acc_args(hid_t loc_id, const H5P_libclass_t *libclass, hbool_t is_collective, hid_t *acspl_id,
+ H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity check */
+ HDassert(libclass);
+ HDassert(acspl_id);
+ HDassert(vol_obj);
+ HDassert(loc_params);
+
+ /* Verify access property list and set up collective metadata if appropriate */
+ if (H5CX_set_apl(acspl_id, libclass, loc_id, is_collective) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set access property list info")
+
+ /* Get the location object */
+ if (NULL == (*vol_obj = (H5VL_object_t *)H5VL_vol_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+
+ /* Set location parameters */
+ loc_params->type = H5VL_OBJECT_BY_SELF;
+ loc_params->obj_type = H5I_get_type(loc_id);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_setup_acc_args() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_setup_self_args
+ *
+ * Purpose: Set up arguments to access an object "by self"
+ *
+ * Return: SUCCEED / FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_setup_self_args(hid_t loc_id, H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity check */
+ HDassert(vol_obj);
+ HDassert(loc_params);
+
+ /* Get the location object */
+ if (NULL == (*vol_obj = (H5VL_object_t *)H5VL_vol_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+
+ /* Set location parameters */
+ loc_params->type = H5VL_OBJECT_BY_SELF;
+ loc_params->obj_type = H5I_get_type(loc_id);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_setup_self_args() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_setup_name_args
+ *
+ * Purpose: Set up arguments to access an object "by name"
+ *
+ * Return: SUCCEED / FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_setup_name_args(hid_t loc_id, const char *name, const H5P_libclass_t *libclass, hbool_t is_collective,
+ hid_t acspl_id, H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity check */
+ HDassert(vol_obj);
+ HDassert(loc_params);
+
+ /* Check args */
+ if (!name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be NULL")
+ if (!*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be an empty string")
+
+ /* Verify access property list and set up collective metadata if appropriate */
+ if (H5CX_set_apl(&acspl_id, libclass, loc_id, is_collective) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set access property list info")
+
+ /* Get the location object */
+ if (NULL == (*vol_obj = (H5VL_object_t *)H5VL_vol_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+
+ /* Set up location parameters */
+ loc_params->type = H5VL_OBJECT_BY_NAME;
+ loc_params->loc_data.loc_by_name.name = name;
+ loc_params->loc_data.loc_by_name.lapl_id = acspl_id;
+ loc_params->obj_type = H5I_get_type(loc_id);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_setup_name_args() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_setup_idx_args
+ *
+ * Purpose: Set up arguments to access an object "by idx"
+ *
+ * Return: SUCCEED / FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_setup_idx_args(hid_t loc_id, const char *name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
+ const H5P_libclass_t *libclass, hbool_t is_collective, hid_t acspl_id,
+ H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity check */
+ HDassert(vol_obj);
+ HDassert(loc_params);
+
+ /* Check args */
+ if (!name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be NULL")
+ if (!*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be an empty string")
+ if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
+ if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
+
+ /* Verify access property list and set up collective metadata if appropriate */
+ if (H5CX_set_apl(&acspl_id, libclass, loc_id, is_collective) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set access property list info")
+
+ /* Get the location object */
+ if (NULL == (*vol_obj = (H5VL_object_t *)H5VL_vol_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+
+ /* Set location parameters */
+ loc_params->type = H5VL_OBJECT_BY_IDX;
+ loc_params->loc_data.loc_by_idx.name = name;
+ loc_params->loc_data.loc_by_idx.idx_type = idx_type;
+ loc_params->loc_data.loc_by_idx.order = order;
+ loc_params->loc_data.loc_by_idx.n = n;
+ loc_params->loc_data.loc_by_idx.lapl_id = acspl_id;
+ loc_params->obj_type = H5I_get_type(loc_id);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_setup_idx_args() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_setup_token_args
+ *
+ * Purpose: Set up arguments to access an object by token
+ *
+ * Return: SUCCEED / FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_setup_token_args(hid_t loc_id, H5O_token_t *obj_token, H5VL_object_t **vol_obj,
+ H5VL_loc_params_t *loc_params)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity check */
+ HDassert(vol_obj);
+ HDassert(loc_params);
+
+ /* Get the location object */
+ if (NULL == (*vol_obj = (H5VL_object_t *)H5VL_vol_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+
+ /* Set location parameters */
+ loc_params->type = H5VL_OBJECT_BY_TOKEN;
+ loc_params->loc_data.loc_by_token.token = obj_token;
+ loc_params->obj_type = H5I_get_type(loc_id);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_setup_token_args() */
diff --git a/src/H5VLnative.c b/src/H5VLnative.c
index 746264f..72c1b0c 100644
--- a/src/H5VLnative.c
+++ b/src/H5VLnative.c
@@ -19,23 +19,23 @@
/* Module Setup */
/****************/
-#define H5VL_FRIEND /* Suppress error about including H5VLpkg */
+#define H5VL_FRIEND /* Suppress error about including H5VLpkg */
/***********/
/* Headers */
/***********/
-#include "H5private.h" /* Generic Functions */
-#include "H5Aprivate.h" /* Attributes */
-#include "H5Dprivate.h" /* Datasets */
-#include "H5Eprivate.h" /* Error handling */
-#include "H5Fprivate.h" /* Files */
-#include "H5Gprivate.h" /* Groups */
-#include "H5Iprivate.h" /* IDs */
-#include "H5Oprivate.h" /* Object headers */
-#include "H5Pprivate.h" /* Property lists */
-#include "H5Tprivate.h" /* Datatypes */
-#include "H5VLpkg.h" /* Virtual Object Layer */
+#include "H5private.h" /* Generic Functions */
+#include "H5Aprivate.h" /* Attributes */
+#include "H5Dprivate.h" /* Datasets */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fprivate.h" /* Files */
+#include "H5Gprivate.h" /* Groups */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Oprivate.h" /* Object headers */
+#include "H5Pprivate.h" /* Property lists */
+#include "H5Tprivate.h" /* Datatypes */
+#include "H5VLpkg.h" /* Virtual Object Layer */
#include "H5VLnative_private.h" /* Native VOL connector */
@@ -556,6 +556,7 @@ H5VL_native_get_file_struct(void *obj, H5I_type_t type, H5F_t **file)
case H5I_ERROR_MSG:
case H5I_ERROR_STACK:
case H5I_SPACE_SEL_ITER:
+ case H5I_EVENTSET:
case H5I_NTYPES:
default:
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
diff --git a/src/H5VLnative_attr.c b/src/H5VLnative_attr.c
index 0c8de6c..3a231c9 100644
--- a/src/H5VLnative_attr.c
+++ b/src/H5VLnative_attr.c
@@ -430,17 +430,18 @@ H5VL__native_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_
}
case H5VL_ATTR_EXISTS: {
- const char *attr_name = HDva_arg(arguments, const char *);
- htri_t * ret = HDva_arg(arguments, htri_t *);
+ const char *attr_name = HDva_arg(arguments, const char *);
+ hbool_t * attr_exists = HDva_arg(arguments, hbool_t *);
if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Aexists */
/* Check if the attribute exists */
- if ((*ret = H5O__attr_exists(loc.oloc, attr_name)) < 0)
+ if (H5O__attr_exists(loc.oloc, attr_name, attr_exists) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists")
} /* end if */
else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Aexists_by_name */
/* Check if the attribute exists */
- if ((*ret = H5A__exists_by_name(loc, loc_params->loc_data.loc_by_name.name, attr_name)) < 0)
+ if (H5A__exists_by_name(loc, loc_params->loc_data.loc_by_name.name, attr_name, attr_exists) <
+ 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists")
} /* end else-if */
else
diff --git a/src/H5VLnative_dataset.c b/src/H5VLnative_dataset.c
index b8c153d..8ba1ef5 100644
--- a/src/H5VLnative_dataset.c
+++ b/src/H5VLnative_dataset.c
@@ -346,6 +346,13 @@ H5VL__native_dataset_specific(void *obj, H5VL_dataset_specific_t specific_type,
break;
}
+ case H5VL_DATASET_WAIT: { /* H5Dwait */
+ /* The native VOL connector doesn't support asynchronous
+ * operations, so this is a no-op.
+ */
+ break;
+ }
+
default:
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation")
} /* end switch */
diff --git a/src/H5VLnative_file.c b/src/H5VLnative_file.c
index 6fc8e9a..50ae9a5 100644
--- a/src/H5VLnative_file.c
+++ b/src/H5VLnative_file.c
@@ -404,6 +404,14 @@ H5VL__native_file_specific(void *obj, H5VL_file_specific_t specific_type, hid_t
break;
}
+ /* H5Fwait */
+ case H5VL_FILE_WAIT: {
+ /* The native VOL connector doesn't support asynchronous
+ * operations, so this is a no-op.
+ */
+ break;
+ }
+
default:
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation")
} /* end switch */
diff --git a/src/H5VLnative_link.c b/src/H5VLnative_link.c
index 33221ae..5ed7f9b 100644
--- a/src/H5VLnative_link.c
+++ b/src/H5VLnative_link.c
@@ -318,14 +318,14 @@ H5VL__native_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_
switch (specific_type) {
case H5VL_LINK_EXISTS: {
- htri_t * ret = HDva_arg(arguments, htri_t *);
+ hbool_t * exists = HDva_arg(arguments, hbool_t *);
H5G_loc_t loc;
if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
/* Check for the existence of the link */
- if ((*ret = H5L__exists(&loc, loc_params->loc_data.loc_by_name.name)) < 0)
+ if (H5L__exists(&loc, loc_params->loc_data.loc_by_name.name, exists) < 0)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to specific link info")
break;
}
diff --git a/src/H5VLpassthru.c b/src/H5VLpassthru.c
index 4097a75..787205c 100644
--- a/src/H5VLpassthru.c
+++ b/src/H5VLpassthru.c
@@ -228,9 +228,9 @@ static herr_t H5VL_pass_through_introspect_opt_query(void *obj, H5VL_subclass_t
uint64_t *flags);
/* Async request callbacks */
-static herr_t H5VL_pass_through_request_wait(void *req, uint64_t timeout, H5ES_status_t *status);
+static herr_t H5VL_pass_through_request_wait(void *req, uint64_t timeout, H5VL_request_status_t *status);
static herr_t H5VL_pass_through_request_notify(void *obj, H5VL_request_notify_t cb, void *ctx);
-static herr_t H5VL_pass_through_request_cancel(void *req);
+static herr_t H5VL_pass_through_request_cancel(void *req, H5VL_request_status_t *status);
static herr_t H5VL_pass_through_request_specific(void *req, H5VL_request_specific_t specific_type,
va_list arguments);
static herr_t H5VL_pass_through_request_optional(void *req, H5VL_request_optional_t opt_type,
@@ -2664,7 +2664,7 @@ H5VL_pass_through_introspect_opt_query(void *obj, H5VL_subclass_t cls, int opt_t
*-------------------------------------------------------------------------
*/
static herr_t
-H5VL_pass_through_request_wait(void *obj, uint64_t timeout, H5ES_status_t *status)
+H5VL_pass_through_request_wait(void *obj, uint64_t timeout, H5VL_request_status_t *status)
{
H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
herr_t ret_value;
@@ -2725,7 +2725,7 @@ H5VL_pass_through_request_notify(void *obj, H5VL_request_notify_t cb, void *ctx)
*-------------------------------------------------------------------------
*/
static herr_t
-H5VL_pass_through_request_cancel(void *obj)
+H5VL_pass_through_request_cancel(void *obj, H5VL_request_status_t *status)
{
H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
herr_t ret_value;
@@ -2734,7 +2734,7 @@ H5VL_pass_through_request_cancel(void *obj)
printf("------- PASS THROUGH VOL REQUEST Cancel\n");
#endif
- ret_value = H5VLrequest_cancel(o->under_object, o->under_vol_id);
+ ret_value = H5VLrequest_cancel(o->under_object, o->under_vol_id, status);
if (ret_value >= 0)
H5VL_pass_through_free_obj(o);
@@ -2822,13 +2822,13 @@ H5VL_pass_through_request_specific(void *obj, H5VL_request_specific_t specific_t
/* Release requests that have completed */
if (H5VL_REQUEST_WAITANY == specific_type) {
- size_t * idx; /* Pointer to the index of completed request */
- H5ES_status_t *status; /* Pointer to the request's status */
+ size_t * idx; /* Pointer to the index of completed request */
+ H5VL_request_status_t *status; /* Pointer to the request's status */
/* Retrieve the remaining arguments */
idx = va_arg(tmp_arguments, size_t *);
assert(*idx <= req_count);
- status = va_arg(tmp_arguments, H5ES_status_t *);
+ status = va_arg(tmp_arguments, H5VL_request_status_t *);
/* Reissue the WAITANY 'request specific' call */
ret_value = H5VL_pass_through_request_specific_reissue(o->under_object, o->under_vol_id,
@@ -2844,15 +2844,15 @@ H5VL_pass_through_request_specific(void *obj, H5VL_request_specific_t specific_t
} /* end if */
} /* end if */
else if (H5VL_REQUEST_WAITSOME == specific_type) {
- size_t * outcount; /* # of completed requests */
- unsigned * array_of_indices; /* Array of indices for completed requests */
- H5ES_status_t *array_of_statuses; /* Array of statuses for completed requests */
+ size_t * outcount; /* # of completed requests */
+ unsigned * array_of_indices; /* Array of indices for completed requests */
+ H5VL_request_status_t *array_of_statuses; /* Array of statuses for completed requests */
/* Retrieve the remaining arguments */
outcount = va_arg(tmp_arguments, size_t *);
assert(*outcount <= req_count);
array_of_indices = va_arg(tmp_arguments, unsigned *);
- array_of_statuses = va_arg(tmp_arguments, H5ES_status_t *);
+ array_of_statuses = va_arg(tmp_arguments, H5VL_request_status_t *);
/* Reissue the WAITSOME 'request specific' call */
ret_value = H5VL_pass_through_request_specific_reissue(
@@ -2872,14 +2872,14 @@ H5VL_pass_through_request_specific(void *obj, H5VL_request_specific_t specific_t
tmp_o = (H5VL_pass_through_t *)req_array[idx_array[u]];
H5VL_pass_through_free_obj(tmp_o);
- } /* end for */
- } /* end if */
- } /* end else-if */
- else { /* H5VL_REQUEST_WAITALL == specific_type */
- H5ES_status_t *array_of_statuses; /* Array of statuses for completed requests */
+ } /* end for */
+ } /* end if */
+ } /* end else-if */
+ else { /* H5VL_REQUEST_WAITALL == specific_type */
+ H5VL_request_status_t *array_of_statuses; /* Array of statuses for completed requests */
/* Retrieve the remaining arguments */
- array_of_statuses = va_arg(tmp_arguments, H5ES_status_t *);
+ array_of_statuses = va_arg(tmp_arguments, H5VL_request_status_t *);
/* Reissue the WAITALL 'request specific' call */
ret_value = H5VL_pass_through_request_specific_reissue(
diff --git a/src/H5VLpassthru.h b/src/H5VLpassthru.h
index 8576d21..917c42c 100644
--- a/src/H5VLpassthru.h
+++ b/src/H5VLpassthru.h
@@ -25,7 +25,7 @@
/* Characteristics of the pass-through VOL connector */
#define H5VL_PASSTHRU_NAME "pass_through"
-#define H5VL_PASSTHRU_VALUE 1 /* VOL connector ID */
+#define H5VL_PASSTHRU_VALUE 1 /* VOL connector ID */
#define H5VL_PASSTHRU_VERSION 0
/* Pass-through VOL connector info */
diff --git a/src/H5VLprivate.h b/src/H5VLprivate.h
index b54d8aa..eefd648 100644
--- a/src/H5VLprivate.h
+++ b/src/H5VLprivate.h
@@ -14,7 +14,7 @@
#define _H5VLprivate_H
/* Include package's public header */
-#include "H5VLpublic.h" /* Generic Functions */
+#include "H5VLpublic.h" /* Generic Functions */
/* Private headers needed by this file */
@@ -60,11 +60,13 @@ typedef enum H5VL_get_connector_kind_t {
/******************************/
/* Utility functions */
-H5_DLL herr_t H5VL_init_phase1(void);
-H5_DLL herr_t H5VL_init_phase2(void);
-H5_DLL herr_t H5VL_cmp_connector_cls(int *cmp_value, const H5VL_class_t *cls1, const H5VL_class_t *cls2);
-H5_DLL herr_t H5VL_conn_copy(H5VL_connector_prop_t *value);
-H5_DLL herr_t H5VL_conn_free(const H5VL_connector_prop_t *info);
+H5_DLL herr_t H5VL_init_phase1(void);
+H5_DLL herr_t H5VL_init_phase2(void);
+H5_DLL herr_t H5VL_cmp_connector_cls(int *cmp_value, const H5VL_class_t *cls1, const H5VL_class_t *cls2);
+H5_DLL herr_t H5VL_conn_copy(H5VL_connector_prop_t *value);
+H5_DLL int64_t H5VL_conn_inc_rc(H5VL_t *connector);
+H5_DLL int64_t H5VL_conn_dec_rc(H5VL_t *connector);
+H5_DLL herr_t H5VL_conn_free(const H5VL_connector_prop_t *info);
/* Functions that deal with VOL connectors */
union H5PL_key_t;
@@ -86,6 +88,7 @@ H5_DLL void *H5VL_object_data(const H5VL_object_t *vol_obj);
H5_DLL void *H5VL_object_unwrap(const H5VL_object_t *vol_obj);
H5_DLL void *H5VL_object_verify(hid_t id, H5I_type_t obj_type);
H5_DLL H5VL_object_t *H5VL_vol_object(hid_t id);
+H5_DLL H5VL_object_t *H5VL_create_object(void *object, H5VL_t *vol_connector);
H5_DLL H5VL_object_t *H5VL_create_object_using_vol_id(H5I_type_t type, void *obj, hid_t connector_id);
H5_DLL herr_t H5VL_free_object(H5VL_object_t *obj);
H5_DLL herr_t H5VL_object_is_native(const H5VL_object_t *obj, hbool_t *is_native);
@@ -115,6 +118,22 @@ H5_DLL hid_t H5VL_register_using_vol_id(H5I_type_t type, void *obj, hid_t conne
H5_DLL herr_t H5VL_register_using_existing_id(H5I_type_t type, void *object, H5VL_t *vol_connector,
hbool_t app_ref, hid_t existing_id);
+/* Object access functions */
+struct H5P_libclass_t;
+H5_DLL herr_t H5VL_setup_args(hid_t loc_id, H5I_type_t id_type, H5VL_object_t **vol_obj);
+H5_DLL herr_t H5VL_setup_loc_args(hid_t loc_id, H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params);
+H5_DLL herr_t H5VL_setup_acc_args(hid_t loc_id, const struct H5P_libclass_t *libclass, hbool_t is_collective,
+ hid_t *acspl_id, H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params);
+H5_DLL herr_t H5VL_setup_self_args(hid_t loc_id, H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params);
+H5_DLL herr_t H5VL_setup_name_args(hid_t loc_id, const char *name, const struct H5P_libclass_t *libclass,
+ hbool_t is_collective, hid_t acspl_id, H5VL_object_t **vol_obj,
+ H5VL_loc_params_t *loc_params);
+H5_DLL herr_t H5VL_setup_idx_args(hid_t loc_id, const char *name, H5_index_t idx_type, H5_iter_order_t order,
+ hsize_t n, const struct H5P_libclass_t *libclass, hbool_t is_collective,
+ hid_t acspl_id, H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params);
+H5_DLL herr_t H5VL_setup_token_args(hid_t loc_id, H5O_token_t *obj_token, H5VL_object_t **vol_obj,
+ H5VL_loc_params_t *loc_params);
+
/**********************************
* VOL connector callback wrappers
*********************************/
@@ -240,9 +259,10 @@ H5_DLL herr_t H5VL_introspect_opt_query(const H5VL_object_t *vol_obj, H5VL_subcl
uint64_t *flags);
/* Asynchronous functions */
-H5_DLL herr_t H5VL_request_wait(const H5VL_object_t *vol_obj, uint64_t timeout, H5ES_status_t *status);
+H5_DLL herr_t H5VL_request_wait(const H5VL_object_t *vol_obj, uint64_t timeout,
+ H5VL_request_status_t *status);
H5_DLL herr_t H5VL_request_notify(const H5VL_object_t *vol_obj, H5VL_request_notify_t cb, void *ctx);
-H5_DLL herr_t H5VL_request_cancel(const H5VL_object_t *vol_obj);
+H5_DLL herr_t H5VL_request_cancel(const H5VL_object_t *vol_obj, H5VL_request_status_t *status);
H5_DLL herr_t H5VL_request_specific(const H5VL_object_t *vol_obj, H5VL_request_specific_t specific_type, ...);
H5_DLL herr_t H5VL_request_optional(const H5VL_object_t *vol_obj, H5VL_request_optional_t opt_type, ...);
H5_DLL herr_t H5VL_request_free(const H5VL_object_t *vol_obj);
diff --git a/src/H5VLpublic.h b/src/H5VLpublic.h
index 03bf807..12250aa 100644
--- a/src/H5VLpublic.h
+++ b/src/H5VLpublic.h
@@ -34,7 +34,7 @@
* implements. The HDF5 library will reject connectors with
* incompatible structs.
*/
-#define H5VL_VERSION 1
+#define H5VL_VERSION 2
/* VOL connector identifier values
* These are H5VL_class_value_t values, NOT hid_t values!
@@ -103,19 +103,19 @@ typedef int H5VL_class_value_t;
* (Used for various queries, etc)
*/
typedef enum H5VL_subclass_t {
- H5VL_SUBCLS_NONE, /**< Operations outside of a subclass */
- H5VL_SUBCLS_INFO, /**< 'Info' subclass */
- H5VL_SUBCLS_WRAP, /**< 'Wrap' subclass */
- H5VL_SUBCLS_ATTR, /**< 'Attribute' subclass */
- H5VL_SUBCLS_DATASET, /**< 'Dataset' subclass */
- H5VL_SUBCLS_DATATYPE, /**< 'Named datatype' subclass */
- H5VL_SUBCLS_FILE, /**< 'File' subclass */
- H5VL_SUBCLS_GROUP, /**< 'Group' subclass */
- H5VL_SUBCLS_LINK, /**< 'Link' subclass */
- H5VL_SUBCLS_OBJECT, /**< 'Object' subclass */
- H5VL_SUBCLS_REQUEST, /**< 'Request' subclass */
- H5VL_SUBCLS_BLOB, /**< 'Blob' subclass */
- H5VL_SUBCLS_TOKEN /**< 'Token' subclass */
+ H5VL_SUBCLS_NONE, /**< Operations outside of a subclass */
+ H5VL_SUBCLS_INFO, /**< 'Info' subclass */
+ H5VL_SUBCLS_WRAP, /**< 'Wrap' subclass */
+ H5VL_SUBCLS_ATTR, /**< 'Attribute' subclass */
+ H5VL_SUBCLS_DATASET, /**< 'Dataset' subclass */
+ H5VL_SUBCLS_DATATYPE, /**< 'Named datatype' subclass */
+ H5VL_SUBCLS_FILE, /**< 'File' subclass */
+ H5VL_SUBCLS_GROUP, /**< 'Group' subclass */
+ H5VL_SUBCLS_LINK, /**< 'Link' subclass */
+ H5VL_SUBCLS_OBJECT, /**< 'Object' subclass */
+ H5VL_SUBCLS_REQUEST, /**< 'Request' subclass */
+ H5VL_SUBCLS_BLOB, /**< 'Blob' subclass */
+ H5VL_SUBCLS_TOKEN /**< 'Token' subclass */
} H5VL_subclass_t;
/********************/
@@ -361,8 +361,8 @@ H5_DLL herr_t H5VLquery_optional(hid_t obj_id, H5VL_subclass_t subcls, int opt_t
#endif
/* Semi-public headers mainly for VOL connector authors */
-#include "H5VLconnector.h" /* VOL connector author routines */
+#include "H5VLconnector.h" /* VOL connector author routines */
#include "H5VLconnector_passthru.h" /* Pass-through VOL connector author routines */
-#include "H5VLnative.h" /* Native VOL connector macros, for VOL connector authors */
+#include "H5VLnative.h" /* Native VOL connector macros, for VOL connector authors */
#endif /* _H5VLpublic_H */
diff --git a/src/H5Znbit.c b/src/H5Znbit.c
index 46585fb..8b928cf 100644
--- a/src/H5Znbit.c
+++ b/src/H5Znbit.c
@@ -95,13 +95,13 @@ H5Z_class2_t H5Z_NBIT[1] = {{
}};
/* Local macros */
-#define H5Z_NBIT_ATOMIC 1 /* Atomic datatype class: integer/floating-point */
-#define H5Z_NBIT_ARRAY 2 /* Array datatype class */
-#define H5Z_NBIT_COMPOUND 3 /* Compound datatype class */
-#define H5Z_NBIT_NOOPTYPE 4 /* Other datatype class: nbit does no compression */
+#define H5Z_NBIT_ATOMIC 1 /* Atomic datatype class: integer/floating-point */
+#define H5Z_NBIT_ARRAY 2 /* Array datatype class */
+#define H5Z_NBIT_COMPOUND 3 /* Compound datatype class */
+#define H5Z_NBIT_NOOPTYPE 4 /* Other datatype class: nbit does no compression */
#define H5Z_NBIT_MAX_NPARMS 4096 /* Max number of parameters for filter */
-#define H5Z_NBIT_ORDER_LE 0 /* Little endian for datatype byte order */
-#define H5Z_NBIT_ORDER_BE 1 /* Big endian for datatype byte order */
+#define H5Z_NBIT_ORDER_LE 0 /* Little endian for datatype byte order */
+#define H5Z_NBIT_ORDER_BE 1 /* Big endian for datatype byte order */
/* Local variables */
diff --git a/src/H5Zpublic.h b/src/H5Zpublic.h
index 56047ae..70278c3 100644
--- a/src/H5Zpublic.h
+++ b/src/H5Zpublic.h
@@ -216,10 +216,10 @@ typedef enum H5Z_SO_scale_type_t {
* Values to decide if EDC is enabled for reading data
*/
typedef enum H5Z_EDC_t {
- H5Z_ERROR_EDC = -1, /**< error value */
- H5Z_DISABLE_EDC = 0,
- H5Z_ENABLE_EDC = 1,
- H5Z_NO_EDC = 2 /**< sentinel */
+ H5Z_ERROR_EDC = -1, /**< error value */
+ H5Z_DISABLE_EDC = 0,
+ H5Z_ENABLE_EDC = 1,
+ H5Z_NO_EDC = 2 /**< sentinel */
} H5Z_EDC_t;
/* Bit flags for H5Zget_filter_info */
@@ -230,10 +230,10 @@ typedef enum H5Z_EDC_t {
* Return values for filter callback function
*/
typedef enum H5Z_cb_return_t {
- H5Z_CB_ERROR = -1,
- H5Z_CB_FAIL = 0, /**< I/O should fail if filter fails. */
- H5Z_CB_CONT = 1, /**< I/O continues if filter fails. */
- H5Z_CB_NO = 2
+ H5Z_CB_ERROR = -1,
+ H5Z_CB_FAIL = 0, /**< I/O should fail if filter fails. */
+ H5Z_CB_CONT = 1, /**< I/O continues if filter fails. */
+ H5Z_CB_NO = 2
} H5Z_cb_return_t;
/**
diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c
index 3330c3f..05309d1 100644
--- a/src/H5Zscaleoffset.c
+++ b/src/H5Zscaleoffset.c
@@ -103,14 +103,14 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{
/* Local macros */
#define H5Z_SCALEOFFSET_TOTAL_NPARMS 20 /* Total number of parameters for filter */
-#define H5Z_SCALEOFFSET_PARM_SCALETYPE 0 /* "User" parameter for scale type */
-#define H5Z_SCALEOFFSET_PARM_SCALEFACTOR 1 /* "User" parameter for scale factor */
-#define H5Z_SCALEOFFSET_PARM_NELMTS 2 /* "Local" parameter for number of elements in the chunk */
-#define H5Z_SCALEOFFSET_PARM_CLASS 3 /* "Local" parameter for datatype class */
-#define H5Z_SCALEOFFSET_PARM_SIZE 4 /* "Local" parameter for datatype size */
-#define H5Z_SCALEOFFSET_PARM_SIGN 5 /* "Local" parameter for integer datatype sign */
-#define H5Z_SCALEOFFSET_PARM_ORDER 6 /* "Local" parameter for datatype byte order */
-#define H5Z_SCALEOFFSET_PARM_FILAVAIL 7 /* "Local" parameter for dataset fill value existence */
+#define H5Z_SCALEOFFSET_PARM_SCALETYPE 0 /* "User" parameter for scale type */
+#define H5Z_SCALEOFFSET_PARM_SCALEFACTOR 1 /* "User" parameter for scale factor */
+#define H5Z_SCALEOFFSET_PARM_NELMTS 2 /* "Local" parameter for number of elements in the chunk */
+#define H5Z_SCALEOFFSET_PARM_CLASS 3 /* "Local" parameter for datatype class */
+#define H5Z_SCALEOFFSET_PARM_SIZE 4 /* "Local" parameter for datatype size */
+#define H5Z_SCALEOFFSET_PARM_SIGN 5 /* "Local" parameter for integer datatype sign */
+#define H5Z_SCALEOFFSET_PARM_ORDER 6 /* "Local" parameter for datatype byte order */
+#define H5Z_SCALEOFFSET_PARM_FILAVAIL 7 /* "Local" parameter for dataset fill value existence */
#define H5Z_SCALEOFFSET_PARM_FILVAL 8 /* "Local" parameter for start location to store dataset fill value */
#define H5Z_SCALEOFFSET_CLS_INTEGER 0 /* Integer (datatype class) */
@@ -1232,7 +1232,7 @@ H5Z__filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_valu
*/
minval_size = sizeof(unsigned long long) <= ((unsigned char *)*buf)[4] ? sizeof(unsigned long long)
: ((unsigned char *)*buf)[4];
- minval = 0;
+ minval = 0;
for (i = 0; i < minval_size; i++) {
minval_mask = ((unsigned char *)*buf)[5 + i];
minval_mask <<= i * 8;
diff --git a/src/H5Zshuffle.c b/src/H5Zshuffle.c
index 6d480d7..3f56e6e 100644
--- a/src/H5Zshuffle.c
+++ b/src/H5Zshuffle.c
@@ -122,7 +122,7 @@ H5Z__filter_shuffle(unsigned flags, size_t cd_nelmts, const unsigned cd_values[]
size_t numofelements; /* Number of elements in buffer */
size_t i; /* Local index variables */
#ifdef NO_DUFFS_DEVICE
- size_t j; /* Local index variable */
+ size_t j; /* Local index variable */
#endif /* NO_DUFFS_DEVICE */
size_t leftover; /* Extra bytes at end of buffer */
size_t ret_value = 0; /* Return value */
diff --git a/src/H5err.txt b/src/H5err.txt
index e2904fa..671eb66 100644
--- a/src/H5err.txt
+++ b/src/H5err.txt
@@ -80,6 +80,7 @@ MAJOR, H5E_PLUGIN, Plugin for dynamically loaded library
MAJOR, H5E_PAGEBUF, Page Buffering
MAJOR, H5E_CONTEXT, API Context
MAJOR, H5E_MAP, Map
+MAJOR, H5E_EVENTSET, Event Set
MAJOR, H5E_NONE_MAJOR, No error
# Sections (for grouping minor errors)
@@ -103,6 +104,8 @@ SECTION, FSPACE, Free space errors
SECTION, PIPELINE, I/O pipeline errors
SECTION, SYSTEM, System level errors
SECTION, PLUGIN, Plugin errors
+SECTION, MAP, Map related errors
+SECTION, ASYNC, Asynchronous I/O errors
SECTION, NONE, No error
# Minor errors
@@ -202,6 +205,7 @@ MINOR, BTREE, H5E_CANTINSERT, Unable to insert object
MINOR, BTREE, H5E_CANTLIST, Unable to list node
MINOR, BTREE, H5E_CANTMODIFY, Unable to modify record
MINOR, BTREE, H5E_CANTREMOVE, Unable to remove object
+MINOR, BTREE, H5E_CANTFIND, Unable to check for record
# Object header related errors
MINOR, OHDR, H5E_LINKCOUNT, Bad object header link count
@@ -281,5 +285,11 @@ MINOR, SYSTEM, H5E_SYSERRSTR, System error message
# Plugin errors
MINOR, PLUGIN, H5E_OPENERROR, Can't open directory or file
+# Map related errors
+MINOR, MAP, H5E_CANTPUT, Can't put value
+
+# Asynchronous operation errors
+MINOR, ASYNC, H5E_CANTWAIT, Can't wait on operation
+
# No error, for backward compatibility */
MINOR, NONE, H5E_NONE_MINOR, No error
diff --git a/src/H5private.h b/src/H5private.h
index fd0d8f5..a539432 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -2923,6 +2923,7 @@ H5_DLL int H5CX_term_package(void);
H5_DLL int H5D_term_package(void);
H5_DLL int H5D_top_term_package(void);
H5_DLL int H5E_term_package(void);
+H5_DLL int H5ES_term_package(void);
H5_DLL int H5F_term_package(void);
H5_DLL int H5FD_term_package(void);
H5_DLL int H5FL_term_package(void);
diff --git a/src/H5public.h b/src/H5public.h
index 6252778..29c8b37 100644
--- a/src/H5public.h
+++ b/src/H5public.h
@@ -91,12 +91,15 @@ extern "C" {
#define H5_GCC_DIAG_ON(x)
#endif
+/* Macro to hide a symbol from further preprocessor substitutions */
+#define H5_NO_EXPAND(x) (x)
+
/* Version numbers */
-#define H5_VERS_MAJOR 1 /* For major interface/format changes */
-#define H5_VERS_MINOR 13 /* For minor interface/format changes */
-#define H5_VERS_RELEASE 0 /* For tweaks, bug-fixes, or development */
-#define H5_VERS_SUBRELEASE "" /* For pre-releases like snap0 */
- /* Empty string for real releases. */
+#define H5_VERS_MAJOR 1 /* For major interface/format changes */
+#define H5_VERS_MINOR 13 /* For minor interface/format changes */
+#define H5_VERS_RELEASE 0 /* For tweaks, bug-fixes, or development */
+#define H5_VERS_SUBRELEASE "" /* For pre-releases like snap0 */
+/* Empty string for real releases. */
#define H5_VERS_INFO "HDF5 library version: 1.13.0" /* Full version string */
#define H5check() H5check_version(H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE)
diff --git a/src/H5trace.c b/src/H5trace.c
index 4beecc3..911aac3 100644
--- a/src/H5trace.c
+++ b/src/H5trace.c
@@ -1128,10 +1128,6 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap)
H5RS_acat(rs, "H5ES_STATUS_FAIL");
break;
- case H5ES_STATUS_CANCELED:
- H5RS_acat(rs, "H5ES_STATUS_CANCELED");
- break;
-
default:
H5RS_asprintf_cat(rs, "%ld", (long)status);
break;
@@ -1663,6 +1659,10 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap)
(unsigned long long)obj);
break;
+ case H5I_EVENTSET:
+ H5RS_asprintf_cat(rs, "0x%0llx (event set)", (unsigned long long)obj);
+ break;
+
case H5I_NTYPES:
H5RS_asprintf_cat(rs, "0x%0llx (ntypes - error)", (unsigned long long)obj);
break;
@@ -1677,6 +1677,15 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap)
case 'I':
switch (type[1]) {
+ case 'D': /* H5I_future_discard_func_t */
+ {
+ H5I_future_discard_func_t ifdisc =
+ (H5I_future_discard_func_t)HDva_arg(ap, H5I_future_discard_func_t);
+
+ H5RS_asprintf_cat(rs, "%p", (void *)(uintptr_t)ifdisc);
+ } /* end block */
+ break;
+
case 'f': /* H5I_free_t */
{
H5I_free_t ifree = (H5I_free_t)HDva_arg(ap, H5I_free_t);
@@ -1753,6 +1762,15 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap)
} /* end block */
break;
+ case 'R': /* H5I_future_realize_func_t */
+ {
+ H5I_future_realize_func_t ifreal =
+ (H5I_future_realize_func_t)HDva_arg(ap, H5I_future_realize_func_t);
+
+ H5RS_asprintf_cat(rs, "%p", (void *)(uintptr_t)ifreal);
+ } /* end block */
+ break;
+
case 's': /* int / int32_t */
{
int is = HDva_arg(ap, int);
@@ -1843,6 +1861,10 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap)
H5RS_acat(rs, "H5I_SPACE_SEL_ITER");
break;
+ case H5I_EVENTSET:
+ H5RS_acat(rs, "H5I_EVENTSET");
+ break;
+
case H5I_NTYPES:
H5RS_acat(rs, "H5I_NTYPES");
break;
@@ -2963,6 +2985,10 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap)
H5RS_acat(rs, "H5VL_DATASET_REFRESH");
break;
+ case H5VL_DATASET_WAIT:
+ H5RS_acat(rs, "H5VL_DATASET_WAIT");
+ break;
+
default:
H5RS_asprintf_cat(rs, "%ld", (long)specific);
break;
@@ -3087,6 +3113,10 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap)
H5RS_acat(rs, "H5VL_FILE_IS_EQUAL");
break;
+ case H5VL_FILE_WAIT:
+ H5RS_acat(rs, "H5VL_FILE_WAIT");
+ break;
+
default:
H5RS_asprintf_cat(rs, "%ld", (long)specific);
break;
@@ -3316,6 +3346,10 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap)
H5RS_acat(rs, "H5VL_REQUEST_WAITALL");
break;
+ case H5VL_REQUEST_GET_ERR_STACK:
+ H5RS_acat(rs, "H5VL_REQUEST_GET_ERR_STACK");
+ break;
+
default:
H5RS_asprintf_cat(rs, "%ld", (long)specific);
break;
diff --git a/src/H5win32defs.h b/src/H5win32defs.h
index d5096e5..4db5327 100644
--- a/src/H5win32defs.h
+++ b/src/H5win32defs.h
@@ -199,7 +199,7 @@ H5_DLL float Wroundf(float arg);
#define HDsetenv(N, V, O) Wsetenv(N, V, O)
#define HDflock(F, L) Wflock(F, L)
#define HDgetlogin() Wgetlogin()
-#define HDsnprintf c99_snprintf /*varargs*/
+#define HDsnprintf c99_snprintf /*varargs*/
#define HDvsnprintf c99_vsnprintf /*varargs*/
/* Non-POSIX functions */
diff --git a/src/Makefile.am b/src/Makefile.am
index e18b0ae..9bb2711 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -58,6 +58,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5lib_settings.c H5system.c \
H5E.c H5Edeprec.c H5Eint.c \
H5EA.c H5EAcache.c H5EAdbg.c H5EAdblkpage.c H5EAdblock.c H5EAhdr.c \
H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \
+ H5ES.c H5ESevent.c H5ESint.c H5ESlist.c \
H5F.c H5Faccum.c H5Fcwfs.c H5Fdbg.c H5Fdeprec.c H5Fefc.c H5Ffake.c \
H5Fint.c H5Fio.c H5Fmount.c H5Fquery.c H5Fsfile.c H5Fspace.c \
H5Fsuper.c H5Fsuper_cache.c H5Ftest.c \
@@ -154,7 +155,7 @@ include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5vers
H5Gpublic.h H5Ipublic.h H5Lpublic.h \
H5Mpublic.h H5MMpublic.h H5Opublic.h H5Ppublic.h \
H5PLextern.h H5PLpublic.h \
- H5Rpublic.h H5Spublic.h H5Tpublic.h \
+ H5Rpublic.h H5Spublic.h H5Tpublic.h H5TSpublic.h \
H5VLconnector.h H5VLconnector_passthru.h \
H5VLnative.h H5VLpassthru.h H5VLpublic.h \
H5Zpublic.h
diff --git a/src/hdf5.h b/src/hdf5.h
index 8ffe826..f22aa2a 100644
--- a/src/hdf5.h
+++ b/src/hdf5.h
@@ -37,6 +37,7 @@
#include "H5Rpublic.h" /* References */
#include "H5Spublic.h" /* Dataspaces */
#include "H5Tpublic.h" /* Datatypes */
+#include "H5TSpublic.h" /* Thread-safety */
#include "H5VLpublic.h" /* Virtual Object Layer */
#include "H5Zpublic.h" /* Data filters */