diff options
-rw-r--r-- | src/H5Fint.c | 11 | ||||
-rw-r--r-- | src/H5Oflush.c | 59 | ||||
-rw-r--r-- | src/H5Oprivate.h | 11 |
3 files changed, 65 insertions, 16 deletions
diff --git a/src/H5Fint.c b/src/H5Fint.c index 440e85c..8ec36d2 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -3598,7 +3598,16 @@ H5F__start_swmr_write(H5F_t *f) /* Refresh (reopen) the objects (groups & datasets) in the file */ for(u = 0; u < grp_dset_count; u++) - if(H5O_refresh_metadata_reopen(obj_ids[u], &obj_glocs[u], vol_connector, TRUE) < 0) + /* XXX This routine probably should prepare legitimate + * H5O_refresh_state_t's, above, and pass those instead of NULL, so + * that non-persistent object properties---e.g., dataset access + * properties---are copied from old objects to reopened objects. + * + * Passing NULL here shouldn't introduce any bugs in Legacy SWMR, + * however, and it lets VFD SWMR development proceed, so I'm not + * going to sweat it, now. + */ + if(H5O_refresh_metadata_reopen(obj_ids[u], &obj_glocs[u], NULL, vol_connector, TRUE) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't refresh-close object") /* Unlock the file */ diff --git a/src/H5Oflush.c b/src/H5Oflush.c index 898184b..eeed75e 100644 --- a/src/H5Oflush.c +++ b/src/H5Oflush.c @@ -28,6 +28,7 @@ #include "H5Omodule.h" /* This source code file is part of the H5O module */ #define H5T_FRIEND /* Suppress error about including H5Tpkg */ +#define H5D_FRIEND /* Suppress error about including H5Dpkg */ /***********/ /* Headers */ @@ -40,6 +41,7 @@ #include "H5Fprivate.h" /* Files */ #include "H5Gprivate.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ +#include "H5Dpkg.h" /* Datasets */ #include "H5Opkg.h" /* Objects */ #include "H5Tpkg.h" /* Datatypes */ @@ -287,7 +289,6 @@ done: herr_t H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc) { - H5VL_object_t *vol_obj = NULL; /* VOL object associated with the ID */ hbool_t objs_incr = FALSE; /* Whether the object count in the file was incremented */ herr_t ret_value = SUCCEED; /* Return value */ @@ -298,7 +299,9 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc) H5G_loc_t obj_loc; H5O_loc_t obj_oloc; H5G_name_t obj_path; - H5O_shared_t cached_H5O_shared; + H5O_refresh_state_t state; + H5D_t *ds; + const H5VL_object_t *vol_obj; H5VL_t *connector = NULL; /* Create empty object location */ @@ -312,11 +315,6 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc) H5F_incr_nopen_objs(oloc.file); objs_incr = TRUE; - /* Save important datatype state */ - if(H5I_get_type(oid) == H5I_DATATYPE) - if(H5T_save_refresh_state(oid, &cached_H5O_shared) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to save datatype state") - /* Get the VOL object from the ID and cache a pointer to the connector. * The vol_obj will disappear when the underlying object is closed, so * we can't use that directly. @@ -325,6 +323,24 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") connector = vol_obj->connector; + /* Save important datatype state */ + switch (H5I_get_type(oid)) { + case H5I_DATATYPE: + if (H5T_save_refresh_state(oid, &state.shared_ohdr_info) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, + "unable to save datatype state"); + break; + case H5I_DATASET: + ds = (H5D_t *)vol_obj->data; + state.dapl_id = ds->shared->dapl_id; + if (H5I_inc_ref(state.dapl_id, false) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "could not increase refcnt"); + break; + default: + break; + } + /* Bump the number of references on the VOL connector. * If you don't do this, VDS refreshes can accidentally close the connector. */ @@ -335,16 +351,27 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") /* Re-open the object, re-fetching its metadata */ - if((H5O_refresh_metadata_reopen(oid, &obj_loc, connector, FALSE)) < 0) + if (H5O_refresh_metadata_reopen(oid, &obj_loc, &state, connector, + FALSE) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") /* Restore the number of references on the VOL connector */ connector->nrefs--; /* Restore important datatype state */ - if(H5I_get_type(oid) == H5I_DATATYPE) - if(H5T_restore_refresh_state(oid, &cached_H5O_shared) < 0) + switch (H5I_get_type(oid)) { + case H5I_DATATYPE: + if(H5T_restore_refresh_state(oid, &state.shared_ohdr_info) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to restore datatype state") + break; + case H5I_DATASET: + if (H5I_dec_ref(state.dapl_id) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "could not decrease refcnt"); + break; + default: + break; + } } /* end if */ @@ -442,7 +469,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, H5VL_t *vol_connector, hbool_t start_swmr) +H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, + const H5O_refresh_state_t *state, H5VL_t *vol_connector, hbool_t start_swmr) { void *object = NULL; /* Object for this operation */ H5I_type_t type; /* Type of object for the ID */ @@ -471,9 +499,12 @@ H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, H5VL_t *vol_connector break; case H5I_DATASET: - /* Re-open the dataset */ - if(NULL == (object = H5D_open(obj_loc, H5P_DATASET_ACCESS_DEFAULT))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open dataset") + object = H5D_open(obj_loc, + (state == NULL) ? H5P_DATASET_ACCESS_DEFAULT : state->dapl_id); + if(NULL == object) { + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, + "unable to open dataset"); + } if(!start_swmr) /* No need to handle multiple opens when H5Fstart_swmr_write() */ if(H5D_mult_refresh_reopen((H5D_t *)object) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to finish refresh for dataset") diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 0be6d89..9a1c1ed 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -275,6 +275,14 @@ typedef struct H5O_shared_t { } u; } H5O_shared_t; +/* Storage for non-persistent (i.e., not stored in the HDF5 file) information + * that has to be preserved when an object is closed & reopened by + * H5O_refresh_metadata(). + */ +typedef union _H5O_refresh_state { + hid_t dapl_id; // dataset refresh: access plist + H5O_shared_t shared_ohdr_info; // datatype refresh +} H5O_refresh_state_t; /* * Link Info Message. @@ -972,7 +980,8 @@ H5_DLL herr_t H5O_msg_get_flags(const H5O_loc_t *loc, unsigned type_id, uint8_t H5_DLL herr_t H5O_flush(H5O_loc_t *oloc, hid_t obj_id); H5_DLL herr_t H5O_flush_common(H5O_loc_t *oloc, hid_t obj_id); H5_DLL herr_t H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc); -H5_DLL herr_t H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, H5VL_t *vol_driver, hbool_t start_swmr); +H5_DLL herr_t H5O_refresh_metadata_reopen(hid_t, H5G_loc_t *, + const H5O_refresh_state_t *, H5VL_t *, hbool_t); /* Cache corking functions */ H5_DLL herr_t H5O_disable_mdc_flushes(H5O_loc_t *oloc); |