summaryrefslogtreecommitdiffstats
path: root/src/H5ES.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5ES.c')
-rw-r--r--src/H5ES.c407
1 files changed, 336 insertions, 71 deletions
diff --git a/src/H5ES.c b/src/H5ES.c
index 2ba8a72..ccc0dd8 100644
--- a/src/H5ES.c
+++ b/src/H5ES.c
@@ -34,11 +34,12 @@
/***********/
/* Headers */
/***********/
-#include "H5private.h" /* Generic Functions */
-#include "H5Eprivate.h" /* Error handling */
+#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 */
/****************/
/* Local Macros */
@@ -103,10 +104,61 @@ done:
} /* end H5EScreate() */
/*-------------------------------------------------------------------------
+ * Function: H5ESinsert_request
+ *
+ * Purpose: Insert a request from a VOL connector into an event set.
+ *
+ * Note: This function is primarily targeted at VOL connector
+ * authors and is _not_ designed for general-purpose application use.
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Friday, December 11, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESinsert_request(hid_t es_id, hid_t connector_id, void *request)
+{
+ H5ES_t *es; /* Event set */
+ H5VL_t *connector = NULL; /* VOL connector */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "ii*x", es_id, connector_id, request);
+
+ /* 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 == request)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL request pointer")
+
+ /* Create new VOL connector object, using the connector ID */
+ if (NULL == (connector = H5VL_new_connector(connector_id)))
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTCREATE, FAIL, "can't create VOL connector object")
+
+ /* Insert request into event set */
+ if (H5ES__insert_request(es, connector, request) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTINSERT, FAIL, "can't insert request into event set")
+
+done:
+ /* Clean up on error */
+ if (ret_value < 0)
+ /* Release newly created connector */
+ if (connector && H5VL_conn_dec_rc(connector) < 0)
+ HDONE_ERROR(H5E_EVENTSET, H5E_CANTDEC, FAIL, "unable to decrement ref count on VOL connector")
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESinsert_request() */
+
+/*-------------------------------------------------------------------------
* Function: H5ESget_count
*
* Purpose: Retrieve the # of events in an event set
*
+ * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op
+ *
* Return: SUCCEED / FAIL
*
* Programmer: Quincey Koziol
@@ -117,19 +169,23 @@ done:
herr_t
H5ESget_count(hid_t es_id, size_t *count /*out*/)
{
- H5ES_t *es; /* Event set */
- herr_t ret_value = SUCCEED; /* Return value */
+ 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")
+ /* Passing H5ES_NONE is valid, but a no-op */
+ if (H5ES_NONE != es_id) {
+ H5ES_t *es; /* Event set */
+
+ /* 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);
+ /* Retrieve the count, if non-NULL */
+ if (count)
+ *count = H5ES__list_count(&es->active);
+ } /* end if */
done:
FUNC_LEAVE_API(ret_value)
@@ -145,6 +201,8 @@ done:
* mechanism for matching operations inserted into the event
* set with [possible] errors that occur.
*
+ * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op
+ *
* Return: SUCCEED / FAIL
*
* Programmer: Quincey Koziol
@@ -155,19 +213,23 @@ done:
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 */
+ 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")
+ /* Passing H5ES_NONE is valid, but a no-op */
+ if (H5ES_NONE != es_id) {
+ H5ES_t *es; /* Event set */
- /* Retrieve the operation counter, if non-NULL */
- if (op_counter)
- *op_counter = es->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;
+ } /* end if */
done:
FUNC_LEAVE_API(ret_value)
@@ -192,6 +254,8 @@ done:
* value returned for the # of operations in progress may be
* inaccurate.
*
+ * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op
+ *
* Return: SUCCEED / FAIL
*
* Programmer: Quincey Koziol
@@ -202,33 +266,82 @@ done:
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 */
+ 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")
+ /* Passing H5ES_NONE is valid, but a no-op */
+ if (H5ES_NONE != es_id) {
+ H5ES_t *es; /* Event set */
+
+ /* 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")
+ } /* end if */
done:
FUNC_LEAVE_API(ret_value)
} /* end H5ESwait() */
/*-------------------------------------------------------------------------
+ * Function: H5EScancel
+ *
+ * Purpose: Attempt to cancel operations in an event set
+ *
+ * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, December 10, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5EScancel(hid_t es_id, size_t *num_not_canceled /*out*/, hbool_t *op_failed /*out*/)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "ixx", es_id, num_not_canceled, op_failed);
+
+ /* Passing H5ES_NONE is valid, but a no-op */
+ if (H5ES_NONE != es_id) {
+ H5ES_t *es; /* Event set */
+
+ /* 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_not_canceled)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL num_not_canceled pointer")
+ if (NULL == op_failed)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL op_failed pointer")
+
+ /* Cancel operations */
+ if (H5ES__cancel(es, num_not_canceled, op_failed) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTCANCEL, FAIL, "can't cancel operations")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5EScancel() */
+
+/*-------------------------------------------------------------------------
* Function: H5ESget_err_status
*
* Purpose: Check if event set has failed operations
*
+ * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op
+ *
* Return: SUCCEED / FAIL
*
* Programmer: Quincey Koziol
@@ -239,19 +352,23 @@ done:
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 */
+ 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")
+ /* Passing H5ES_NONE is valid, but a no-op */
+ if (H5ES_NONE != es_id) {
+ H5ES_t *es; /* Event set */
- /* Retrieve the error flag, if non-NULL */
- if (err_status)
- *err_status = es->err_occurred;
+ /* 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;
+ } /* end if */
done:
FUNC_LEAVE_API(ret_value)
@@ -265,6 +382,8 @@ done:
* Note: Does not wait for active operations to complete, so count may
* not include all failures.
*
+ * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op
+ *
* Return: SUCCEED / FAIL
*
* Programmer: Quincey Koziol
@@ -275,23 +394,27 @@ done:
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 */
+ 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")
+ /* Passing H5ES_NONE is valid, but a no-op */
+ if (H5ES_NONE != es_id) {
+ H5ES_t *es; /* Event set */
- /* 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 */
+ /* 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 */
+ } /* end if */
done:
FUNC_LEAVE_API(ret_value)
@@ -305,6 +428,8 @@ done:
* Note: The strings retrieved for each error info must be released
* by calling H5free_memory().
*
+ * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op
+ *
* Return: SUCCEED / FAIL
*
* Programmer: Quincey Koziol
@@ -316,29 +441,164 @@ 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 */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE4("e", "izxx", es_id, num_err_info, err_info, num_cleared);
+ /* Passing H5ES_NONE is valid, but a no-op */
+ if (H5ES_NONE != es_id) {
+ H5ES_t *es; /* Event set */
+
+ /* 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)")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESget_err_info() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ESfree_err_info
+ *
+ * Purpose: Convenience routine to free 1+ H5ES_err_info_t structs.
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Friday, March 5, 2021
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESfree_err_info(size_t num_err_info, H5ES_err_info_t err_info[])
+{
+ size_t u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "z*#", num_err_info, err_info);
+
/* 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)")
+ /* Iterate over array, releasing error information */
+ for (u = 0; u < num_err_info; u++) {
+ H5MM_xfree(err_info[u].api_name);
+ H5MM_xfree(err_info[u].api_args);
+ H5MM_xfree(err_info[u].app_file_name);
+ H5MM_xfree(err_info[u].app_func_name);
+ if (H5I_dec_app_ref(err_info[u].err_stack_id) < 0)
+ HGOTO_ERROR(H5E_EVENTSET, H5E_CANTDEC, FAIL, "can't close error stack for err_info #%zu", u)
+ } /* end for */
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5ESget_err_info() */
+} /* end H5ESfree_err_info() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ESregister_insert_func
+ *
+ * Purpose: Registers a callback to invoke when a new operation is inserted
+ * into an event set.
+ *
+ * Note: Only one insert callback can be registered for each event set.
+ * Registering a new callback will replace the existing one.
+ *
+ * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Friday, December 11, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESregister_insert_func(hid_t es_id, H5ES_event_insert_func_t func, void *ctx)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "iEI*x", es_id, func, ctx);
+
+ /* Passing H5ES_NONE is valid, but a no-op */
+ if (H5ES_NONE != es_id) {
+ H5ES_t *es; /* Event set */
+
+ /* 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 == func)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL function callback pointer")
+
+ /* Set the event set's insert callback */
+ es->ins_func = func;
+ es->ins_ctx = ctx;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESregister_insert_func() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5ESregister_complete_func
+ *
+ * Purpose: Registers a callback to invoke when an operation completes
+ * within an event set.
+ *
+ * Note: Only one complete callback can be registered for each event set.
+ * Registering a new callback will replace the existing one.
+ *
+ * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op
+ *
+ * Return: SUCCEED / FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Friday, December 11, 2020
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5ESregister_complete_func(hid_t es_id, H5ES_event_complete_func_t func, void *ctx)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "iEC*x", es_id, func, ctx);
+
+ /* Passing H5ES_NONE is valid, but a no-op */
+ if (H5ES_NONE != es_id) {
+ H5ES_t *es; /* Event set */
+
+ /* 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 == func)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL function callback pointer")
+
+ /* Set the event set's completion callback */
+ es->comp_func = func;
+ es->comp_ctx = ctx;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5ESregister_complete_func() */
/*-------------------------------------------------------------------------
* Function: H5ESclose
@@ -347,6 +607,8 @@ done:
*
* Note: Fails if active operations are present.
*
+ * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op
+ *
* Return: SUCCEED / FAIL
*
* Programmer: Quincey Koziol
@@ -362,16 +624,19 @@ H5ESclose(hid_t es_id)
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")
+ /* Passing H5ES_NONE is valid, but a no-op */
+ if (H5ES_NONE != 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")
+ } /* end if */
done:
FUNC_LEAVE_API(ret_value)