diff options
Diffstat (limited to 'src/H5VLint.c')
-rw-r--r-- | src/H5VLint.c | 396 |
1 files changed, 359 insertions, 37 deletions
diff --git a/src/H5VLint.c b/src/H5VLint.c index bdb2908..9d9dc94 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -51,7 +51,7 @@ /* Object wrapping context info */ typedef struct H5VL_wrap_ctx_t { unsigned rc; /* Ref. count for the # of times the context was set / reset */ - const H5VL_t *connector; /* VOL connector for "outermost" class to start wrap */ + H5VL_t *connector; /* VOL connector for "outermost" class to start wrap */ void *obj_wrap_ctx; /* "wrap context" for outermost connector */ } H5VL_wrap_ctx_t; @@ -65,10 +65,13 @@ typedef struct H5VL_wrap_ctx_t { /* Local Prototypes */ /********************/ static herr_t H5VL__free_cls(H5VL_class_t *cls); -static void *H5VL__wrap_obj(void *obj); +static void *H5VL__wrap_obj(void *obj, H5I_type_t obj_type); static H5VL_object_t *H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t wrap_obj); +static int64_t H5VL__conn_inc_rc(H5VL_t *connector); +static int64_t H5VL__conn_dec_rc(H5VL_t *connector); static void *H5VL__object(hid_t id, H5I_type_t obj_type); +static herr_t H5VL__free_vol_wrapper(H5VL_wrap_ctx_t *vol_wrap_ctx); /*********************/ @@ -248,7 +251,7 @@ done: *------------------------------------------------------------------------- */ static void * -H5VL__wrap_obj(void *obj) +H5VL__wrap_obj(void *obj, H5I_type_t obj_type) { H5VL_wrap_ctx_t *vol_wrap_ctx = NULL; /* Object wrapping context */ void *ret_value = NULL; /* Return value */ @@ -265,7 +268,7 @@ H5VL__wrap_obj(void *obj) /* If there is a VOL object wrapping context, wrap the object */ if(vol_wrap_ctx) { /* Wrap object, using the VOL callback */ - if(NULL == (ret_value = H5VL_wrap_object(vol_wrap_ctx->connector->cls, vol_wrap_ctx->obj_wrap_ctx, obj))) + if(NULL == (ret_value = H5VL_wrap_object(vol_wrap_ctx->connector->cls, vol_wrap_ctx->obj_wrap_ctx, obj, obj_type))) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "can't wrap object") } /* end if */ else @@ -310,14 +313,14 @@ H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, NULL, "can't allocate memory for VOL object") new_vol_obj->connector = vol_connector; if(wrap_obj) { - if(NULL == (new_vol_obj->data = H5VL__wrap_obj(object))) + if(NULL == (new_vol_obj->data = H5VL__wrap_obj(object, type))) HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, NULL, "can't wrap library object") } /* end if */ else new_vol_obj->data = object; /* Bump the reference count on the VOL connector */ - vol_connector->nrefs++; + H5VL__conn_inc_rc(vol_connector); /* If this is a datatype, we have to hide the VOL object under the H5T_t pointer */ if(H5I_DATATYPE == type) { @@ -550,6 +553,76 @@ done: /*------------------------------------------------------------------------- + * Function: H5VL__conn_inc_rc + * + * Purpose: Wrapper to increment the ref. count on a connector. + * + * Return: Current ref. count (can't fail) + * + * Programmer: Quincey Koziol + * February 23, 2019 + * + *------------------------------------------------------------------------- + */ +static int64_t +H5VL__conn_inc_rc(H5VL_t *connector) +{ + FUNC_ENTER_STATIC_NOERR + + /* Check arguments */ + HDassert(connector); + + /* Increment refcount for connector */ + connector->nrefs++; + + FUNC_LEAVE_NOAPI(connector->nrefs) +} /* end H5VL__conn_inc_rc() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__conn_dec_rc + * + * Purpose: Wrapper to decrement the ref. count on a connector. + * + * Return: Current ref. count (>=0) on success, <0 on failure + * + * Programmer: Quincey Koziol + * February 23, 2019 + * + *------------------------------------------------------------------------- + */ +static int64_t +H5VL__conn_dec_rc(H5VL_t *connector) +{ + int64_t ret_value = -1; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ + HDassert(connector); + + /* Decrement refcount for connector */ + connector->nrefs--; + + /* Check for last reference */ + if(0 == connector->nrefs) { + if(H5I_dec_ref(connector->id) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement ref count on VOL connector") + H5FL_FREE(H5VL_t, connector); + + /* Set return value */ + ret_value = 0; + } /* end if */ + else + /* Set return value */ + ret_value = connector->nrefs; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__conn_dec_rc() */ + + +/*------------------------------------------------------------------------- * Function: H5VL_free_object * * Purpose: Wrapper to unregister an object ID with a VOL aux struct @@ -562,20 +635,16 @@ done: herr_t H5VL_free_object(H5VL_object_t *vol_obj) { - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(SUCCEED) + FUNC_ENTER_NOAPI(FAIL) /* Check arguments */ HDassert(vol_obj); - vol_obj->connector->nrefs --; - - if(0 == vol_obj->connector->nrefs) { - if(H5I_dec_ref(vol_obj->connector->id) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement ref count on VOL connector") - vol_obj->connector = H5FL_FREE(H5VL_t, vol_obj->connector); - } /* end if */ + /* Decrement refcount on connector */ + if(H5VL__conn_dec_rc(vol_obj->connector) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement ref count on VOL connector") vol_obj = H5FL_FREE(H5VL_object_t, vol_obj); @@ -612,7 +681,7 @@ H5VL_register_connector(const void *_cls, hbool_t app_ref, hid_t vipl_id) /* Copy the class structure so the caller can reuse or free it */ if (NULL == (saved = H5FL_CALLOC(H5VL_class_t))) HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, H5I_INVALID_HID, "memory allocation failed for VOL connector class struct") - HDmemcpy(saved, cls, sizeof(H5VL_class_t)); + H5MM_memcpy(saved, cls, sizeof(H5VL_class_t)); if(NULL == (saved->name = H5MM_strdup(cls->name))) HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, H5I_INVALID_HID, "memory allocation failed for VOL connector name") @@ -740,8 +809,8 @@ H5VL_object_data(const H5VL_object_t *vol_obj) FUNC_ENTER_NOAPI_NOINIT_NOERR /* Check for 'get_object' callback in connector */ - if(vol_obj->connector->cls->get_object) - ret_value = (vol_obj->connector->cls->get_object)(vol_obj->data); + if(vol_obj->connector->cls->wrap_cls.get_object) + ret_value = (vol_obj->connector->cls->wrap_cls.get_object)(vol_obj->data); else ret_value = vol_obj->data; @@ -933,15 +1002,15 @@ H5VL_cmp_connector_cls(int *cmp_value, const H5VL_class_t *cls1, const H5VL_clas HDassert(cls1->version == cls2->version); /* Compare connector info */ - if(cls1->info_size < cls2->info_size) { + if(cls1->info_cls.size < cls2->info_cls.size) { *cmp_value = -1; HGOTO_DONE(SUCCEED) } /* end if */ - if(cls1->info_size > cls2->info_size) { + if(cls1->info_cls.size > cls2->info_cls.size) { *cmp_value = 1; HGOTO_DONE(SUCCEED) } /* end if */ - HDassert(cls1->info_size == cls2->info_size); + HDassert(cls1->info_cls.size == cls2->info_cls.size); /* Set comparison value to 'equal' */ *cmp_value = 0; @@ -952,6 +1021,189 @@ done: /*------------------------------------------------------------------------- + * Function: H5VL_retrieve_lib_state + * + * Purpose: Retrieve the state of the library. + * + * Note: Currently just retrieves the API context state, but could be + * expanded in the future. + * + * Return: Success: Non-negative, *state set + * Failure: Negative, *state unset + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_retrieve_lib_state(void **state) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(state); + + /* Retrieve the API context state */ + if(H5CX_retrieve_state((H5CX_state_t **)state) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get API context state") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_retrieve_lib_state() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_restore_lib_state + * + * Purpose: Restore the state of the library. + * + * Note: Currently just restores the API context state, but could be + * expanded in the future. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Thursday, January 10, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_restore_lib_state(const void *state) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(state); + + /* Push a new API context on the stack */ + if(H5CX_push() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't push API context") + + /* Restore the API context state */ + if(H5CX_restore_state((const H5CX_state_t *)state) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set API context state") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_restore_lib_state() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_reset_lib_state + * + * Purpose: Reset the state of the library, undoing affects of + * H5VL_restore_lib_state. + * + * Note: Currently just resets the API context state, but could be + * expanded in the future. + * + * Note: This routine must be called as a "pair" with + * H5VL_restore_lib_state. It can be called before / after / + * independently of H5VL_free_lib_state. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Saturday, February 23, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_reset_lib_state(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Pop the API context off the stack */ + if(H5CX_pop() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't pop API context") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_reset_lib_state() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_free_lib_state + * + * Purpose: Free a library state. + * + * Note: This routine must be called as a "pair" with + * H5VL_retrieve_lib_state. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Thursday, January 10, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_free_lib_state(void *state) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(state); + + /* Free the API context state */ + if(H5CX_free_state((H5CX_state_t *)state) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "can't free API context state") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_free_lib_state() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__free_vol_wrapper + * + * Purpose: Free object wrapping context for VOL connector + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Wednesday, January 9, 2019 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__free_vol_wrapper(H5VL_wrap_ctx_t *vol_wrap_ctx) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(vol_wrap_ctx); + HDassert(0 == vol_wrap_ctx->rc); + HDassert(vol_wrap_ctx->connector); + HDassert(vol_wrap_ctx->connector->cls); + + /* If there is a VOL connector object wrapping context, release it */ + if(vol_wrap_ctx->obj_wrap_ctx) + /* Release the VOL connector's object wrapping context */ + if((*vol_wrap_ctx->connector->cls->wrap_cls.free_wrap_ctx)(vol_wrap_ctx->obj_wrap_ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to release connector's object wrapping context") + + /* Decrement refcount on connector */ + if(H5VL__conn_dec_rc(vol_wrap_ctx->connector) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement ref count on VOL connector") + + /* Release object wrapping context */ + H5FL_FREE(H5VL_wrap_ctx_t, vol_wrap_ctx); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__free_vol_wrapper() */ + + +/*------------------------------------------------------------------------- * Function: H5VL_set_vol_wrapper * * Purpose: Set up object wrapping context for current VOL connector @@ -961,7 +1213,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_set_vol_wrapper(void *obj, const H5VL_t *connector) +H5VL_set_vol_wrapper(void *obj, H5VL_t *connector) { H5VL_wrap_ctx_t *vol_wrap_ctx = NULL; /* Object wrapping context */ void *obj_wrap_ctx = NULL; /* VOL connector's wrapping context */ @@ -980,12 +1232,12 @@ H5VL_set_vol_wrapper(void *obj, const H5VL_t *connector) /* Check for existing wrapping context */ if(NULL == vol_wrap_ctx) { /* Check if the connector can create a wrap context */ - if(connector->cls->get_wrap_ctx) { + if(connector->cls->wrap_cls.get_wrap_ctx) { /* Sanity check */ - HDassert(connector->cls->free_wrap_ctx); + HDassert(connector->cls->wrap_cls.free_wrap_ctx); /* Get the wrap context from the connector */ - if((connector->cls->get_wrap_ctx)(obj, &obj_wrap_ctx) < 0) + if((connector->cls->wrap_cls.get_wrap_ctx)(obj, &obj_wrap_ctx) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't retrieve VOL connector's object wrap context") } /* end if */ @@ -993,8 +1245,11 @@ H5VL_set_vol_wrapper(void *obj, const H5VL_t *connector) if(NULL == (vol_wrap_ctx = H5FL_MALLOC(H5VL_wrap_ctx_t))) HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "can't allocate VOL wrap context") + /* Increment the outstanding objects that are using the connector */ + H5VL__conn_inc_rc(connector); + /* Set up VOL object wrapper context */ - vol_wrap_ctx->rc = 1;; + vol_wrap_ctx->rc = 1; vol_wrap_ctx->connector = connector; vol_wrap_ctx->obj_wrap_ctx = obj_wrap_ctx; } /* end if */ @@ -1016,6 +1271,80 @@ done: /*------------------------------------------------------------------------- + * Function: H5VL_inc_vol_wrapper + * + * Purpose: Increment refcount on object wrapping context + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Wednesday, January 9, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_inc_vol_wrapper(void *_vol_wrap_ctx) +{ + H5VL_wrap_ctx_t *vol_wrap_ctx = (H5VL_wrap_ctx_t *)_vol_wrap_ctx; /* VOL object wrapping context */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check for valid, active VOL object wrap context */ + if(NULL == vol_wrap_ctx) + HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "no VOL object wrap context?") + if(0 == vol_wrap_ctx->rc) + HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "bad VOL object wrap context refcount?") + + /* Increment ref count on wrapping context */ + vol_wrap_ctx->rc++; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_inc_vol_wrapper() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_dec_vol_wrapper + * + * Purpose: Decrement refcount on object wrapping context, releasing it + * if the refcount drops to zero. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Wednesday, January 9, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_dec_vol_wrapper(void *_vol_wrap_ctx) +{ + H5VL_wrap_ctx_t *vol_wrap_ctx = (H5VL_wrap_ctx_t *)_vol_wrap_ctx; /* VOL object wrapping context */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check for valid, active VOL object wrap context */ + if(NULL == vol_wrap_ctx) + HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "no VOL object wrap context?") + if(0 == vol_wrap_ctx->rc) + HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "bad VOL object wrap context refcount?") + + /* Decrement ref count on wrapping context */ + vol_wrap_ctx->rc--; + + /* Release context if the ref count drops to zero */ + if(0 == vol_wrap_ctx->rc) + if(H5VL__free_vol_wrapper(vol_wrap_ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to release VOL object wrapping context") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_dec_vol_wrapper() */ + + +/*------------------------------------------------------------------------- * Function: H5VL_reset_vol_wrapper * * Purpose: Reset object wrapping context for current VOL connector @@ -1045,25 +1374,18 @@ H5VL_reset_vol_wrapper(void) /* Release context if the ref count drops to zero */ if(0 == vol_wrap_ctx->rc) { - /* If there is a VOL connector object wrapping context, release it */ - if(vol_wrap_ctx->obj_wrap_ctx) { - /* Release the VOL connector's object wrapping context */ - if((*vol_wrap_ctx->connector->cls->free_wrap_ctx)(vol_wrap_ctx->obj_wrap_ctx) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to release connector's object wrapping context") - } /* end if */ - /* Release object wrapping context */ - H5FL_FREE(H5VL_wrap_ctx_t, vol_wrap_ctx); + if(H5VL__free_vol_wrapper(vol_wrap_ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to release VOL object wrapping context") /* Reset the wrapper context */ if(H5CX_set_vol_wrap_ctx(NULL) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL object wrap context") } /* end if */ - else { + else /* Save the updated wrapper context */ if(H5CX_set_vol_wrap_ctx(vol_wrap_ctx) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL object wrap context") - } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -1099,7 +1421,7 @@ H5VL_wrap_register(H5I_type_t type, void *obj, hbool_t app_ref) HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, H5I_INVALID_HID, "can't wrap an uncommitted datatype") /* Wrap the object with VOL connector info */ - if(NULL == (new_obj = H5VL__wrap_obj(obj))) + if(NULL == (new_obj = H5VL__wrap_obj(obj, type))) HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, H5I_INVALID_HID, "can't wrap library object") /* Retrieve the VOL object wrapping context */ |