diff options
-rw-r--r-- | examples/test_client.c | 39 | ||||
-rw-r--r-- | src/H5D.c | 14 | ||||
-rw-r--r-- | src/H5EQ.c | 13 | ||||
-rw-r--r-- | src/H5EQprivate.h | 2 | ||||
-rw-r--r-- | src/H5F.c | 11 | ||||
-rw-r--r-- | src/H5FF.c | 230 | ||||
-rw-r--r-- | src/H5FFpublic.h | 19 | ||||
-rw-r--r-- | src/H5G.c | 11 | ||||
-rw-r--r-- | src/H5VLint.c | 96 | ||||
-rw-r--r-- | src/H5VLiod.c | 260 | ||||
-rw-r--r-- | src/H5VLiod_client.c | 318 | ||||
-rw-r--r-- | src/H5VLiod_client.h | 1 | ||||
-rw-r--r-- | src/H5VLiod_server.c | 2 | ||||
-rw-r--r-- | src/H5VLpublic.h | 2 |
14 files changed, 767 insertions, 251 deletions
diff --git a/examples/test_client.c b/examples/test_client.c index 30500fd..4a8f93e 100644 --- a/examples/test_client.c +++ b/examples/test_client.c @@ -233,28 +233,35 @@ int main(int argc, char **argv) { assert(plist_id);
H5Pclose(plist_id);
- assert(H5Dset_extent(did1, &temp) == 0);
+ /* change the dataset dimensions for Dataset D1. This is
+ asynchronous, but internally there is a built in
+ "wait_some" on operations pending on that dataset */
+ H5Dset_extent_ff(did1, &temp, event_q);
}
/* closing did1 acts as a wait_some on all pending requests that are issued
- on did1 (the H5Dwrite and 2 H5Dreads above). */
- H5Dclose(did1);
+ on did1 (the H5Dwrite and 2 H5Dreads above). This is asynchronous. */
+ H5Dclose_ff(did1, event_q);
/* closing did2 acts as a wait_some on all pending requests that are issued
- on did2 (the H5Dwrite above). */
- H5Dclose(did2);
+ on did2 (the H5Dwrite above). This is asynchronous. */
+ H5Dclose_ff(did2, event_q);
/* closing did3 acts as a wait_some on all pending requests that are issued
- on did3 (the H5Dwrite above). */
- H5Dclose(did3);
+ on did3 (the H5Dwrite above). This is asynchronous. */
+ H5Dclose_ff(did3, event_q);
- H5Gclose(gid1);
+ H5Gclose_ff(gid1, event_q);
- H5Fflush(file_id, H5F_SCOPE_GLOBAL);
+ /* flush all the contents of file to disk. This is asynchronous. */
+ H5Fflush_ff(file_id, H5F_SCOPE_GLOBAL, event_q);
+ /* closing the container also acts as a wait all on all pending requests
+ on the container. */
+ H5Fclose_ff(file_id, event_q);
H5EQwait(event_q, &num_requests, &status);
- fprintf(stderr, "%d requests in event queue. Expecting 7. Completions: ", num_requests);
+ fprintf(stderr, "%d requests in event queue. Expecting 14. Completions: ", num_requests);
for(i=0 ; i<num_requests; i++)
fprintf(stderr, "%d ",status[i]);
fprintf(stderr, "\n");
@@ -267,10 +274,6 @@ int main(int argc, char **argv) { fprintf(stderr, "\n");
free(status);
- /* closing the container also acts as a wait all on all pending requests
- on the container. */
- H5Fclose(file_id);
-
/* If the read request did no complete earlier when we tested it, Wait on it now.
We have to do this since we popped it earlier from the event queue */
if(H5AO_PENDING != status1) {
@@ -317,6 +320,10 @@ int main(int argc, char **argv) { did1 = H5Dopen_ff(file_id,"G1/G2/G3/D1", H5P_DEFAULT, 0, event_q);
assert(did1);
+ H5Dclose(did1);
+ H5Gclose(gid1);
+ H5Fclose(file_id);
+
H5EQwait(event_q, &num_requests, &status);
fprintf(stderr, "%d requests in event queue. Expecting 3. Completions: ", num_requests);
for(i=0 ; i<num_requests; i++)
@@ -324,10 +331,6 @@ int main(int argc, char **argv) { fprintf(stderr, "\n");
free(status);
- H5Dclose(did1);
- H5Gclose(gid1);
- H5Fclose(file_id);
-
H5EQclose(event_q);
H5Pclose(fapl_id);
@@ -394,6 +394,7 @@ done: herr_t H5Dclose(hid_t dset_id) { + H5VL_t *vol_plugin = NULL; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -403,6 +404,13 @@ H5Dclose(hid_t dset_id) if(H5I_DATASET != H5I_get_type(dset_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset ID") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information"); + /* set the event queue and dxpl IDs to be passed on to the VOL layer */ + vol_plugin->close_eq_id = H5_EVENT_QUEUE_NULL; + vol_plugin->close_dxpl_id = H5AC_dxpl_id; + /* * Decrement the counter on the dataset. It will be freed if the count * reaches zero. @@ -1021,7 +1029,8 @@ H5Dset_extent(hid_t dset_id, const hsize_t size[]) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") /* set the extent through the VOL */ - if((ret_value = H5VL_dataset_set_extent(dset, vol_plugin, size, H5AC_dxpl_id, H5_EVENT_QUEUE_NULL)) < 0) + if((ret_value = H5VL_dataset_set_extent(dset, vol_plugin, size, H5AC_dxpl_id, + H5_EVENT_QUEUE_NULL)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set extent of dataset") done: @@ -1051,7 +1060,8 @@ H5D_close_dataset(void *dset, H5VL_t *vol_plugin) FUNC_ENTER_NOAPI_NOINIT /* Close the dataset through the VOL*/ - if((ret_value = H5VL_dataset_close(dset, vol_plugin, H5AC_dxpl_id, H5_EVENT_QUEUE_NULL)) < 0) + if((ret_value = H5VL_dataset_close(dset, vol_plugin, vol_plugin->close_dxpl_id, + vol_plugin->close_eq_id)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to close dataset") done: @@ -331,7 +331,8 @@ herr_t H5EQwait(hid_t eq_id, int *num_requests/*OUT*/, H5_status_t **status/*OUT*/) { void *eq = NULL; /* event queue token */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_t *vol_plugin = NULL; /* VOL plugin pointer this event queue should use */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -343,8 +344,12 @@ H5EQwait(hid_t eq_id, int *num_requests/*OUT*/, H5_status_t **status/*OUT*/) if(NULL == (eq = (void *)H5I_object(eq_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event queue identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(eq_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information"); + /* Wait request in the event queue */ - if(H5EQ_wait((H5EQ_t *)eq, num_requests, status) < 0) + if(H5EQ_wait((H5EQ_t *)eq, vol_plugin, num_requests, status) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to wait request into event queue") done: @@ -559,7 +564,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5EQ_wait(H5EQ_t *eq, int *num_requests/*OUT*/, H5_status_t **_status/*OUT*/) +H5EQ_wait(H5EQ_t *eq, H5VL_t *vol_plugin, int *num_requests/*OUT*/, H5_status_t **_status/*OUT*/) { H5_priv_request_t *cur = NULL, *head = NULL, *next = NULL; int i = 0; @@ -587,7 +592,7 @@ H5EQ_wait(H5EQ_t *eq, int *num_requests/*OUT*/, H5_status_t **_status/*OUT*/) eq->tail = eq->head; /* wait on and free the request */ - if(head->req && H5VL_request_wait(&head->req, head->vol_plugin, &status[i++]) < 0) + if(head->req && H5VL_request_wait(&head->req, vol_plugin, &status[i++]) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to test request"); head->req = NULL; head->vol_plugin = NULL; diff --git a/src/H5EQprivate.h b/src/H5EQprivate.h index 1e4f17c..fcb89b6 100644 --- a/src/H5EQprivate.h +++ b/src/H5EQprivate.h @@ -64,7 +64,7 @@ herr_t H5EQ_init(void); /* API wrappers */ H5_DLL H5EQ_t *H5EQ_create(H5VL_t **plugin, H5P_genplist_t *plist); H5_DLL herr_t H5EQ_insert(H5EQ_t *eq, H5_priv_request_t *req); -H5_DLL herr_t H5EQ_wait(H5EQ_t *eq, int *num_requests, H5_status_t **status); +H5_DLL herr_t H5EQ_wait(H5EQ_t *eq, H5VL_t *vol_plugin, int *num_requests, H5_status_t **status); H5_DLL herr_t H5EQ_test(H5EQ_t *eq, int *num_remaining); H5_DLL herr_t H5EQ_close(void *grp, H5VL_t *vol_plugin); @@ -699,6 +699,7 @@ done: herr_t H5Fclose(hid_t file_id) { + H5VL_t *vol_plugin = NULL; herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) @@ -708,6 +709,13 @@ H5Fclose(hid_t file_id) if(H5I_FILE != H5I_get_type(file_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information"); + /* set the event queue and dxpl IDs to be passed on to the VOL layer */ + vol_plugin->close_eq_id = H5_EVENT_QUEUE_NULL; + vol_plugin->close_dxpl_id = H5AC_dxpl_id; + /* Decrement reference count on atom. When it reaches zero the file will be closed. */ if(H5I_dec_app_ref(file_id) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed") @@ -757,7 +765,8 @@ H5F_close_file(void *file, H5VL_t *vol_plugin) FUNC_ENTER_NOAPI_NOINIT /* Close the file through the VOL*/ - if((ret_value = H5VL_file_close(file, vol_plugin, H5AC_dxpl_id, H5_EVENT_QUEUE_NULL)) < 0) + if((ret_value = H5VL_file_close(file, vol_plugin, vol_plugin->close_dxpl_id, + vol_plugin->close_eq_id)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file") done: FUNC_LEAVE_NOAPI(ret_value) @@ -195,6 +195,102 @@ done: /*------------------------------------------------------------------------- + * Function: H5Fflush_ff + * + * Purpose: FF version of H5Fflush() + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April 2013 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Fflush_ff(hid_t object_id, H5F_scope_t scope, hid_t eq_id) +{ + H5VL_t *vol_plugin; + void *obj; + H5I_type_t obj_type; + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + + obj_type = H5I_get_type(object_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") + } + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(object_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(object_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = obj_type; + + if((ret_value = H5VL_file_flush(obj, loc_params, vol_plugin, scope, + H5AC_dxpl_id, eq_id)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fflush_ff() */ + + +/*------------------------------------------------------------------------- + * Function: H5Fclose_ff + * + * Purpose: This function closes the file specified by FILE_ID by + * flushing all data to storage, and terminating access to the + * file through FILE_ID. If objects (e.g., datasets, groups, + * etc.) are open in the file then the underlying storage is not + * closed until those objects are closed; however, all data for + * the file and the open objects is flushed. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * April 2013 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Fclose_ff(hid_t file_id, hid_t eq_id) +{ + H5VL_t *vol_plugin = NULL; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", file_id); + + /* Check/fix arguments. */ + if(H5I_FILE != H5I_get_type(file_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID") + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information"); + /* set the event queue and dxpl IDs to be passed on to the VOL layer */ + vol_plugin->close_eq_id = eq_id; + vol_plugin->close_dxpl_id = H5AC_dxpl_id; + + /* Decrement reference count on atom. When it reaches zero the file will be closed. */ + if(H5I_dec_app_ref(file_id) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fclose_ff() */ + + +/*------------------------------------------------------------------------- * Function: H5Gcreate_ff * * Purpose: Asynchronous wrapper around H5Gcreate(). @@ -348,6 +444,50 @@ done: /*------------------------------------------------------------------------- + * Function: H5Gclose_ff + * + * Purpose: Closes the specified group. The group ID will no longer be + * valid for accessing the group. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April 2013 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Gclose_ff(hid_t group_id, hid_t eq_id) +{ + H5VL_t *vol_plugin = NULL; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + + /* Check args */ + if(NULL == H5I_object_verify(group_id,H5I_GROUP)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group") + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(group_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information"); + /* set the event queue and dxpl IDs to be passed on to the VOL layer */ + vol_plugin->close_eq_id = eq_id; + vol_plugin->close_dxpl_id = H5AC_dxpl_id; + + /* + * Decrement the counter on the group atom. It will be freed if the count + * reaches zero. + */ + if(H5I_dec_app_ref(group_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Gclose_ff() */ + + +/*------------------------------------------------------------------------- * Function: H5Dcreate_ff * * Purpose: Asynchronous wrapper around H5Dcreate(). @@ -609,6 +749,96 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Dread_ff() */ + +/*------------------------------------------------------------------------- + * Function: H5Dset_extent_ff + * + * Purpose: Modifies the dimensions of a dataset. + * Can change to a smaller dimension. + * + * Return: Non-negative on success, negative on failure + * + * Programmer: Mohamad Chaarawi + * April 2013 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dset_extent_ff(hid_t dset_id, const hsize_t size[], hid_t eq_id) +{ + H5VL_t *vol_plugin; + void *dset; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + + if(!size) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no size specified") + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (dset = (void *)H5I_object(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") + + /* set the extent through the VOL */ + if((ret_value = H5VL_dataset_set_extent(dset, vol_plugin, size, H5AC_dxpl_id, eq_id)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set extent of dataset") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Dset_extent_ff() */ + + +/*------------------------------------------------------------------------- + * Function: H5Dclose_ff + * + * Purpose: Closes access to a dataset (DATASET_ID) and releases + * resources used by it. It is illegal to subsequently use that + * same dataset ID in calls to other dataset functions. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April 2013 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dclose_ff(hid_t dset_id, hid_t eq_id) +{ + H5VL_t *vol_plugin = NULL; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + + /* Check/fix arguments. */ + if(H5I_DATASET != H5I_get_type(dset_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset ID") + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information"); + /* set the event queue and dxpl IDs to be passed on to the VOL layer */ + vol_plugin->close_eq_id = eq_id; + vol_plugin->close_dxpl_id = H5AC_dxpl_id; + + /* + * Decrement the counter on the dataset. It will be freed if the count + * reaches zero. + * + * Pass in TRUE for the 3rd parameter to tell the function to remove + * dataset's ID even though the freeing function might fail. Please + * see the comments in H5I_dec_ref for details. (SLU - 2010/9/7) + */ + if(H5I_dec_app_ref_always_close(dset_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Dclose() */ + #if 0 /*------------------------------------------------------------------------- diff --git a/src/H5FFpublic.h b/src/H5FFpublic.h index 4453620..a1d87af 100644 --- a/src/H5FFpublic.h +++ b/src/H5FFpublic.h @@ -51,22 +51,29 @@ H5_DLL hid_t H5Fcreate_ff(const char *filename, unsigned flags, hid_t fcpl, hid_t fapl, hid_t eq_id); H5_DLL hid_t H5Fopen_ff(const char *filename, unsigned flags, hid_t fapl_id, hid_t eq_id); +H5_DLL herr_t H5Fflush_ff(hid_t object_id, H5F_scope_t scope, hid_t eq_id); +H5_DLL herr_t H5Fclose_ff(hid_t file_id, hid_t eq_id); + H5_DLL hid_t H5Gcreate_ff(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, - uint64_t /* UNUSED */ trans, hid_t eq_id); + uint64_t trans, hid_t eq_id); H5_DLL hid_t H5Gopen_ff(hid_t loc_id, const char *name, hid_t gapl_id, - uint64_t /* UNUSED */ trans, hid_t eq_id); + uint64_t trans, hid_t eq_id); +H5_DLL herr_t H5Gclose_ff(hid_t group_id, hid_t eq_id); + H5_DLL hid_t H5Dcreate_ff(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, - uint64_t /* UNUSED */ trans, hid_t eq_id); + uint64_t trans, hid_t eq_id); H5_DLL hid_t H5Dopen_ff(hid_t loc_id, const char *name, hid_t dapl_id, - uint64_t /* UNUSED */ trans, hid_t eq_id); + uint64_t trans, hid_t eq_id); H5_DLL herr_t H5Dwrite_ff(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, - uint64_t /* UNUSED */ trans, hid_t eq_id); + uint64_t trans, hid_t eq_id); H5_DLL herr_t H5Dread_ff(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*/, - uint64_t /* UNUSED */ trans, hid_t eq_id); + uint64_t trans, hid_t eq_id); +H5_DLL herr_t H5Dset_extent_ff(hid_t dset_id, const hsize_t size[], hid_t eq_id); +H5_DLL herr_t H5Dclose_ff(hid_t dset_id, hid_t eq_id); #endif /* H5_HAVE_EFF */ @@ -729,6 +729,7 @@ done: herr_t H5Gclose(hid_t group_id) { + H5VL_t *vol_plugin = NULL; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -738,6 +739,13 @@ H5Gclose(hid_t group_id) if(NULL == H5I_object_verify(group_id,H5I_GROUP)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(group_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information"); + /* set the event queue and dxpl IDs to be passed on to the VOL layer */ + vol_plugin->close_eq_id = H5_EVENT_QUEUE_NULL; + vol_plugin->close_dxpl_id = H5AC_dxpl_id; + /* * Decrement the counter on the group atom. It will be freed if the count * reaches zero. @@ -777,7 +785,8 @@ H5G_close_group(void *grp, H5VL_t *vol_plugin) FUNC_ENTER_NOAPI_NOINIT /* Close the group through the VOL*/ - if((ret_value = H5VL_group_close(grp, vol_plugin, H5AC_dxpl_id, H5_EVENT_QUEUE_NULL)) < 0) + if((ret_value = H5VL_group_close(grp, vol_plugin, vol_plugin->close_dxpl_id, + vol_plugin->close_eq_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to close group") done: diff --git a/src/H5VLint.c b/src/H5VLint.c index 29a854a..2dff9cd 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -1104,15 +1104,32 @@ herr_t H5VL_dataset_set_extent(void *dset, H5VL_t *vol_plugin, const hsize_t size[], hid_t dxpl_id, hid_t eq_id) { + H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */ + void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(FAIL) + if(eq_id != H5_EVENT_QUEUE_NULL) { + /* create the private request */ + if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + request->req = NULL; + req = &request->req; + request->next = NULL; + request->vol_plugin = vol_plugin; + } + if(NULL == vol_plugin->cls->dataset_cls.set_extent) HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `dataset set_extent' method") - if((ret_value = (vol_plugin->cls->dataset_cls.set_extent)(dset, size, dxpl_id, H5_REQUEST_NULL)) < 0) + if((ret_value = (vol_plugin->cls->dataset_cls.set_extent)(dset, size, dxpl_id, req)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "set_extent failed") + if(request && *req) { + if(H5EQinsert(eq_id, request) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event queue"); + } + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_dataset_set_extent() */ @@ -1189,10 +1206,22 @@ done: herr_t H5VL_dataset_close(void *dset, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t eq_id) { + H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */ + void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(FAIL) + if(eq_id != H5_EVENT_QUEUE_NULL) { + /* create the private request */ + if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + request->req = NULL; + req = &request->req; + request->next = NULL; + request->vol_plugin = vol_plugin; + } + /* if the VOL class does not implement a specific dataset close callback, try the object close */ if(NULL == vol_plugin->cls->dataset_cls.close){ @@ -1203,10 +1232,15 @@ H5VL_dataset_close(void *dset, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t eq_id) #endif } else { - if((ret_value = (vol_plugin->cls->dataset_cls.close)(dset, dxpl_id, H5_REQUEST_NULL)) < 0) + if((ret_value = (vol_plugin->cls->dataset_cls.close)(dset, dxpl_id, req)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed") } + if(request && *req) { + if(H5EQinsert(eq_id, request) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event queue"); + } + vol_plugin->nrefs --; if (0 == vol_plugin->nrefs) { vol_plugin->container_name = (const char *)H5MM_xfree(vol_plugin->container_name); @@ -1376,15 +1410,33 @@ herr_t H5VL_file_flush(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5F_scope_t scope, hid_t dxpl_id, hid_t eq_id) { + H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */ + void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(FAIL) + if(eq_id != H5_EVENT_QUEUE_NULL) { + /* create the private request */ + if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + request->req = NULL; + req = &request->req; + request->next = NULL; + request->vol_plugin = vol_plugin; + } + if(NULL == vol_plugin->cls->file_cls.flush) HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `file flush' method") - if((ret_value = (vol_plugin->cls->file_cls.flush)(obj, loc_params, scope, dxpl_id, H5_REQUEST_NULL)) < 0) + if((ret_value = (vol_plugin->cls->file_cls.flush)(obj, loc_params, scope, + dxpl_id, req)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTFLUSH, FAIL, "flush failed") + if(request && *req) { + if(H5EQinsert(eq_id, request) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event queue"); + } + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_file_flush() */ @@ -1541,15 +1593,32 @@ done: herr_t H5VL_file_close(void *file, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t eq_id) { + H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */ + void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(FAIL) + if(eq_id != H5_EVENT_QUEUE_NULL) { + /* create the private request */ + if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + request->req = NULL; + req = &request->req; + request->next = NULL; + request->vol_plugin = vol_plugin; + } + if(NULL == vol_plugin->cls->file_cls.close) HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `file close' method") - if((ret_value = (vol_plugin->cls->file_cls.close)(file, dxpl_id, H5_REQUEST_NULL)) < 0) + if((ret_value = (vol_plugin->cls->file_cls.close)(file, dxpl_id, req)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEFILE, FAIL, "close failed") + if(request && *req) { + if(H5EQinsert(eq_id, request) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event queue"); + } + vol_plugin->nrefs --; if (0 == vol_plugin->nrefs) { vol_plugin->container_name = (const char *)H5MM_xfree(vol_plugin->container_name); @@ -1727,10 +1796,22 @@ done: herr_t H5VL_group_close(void *grp, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t eq_id) { + H5_priv_request_t *request = NULL; /* private request struct inserted in event queue */ + void **req = NULL; /* pointer to plugin generate requests (Stays NULL if plugin does not support async */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(FAIL) + if(eq_id != H5_EVENT_QUEUE_NULL) { + /* create the private request */ + if(NULL == (request = (H5_priv_request_t *)H5MM_calloc(sizeof(H5_priv_request_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + request->req = NULL; + req = &request->req; + request->next = NULL; + request->vol_plugin = vol_plugin; + } + /* if the VOL class does not implement a specific group close callback, try the object close */ if(NULL == vol_plugin->cls->group_cls.close) { @@ -1741,10 +1822,15 @@ H5VL_group_close(void *grp, H5VL_t *vol_plugin, hid_t dxpl_id, hid_t eq_id) #endif } else { - if((ret_value = (vol_plugin->cls->group_cls.close)(grp, dxpl_id, H5_REQUEST_NULL)) < 0) + if((ret_value = (vol_plugin->cls->group_cls.close)(grp, dxpl_id, req)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed") } + if(request && *req) { + if(H5EQinsert(eq_id, request) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "failed to insert request in event queue"); + } + vol_plugin->nrefs --; if (0 == vol_plugin->nrefs) { vol_plugin->container_name = (const char *)H5MM_xfree(vol_plugin->container_name); diff --git a/src/H5VLiod.c b/src/H5VLiod.c index 6b703ce..9f82cb4 100644 --- a/src/H5VLiod.c +++ b/src/H5VLiod.c @@ -827,11 +827,12 @@ H5VL_iod_file_flush(void *_obj, H5VL_loc_params_t loc_params, H5F_scope_t scope, H5VL_iod_object_t *obj = (H5VL_iod_object_t *)_obj; H5VL_iod_file_t *file = obj->file; fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ - fs_request_t *fs_req = &_fs_req; + fs_request_t *fs_req = NULL; int *status; H5VL_iod_file_flush_input_t input; H5VL_iod_request_t _request; /* Local request, for sync. operations */ - H5VL_iod_request_t *request = &_request; + H5VL_iod_request_t *request = NULL; + hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -847,10 +848,26 @@ H5VL_iod_file_flush(void *_obj, H5VL_loc_params_t loc_params, H5F_scope_t scope, /* allocate an integer to receive the return value if the file close succeeded or not */ status = (int *)malloc(sizeof(int)); + /* get a function shipper request */ + if(do_async) { + if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate a FS request"); + } /* end if */ + else + fs_req = &_fs_req; + /* forward the call to the ION */ if(fs_forward(PEER, H5VL_FILE_FLUSH_ID, &input, status, fs_req) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to ship file close"); + /* Get async request for operation */ + if(do_async) { + if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); + } /* end if */ + else + request = &_request; + /* Set up request */ HDmemset(request, 0, sizeof(*request)); request->type = FS_FILE_FLUSH; @@ -861,12 +878,23 @@ H5VL_iod_file_flush(void *_obj, H5VL_loc_params_t loc_params, H5F_scope_t scope, /* add request to container's linked list */ H5VL_iod_request_add(file, request); - /* Synchronously wait on the request (no way to return request object currently) */ - if(H5VL_iod_request_wait(file, request) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't wait on FS request"); - if(SUCCEED != *status) - HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "file flush failed at the server") - free(status); + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + *req = request; + + /* Track request */ + file->common.request = request; + } /* end if */ + else { + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(file, request) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't wait on FS request"); + /* Sanity check */ + HDassert(request == &_request); + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -894,6 +922,7 @@ H5VL_iod_file_get(void *_obj, H5VL_file_get_t get_type, hid_t dxpl_id, void **re fs_request_t *fs_req; int *status; H5VL_iod_request_t *request; + hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -1026,6 +1055,7 @@ done: static herr_t H5VL_iod_file_misc(void *obj, H5VL_file_misc_t misc_type, hid_t dxpl_id, void **req, va_list arguments) { + hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -1093,10 +1123,11 @@ H5VL_iod_file_close(void *_file, hid_t dxpl_id, void **req) { H5VL_iod_file_t *file = (H5VL_iod_file_t *)_file; fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ - fs_request_t *fs_req = &_fs_req; + fs_request_t *fs_req = NULL; int *status; H5VL_iod_request_t _request; /* Local request, for sync. operations */ - H5VL_iod_request_t *request = &_request; + H5VL_iod_request_t *request = NULL; + hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -1108,10 +1139,26 @@ H5VL_iod_file_close(void *_file, hid_t dxpl_id, void **req) /* allocate an integer to receive the return value if the file close succeeded or not */ status = (int *)malloc(sizeof(int)); + /* get a function shipper request */ + if(do_async) { + if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate a FS request"); + } /* end if */ + else + fs_req = &_fs_req; + /* forward the call to the ION */ if(fs_forward(PEER, H5VL_FILE_CLOSE_ID, &file->remote_file, status, fs_req) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to ship file close"); + /* Get async request for operation */ + if(do_async) { + if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); + } /* end if */ + else + request = &_request; + /* Set up request */ HDmemset(request, 0, sizeof(*request)); request->type = FS_FILE_CLOSE; @@ -1122,22 +1169,23 @@ H5VL_iod_file_close(void *_file, hid_t dxpl_id, void **req) /* add request to container's linked list */ H5VL_iod_request_add(file, request); - /* MSC - just wait for the file close here for now, till we give requests to the API */ - if(H5VL_iod_request_wait(file, request) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wait on FS request"); - if(SUCCEED != *status) - HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "File close failed at the server"); - free(status); - - /* free everything */ - free(file->file_name); - free(file->common.obj_name); - if(file->fapl_id != H5P_FILE_ACCESS_DEFAULT && H5Pclose(file->fapl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); - if(file->remote_file.fcpl_id != H5P_FILE_CREATE_DEFAULT && - H5Pclose(file->remote_file.fcpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); - file = H5FL_FREE(H5VL_iod_file_t, file); + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + *req = request; + + /* Track request */ + file->common.request = request; + } /* end if */ + else { + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(file, request) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't wait on FS request"); + /* Sanity check */ + HDassert(request == &_request); + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -1436,6 +1484,7 @@ static herr_t H5VL_iod_group_get(void *_grp, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, va_list arguments) { H5VL_iod_group_t *grp = (H5VL_iod_group_t *)_grp; + hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -1482,11 +1531,12 @@ static herr_t H5VL_iod_group_close(void *_grp, hid_t dxpl_id, void **req) { H5VL_iod_group_t *grp = (H5VL_iod_group_t *)_grp; - fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ - fs_request_t *fs_req = &_fs_req; int *status; + fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ + fs_request_t *fs_req = NULL; H5VL_iod_request_t _request; /* Local request, for sync. operations */ - H5VL_iod_request_t *request = &_request; + H5VL_iod_request_t *request = NULL; + hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -1506,10 +1556,26 @@ H5VL_iod_group_close(void *_grp, hid_t dxpl_id, void **req) /* allocate an integer to receive the return value if the group close succeeded or not */ status = (int *)malloc(sizeof(int)); + /* get a function shipper request */ + if(do_async) { + if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate a FS request"); + } /* end if */ + else + fs_req = &_fs_req; + /* forward the call to the IONs */ if(fs_forward(PEER, H5VL_GROUP_CLOSE_ID, &grp->remote_group, status, fs_req) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to ship group close"); + /* Get async request for operation */ + if(do_async) { + if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); + } /* end if */ + else + request = &_request; + /* Set up request */ HDmemset(request, 0, sizeof(*request)); request->type = FS_GROUP_CLOSE; @@ -1520,20 +1586,23 @@ H5VL_iod_group_close(void *_grp, hid_t dxpl_id, void **req) /* add request to container's linked list */ H5VL_iod_request_add(grp->common.file, request); - /* Synchronously wait on the request (no way to return request object currently) */ - if(H5VL_iod_request_wait(grp->common.file, request) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't wait on FS request"); - if(SUCCEED != *status) - HGOTO_ERROR(H5E_SYM, H5E_CANTCLOSEOBJ, FAIL, "group close failed at the server") - free(status); - - free(grp->common.obj_name); - if(grp->gapl_id != H5P_GROUP_ACCESS_DEFAULT && H5Pclose(grp->gapl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); - if(grp->remote_group.gcpl_id != H5P_GROUP_CREATE_DEFAULT && - H5Pclose(grp->remote_group.gcpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); - grp = H5FL_FREE(H5VL_iod_group_t, grp); + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + *req = request; + + /* Track request */ + grp->common.request = request; + } /* end if */ + else { + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(grp->common.file, request) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't wait on FS request"); + /* Sanity check */ + HDassert(request == &_request); + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -2176,9 +2245,10 @@ H5VL_iod_dataset_set_extent(void *_dset, const hsize_t size[], hid_t dxpl_id, vo iod_obj_id_t iod_id; iod_handle_t iod_oh; fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ - fs_request_t *fs_req = &_fs_req; + fs_request_t *fs_req = NULL; H5VL_iod_request_t _request; /* Local request, for sync. operations */ - H5VL_iod_request_t *request = &_request; + H5VL_iod_request_t *request = NULL; + hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */ int *status = NULL; herr_t ret_value = SUCCEED; /* Return value */ @@ -2207,10 +2277,26 @@ H5VL_iod_dataset_set_extent(void *_dset, const hsize_t size[], hid_t dxpl_id, vo status = (int *)malloc(sizeof(int)); + /* get a function shipper request */ + if(do_async) { + if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate a FS request"); + } /* end if */ + else + fs_req = &_fs_req; + /* forward the call to the IONs */ if(fs_forward(PEER, H5VL_DSET_SET_EXTENT_ID, &input, status, fs_req) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "failed to ship dataset write"); + /* Get async request for operation */ + if(do_async) { + if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); + } /* end if */ + else + request = &_request; + /* Set up request */ HDmemset(request, 0, sizeof(*request)); request->type = FS_DSET_SET_EXTENT; @@ -2221,12 +2307,23 @@ H5VL_iod_dataset_set_extent(void *_dset, const hsize_t size[], hid_t dxpl_id, vo /* add request to container's linked list */ H5VL_iod_request_add(dset->common.file, request); - /* Synchronously wait on the request (no way to return request object currently) */ - if(H5VL_iod_request_wait(dset->common.file, request) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on FS request"); - if(SUCCEED != *status) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "dataset close failed at the server") - free(status); + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + *req = request; + + /* Track request */ + dset->common.request = request; + } /* end if */ + else { + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(dset->common.file, request) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't wait on FS request"); + /* Sanity check */ + HDassert(request == &_request); + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -2251,6 +2348,7 @@ H5VL_iod_dataset_get(void *_dset, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, va_list arguments) { H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)_dset; + hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -2325,11 +2423,12 @@ static herr_t H5VL_iod_dataset_close(void *_dset, hid_t dxpl_id, void **req) { H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)_dset; - fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ - fs_request_t *fs_req = &_fs_req; int *status; + fs_request_t _fs_req; /* Local function shipper request, for sync. operations */ + fs_request_t *fs_req = NULL; H5VL_iod_request_t _request; /* Local request, for sync. operations */ - H5VL_iod_request_t *request = &_request; + H5VL_iod_request_t *request = NULL; + hbool_t do_async = (req == NULL) ? FALSE : TRUE; /* Whether we're performing async. I/O */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -2350,10 +2449,26 @@ H5VL_iod_dataset_close(void *_dset, hid_t dxpl_id, void **req) status = (int *)malloc(sizeof(int)); + /* get a function shipper request */ + if(do_async) { + if(NULL == (fs_req = (fs_request_t *)H5MM_malloc(sizeof(fs_request_t)))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate a FS request"); + } /* end if */ + else + fs_req = &_fs_req; + /* forward the call to the IONs */ if(fs_forward(PEER, H5VL_DSET_CLOSE_ID, &dset->remote_dset, status, fs_req) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to ship dset close"); + /* Get async request for operation */ + if(do_async) { + if(NULL == (request = (H5VL_iod_request_t *)H5MM_malloc(sizeof(H5VL_iod_request_t)))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate IOD VOL request struct"); + } /* end if */ + else + request = &_request; + /* Set up request */ HDmemset(request, 0, sizeof(*request)); request->type = FS_DSET_CLOSE; @@ -2364,26 +2479,23 @@ H5VL_iod_dataset_close(void *_dset, hid_t dxpl_id, void **req) /* add request to container's linked list */ H5VL_iod_request_add(dset->common.file, request); - /* Synchronously wait on the request (no way to return request object currently) */ - if(H5VL_iod_request_wait(dset->common.file, request) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't wait on FS request"); - if(SUCCEED != *status) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "dataset close failed at the server") - free(status); - - free(dset->common.obj_name); - if(dset->remote_dset.dcpl_id != H5P_DATASET_CREATE_DEFAULT && - H5Pclose(dset->remote_dset.dcpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); - if(dset->dapl_id != H5P_DATASET_ACCESS_DEFAULT && - H5Pclose(dset->dapl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); - if(H5Tclose(dset->remote_dset.type_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dtype"); - if(H5Sclose(dset->remote_dset.space_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dspace"); - - dset = H5FL_FREE(H5VL_iod_dset_t, dset); + /* Store/wait on request */ + if(do_async) { + /* Sanity check */ + HDassert(request != &_request); + + *req = request; + + /* Track request */ + dset->common.request = request; + } /* end if */ + else { + /* Synchronously wait on the request */ + if(H5VL_iod_request_wait(dset->common.file, request) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't wait on FS request"); + /* Sanity check */ + HDassert(request == &_request); + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5VLiod_client.c b/src/H5VLiod_client.c index 34f4000..661c5e3 100644 --- a/src/H5VLiod_client.c +++ b/src/H5VLiod_client.c @@ -34,6 +34,10 @@ #ifdef H5_HAVE_EFF +H5FL_EXTERN(H5VL_iod_file_t); +H5FL_EXTERN(H5VL_iod_group_t); +H5FL_EXTERN(H5VL_iod_dset_t); + herr_t H5VL_iod_request_add(H5VL_iod_file_t *file, H5VL_iod_request_t *request) { @@ -146,72 +150,20 @@ H5VL_iod_request_wait(H5VL_iod_file_t *file, H5VL_iod_request_t *request) } else { if(tmp_status) { - if(FS_DSET_WRITE == cur_req->type || FS_DSET_READ == cur_req->type) { - H5VL_iod_io_info_t *info = (H5VL_iod_io_info_t *)cur_req->data; - - /* Free memory handle */ - if(S_SUCCESS != bds_handle_free(*info->bds_handle)) { - fprintf(stderr, "failed to free bds handle\n"); - cur_req->status = H5AO_FAILED; - cur_req->state = H5VL_IOD_COMPLETED; - H5VL_iod_request_delete(file, cur_req); - cur_req = tmp_req; - continue; - } - - if(FS_DSET_WRITE == cur_req->type && SUCCEED != *((int *)info->status)) { - fprintf(stderr, "Dataset Write operation failed\n"); - cur_req->status = H5AO_FAILED; - cur_req->state = H5VL_IOD_COMPLETED; - H5VL_iod_request_delete(file, cur_req); - cur_req = tmp_req; - continue; - } - else if(FS_DSET_READ == cur_req->type) { - H5VL_iod_read_status_t *read_status = (H5VL_iod_read_status_t *)info->status; - - if(SUCCEED != read_status->ret) { - fprintf(stderr, "Dataset READ operation failed\n"); - free(info->status); - info->status = NULL; - info->bds_handle = (bds_handle_t *)H5MM_xfree(info->bds_handle); - info = (H5VL_iod_io_info_t *)H5MM_xfree(info); - cur_req->status = H5AO_FAILED; - cur_req->state = H5VL_IOD_COMPLETED; - H5VL_iod_request_delete(file, cur_req); - cur_req = tmp_req; - continue; - } - if(info->checksum && info->checksum != read_status->cs) { - //free(info->status); - //info->status = NULL; - //info->bds_handle = (bds_handle_t *)H5MM_xfree(info->bds_handle); - //HDfree(cur_req->obj_name); - //info = (H5VL_iod_io_info_t *)H5MM_xfree(info); - /* MSC not returning an error because we injected this failure */ - fprintf(stderr, "Fatal Error! Data integrity failure (expecting %u got %u).\n", - info->checksum, read_status->cs); - //HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, SUCCEED, "Data Integrity Fail - bad Checksum"); - } - } - - free(info->status); - info->status = NULL; - info->bds_handle = (bds_handle_t *)H5MM_xfree(info->bds_handle); - info = (H5VL_iod_io_info_t *)H5MM_xfree(info); - } cur_req->status = H5AO_SUCCEEDED; cur_req->state = H5VL_IOD_COMPLETED; - H5VL_iod_request_delete(file, cur_req); + if(H5VL_iod_request_complete(file, cur_req) < 0) + fprintf(stderr, "Operation Failed!\n"); } } /* next time, test the next request in the list */ cur_req = tmp_req; } } - /* request complete, remove it from list break */ + /* request complete, remove it from list & break */ else { - H5VL_iod_request_delete(file, request); + if(H5VL_iod_request_complete(file, request) < 0) + fprintf(stderr, "Operation Failed!\n"); break; } } @@ -245,48 +197,9 @@ H5VL_iod_request_wait_all(H5VL_iod_file_t *file) cur_req->state = H5VL_IOD_COMPLETED; } - if(FS_DSET_WRITE == cur_req->type || FS_DSET_READ == cur_req->type) { - H5VL_iod_io_info_t *info = (H5VL_iod_io_info_t *)cur_req->data; - - /* Free memory handle */ - if(S_SUCCESS != bds_handle_free(*info->bds_handle)) { - fprintf(stderr, "failed to free bds handle\n"); - cur_req->status = H5AO_FAILED; - cur_req->state = H5VL_IOD_COMPLETED; - } - - if(FS_DSET_WRITE == cur_req->type && SUCCEED != *((int *)info->status)) { - fprintf(stderr, "write failed\n"); - cur_req->status = H5AO_FAILED; - cur_req->state = H5VL_IOD_COMPLETED; - } - else if(FS_DSET_READ == cur_req->type) { - H5VL_iod_read_status_t *read_status = (H5VL_iod_read_status_t *)info->status; - - if(SUCCEED != read_status->ret) { - fprintf(stderr, "read failed\n"); - cur_req->status = H5AO_FAILED; - cur_req->state = H5VL_IOD_COMPLETED; - } - if(info->checksum && info->checksum != read_status->cs) { - //free(info->status); - //info->status = NULL; - //info->bds_handle = (bds_handle_t *)H5MM_xfree(info->bds_handle); - //HDfree(cur_req->obj_name); - //info = (H5VL_iod_io_info_t *)H5MM_xfree(info); - /* MSC not returning an error because we injected this failure */ - fprintf(stderr, "Fatal Error! Data integrity failure (expecting %u got %u).\n", - info->checksum, read_status->cs); - } - } + if(H5VL_iod_request_complete(file, cur_req) < 0) + fprintf(stderr, "Operation Failed!\n"); - free(info->status); - info->status = NULL; - info->bds_handle = (bds_handle_t *)H5MM_xfree(info->bds_handle); - info = (H5VL_iod_io_info_t *)H5MM_xfree(info); - cur_req->data = NULL; - } - H5VL_iod_request_delete(file, cur_req); cur_req = tmp_req; } @@ -324,54 +237,185 @@ H5VL_iod_request_wait_some(H5VL_iod_file_t *file, const void *object) cur_req->status = H5AO_SUCCEEDED; cur_req->state = H5VL_IOD_COMPLETED; } - if(FS_DSET_WRITE == cur_req->type || FS_DSET_READ == cur_req->type) { - H5VL_iod_io_info_t *info = (H5VL_iod_io_info_t *)cur_req->data; - /* Free memory handle */ - if(S_SUCCESS != bds_handle_free(*info->bds_handle)) { - fprintf(stderr, "failed to free bds handle\n"); - cur_req->status = H5AO_FAILED; - cur_req->state = H5VL_IOD_COMPLETED; + if(H5VL_iod_request_complete(file, cur_req) < 0) + fprintf(stderr, "Operation Failed!\n"); + } + cur_req = tmp_req; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_iod_request_wait_some */ + +herr_t +H5VL_iod_request_complete(H5VL_iod_file_t *file, H5VL_iod_request_t *req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + switch(req->type) { + case FS_FILE_CREATE: + case FS_FILE_OPEN: + case FS_GROUP_CREATE: + case FS_GROUP_OPEN: + case FS_DSET_CREATE: + case FS_DSET_OPEN: + H5VL_iod_request_delete(file, req); + break; + case FS_DSET_WRITE: + case FS_DSET_READ: + { + H5VL_iod_io_info_t *info = (H5VL_iod_io_info_t *)req->data; + + /* Free memory handle */ + if(S_SUCCESS != bds_handle_free(*info->bds_handle)) { + fprintf(stderr, "failed to free bds handle\n"); + req->status = H5AO_FAILED; + req->state = H5VL_IOD_COMPLETED; + } + if(FS_DSET_WRITE == req->type && SUCCEED != *((int *)info->status)) { + fprintf(stderr, "write failed\n"); + req->status = H5AO_FAILED; + req->state = H5VL_IOD_COMPLETED; + } + else if(FS_DSET_READ == req->type) { + H5VL_iod_read_status_t *read_status = (H5VL_iod_read_status_t *)info->status; + + if(SUCCEED != read_status->ret) { + fprintf(stderr, "read failed\n"); + req->status = H5AO_FAILED; + req->state = H5VL_IOD_COMPLETED; } - if(FS_DSET_WRITE == cur_req->type && SUCCEED != *((int *)info->status)) { - fprintf(stderr, "write failed\n"); - cur_req->status = H5AO_FAILED; - cur_req->state = H5VL_IOD_COMPLETED; + if(info->checksum && info->checksum != read_status->cs) { + //free(info->status); + //info->status = NULL; + //info->bds_handle = (bds_handle_t *)H5MM_xfree(info->bds_handle); + //HDfree(req->obj_name); + //info = (H5VL_iod_io_info_t *)H5MM_xfree(info); + /* MSC not returning an error because we injected this failure */ + fprintf(stderr, "Fatal Error! Data integrity failure (expecting %u got %u).\n", + info->checksum, read_status->cs); } - else if(FS_DSET_READ == cur_req->type) { - H5VL_iod_read_status_t *read_status = (H5VL_iod_read_status_t *)info->status; + } - if(SUCCEED != read_status->ret) { - fprintf(stderr, "read failed\n"); - cur_req->status = H5AO_FAILED; - cur_req->state = H5VL_IOD_COMPLETED; - } - if(info->checksum && info->checksum != read_status->cs) { - //free(info->status); - //info->status = NULL; - //info->bds_handle = (bds_handle_t *)H5MM_xfree(info->bds_handle); - //HDfree(cur_req->obj_name); - //info = (H5VL_iod_io_info_t *)H5MM_xfree(info); - /* MSC not returning an error because we injected this failure */ - fprintf(stderr, "Fatal Error! Data integrity failure (expecting %u got %u).\n", - info->checksum, read_status->cs); - } - } + free(info->status); + info->status = NULL; + info->bds_handle = (bds_handle_t *)H5MM_xfree(info->bds_handle); + info = (H5VL_iod_io_info_t *)H5MM_xfree(info); + req->data = NULL; + H5VL_iod_request_delete(file, req); + break; + } + case FS_FILE_FLUSH: + { + int *status = (int *)req->data; - free(info->status); - info->status = NULL; - info->bds_handle = (bds_handle_t *)H5MM_xfree(info->bds_handle); - info = (H5VL_iod_io_info_t *)H5MM_xfree(info); - cur_req->data = NULL; - } - H5VL_iod_request_delete(file, cur_req); + if(SUCCEED != *status) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "file flush failed at the server"); + + free(status); + req->data = NULL; + file->common.request = NULL; + H5VL_iod_request_delete(file, req); + break; } - cur_req = tmp_req; + case FS_FILE_CLOSE: + { + int *status = (int *)req->data; + + if(SUCCEED != *status) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "file close failed at the server"); + + free(status); + req->data = NULL; + file->common.request = NULL; + H5VL_iod_request_delete(file, req); + + /* free everything */ + free(file->file_name); + free(file->common.obj_name); + if(file->fapl_id != H5P_FILE_ACCESS_DEFAULT && H5Pclose(file->fapl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); + if(file->remote_file.fcpl_id != H5P_FILE_CREATE_DEFAULT && + H5Pclose(file->remote_file.fcpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); + file = H5FL_FREE(H5VL_iod_file_t, file); + break; + } + case FS_GROUP_CLOSE: + { + int *status = (int *)req->data; + H5VL_iod_group_t *grp = (H5VL_iod_group_t *)req->obj; + + if(SUCCEED != *status) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "group close failed at the server"); + + free(status); + req->data = NULL; + grp->common.request = NULL; + H5VL_iod_request_delete(file, req); + + /* free group components */ + free(grp->common.obj_name); + if(grp->gapl_id != H5P_GROUP_ACCESS_DEFAULT && H5Pclose(grp->gapl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); + if(grp->remote_group.gcpl_id != H5P_GROUP_CREATE_DEFAULT && + H5Pclose(grp->remote_group.gcpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); + grp = H5FL_FREE(H5VL_iod_group_t, grp); + break; + } + case FS_DSET_SET_EXTENT: + { + int *status = (int *)req->data; + H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)req->obj; + + if(SUCCEED != *status) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "Dataset set extent failed at the server"); + + free(status); + req->data = NULL; + dset->common.request = NULL; + H5VL_iod_request_delete(file, req); + break; + } + case FS_DSET_CLOSE: + { + int *status = (int *)req->data; + H5VL_iod_dset_t *dset = (H5VL_iod_dset_t *)req->obj; + + if(SUCCEED != *status) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "dset close failed at the server"); + + free(status); + req->data = NULL; + dset->common.request = NULL; + H5VL_iod_request_delete(file, req); + + /* free dset components */ + free(dset->common.obj_name); + if(dset->remote_dset.dcpl_id != H5P_DATASET_CREATE_DEFAULT && + H5Pclose(dset->remote_dset.dcpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); + if(dset->dapl_id != H5P_DATASET_ACCESS_DEFAULT && + H5Pclose(dset->dapl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist"); + if(H5Tclose(dset->remote_dset.type_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dtype"); + if(H5Sclose(dset->remote_dset.space_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dspace"); + dset = H5FL_FREE(H5VL_iod_dset_t, dset); + break; + } + default: + H5VL_iod_request_delete(file, req); + HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "Request Type not supported"); } - done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL_iod_request_wait_some */ +} herr_t H5VL_iod_local_traverse(H5VL_iod_object_t *obj, H5VL_loc_params_t UNUSED loc_params, const char *name, diff --git a/src/H5VLiod_client.h b/src/H5VLiod_client.h index a2f19fe..a992574 100644 --- a/src/H5VLiod_client.h +++ b/src/H5VLiod_client.h @@ -109,6 +109,7 @@ H5_DLL herr_t H5VL_iod_request_add(H5VL_iod_file_t *file, H5VL_iod_request_t *re H5_DLL herr_t H5VL_iod_request_wait(H5VL_iod_file_t *file, H5VL_iod_request_t *request); H5_DLL herr_t H5VL_iod_request_wait_all(H5VL_iod_file_t *file); H5_DLL herr_t H5VL_iod_request_wait_some(H5VL_iod_file_t *file, const void *object); +H5_DLL herr_t H5VL_iod_request_complete(H5VL_iod_file_t *file, H5VL_iod_request_t *req); H5_DLL herr_t H5VL_iod_local_traverse(H5VL_iod_object_t *obj, H5VL_loc_params_t loc_params, const char *name, iod_obj_id_t *id, iod_handle_t *oh, char **new_name); diff --git a/src/H5VLiod_server.c b/src/H5VLiod_server.c index 7f46408..e20ef36 100644 --- a/src/H5VLiod_server.c +++ b/src/H5VLiod_server.c @@ -1544,9 +1544,7 @@ H5VL_iod_server_dset_create_cb(size_t UNUSED num_necessary_parents, AXE_task_t U name += nchars; } /* end while */ - printf("HERE1\n"); array.cell_size = H5Tget_size(input->type_id); - printf("HERE1\n"); array.num_dims = H5Sget_simple_extent_ndims(input->space_id); if(NULL == (array.current_dims = (iod_size_t *)malloc (sizeof(iod_size_t) * array.num_dims))) diff --git a/src/H5VLpublic.h b/src/H5VLpublic.h index 512aca3..c62c2a9 100644 --- a/src/H5VLpublic.h +++ b/src/H5VLpublic.h @@ -326,6 +326,8 @@ struct H5VL_t { const char *container_name; /* name of the underlying storage container */ unsigned long feature_flags; /* VOL Driver feature Flags */ int nrefs; /* number of references by objects using this struct */ + hid_t close_eq_id; + hid_t close_dxpl_id; }; #ifdef __cplusplus |