diff options
author | Mohamad Chaarawi <chaarawi@hdfgroup.org> | 2012-02-20 18:45:47 (GMT) |
---|---|---|
committer | Mohamad Chaarawi <chaarawi@hdfgroup.org> | 2012-02-20 18:45:47 (GMT) |
commit | d7147ff0eca5df777e2d9371aca7d1d98cbe45b4 (patch) | |
tree | 496b1c9be3327734653b7c7058add98eaaf782c7 | |
parent | 92d5cd3baf317573ed223d7fd373d8a8dc980547 (diff) | |
download | hdf5-d7147ff0eca5df777e2d9371aca7d1d98cbe45b4.zip hdf5-d7147ff0eca5df777e2d9371aca7d1d98cbe45b4.tar.gz hdf5-d7147ff0eca5df777e2d9371aca7d1d98cbe45b4.tar.bz2 |
[svn-r21964] a working version that works with the entire test suite
-rw-r--r-- | src/H5Eterm.h | 1 | ||||
-rw-r--r-- | src/H5F.c | 72 | ||||
-rw-r--r-- | src/H5Fefc.c | 77 | ||||
-rw-r--r-- | src/H5O.c | 7 | ||||
-rw-r--r-- | src/H5VL.c | 180 | ||||
-rw-r--r-- | src/H5VLnative.c | 39 | ||||
-rw-r--r-- | src/H5VLprivate.h | 10 | ||||
-rw-r--r-- | src/H5VLpublic.h | 7 |
8 files changed, 248 insertions, 145 deletions
diff --git a/src/H5Eterm.h b/src/H5Eterm.h index 921b3b6..1860c19 100644 --- a/src/H5Eterm.h +++ b/src/H5Eterm.h @@ -27,6 +27,7 @@ H5E_FILE_g= H5E_SOHM_g= H5E_SYM_g= H5E_VFL_g= +H5E_VOL_g= H5E_INTERNAL_g= H5E_BTREE_g= H5E_REFERENCE_g= @@ -117,7 +117,7 @@ H5F_init_interface(void) /* * Initialize the atom group for the file IDs. */ - if(H5I_register_type(H5I_FILE, (size_t)H5I_FILEID_HASHSIZE, 0, (H5I_free_t)H5VL_close)<H5I_FILE) + if(H5I_register_type(H5I_FILE, (size_t)H5I_FILEID_HASHSIZE, 0, (H5I_free_t)H5F_close)<H5I_FILE) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to initialize interface") done: @@ -1398,7 +1398,6 @@ done: hid_t H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) { - H5F_t *new_file = NULL; /*file struct for new file */ hid_t ret_value; /*return value */ FUNC_ENTER_API(H5Fcreate, FAIL) @@ -1442,27 +1441,10 @@ H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* * Create a new file or truncate an existing file. */ - if(NULL == (new_file = H5VL_create(filename, flags, fcpl_id, fapl_id))) + if((ret_value = H5VL_create(filename, flags, fcpl_id, fapl_id)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create file") - /* - if(NULL == (new_file = H5F_open(filename, flags, fcpl_id, fapl_id, H5AC_dxpl_id))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create file") - */ - /* Get an atom for the file */ - if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file") - - /* Keep this ID in file object structure */ - new_file->file_id = ret_value; done: - if(ret_value < 0 && new_file) - if(H5VL_close(new_file) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file") - /* - if(H5F_close(new_file) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file") - */ FUNC_LEAVE_API(ret_value) } /* end H5Fcreate() */ @@ -1510,7 +1492,6 @@ done: hid_t H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) { - H5F_t *new_file = NULL; /*file struct for new file */ hid_t ret_value; /*return value */ FUNC_ENTER_API(H5Fopen, FAIL) @@ -1530,24 +1511,21 @@ H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list") /* Open the file */ - if(NULL == (new_file = H5VL_open(filename, flags, fapl_id))) + if((ret_value = H5VL_open(filename, flags, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))<0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to open file") - /* Open the file +#if 0 + /* Open the file */ if(NULL == (new_file = H5F_open(filename, flags, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to open file") - */ /* Get an atom for the file */ if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle") - /* Keep this ID in file object structure */ new_file->file_id = ret_value; +#endif done: - if(ret_value < 0 && new_file && H5F_try_close(new_file) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file") - FUNC_LEAVE_API(ret_value) } /* end H5Fopen() */ @@ -1919,10 +1897,10 @@ H5F_try_close(H5F_t *f) /* Check if this is a child file in a mounting hierarchy & proceed up the * hierarchy if so. */ - if(f->parent) + if(f->parent) { if(H5F_try_close(f->parent) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close parent file") - + } /* Unmount and close each child before closing the current file. */ if(H5F_close_mounts(f) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't unmount child files") @@ -1975,37 +1953,14 @@ done: herr_t H5Fclose(hid_t file_id) { - H5F_t *f = NULL; - int nref; herr_t ret_value = SUCCEED; FUNC_ENTER_API(H5Fclose, 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") - - /* Flush file if this is the last reference to this id and we have write - * intent, unless it will be flushed by the "shared" file being closed. - * This is only necessary to replicate previous behaviour, and could be - * disabled by an option/property to improve performance. */ - if(NULL == (f = (H5F_t *)H5I_object(file_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - if((f->shared->nrefs > 1) && (H5F_INTENT(f) & H5F_ACC_RDWR)) { - if((nref = H5I_get_ref(file_id, FALSE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID ref count") - if(nref == 1) - if(H5F_flush(f, H5AC_dxpl_id, FALSE) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") - } /* end if */ - - /* - * 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") + /* Close the file */ + if((ret_value = H5VL_close(file_id)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file") done: FUNC_LEAVE_API(ret_value) @@ -2052,6 +2007,11 @@ H5Freopen(hid_t file_id) if(NULL == (new_file = H5F_new(old_file->shared, H5P_FILE_CREATE_DEFAULT, H5P_FILE_ACCESS_DEFAULT, NULL))) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file") + /* assign the vol id to this file and increment the ref count on it */ + new_file->vol_id = old_file->vol_id; + if(H5I_inc_ref(new_file->vol_id, FALSE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINC, FAIL, "unable to increment ref count on VOL") + /* Keep old file's read/write intent in new file */ new_file->intent = old_file->intent; diff --git a/src/H5Fefc.c b/src/H5Fefc.c index 1dc7f70..f8330db 100644 --- a/src/H5Fefc.c +++ b/src/H5Fefc.c @@ -35,7 +35,8 @@ #include "H5Fpkg.h" /* File access */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ - +#include "H5VLprivate.h" /* VOL */ +#include "H5Iprivate.h" /* IDs */ /* Special values for the "tag" field below */ #define H5F_EFC_TAG_DEFAULT -1 @@ -147,6 +148,9 @@ H5F_efc_open(H5F_t *parent, const char *name, unsigned flags, hid_t fcpl_id, H5F_efc_t *efc = NULL; /* External file cache for parent file */ H5F_efc_ent_t *ent = NULL; /* Entry for target file in efc */ hbool_t open_file = FALSE; /* Whether ent->file needs to be closed in case of error */ + H5P_genplist_t *plist ; /* Property list pointer */ + hid_t vol_id = -1; /* VOL ID */ + H5VL_class_t *vol_plugin; /* VOL for file */ H5F_t *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5F_efc_open) @@ -156,6 +160,14 @@ H5F_efc_open(H5F_t *parent, const char *name, unsigned flags, hid_t fcpl_id, HDassert(parent->shared); HDassert(name); + /* get the VOL info from the fapl */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list") + if(H5P_get(plist, H5F_ACS_VOL_ID_NAME, &vol_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get vol plugin ID") + if(NULL == (vol_plugin = (H5VL_class_t *)H5I_object(vol_id))) + HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, NULL, "invalid vol plugin ID in file access property list") + /* Get external file cache */ efc = parent->shared->efc; @@ -163,10 +175,23 @@ H5F_efc_open(H5F_t *parent, const char *name, unsigned flags, hid_t fcpl_id, * support this so clients do not have to make 2 different calls depending * on the state of the efc. */ if(!efc) { +#if 0 if(NULL == (ret_value = H5F_open(name, flags, fcpl_id, fapl_id, - dxpl_id))) + dxpl_id))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open file") - +#endif +#if 1 + /* check if the corresponding VOL open callback exists */ + if(NULL == vol_plugin->file_cls.open) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `file open' method") + /* call the corresponding VOL open callback */ + if(NULL == (ret_value = (vol_plugin->file_cls.open)(name, flags, fcpl_id, fapl_id, dxpl_id))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed") + ret_value->vol_id = vol_id; + /* increment the ref count on the vol ID */ + if(H5I_inc_ref(ret_value->vol_id, FALSE) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINC, NULL, "unable to increment ref count on VOL plugin") +#endif /* Increment the number of open objects to prevent the file from being * closed out from under us - "simulate" having an open file id. Note * that this behaviour replaces the calls to H5F_incr_nopen_objs() and @@ -236,10 +261,23 @@ H5F_efc_open(H5F_t *parent, const char *name, unsigned flags, hid_t fcpl_id, } /* end if */ else { /* Cannot cache file, just open file and return */ +#if 0 if(NULL == (ret_value = H5F_open(name, flags, fcpl_id, fapl_id, - dxpl_id))) + dxpl_id))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open file") - +#endif +#if 1 + /* check if the corresponding VOL open callback exists */ + if(NULL == vol_plugin->file_cls.open) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `file open' method") + /* call the corresponding VOL open callback */ + if(NULL == (ret_value = (vol_plugin->file_cls.open)(name, flags, fcpl_id, fapl_id, dxpl_id))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed") + ret_value->vol_id = vol_id; + /* increment the ref count on the vol ID */ + if(H5I_inc_ref(ret_value->vol_id, FALSE) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINC, NULL, "unable to increment ref count on VOL plugin") +#endif /* Increment the number of open objects to prevent the file from * being closed out from under us - "simulate" having an open * file id */ @@ -256,11 +294,24 @@ H5F_efc_open(H5F_t *parent, const char *name, unsigned flags, hid_t fcpl_id, /* Build new entry */ if(NULL == (ent->name = H5MM_strdup(name))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - +#if 0 /* Open the file */ if(NULL == (ent->file = H5F_open(name, flags, fcpl_id, fapl_id, - dxpl_id))) + dxpl_id))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open file") +#endif +#if 1 + /* check if the corresponding VOL open callback exists */ + if(NULL == vol_plugin->file_cls.open) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `file open' method") + /* call the corresponding VOL open callback */ + if(NULL == (ent->file = (vol_plugin->file_cls.open)(name, flags, fcpl_id, fapl_id, dxpl_id))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed") + ent->file->vol_id = vol_id; + /* increment the ref count on the vol ID */ + if(H5I_inc_ref(ent->file->vol_id, FALSE) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINC, NULL, "unable to increment ref count on VOL plugin") +#endif open_file = TRUE; /* Increment the number of open objects to prevent the file from being @@ -305,6 +356,9 @@ done: if(ent) { if(open_file) { ent->file->nopen_objs--; + /* Decrement ref count on VOL ID */ + if(H5I_dec_ref(ent->file->vol_id) < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTDEC, NULL, "can't close plugin ID") if(H5F_try_close(ent->file) < 0) HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "can't close external file") } /* end if */ @@ -354,6 +408,9 @@ H5F_efc_close(H5F_t *parent, H5F_t *file) * on the state of the efc. */ if(!efc) { file->nopen_objs--; + /* Decrement ref count on VOL ID */ + if(H5I_dec_ref(file->vol_id) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "can't close plugin ID") if(H5F_try_close(file) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close external file") @@ -368,6 +425,9 @@ H5F_efc_close(H5F_t *parent, H5F_t *file) for(ent = efc->LRU_head; ent && ent->file != file; ent = ent->LRU_next); if(!ent) { file->nopen_objs--; + /* Decrement ref count on VOL ID */ + if(H5I_dec_ref(file->vol_id) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "can't close plugin ID") if(H5F_try_close(file) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close external file") } /* end if */ @@ -576,6 +636,9 @@ H5F_efc_remove_ent(H5F_efc_t *efc, H5F_efc_ent_t *ent) * However we must still manipulate the nopen_objs field to prevent the file * from being closed out from under us. */ ent->file->nopen_objs--; + /* Decrement ref count on VOL ID */ + if(H5I_dec_ref(ent->file->vol_id) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "can't close plugin ID") if(H5F_try_close(ent->file) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close external file") ent->file = NULL; @@ -46,7 +46,7 @@ #include "H5MFprivate.h" /* File memory management */ #include "H5Opkg.h" /* Object headers */ #include "H5SMprivate.h" /* Shared object header messages */ - +#include "H5VLprivate.h" /* Virtual Object Layer */ /****************/ /* Local Macros */ @@ -1069,6 +1069,7 @@ H5Oclose(hid_t object_id) case H5I_ATTR: case H5I_REFERENCE: case H5I_VFL: + case H5I_VOL: case H5I_GENPROP_CLS: case H5I_GENPROP_LST: case H5I_ERROR_CLASS: @@ -1454,10 +1455,11 @@ H5O_close(H5O_loc_t *loc) * If the file open object count has reached the number of open mount points * (each of which has a group open in the file) attempt to close the file. */ - if(H5F_NOPEN_OBJS(loc->file) == H5F_NMOUNTS(loc->file)) + if(H5F_NOPEN_OBJS(loc->file) == H5F_NMOUNTS(loc->file)) { /* Attempt to close down the file hierarchy */ if(H5F_try_close(loc->file) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCLOSEFILE, FAIL, "problem attempting file close") + } /* Release location information */ if(H5O_loc_free(loc) < 0) @@ -2472,6 +2474,7 @@ H5O_get_loc(hid_t object_id) case H5I_ATTR: case H5I_REFERENCE: case H5I_VFL: + case H5I_VOL: case H5I_GENPROP_CLS: case H5I_GENPROP_LST: case H5I_ERROR_CLASS: @@ -102,7 +102,7 @@ H5VL_init_interface(void) FUNC_ENTER_NOAPI_NOINIT(H5VL_init_interface) if(H5I_register_type(H5I_VOL, (size_t)H5I_VOL_HASHSIZE, 0, (H5I_free_t)H5VL_free_cls)<H5I_FILE) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize interface") + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize interface") done: FUNC_LEAVE_NOAPI(ret_value) @@ -140,7 +140,7 @@ H5VL_term_interface(void) if((n=H5I_nmembers(H5I_VOL))!=0) { H5I_clear_type(H5I_VOL, FALSE, FALSE); } else { - H5I_dec_type_ref(H5I_VFL); + H5I_dec_type_ref(H5I_VOL); H5_interface_initialize_g = 0; n = 1; /*H5I*/ } @@ -262,7 +262,7 @@ H5VL_register(const void *_cls, size_t size, hbool_t app_ref) HDmemcpy(saved, cls, size); /* Create the new class ID */ - if((ret_value = H5I_register(H5I_VFL, saved, app_ref)) < 0) + if((ret_value = H5I_register(H5I_VOL, saved, app_ref)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register vol plugin ID") done: @@ -300,12 +300,12 @@ H5VLunregister(hid_t vol_id) H5TRACE1("e", "i", vol_id); /* Check arguments */ - if(NULL == H5I_object_verify(vol_id, H5I_VFL)) + if(NULL == H5I_object_verify(vol_id, H5I_VOL)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a vol plugin") /* The H5VL_class_t struct will be freed by this function */ if(H5I_dec_app_ref(vol_id) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "unable to unregister vol plugin") + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to unregister vol plugin") done: FUNC_LEAVE_API(ret_value) @@ -338,7 +338,7 @@ H5VL_get_class(hid_t id) FUNC_ENTER_NOAPI(H5VL_get_class, NULL) - if(H5I_VFL == H5I_get_type(id)) + if(H5I_VOL == H5I_get_type(id)) ret_value = (H5VL_class_t *)H5I_object(id); else { H5P_genplist_t *plist; /* Property list pointer */ @@ -417,7 +417,7 @@ done: herr_t H5VL_fapl_open(H5P_genplist_t *plist, hid_t vol_id, const void *vol_info) { - void *copied_vol_info = NULL; /* Temporary VFL vol info */ + void *copied_vol_info = NULL; /* Temporary VOL vol info */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5VL_fapl_open, FAIL) @@ -544,6 +544,37 @@ done: /*------------------------------------------------------------------------- + * Function: H5VLdec_file_vol_ref + * + * Purpose: Utility function to decrement the VOL ID ref count on the + * file structure. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * February, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_dec_file_vol_ref(H5F_t *f) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5VL_dec_file_vol_ref) + + if(H5I_dec_ref(f->vol_id) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to dec_file_vol_ref vol plugin") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VLdec_file_vol_ref() */ + + + +/*------------------------------------------------------------------------- * Function: H5VL_open * * Purpose: Private version of H5VLopen() @@ -557,42 +588,53 @@ done: * *------------------------------------------------------------------------- */ -H5F_t * -H5VL_open(const char *name, unsigned flags, hid_t fapl_id) +hid_t +H5VL_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id) { H5VL_class_t *vol_plugin; /* VOL for file */ - H5F_t *file = NULL; /* VOL file struct */ + H5F_t *new_file = NULL; /* file struct */ hid_t plugin_id = -1; /* VOL ID */ - H5P_genplist_t *plist; /* Property list pointer */ - H5F_t *ret_value; /* Return value */ + H5P_genplist_t *plist; /* Property list pointer */ + hid_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5VL_open, NULL) + FUNC_ENTER_NOAPI(H5VL_open, FAIL) + /* get the VOL info from the fapl */ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") if(H5P_get(plist, H5F_ACS_VOL_ID_NAME, &plugin_id) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get vol plugin ID") + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get vol plugin ID") if(NULL == (vol_plugin = (H5VL_class_t *)H5I_object(plugin_id))) - HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, NULL, "invalid vol plugin ID in file access property list") + HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid vol plugin ID in file access property list") + /* check if the corresponding VOL open callback exists */ if(NULL == vol_plugin->file_cls.open) - HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `file open' method") - if(NULL == (file = (vol_plugin->file_cls.open)(name, flags, fapl_id))) - HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed") + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `file open' method") + /* call the corresponding VOL open callback */ + if(NULL == (new_file = (vol_plugin->file_cls.open)(name, flags, fcpl_id, fapl_id, dxpl_id))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "open failed") /* * Fill in public fields. We must increment the reference count on the * vol plugin ID to prevent it from being freed while this file is open. */ - file->vol_id = plugin_id; - if(H5I_inc_ref(file->vol_id, FALSE) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTINC, NULL, "unable to increment ref count on VOL plugin") - //file->vol_cls = vol_plugin; + new_file->vol_id = plugin_id; + //new_file->vol_cls = vol_plugin; + if(H5I_inc_ref(new_file->vol_id, FALSE) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINC, FAIL, "unable to increment ref count on VOL plugin") + + /* Get an atom for the file */ + if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle") - /* Set return value */ - ret_value = file; + /* Keep this ID in file object structure */ + new_file->file_id = ret_value; done: + /* MSC try_close should be VL_close */ + if(ret_value < 0 && new_file && H5F_try_close(new_file) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_open() */ @@ -604,49 +646,56 @@ done: * * Return: Success: Pointer to a new file struct * - * Failure: NULL + * Failure: FAIL * * Programmer: Mohamad Chaarawi * January, 2012 * *------------------------------------------------------------------------- */ -H5F_t * +hid_t H5VL_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) { H5VL_class_t *vol_plugin; /* VOL for file */ - H5F_t *file = NULL; /* VOL file struct */ + H5F_t *new_file = NULL; /* file struct */ hid_t plugin_id = -1; /* VOL ID */ - H5P_genplist_t *plist; /* Property list pointer */ - H5F_t *ret_value; /* Return value */ + H5P_genplist_t *plist ; /* Property list pointer */ + hid_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5VL_create, NULL) + FUNC_ENTER_NOAPI(H5VL_create, FAIL) + /* get the VOL info from the fapl */ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") if(H5P_get(plist, H5F_ACS_VOL_ID_NAME, &plugin_id) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get vol plugin ID") + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get vol plugin ID") + //printf ("VOL REF COUNT: %d\n",H5I_get_ref (plugin_id, FALSE)); if(NULL == (vol_plugin = (H5VL_class_t *)H5I_object(plugin_id))) - HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, NULL, "invalid vol plugin ID in file access property list") + HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid vol plugin ID in file access property list") + /* check if the corresponding VOL create callback exists */ if(NULL == vol_plugin->file_cls.create) - HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `file create' method") - if(NULL == (file = (vol_plugin->file_cls.create)(name, flags, fcpl_id, fapl_id))) - HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "create failed") + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `file create' method") + /* call the corresponding VOL create callback */ + if(NULL == (new_file = (vol_plugin->file_cls.create)(name, flags, fcpl_id, fapl_id))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "create failed") - /* - * Fill in public fields. We must increment the reference count on the - * vol plugin ID to prevent it from being freed while this file is open. - */ - file->vol_id = plugin_id; - //file->vol_cls = vol_plugin; - if(H5I_inc_ref(file->vol_id, FALSE) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTINC, NULL, "unable to increment ref count on VOL plugin") + new_file->vol_id = plugin_id; + //new_file->vol_cls = vol_plugin; + if(H5I_inc_ref(new_file->vol_id, FALSE) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINC, FAIL, "unable to increment ref count on VOL plugin") + + /* Get an atom for the file */ + if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file") - /* Set return value */ - ret_value = file; + /* Keep this ID in file object structure */ + new_file->file_id = ret_value; done: + if(ret_value < 0 && new_file) + if(H5VL_close(new_file->file_id) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file") FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_create() */ @@ -658,7 +707,7 @@ done: * * Return: Success: Pointer to a new file struct * - * Failure: NULL + * Failure: FAIL * * Programmer: Mohamad Chaarawi * January, 2012 @@ -666,31 +715,34 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_close(H5F_t *file) +H5VL_close(hid_t file_id) { - H5VL_class_t *vol_plugin; /* VOL for file */ - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value = SUCCEED; + H5VL_class_t *vol_plugin ; /* VOL for file */ + H5F_t *f = NULL; + herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(H5VL_close, FAIL) - /* check args */ - HDassert(file); + /* Check/fix arguments. */ + if(H5I_FILE != H5I_get_type(file_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID") - /* Prepare to close file by clearing all public fields */ - if(NULL == (vol_plugin = (H5VL_class_t *)H5I_object(file->vol_id))) - HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid vol plugin ID in file") + /* get the file struct */ + if(NULL == (f = (H5F_t *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - if(H5I_dec_ref(file->vol_id) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close plugin ID") + /* get VOL plugin info */ + if(NULL == (vol_plugin = (H5VL_class_t *)H5I_object(f->vol_id))) + HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid vol plugin ID in file") - /* - * Dispatch to the driver for actual close. If the driver fails to - * close the file then the file will be in an unusable state. - */ + //printf ("VL_CLOSE VOL REF COUNT: %d\n",H5I_get_ref (f->vol_id, FALSE)); + /* Decrement ref count on VOL ID + if(H5I_dec_ref(f->vol_id) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "can't close plugin ID") + */ if(NULL == vol_plugin->file_cls.close) HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `file close' method") - if((vol_plugin->file_cls.close)(file) < 0) + if((vol_plugin->file_cls.close)(f) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEFILE, FAIL, "close failed") done: diff --git a/src/H5VLnative.c b/src/H5VLnative.c index a14e045..1a4582e 100644 --- a/src/H5VLnative.c +++ b/src/H5VLnative.c @@ -21,6 +21,8 @@ * using HDF5 VFDs. */ +#define H5F_PACKAGE /*suppress error about including H5Fpkg */ + /* Interface initialization */ #define H5_INTERFACE_INIT_FUNC H5VL_native_init_interface @@ -28,8 +30,9 @@ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* File access */ +#include "H5Fpkg.h" /* File pkg */ #include "H5VLprivate.h" /* VOL plugins */ -#include "H5VLnative.h" /* Native VOL plugin */ +#include "H5VLnative.h" /* Native VOL plugin */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ @@ -39,7 +42,8 @@ static hid_t H5VL_NATIVE_g = 0; /* Prototypes */ -static H5F_t *H5VL_native_open(const char *name, unsigned flags, hid_t fapl_id); +static H5F_t *H5VL_native_open(const char *name, unsigned flags, hid_t fcpl_id, + hid_t fapl_id, hid_t dxpl_id); static herr_t H5VL_native_close(H5F_t *f); static H5F_t *H5VL_native_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id); static herr_t H5VL_native_term(void); @@ -231,14 +235,15 @@ done: *------------------------------------------------------------------------- */ static H5F_t * -H5VL_native_open(const char *name, unsigned flags, hid_t fapl_id) +H5VL_native_open(const char *name, unsigned flags, hid_t fcpl_id, + hid_t fapl_id, hid_t dxpl_id) { - H5F_t *ret_value = NULL; + H5F_t *ret_value = NULL; /* file struct */ FUNC_ENTER_NOAPI_NOINIT(H5VL_native_open) /* Open the file */ - if(NULL == (ret_value = H5F_open(name, flags, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) + if(NULL == (ret_value= H5F_open(name, flags, fcpl_id, fapl_id, dxpl_id))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file") done: @@ -289,15 +294,31 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL_native_close(H5F_t *file) +H5VL_native_close(H5F_t *f) { + int nref; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5VL_native_close) - /* Close the file */ - if(H5F_close(file) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEFILE, FAIL, "unable to close file") + /* Flush file if this is the last reference to this id and we have write + * intent, unless it will be flushed by the "shared" file being closed. + * This is only necessary to replicate previous behaviour, and could be + * disabled by an option/property to improve performance. */ + if((f->shared->nrefs > 1) && (H5F_INTENT(f) & H5F_ACC_RDWR)) { + if((nref = H5I_get_ref(f->file_id, FALSE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID ref count") + if(nref == 1) + if(H5F_flush(f, H5AC_dxpl_id, FALSE) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") + } /* end if */ + + /* + * Decrement reference count on atom. When it reaches zero the file will + * be closed. + */ + if(H5I_dec_app_ref(f->file_id) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed") done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5VLprivate.h b/src/H5VLprivate.h index 1063ae7..6d4c37c 100644 --- a/src/H5VLprivate.h +++ b/src/H5VLprivate.h @@ -45,12 +45,14 @@ struct H5F_t; H5_DLL int H5VL_term_interface(void); H5_DLL H5VL_class_t *H5VL_get_class(hid_t id); //H5_DLL hsize_t H5VL_sb_size(H5F_t *file); -H5_DLL hid_t H5VL_register(const void *cls, size_t size, hbool_t app_ref); -H5_DLL H5F_t *H5VL_open(const char *name, unsigned flags, hid_t fapl_id); -H5_DLL H5F_t *H5VL_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id); -H5_DLL herr_t H5VL_close(H5F_t *f); +H5_DLL hid_t H5VL_register(const void *cls, size_t size, hbool_t app_ref); +H5_DLL hid_t H5VL_open(const char *name, unsigned flags, hid_t fcpl_id, + hid_t fapl_id, hid_t dxpl_id); +H5_DLL hid_t H5VL_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id); +H5_DLL herr_t H5VL_close(hid_t file_id); H5_DLL herr_t H5VL_fapl_open(struct H5P_genplist_t *plist, hid_t vol_id, const void *vol_info); H5_DLL herr_t H5VL_fapl_copy(hid_t vol_id, const void *fapl, void **copied_fapl); H5_DLL herr_t H5VL_fapl_close(hid_t vol_id, void *fapl); +H5_DLL herr_t H5VL_dec_file_vol_ref(H5F_t *f); #endif /* !_H5VLprivate_H */ diff --git a/src/H5VLpublic.h b/src/H5VLpublic.h index 62407d9..bf77239 100644 --- a/src/H5VLpublic.h +++ b/src/H5VLpublic.h @@ -37,14 +37,15 @@ typedef struct H5VL_general_class_t { /* H5F routines */ typedef struct H5VL_file_class_t { - H5F_t *(*open) (const char *name, unsigned flags, hid_t fapl_id); + H5F_t *(*open) (const char *name, unsigned flags, hid_t fcpl_id, + hid_t fapl_id, hid_t dxpl_id); herr_t (*close) (H5F_t *file); - H5F_t *(*create) (const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id); + H5F_t *(*create) (const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id); herr_t (*flush) (hid_t object_id, H5F_scope_t scope); htri_t (*is_hdf5) (const char *name); herr_t (*mount) (hid_t loc_id, const char *name, hid_t child_id, hid_t plist_id); herr_t (*unmount) (hid_t loc_id, const char *name); - hid_t (*reopen) (hid_t file_id); + hid_t (*reopen) (hid_t file_id); } H5VL_file_class_t; /* H5D routines */ |