From dd6ad33c75bf084f08d4e84f92ab997c704b2096 Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Thu, 20 Jan 2022 07:34:43 -0600 Subject: Implement H5ESget requests function to retrieve requests from an event set (#1355) Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> --- release_docs/RELEASE.txt | 7 + src/H5ES.c | 55 ++++++ src/H5ESdevelop.h | 2 + src/H5ESint.c | 108 ++++++++++- src/H5ESlist.c | 11 +- src/H5ESpkg.h | 5 +- test/event_set.c | 489 ++++++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 659 insertions(+), 18 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index fc7d4dd..d059fb3 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -516,6 +516,13 @@ New Features Library: -------- + - Add a new public function, H5ESget_requests() + + This function allows the user to retrieve request pointers from an event + set. It is intended for use primarily by VOL plug in developers. + + (NAF - 2022/01/11) + - Adds new file driver-level memory copy operation for "ctl" callback and updates compact dataset I/O routines to utilize it diff --git a/src/H5ES.c b/src/H5ES.c index ccc0dd8..9abaa54 100644 --- a/src/H5ES.c +++ b/src/H5ES.c @@ -236,6 +236,61 @@ done: } /* end H5ESget_op_counter() */ /*------------------------------------------------------------------------- + * Function: H5ESget_requests + * + * Purpose: Retrieve the requests in an event set. Up to *count + * requests are stored in the provided requests array, and + * the connector ids corresponding to these requests are + * stored in the provided connector_ids array. Either or + * both of these arrays may be NULL, in which case this + * information is not returned. If these arrays are + * non-NULL, they must be large enough to contain *count + * entries. On exit, *count is set to the total number of + * events in the event set. + * + * Events are returned in the order they were added to the + * event set. If order is H5_ITER_INC or H5_ITER_NATIVE, + * events will be returned starting from the oldest. If order + * is H5_ITER_DEC, events will be returned starting with the + * newest/most recent. + * + * Return: SUCCEED / FAIL + * + * Programmer: Neil Fortner + * Tuesday, November 23, 2021 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ESget_requests(hid_t es_id, H5_iter_order_t order, hid_t *connector_ids, void **requests, size_t array_len, + size_t *count /*out*/) +{ + H5ES_t *es; /* Event set */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "iIo*i**xx", es_id, order, connector_ids, requests, count); + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") + + /* Call internal routine */ + if (array_len > 0 && (requests || connector_ids)) + if (H5ES__get_requests(es, order, connector_ids, requests, array_len) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, FAIL, "can't get requests") + + /* Retrieve the count, if non-NULL */ + if (count) + *count = H5ES__list_count(&es->active); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5ESget_requests() */ + +/*------------------------------------------------------------------------- * Function: H5ESwait * * Purpose: Wait (with timeout) for operations in event set to complete diff --git a/src/H5ESdevelop.h b/src/H5ESdevelop.h index 5a0f2b4..2fb9aeb 100644 --- a/src/H5ESdevelop.h +++ b/src/H5ESdevelop.h @@ -42,6 +42,8 @@ extern "C" { #endif H5_DLL herr_t H5ESinsert_request(hid_t es_id, hid_t connector_id, void *request); +H5_DLL herr_t H5ESget_requests(hid_t es_id, H5_iter_order_t order, hid_t *connector_ids, void **requests, + size_t array_len, size_t *count); #ifdef __cplusplus } diff --git a/src/H5ESint.c b/src/H5ESint.c index c66be16..7eb5909 100644 --- a/src/H5ESint.c +++ b/src/H5ESint.c @@ -50,6 +50,14 @@ /* Local Typedefs */ /******************/ +/* Callback context for get events operations */ +typedef struct H5ES_get_requests_ctx_t { + hid_t *connector_ids; /* Output buffer for list of connector IDs that match the above requests */ + void **requests; /* Output buffer for list of requests in event set */ + size_t array_len; /* Length of the above output buffers */ + size_t i; /* Number of elements filled in output buffers */ +} H5ES_get_requests_ctx_t; + /* Callback context for wait operations */ typedef struct H5ES_wait_ctx_t { H5ES_t * es; /* Event set being operated on */ @@ -84,6 +92,7 @@ static herr_t H5ES__close(H5ES_t *es); static herr_t H5ES__close_cb(void *es, void **request_token); static herr_t H5ES__insert(H5ES_t *es, H5VL_t *connector, void *request_token, const char *app_file, const char *app_func, unsigned app_line, const char *caller, const char *api_args); +static int H5ES__get_requests_cb(H5ES_event_t *ev, void *_ctx); static herr_t H5ES__handle_fail(H5ES_t *es, H5ES_event_t *ev); static herr_t H5ES__op_complete(H5ES_t *es, H5ES_event_t *ev, H5VL_request_status_t ev_status); static int H5ES__wait_cb(H5ES_event_t *ev, void *_ctx); @@ -282,7 +291,8 @@ H5ES__insert(H5ES_t *es, H5VL_t *connector, void *request_token, const char *app * there's no need to duplicate it. */ ev->op_info.api_name = caller; - if (NULL == (ev->op_info.api_args = H5MM_xstrdup(api_args))) + HDassert(ev->op_info.api_args == NULL); + if (api_args && NULL == (ev->op_info.api_args = H5MM_xstrdup(api_args))) HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy API routine arguments") /* Append fully initialized event onto the event set's 'active' list */ @@ -419,6 +429,86 @@ done: } /* end H5ES__insert_request() */ /*------------------------------------------------------------------------- + * Function: H5ES__get_requests_cb + * + * Purpose: Iterator callback for H5ES__get_events - adds the event to + * the list. + * + * Return: SUCCEED / FAIL + * + * Programmer: Neil Fortner + * Tuesday, November 23, 2021 + * + *------------------------------------------------------------------------- + */ +static int +H5ES__get_requests_cb(H5ES_event_t *ev, void *_ctx) +{ + H5ES_get_requests_ctx_t *ctx = (H5ES_get_requests_ctx_t *)_ctx; /* Callback context */ + int ret_value = H5_ITER_CONT; /* Return value */ + + FUNC_ENTER_STATIC_NOERR + + /* Sanity check */ + HDassert(ev); + HDassert(ctx); + HDassert(ctx->i < ctx->array_len); + + /* Get the connector ID for the event */ + if (ctx->connector_ids) + ctx->connector_ids[ctx->i] = ev->request->connector->id; + + /* Get the request for the event */ + if (ctx->requests) + ctx->requests[ctx->i] = ev->request->data; + + /* Check if we've run out of room in the arrays */ + if (++ctx->i == ctx->array_len) + ret_value = H5_ITER_STOP; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__get_requests_cb() */ + +/*------------------------------------------------------------------------- + * Function: H5ES__get_requests + * + * Purpose: Get all requests in an event set. + * + * Return: SUCCEED / FAIL + * + * Programmer: Neil Fortner + * Tuesday, November 23, 2021 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ES__get_requests(H5ES_t *es, H5_iter_order_t order, hid_t *connector_ids, void **requests, size_t array_len) +{ + H5ES_get_requests_ctx_t ctx; /* Callback context */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(es); + HDassert(array_len > 0); + HDassert(requests || connector_ids); + + /* Set up context for iterator callbacks */ + ctx.connector_ids = connector_ids; + ctx.requests = requests; + ctx.array_len = array_len; + ctx.i = 0; + + /* Iterate over the events in the set */ + if (H5ES__list_iterate(&es->active, order, H5ES__get_requests_cb, &ctx) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_BADITER, FAIL, "iteration failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__get_requests() */ + +/*------------------------------------------------------------------------- * Function: H5ES__handle_fail * * Purpose: Handle a failed event @@ -661,7 +751,7 @@ H5ES__wait(H5ES_t *es, uint64_t timeout, size_t *num_in_progress, hbool_t *op_fa 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) + if (H5ES__list_iterate(&es->active, H5_ITER_NATIVE, H5ES__wait_cb, &ctx) < 0) HGOTO_ERROR(H5E_EVENTSET, H5E_BADITER, FAIL, "iteration failed") done: @@ -769,7 +859,7 @@ H5ES__cancel(H5ES_t *es, size_t *num_not_canceled, hbool_t *op_failed) ctx.op_failed = op_failed; /* Iterate over the events in the set, attempting to cancel them */ - if (H5ES__list_iterate(&es->active, H5ES__cancel_cb, &ctx) < 0) + if (H5ES__list_iterate(&es->active, H5_ITER_NATIVE, H5ES__cancel_cb, &ctx) < 0) HGOTO_ERROR(H5E_EVENTSET, H5E_BADITER, FAIL, "iteration failed") done: @@ -806,13 +896,13 @@ H5ES__get_err_info_cb(H5ES_event_t *ev, void *_ctx) * so there's no need to duplicate them internally, but they are duplicated * here, when they are given back to the user. */ - if (NULL == (ctx->curr_err_info->api_name = H5MM_strdup(ev->op_info.api_name))) + if (NULL == (ctx->curr_err_info->api_name = H5MM_xstrdup(ev->op_info.api_name))) HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 API routine name") - if (NULL == (ctx->curr_err_info->api_args = H5MM_strdup(ev->op_info.api_args))) + if (NULL == (ctx->curr_err_info->api_args = H5MM_xstrdup(ev->op_info.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->op_info.app_file_name))) + if (NULL == (ctx->curr_err_info->app_file_name = H5MM_xstrdup(ev->op_info.app_file_name))) HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 application file name") - if (NULL == (ctx->curr_err_info->app_func_name = H5MM_strdup(ev->op_info.app_func_name))) + if (NULL == (ctx->curr_err_info->app_func_name = H5MM_xstrdup(ev->op_info.app_func_name))) HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 application function name") ctx->curr_err_info->app_line_num = ev->op_info.app_line_num; ctx->curr_err_info->op_ins_count = ev->op_info.op_ins_count; @@ -883,7 +973,7 @@ H5ES__get_err_info(H5ES_t *es, size_t num_err_info, H5ES_err_info_t err_info[], 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) + if (H5ES__list_iterate(&es->failed, H5_ITER_NATIVE, 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 */ @@ -957,7 +1047,7 @@ H5ES__close(H5ES_t *es) "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) + if (H5ES__list_iterate(&es->failed, H5_ITER_NATIVE, H5ES__close_failed_cb, (void *)es) < 0) HGOTO_ERROR(H5E_EVENTSET, H5E_BADITER, FAIL, "iteration failed") /* Release the event set */ diff --git a/src/H5ESlist.c b/src/H5ESlist.c index 3180322..61a9dd1 100644 --- a/src/H5ESlist.c +++ b/src/H5ESlist.c @@ -135,7 +135,10 @@ H5ES__list_count(const H5ES_event_list_t *el) * each event. * * Note: Iteration is safe for deleting the current event. Modifying - * the list in other ways is likely unsafe. + * the list in other ways is likely unsafe. If order is + * H5_ITER_INC or H5_ITER_NATIVE events are visited starting + * with the oldest, otherwise they are visited starting with + * the newest. * * Return: SUCCEED / FAIL * @@ -145,7 +148,7 @@ H5ES__list_count(const H5ES_event_list_t *el) *------------------------------------------------------------------------- */ int -H5ES__list_iterate(H5ES_event_list_t *el, H5ES_list_iter_func_t cb, void *ctx) +H5ES__list_iterate(H5ES_event_list_t *el, H5_iter_order_t order, H5ES_list_iter_func_t cb, void *ctx) { H5ES_event_t *ev; /* Event in list */ int ret_value = H5_ITER_CONT; /* Return value */ @@ -157,12 +160,12 @@ H5ES__list_iterate(H5ES_event_list_t *el, H5ES_list_iter_func_t cb, void *ctx) HDassert(cb); /* Iterate over events in list */ - ev = el->head; + ev = (order == H5_ITER_DEC) ? el->tail : 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; + tmp = (order == H5_ITER_DEC) ? ev->prev : ev->next; /* Perform iterator callback */ if ((ret_value = (*cb)(ev, ctx)) != H5_ITER_CONT) { diff --git a/src/H5ESpkg.h b/src/H5ESpkg.h index a7a8e20..6ee50fa 100644 --- a/src/H5ESpkg.h +++ b/src/H5ESpkg.h @@ -81,6 +81,8 @@ typedef int (*H5ES_list_iter_func_t)(H5ES_event_t *ev, void *ctx); H5_DLL H5ES_t *H5ES__create(void); H5_DLL herr_t H5ES__insert_request(H5ES_t *es, H5VL_t *connector, void *token); 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_requests(H5ES_t *es, H5_iter_order_t order, hid_t *connector_ids, void **requests, + size_t array_len); H5_DLL herr_t H5ES__cancel(H5ES_t *es, size_t *num_not_canceled, 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); @@ -88,7 +90,8 @@ H5_DLL herr_t H5ES__get_err_info(H5ES_t *es, size_t num_err_info, H5ES_err_info /* 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 int H5ES__list_iterate(H5ES_event_list_t *el, H5_iter_order_t order, 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 */ diff --git a/test/event_set.c b/test/event_set.c index 5df49e9..22df510 100644 --- a/test/event_set.c +++ b/test/event_set.c @@ -19,8 +19,157 @@ #include "h5test.h" #include "H5srcdir.h" +#define EVENT_SET_NUM_CONNECTOR_IDS 2 + const char *FILENAME[] = {"event_set_1", NULL}; +hid_t connector_ids_g[EVENT_SET_NUM_CONNECTOR_IDS]; + +herr_t fake_wait_request_wait(void *req, uint64_t timeout, H5VL_request_status_t *status); +herr_t fake_wait_request_free(void *req); + +/* A VOL class struct that describes a VOL class with no + * functionality, other than a wait that returns success. + */ +static const H5VL_class_t fake_wait_vol_g = { + H5VL_VERSION, /* VOL class struct version */ + ((H5VL_class_value_t)501), /* value */ + "fake_wait", /* name */ + 0, /* connector version */ + 0, /* capability flags */ + NULL, /* initialize */ + NULL, /* terminate */ + { + /* info_cls */ + (size_t)0, /* size */ + NULL, /* copy */ + NULL, /* compare */ + NULL, /* free */ + NULL, /* to_str */ + NULL, /* from_str */ + }, + { + /* wrap_cls */ + NULL, /* get_object */ + NULL, /* get_wrap_ctx */ + NULL, /* wrap_object */ + NULL, /* unwrap_object */ + NULL, /* free_wrap_ctx */ + }, + { + /* attribute_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* read */ + NULL, /* write */ + NULL, /* get */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* close */ + }, + { + /* dataset_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* read */ + NULL, /* write */ + NULL, /* get */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* close */ + }, + { + /* datatype_cls */ + NULL, /* commit */ + NULL, /* open */ + NULL, /* get */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* close */ + }, + { + /* file_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* get */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* close */ + }, + { + /* group_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* get */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* close */ + }, + { + /* link_cls */ + NULL, /* create */ + NULL, /* copy */ + NULL, /* move */ + NULL, /* get */ + NULL, /* specific */ + NULL /* optional */ + }, + { + /* object_cls */ + NULL, /* open */ + NULL, /* copy */ + NULL, /* get */ + NULL, /* specific */ + NULL /* optional */ + }, + { + /* introspect_cls */ + NULL, /* get_conn_cls */ + NULL, /* get_cap_flags */ + NULL, /* opt_query */ + }, + { + /* request_cls */ + fake_wait_request_wait, /* wait */ + NULL, /* notify */ + NULL, /* cancel */ + NULL, /* specific */ + NULL, /* optional */ + fake_wait_request_free /* free */ + }, + { + /* blob_cls */ + NULL, /* put */ + NULL, /* get */ + NULL, /* specific */ + NULL /* optional */ + }, + { + /* token_cls */ + NULL, /* cmp */ + NULL, /* to_str */ + NULL /* from_str */ + }, + NULL /* optional */ +}; + +herr_t +fake_wait_request_wait(void H5_ATTR_UNUSED *req, uint64_t H5_ATTR_UNUSED timeout, + H5VL_request_status_t *status) +{ + /* Set status if requested */ + if (status) + *status = H5VL_REQUEST_STATUS_SUCCEED; + + return 0; +} /* end H5_daos_req_wait() */ + +herr_t +fake_wait_request_free(void H5_ATTR_UNUSED *req) +{ + return 0; +} /* end fake_wait_request_free() */ + /*------------------------------------------------------------------------- * Function: test_es_create * @@ -159,6 +308,324 @@ error: } /*------------------------------------------------------------------------- + * Function: test_es_get_requests + * + * Purpose: Tests getting requests from event set. + * + * Return: Success: 0 + * Failure: number of errors + * + * Programmer: Neil Fortner + * Wednesday, November 24, 2021 + * + *------------------------------------------------------------------------- + */ +static int +test_es_get_requests(void) +{ + hid_t es_id; /* Event set ID */ + hid_t connector_ids[2]; /* Connector IDs */ + void * requests[2]; /* Requests */ + int req_targets[2]; /* Dummy targets for void * requests */ + size_t count; /* # of events in set */ + hbool_t op_failed; /* Whether an operation failed (unused) */ + + TESTING("event set get requests"); + + /* Create an event set */ + if ((es_id = H5EScreate()) < 0) + TEST_ERROR + + /* Get number of requests in event set */ + count = 3; + if (H5ESget_requests(es_id, H5_ITER_NATIVE, NULL, NULL, 0, &count) < 0) + TEST_ERROR + if (count != 0) + TEST_ERROR + + /* Get only connector IDs */ + count = 3; + if (H5ESget_requests(es_id, H5_ITER_NATIVE, connector_ids, NULL, 2, &count) < 0) + TEST_ERROR + if (count != 0) + TEST_ERROR + + /* Get only requests */ + count = 3; + if (H5ESget_requests(es_id, H5_ITER_NATIVE, NULL, requests, 2, &count) < 0) + TEST_ERROR + if (count != 0) + TEST_ERROR + + /* Get both */ + count = 3; + if (H5ESget_requests(es_id, H5_ITER_NATIVE, connector_ids, requests, 2, &count) < 0) + TEST_ERROR + if (count != 0) + TEST_ERROR + + /* Insert event into event set */ + if (H5ESinsert_request(es_id, connector_ids_g[0], &req_targets[0]) < 0) + TEST_ERROR + + /* Get number of requests in event set */ + count = 0; + if (H5ESget_requests(es_id, H5_ITER_NATIVE, NULL, NULL, 0, &count) < 0) + TEST_ERROR + if (count != 1) + TEST_ERROR + + /* Get only connector IDs */ + count = 0; + connector_ids[0] = H5I_INVALID_HID; + connector_ids[1] = H5I_INVALID_HID; + if (H5ESget_requests(es_id, H5_ITER_NATIVE, connector_ids, NULL, 2, &count) < 0) + TEST_ERROR + if (count != 1) + TEST_ERROR + if (connector_ids[0] != connector_ids_g[0]) + TEST_ERROR + if (connector_ids[1] != H5I_INVALID_HID) + TEST_ERROR + + /* Get only requests */ + count = 0; + requests[0] = NULL; + requests[1] = NULL; + if (H5ESget_requests(es_id, H5_ITER_NATIVE, NULL, requests, 2, &count) < 0) + TEST_ERROR + if (count != 1) + TEST_ERROR + if (requests[0] != &req_targets[0]) + TEST_ERROR + if (requests[1] != NULL) + TEST_ERROR + + /* Get both */ + count = 0; + connector_ids[0] = H5I_INVALID_HID; + connector_ids[1] = H5I_INVALID_HID; + requests[0] = NULL; + requests[1] = NULL; + if (H5ESget_requests(es_id, H5_ITER_NATIVE, connector_ids, requests, 2, &count) < 0) + TEST_ERROR + if (count != 1) + TEST_ERROR + if (connector_ids[0] != connector_ids_g[0]) + TEST_ERROR + if (connector_ids[1] != H5I_INVALID_HID) + TEST_ERROR + if (requests[0] != &req_targets[0]) + TEST_ERROR + if (requests[1] != NULL) + TEST_ERROR + + /* Insert second event into event set */ + if (H5ESinsert_request(es_id, connector_ids_g[1], &req_targets[1]) < 0) + TEST_ERROR + + /* Get number of requests in event set */ + count = 0; + if (H5ESget_requests(es_id, H5_ITER_NATIVE, NULL, NULL, 0, &count) < 0) + TEST_ERROR + if (count != 2) + TEST_ERROR + + /* Get only connector IDs */ + count = 0; + connector_ids[0] = H5I_INVALID_HID; + connector_ids[1] = H5I_INVALID_HID; + if (H5ESget_requests(es_id, H5_ITER_INC, connector_ids, NULL, 2, &count) < 0) + TEST_ERROR + if (count != 2) + TEST_ERROR + if (connector_ids[0] != connector_ids_g[0]) + TEST_ERROR + if (connector_ids[1] != connector_ids_g[1]) + TEST_ERROR + + /* Try with H5_ITER_DEC */ + count = 0; + connector_ids[0] = H5I_INVALID_HID; + connector_ids[1] = H5I_INVALID_HID; + if (H5ESget_requests(es_id, H5_ITER_DEC, connector_ids, NULL, 2, &count) < 0) + TEST_ERROR + if (count != 2) + TEST_ERROR + if (connector_ids[0] != connector_ids_g[1]) + TEST_ERROR + if (connector_ids[1] != connector_ids_g[0]) + TEST_ERROR + + /* Get only requests */ + count = 0; + requests[0] = NULL; + requests[1] = NULL; + if (H5ESget_requests(es_id, H5_ITER_INC, NULL, requests, 2, &count) < 0) + TEST_ERROR + if (count != 2) + TEST_ERROR + if (requests[0] != &req_targets[0]) + TEST_ERROR + if (requests[1] != &req_targets[1]) + TEST_ERROR + + /* Try with H5_ITER_DEC */ + count = 0; + requests[0] = NULL; + requests[1] = NULL; + if (H5ESget_requests(es_id, H5_ITER_DEC, NULL, requests, 2, &count) < 0) + TEST_ERROR + if (count != 2) + TEST_ERROR + if (requests[0] != &req_targets[1]) + TEST_ERROR + if (requests[1] != &req_targets[0]) + TEST_ERROR + + /* Get both */ + count = 0; + connector_ids[0] = H5I_INVALID_HID; + connector_ids[1] = H5I_INVALID_HID; + requests[0] = NULL; + requests[1] = NULL; + if (H5ESget_requests(es_id, H5_ITER_INC, connector_ids, requests, 2, &count) < 0) + TEST_ERROR + if (count != 2) + TEST_ERROR + if (connector_ids[0] != connector_ids_g[0]) + TEST_ERROR + if (connector_ids[1] != connector_ids_g[1]) + TEST_ERROR + if (requests[0] != &req_targets[0]) + TEST_ERROR + if (requests[1] != &req_targets[1]) + TEST_ERROR + + /* Try with H5_ITER_DEC */ + count = 0; + connector_ids[0] = H5I_INVALID_HID; + connector_ids[1] = H5I_INVALID_HID; + requests[0] = NULL; + requests[1] = NULL; + if (H5ESget_requests(es_id, H5_ITER_DEC, connector_ids, requests, 2, &count) < 0) + TEST_ERROR + if (count != 2) + TEST_ERROR + if (connector_ids[0] != connector_ids_g[1]) + TEST_ERROR + if (connector_ids[1] != connector_ids_g[0]) + TEST_ERROR + if (requests[0] != &req_targets[1]) + TEST_ERROR + if (requests[1] != &req_targets[0]) + TEST_ERROR + + /* Get only first connector ID */ + count = 0; + connector_ids[0] = H5I_INVALID_HID; + connector_ids[1] = H5I_INVALID_HID; + if (H5ESget_requests(es_id, H5_ITER_INC, connector_ids, NULL, 1, &count) < 0) + TEST_ERROR + if (count != 2) + TEST_ERROR + if (connector_ids[0] != connector_ids_g[0]) + TEST_ERROR + if (connector_ids[1] != H5I_INVALID_HID) + TEST_ERROR + + /* Try with H5_ITER_DEC */ + count = 0; + connector_ids[0] = H5I_INVALID_HID; + connector_ids[1] = H5I_INVALID_HID; + if (H5ESget_requests(es_id, H5_ITER_DEC, connector_ids, NULL, 1, &count) < 0) + TEST_ERROR + if (count != 2) + TEST_ERROR + if (connector_ids[0] != connector_ids_g[1]) + TEST_ERROR + if (connector_ids[1] != H5I_INVALID_HID) + TEST_ERROR + + /* Get only first request */ + count = 0; + requests[0] = NULL; + requests[1] = NULL; + if (H5ESget_requests(es_id, H5_ITER_INC, NULL, requests, 1, &count) < 0) + TEST_ERROR + if (count != 2) + TEST_ERROR + if (requests[0] != &req_targets[0]) + TEST_ERROR + if (requests[1] != NULL) + TEST_ERROR + + /* Try with H5_ITER_DEC */ + count = 0; + requests[0] = NULL; + requests[1] = NULL; + if (H5ESget_requests(es_id, H5_ITER_DEC, NULL, requests, 1, &count) < 0) + TEST_ERROR + if (count != 2) + TEST_ERROR + if (requests[0] != &req_targets[1]) + TEST_ERROR + if (requests[1] != NULL) + TEST_ERROR + + /* Get only first of both */ + count = 0; + connector_ids[0] = H5I_INVALID_HID; + connector_ids[1] = H5I_INVALID_HID; + requests[0] = NULL; + requests[1] = NULL; + if (H5ESget_requests(es_id, H5_ITER_INC, connector_ids, requests, 1, &count) < 0) + TEST_ERROR + if (connector_ids[0] != connector_ids_g[0]) + TEST_ERROR + if (connector_ids[1] != H5I_INVALID_HID) + TEST_ERROR + if (requests[0] != &req_targets[0]) + TEST_ERROR + if (requests[1] != NULL) + TEST_ERROR + + /* Try with H5_ITER_DEC */ + count = 0; + connector_ids[0] = H5I_INVALID_HID; + connector_ids[1] = H5I_INVALID_HID; + requests[0] = NULL; + requests[1] = NULL; + if (H5ESget_requests(es_id, H5_ITER_DEC, connector_ids, requests, 1, &count) < 0) + TEST_ERROR + if (connector_ids[0] != connector_ids_g[1]) + TEST_ERROR + if (connector_ids[1] != H5I_INVALID_HID) + TEST_ERROR + if (requests[0] != &req_targets[1]) + TEST_ERROR + if (requests[1] != NULL) + TEST_ERROR + + /* Close the event set */ + if (H5ESwait(es_id, 10000000, &count, &op_failed) < 0) + TEST_ERROR + if (H5ESclose(es_id) < 0) + TEST_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY + { + H5ESclose(es_id); + } + H5E_END_TRY; + return 1; +} + +/*------------------------------------------------------------------------- * Function: main * * Purpose: Tests event sets @@ -175,27 +642,41 @@ int main(void) { hid_t fapl_id = H5I_INVALID_HID; /* File access property list */ + int i; /* Local index variable */ int nerrors = 0; /* Error count */ /* Setup */ h5_reset(); fapl_id = h5_fileaccess(); + /* Register dummy connector IDs */ + for (i = 0; i < EVENT_SET_NUM_CONNECTOR_IDS; i++) + if ((connector_ids_g[i] = H5VLregister_connector(&fake_wait_vol_g, H5P_DEFAULT)) < 0) + TEST_ERROR + /* Tests */ nerrors += test_es_create(); nerrors += test_es_none(); + nerrors += test_es_get_requests(); + + /* Unregister dummy connectors */ + for (i = 0; i < EVENT_SET_NUM_CONNECTOR_IDS; i++) + if (H5VLunregister_connector(connector_ids_g[i]) < 0) + TEST_ERROR /* Cleanup */ h5_cleanup(FILENAME, fapl_id); /* Check for any errors */ - if (nerrors) { - HDputs("***** EVENT SET TESTS FAILED *****"); - HDexit(EXIT_FAILURE); - } /* end if */ + if (nerrors) + goto error; /* Report status */ HDputs("All event set tests passed."); HDexit(EXIT_SUCCESS); + +error: + HDputs("***** EVENT SET TESTS FAILED *****"); + HDexit(EXIT_FAILURE); } /* end main() */ -- cgit v0.12