diff options
Diffstat (limited to 'src/H5F.c')
-rw-r--r-- | src/H5F.c | 658 |
1 files changed, 558 insertions, 100 deletions
@@ -24,6 +24,7 @@ #include "H5ACprivate.h" /* Metadata cache */ #include "H5CXprivate.h" /* API Contexts */ #include "H5Eprivate.h" /* Error handling */ +#include "H5ESprivate.h" /* Event Sets */ #include "H5Fpkg.h" /* File access */ #include "H5FLprivate.h" /* Free lists */ #include "H5Iprivate.h" /* IDs */ @@ -67,6 +68,15 @@ static int H5F__get_all_count_cb(void H5_ATTR_UNUSED *obj_ptr, hid_t H5_ATTR_UNU /* Callback for getting IDs for open objects in a file */ static int H5F__get_all_ids_cb(void H5_ATTR_UNUSED *obj_ptr, hid_t obj_id, void *key); +/* Helper routines for sync/async API calls */ +static herr_t H5F__post_open_api_common(H5VL_object_t *vol_obj, void **token_ptr); +static hid_t H5F__create_api_common(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id, + void **token_ptr); +static hid_t H5F__open_api_common(const char *filename, unsigned flags, hid_t fapl_id, void **token_ptr); +static hid_t H5F__reopen_api_common(hid_t file_id, void **token_ptr); +static herr_t H5F__flush_api_common(hid_t object_id, H5F_scope_t scope, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); + /*********************/ /* Package Variables */ /*********************/ @@ -447,40 +457,53 @@ done: } /* end H5Fis_accessible() */ /*------------------------------------------------------------------------- - * Function: H5Fcreate + * Function: H5F__post_open_api_common * - * Purpose: This is the primary function for creating HDF5 files . The - * flags parameter determines whether an existing file will be - * overwritten or not. All newly created files are opened for - * both reading and writing. All flags may be combined with the - * bit-wise OR operator (`|') to change the behavior of the file - * create call. + * Purpose: This is the common function for 'post open' operations * - * The more complex behaviors of a file's creation and access - * are controlled through the file-creation and file-access - * property lists. The value of H5P_DEFAULT for a template - * value indicates that the library should use the default - * values for the appropriate template. + * Return: SUCCEED/FAIL * - * See also: H5Fpublic.h for the list of supported flags. H5Ppublic.h for - * the list of file creation and file access properties. + *------------------------------------------------------------------------- + */ +static herr_t +H5F__post_open_api_common(H5VL_object_t *vol_obj, void **token_ptr) +{ + uint64_t supported; /* Whether 'post open' operation is supported by VOL connector */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check for 'post open' callback */ + supported = 0; + if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't check for 'post open' operation") + if (supported & H5VL_OPT_QUERY_SUPPORTED) + /* Make the 'post open' callback */ + if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_POST_OPEN, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to make file 'post open' callback") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F__post_open_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5F__create_api_common + * + * Purpose: This is the common function for creating new HDF5 files. * * Return: Success: A file ID * Failure: H5I_INVALID_HID *------------------------------------------------------------------------- */ -hid_t -H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) +static hid_t +H5F__create_api_common(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id, void **token_ptr) { void * new_file = NULL; /* File struct for new file */ - H5P_genplist_t * plist; /* Property list pointer */ - H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ - H5VL_object_t * vol_obj = NULL; /* VOL object for file */ - uint64_t supported; /* Whether 'post open' operation is supported by VOL connector */ - hid_t ret_value; /* return value */ + H5P_genplist_t * plist; /* Property list pointer */ + H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ - FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE4("i", "*sIuii", filename, flags, fcpl_id, fapl_id); + FUNC_ENTER_STATIC /* Check/fix arguments */ if (!filename || !*filename) @@ -528,40 +551,71 @@ H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* Create a new file or truncate an existing file through the VOL */ if (NULL == (new_file = H5VL_file_create(&connector_prop, filename, flags, fcpl_id, fapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) + H5P_DATASET_XFER_DEFAULT, token_ptr))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to create file") /* Get an ID for the file */ if ((ret_value = H5VL_register_using_vol_id(H5I_FILE, new_file, connector_prop.connector_id, TRUE)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register file handle") +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F__create_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Fcreate + * + * Purpose: This is the primary function for creating HDF5 files . The + * flags parameter determines whether an existing file will be + * overwritten or not. All newly created files are opened for + * both reading and writing. All flags may be combined with the + * bit-wise OR operator (`|') to change the behavior of the file + * create call. + * + * The more complex behaviors of a file's creation and access + * are controlled through the file-creation and file-access + * property lists. The value of H5P_DEFAULT for a template + * value indicates that the library should use the default + * values for the appropriate template. + * + * See also: H5Fpublic.h for the list of supported flags. H5Ppublic.h for + * the list of file creation and file access properties. + * + * Return: Success: A file ID + * + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) +{ + H5VL_object_t *vol_obj = NULL; /* File object */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE4("i", "*sIuii", filename, flags, fcpl_id, fapl_id); + + /* Create the file synchronously */ + if ((ret_value = H5F__create_api_common(filename, flags, fcpl_id, fapl_id, NULL)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously create file") + /* Get the file object */ if (NULL == (vol_obj = H5VL_vol_object(ret_value))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier") + HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier") - /* Make the 'post open' callback */ - supported = 0; - if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't check for 'post open' operation") - if (supported & H5VL_OPT_QUERY_SUPPORTED) - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_POST_OPEN, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to make file 'post open' callback") + /* Perform 'post open' operation */ + if (H5F__post_open_api_common(vol_obj, NULL) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed") done: FUNC_LEAVE_API(ret_value) } /* end H5Fcreate() */ /*------------------------------------------------------------------------- - * Function: H5Fopen + * Function: H5Fcreate_async * - * Purpose: This is the primary function for accessing existing HDF5 - * files. The FLAGS argument determines whether writing to an - * existing file will be allowed or not. All flags may be - * combined with the bit-wise OR operator (`|') to change the - * behavior of the file open call. The more complex behaviors - * of a file's access are controlled through the file-access - * property list. + * Purpose: Asynchronous version of H5Fcreate * * See Also: H5Fpublic.h for a list of possible values for FLAGS. * @@ -570,17 +624,78 @@ done: *------------------------------------------------------------------------- */ hid_t -H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) +H5Fcreate_async(const char *app_file, const char *app_func, unsigned app_line, const char *filename, + unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t es_id) { - void * new_file = NULL; /* File struct for new file */ - H5P_genplist_t * plist; /* Property list pointer */ - H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ - H5VL_object_t * vol_obj = NULL; /* VOL object for file */ - uint64_t supported; /* Whether 'post open' operation is supported by VOL connector */ - hid_t ret_value; /* Return value */ + H5VL_object_t *vol_obj = NULL; /* File object */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE3("i", "*sIui", filename, flags, fapl_id); + H5TRACE8("i", "*s*sIu*sIuiii", app_file, app_func, app_line, filename, flags, fcpl_id, fapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Create the file, possibly asynchronously */ + if ((ret_value = H5F__create_api_common(filename, flags, fcpl_id, fapl_id, token_ptr)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously create file") + + /* Get the file object */ + if (NULL == (vol_obj = H5VL_vol_object(ret_value))) + HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE8(FUNC, "*s*sIu*sIuiii", app_file, app_func, app_line, filename, flags, + fcpl_id, fapl_id, es_id)) < 0) { + if (H5I_dec_app_ref(ret_value) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on file ID") + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + + /* Reset token for 'post open' operation */ + /* (Unnecessary if create operation didn't change it, but not worth checking -QAK) */ + token = NULL; + + /* Perform 'post open' operation */ + if (H5F__post_open_api_common(vol_obj, token_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE8(FUNC, "*s*sIu*sIuiii", app_file, app_func, app_line, filename, flags, + fcpl_id, fapl_id, es_id)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fcreate_async() */ + +/*------------------------------------------------------------------------- + * Function: H5F__open_api_common + * + * Purpose: This is the common function for accessing existing HDF5 + * files. + * + * Return: Success: A file ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5F__open_api_common(const char *filename, unsigned flags, hid_t fapl_id, void **token_ptr) +{ + H5F_t * new_file = NULL; /* File struct for new file */ + H5P_genplist_t * plist; /* Property list pointer */ + H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_STATIC /* Check arguments */ if (!filename || !*filename) @@ -615,51 +730,146 @@ H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set VOL connector info in API context") /* Open the file through the VOL layer */ - if (NULL == (new_file = H5VL_file_open(&connector_prop, filename, flags, fapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) + if (NULL == (new_file = (H5F_t *)H5VL_file_open(&connector_prop, filename, flags, fapl_id, + H5P_DATASET_XFER_DEFAULT, token_ptr))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to open file") /* Get an ID for the file */ if ((ret_value = H5VL_register_using_vol_id(H5I_FILE, new_file, connector_prop.connector_id, TRUE)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register file handle") +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F__open_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Fopen + * + * Purpose: This is the primary function for accessing existing HDF5 + * files. The FLAGS argument determines whether writing to an + * existing file will be allowed or not. All flags may be + * combined with the bit-wise OR operator (`|') to change the + * behavior of the file open call. The more complex behaviors + * of a file's access are controlled through the file-access + * property list. + * + * See Also: H5Fpublic.h for a list of possible values for FLAGS. + * + * Return: Success: A file ID + * + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) +{ + H5VL_object_t *vol_obj = NULL; /* File object */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE3("i", "*sIui", filename, flags, fapl_id); + + /* Open the file synchronously */ + if ((ret_value = H5F__open_api_common(filename, flags, fapl_id, NULL)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to synchronously open file") + /* Get the file object */ if (NULL == (vol_obj = H5VL_vol_object(ret_value))) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "invalid object identifier") + HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier") - /* Make the 'post open' callback */ - supported = 0; - if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't check for 'post open' operation") - if (supported & H5VL_OPT_QUERY_SUPPORTED) - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_POST_OPEN, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to make file 'post open' callback") + /* Perform 'post open' operation */ + if (H5F__post_open_api_common(vol_obj, NULL) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed") done: FUNC_LEAVE_API(ret_value) } /* end H5Fopen() */ /*------------------------------------------------------------------------- - * Function: H5Fflush + * Function: H5Fopen_async * - * Purpose: Flushes all outstanding buffers of a file to disk but does - * not remove them from the cache. The OBJECT_ID can be a file, - * dataset, group, attribute, or named data type. + * Purpose: Asynchronous version of H5Fopen + * + * See Also: H5Fpublic.h for a list of possible values for FLAGS. + * + * Return: Success: A file ID + * Failure: H5I_INVALID_HID * - * Return: Success: Non-negative - * Failure: Negative *------------------------------------------------------------------------- */ -herr_t -H5Fflush(hid_t object_id, H5F_scope_t scope) +hid_t +H5Fopen_async(const char *app_file, const char *app_func, unsigned app_line, const char *filename, + unsigned flags, hid_t fapl_id, hid_t es_id) { - H5VL_object_t *vol_obj = NULL; /* Object info */ - H5I_type_t obj_type; /* Type of object */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t *vol_obj = NULL; /* File object */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ - FUNC_ENTER_API(FAIL) - H5TRACE2("e", "iFs", object_id, scope); + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE7("i", "*s*sIu*sIuii", app_file, app_func, app_line, filename, flags, fapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Open the file, possibly asynchronously */ + if ((ret_value = H5F__open_api_common(filename, flags, fapl_id, token_ptr)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to asynchronously open file") + + /* Get the file object */ + if (NULL == (vol_obj = H5VL_vol_object(ret_value))) + HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIu*sIuii", app_file, app_func, app_line, filename, flags, + fapl_id, es_id)) < 0) { + if (H5I_dec_app_ref(ret_value) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on file ID") + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + + /* Reset token for 'post open' operation */ + /* (Unnecessary if create operation didn't change it, but not worth checking -QAK) */ + token = NULL; + + /* Perform 'post open' operation */ + if (H5F__post_open_api_common(vol_obj, token_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIu*sIuii", app_file, app_func, app_line, filename, flags, + fapl_id, es_id)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fopen_async() */ + +/*------------------------------------------------------------------------- + * Function: H5F__flush_api_common + * + * Purpose: This is the common function for flushing an HDF5 file. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F__flush_api_common(hid_t object_id, H5F_scope_t scope, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5I_type_t obj_type; /* Type of object to use */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC /* Get the type of object we're flushing + sanity check */ obj_type = H5I_get_type(object_id); @@ -668,19 +878,87 @@ H5Fflush(hid_t object_id, H5F_scope_t scope) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* Get the file object */ - if (NULL == (vol_obj = H5VL_vol_object(object_id))) + if (NULL == (*vol_obj_ptr = H5VL_vol_object(object_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") /* Flush the object */ - if (H5VL_file_specific(vol_obj, H5VL_FILE_FLUSH, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (int)obj_type, + if (H5VL_file_specific(*vol_obj_ptr, H5VL_FILE_FLUSH, H5P_DATASET_XFER_DEFAULT, token_ptr, (int)obj_type, (int)scope) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file") done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5F__flush_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Fflush + * + * Purpose: Flushes all outstanding buffers of a file to disk but does + * not remove them from the cache. The OBJECT_ID can be a file, + * dataset, group, attribute, or named data type. + * + * Return: Success: Non-negative + * Failure: Negative + *------------------------------------------------------------------------- + */ +herr_t +H5Fflush(hid_t object_id, H5F_scope_t scope) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "iFs", object_id, scope); + + /* Flush the file synchronously */ + if (H5F__flush_api_common(object_id, scope, NULL, NULL) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to synchronously flush file") + +done: FUNC_LEAVE_API(ret_value) } /* end H5Fflush() */ /*------------------------------------------------------------------------- + * Function: H5Fflush_async + * + * Purpose: Asynchronous version of H5Fflush + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5Fflush_async(const char *app_file, const char *app_func, unsigned app_line, hid_t object_id, + H5F_scope_t scope, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE6("e", "*s*sIuiFsi", app_file, app_func, app_line, object_id, scope, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Flush the file asynchronously */ + if (H5F__flush_api_common(object_id, scope, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to asynchronously flush file") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + if (H5ES_insert( + es_id, vol_obj->connector, token, + H5ARG_TRACE6(FUNC, "*s*sIuiFsi", app_file, app_func, app_line, object_id, scope, es_id)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fflush_async() */ + +/*------------------------------------------------------------------------- * Function: H5Fclose * * Purpose: This function closes the file specified by FILE_ID by @@ -717,6 +995,65 @@ done: } /* end H5Fclose() */ /*------------------------------------------------------------------------- + * Function: H5Fclose_async + * + * Purpose: Asynchronous version of H5Fclose + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Fclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t file_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + H5VL_t * connector = NULL; /* VOL connector */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, file_id, es_id); + + /* Check arguments */ + if (H5I_FILE != H5I_get_type(file_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID") + + /* Prepare for possible asynchronous operation */ + if (H5ES_NONE != es_id) { + /* Get file object's connector */ + if (NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get VOL object for file") + + /* Increase connector's refcount, so it doesn't get closed if closing + * this file ID closes the file */ + connector = vol_obj->connector; + H5VL_conn_inc_rc(connector); + + /* Point at token for operation to set up */ + token_ptr = &token; + } /* end if */ + + /* Asynchronously decrement reference count on ID. + * When it reaches zero the file will be closed. + */ + if (H5I_dec_app_ref_async(file_id, token_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, file_id, es_id)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + if (connector && H5VL_conn_dec_rc(connector) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't decrement ref count on connector") + + FUNC_LEAVE_API(ret_value) +} /* end H5Fclose_async() */ + +/*------------------------------------------------------------------------- * Function: H5Fdelete * * Purpose: Deletes an HDF5 file. @@ -888,37 +1225,31 @@ done: } /* end H5Funmount() */ /*------------------------------------------------------------------------- - * Function: H5Freopen - * - * Purpose: Reopen a file. The new file handle which is returned points - * to the same file as the specified file handle. Both handles - * share caches and other information. The only difference - * between the handles is that the new handle is not mounted - * anywhere and no files are mounted on it. + * Function: H5F__reopen_api_common * - * Return: Success: New file ID + * Purpose: This is the common function for reopening an HDF5 file + * files. * + * Return: Success: A file ID * Failure: H5I_INVALID_HID * *------------------------------------------------------------------------- */ -hid_t -H5Freopen(hid_t file_id) +static hid_t +H5F__reopen_api_common(hid_t file_id, void **token_ptr) { - void * file = NULL; /* File struct for new file */ - H5VL_object_t *vol_obj = NULL; /* VOL object for file */ - uint64_t supported; /* Whether 'post open' operation is supported by VOL connector */ + void * file = NULL; /* File struct for new file */ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ hid_t ret_value = H5I_INVALID_HID; /* Return value */ - FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE1("i", "i", file_id); + FUNC_ENTER_STATIC /* Get the file object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier") /* Reopen the file */ - if (H5VL_file_specific(vol_obj, H5VL_FILE_REOPEN, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &file) < 0) + if (H5VL_file_specific(vol_obj, H5VL_FILE_REOPEN, H5P_DATASET_XFER_DEFAULT, token_ptr, &file) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to reopen file via the VOL connector") /* Make sure that worked */ @@ -929,24 +1260,114 @@ H5Freopen(hid_t file_id) if ((ret_value = H5VL_register(H5I_FILE, file, vol_obj->connector, TRUE)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register file handle") +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F__reopen_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Freopen + * + * Purpose: Reopen a file. The new file handle which is returned points + * to the same file as the specified file handle. Both handles + * share caches and other information. The only difference + * between the handles is that the new handle is not mounted + * anywhere and no files are mounted on it. + * + * Return: Success: New file ID + * + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Freopen(hid_t file_id) +{ + H5VL_object_t *vol_obj = NULL; /* File object */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE1("i", "i", file_id); + + /* Reopen the file synchronously */ + if ((ret_value = H5F__reopen_api_common(file_id, NULL)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to synchronously reopen file") + /* Get the file object */ if (NULL == (vol_obj = H5VL_vol_object(ret_value))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier") + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't get handle for re-opened file") - /* Make the 'post open' callback */ - supported = 0; - if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't check for 'post open' operation") - if (supported & H5VL_OPT_QUERY_SUPPORTED) - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_POST_OPEN, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to make file 'post open' callback") + /* Perform 'post open' operation */ + if (H5F__post_open_api_common(vol_obj, NULL) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed") done: + /* XXX (VOL MERGE): If registration fails, file will not be closed */ FUNC_LEAVE_API(ret_value) } /* end H5Freopen() */ /*------------------------------------------------------------------------- + * Function: H5Freopen_async + * + * Purpose: Asynchronous version of H5Freopen + * + * See Also: H5Fpublic.h for a list of possible values for FLAGS. + * + * Return: Success: A file ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Freopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t file_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE5("i", "*s*sIuii", app_file, app_func, app_line, file_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Reopen the file, possibly asynchronously */ + if ((ret_value = H5F__reopen_api_common(file_id, token_ptr)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to asynchronously reopen file") + + /* Get the file object */ + if (NULL == (vol_obj = H5VL_vol_object(ret_value))) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't get handle for re-opened file") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, file_id, es_id)) < 0) { + if (H5I_dec_app_ref(ret_value) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on file ID") + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + + /* Reset token for 'post open' operation */ + /* (Unnecessary if create operation didn't change it, but not worth checking -QAK) */ + token = NULL; + + /* Perform 'post open' operation */ + if (H5F__post_open_api_common(vol_obj, token_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, file_id, es_id)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Freopen_async() */ + +/*------------------------------------------------------------------------- * Function: H5Fget_intent * * Purpose: Public API to retrieve the file's 'intent' flags passed @@ -1990,3 +2411,40 @@ H5Fset_dset_no_attrs_hint(hid_t file_id, hbool_t minimize) done: FUNC_LEAVE_API(ret_value) } /* H5Fset_dset_no_attrs_hint */ + +/*------------------------------------------------------------------------- + * Function: H5Fwait + * + * Purpose: Wait for all operations on a dataset. + * Tang: added for async + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Fwait(hid_t file_id) +{ + H5VL_object_t *vol_obj; /* File for this operation */ + H5I_type_t obj_type; /* Type of object */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", file_id); + + /* Get the type of object we're flushing + sanity check */ + obj_type = H5I_get_type(file_id); + if (H5I_FILE != obj_type && H5I_GROUP != obj_type && H5I_DATATYPE != obj_type && + H5I_DATASET != obj_type && H5I_ATTR != obj_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "file_id parameter is not a valid file identifier") + + if ((ret_value = H5VL_file_specific(vol_obj, H5VL_FILE_WAIT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, + file_id)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPERATE, FAIL, "unable to wait file") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Fwait() */ |