summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@koziol.gov>2019-04-21 19:45:54 (GMT)
committerQuincey Koziol <koziol@koziol.gov>2019-04-21 19:45:54 (GMT)
commit62198c2436ac3787afb49fa990d1ba8204264dba (patch)
treece6f47307d75ffa61f49de88fdf72a014adfd1fb /src
parent500f6cccbd4bfe01b67f2bd02f74df58edef045f (diff)
downloadhdf5-62198c2436ac3787afb49fa990d1ba8204264dba.zip
hdf5-62198c2436ac3787afb49fa990d1ba8204264dba.tar.gz
hdf5-62198c2436ac3787afb49fa990d1ba8204264dba.tar.bz2
Add an 'unwrap' VOL callback, so that connectors can unwrap an underlying
object without closing it. (Especially needed for pass-through connectors)
Diffstat (limited to 'src')
-rw-r--r--src/H5Dvirtual.c2
-rw-r--r--src/H5I.c2
-rw-r--r--src/H5VLcallback.c165
-rw-r--r--src/H5VLint.c28
-rw-r--r--src/H5VLnative.c1
-rw-r--r--src/H5VLpassthru.c67
-rw-r--r--src/H5VLprivate.h6
-rw-r--r--src/H5VLpublic.h2
8 files changed, 213 insertions, 60 deletions
diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c
index d38df1b..e3e0aa5 100644
--- a/src/H5Dvirtual.c
+++ b/src/H5Dvirtual.c
@@ -3035,7 +3035,7 @@ H5D__virtual_refresh_source_dset(H5D_t **dset)
/* Discard the identifier & replace the dataset */
if(NULL == (vol_obj = (H5VL_object_t *)H5I_remove(temp_id)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTREMOVE, FAIL, "can't unregister source dataset ID")
- if(NULL == (*dset = (H5D_t *)H5VL_object_data(vol_obj)))
+ if(NULL == (*dset = (H5D_t *)H5VL_object_unwrap(vol_obj)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't retrieve library object from VOL object")
vol_obj->data = NULL;
diff --git a/src/H5I.c b/src/H5I.c
index 345c010..2edea9b 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -1134,7 +1134,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-void *
+static void *
H5I__remove_verify(hid_t id, H5I_type_t id_type)
{
void * ret_value = NULL; /*return value */
diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c
index 03828fa..b785747 100644
--- a/src/H5VLcallback.c
+++ b/src/H5VLcallback.c
@@ -740,84 +740,89 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5VL_free_wrap_ctx
+ * Function: H5VL_wrap_object
*
- * Purpose: Free object wrapping context for a connector
+ * Purpose: Wrap an object with connector
*
- * Return: Success: Non-negative
- * Failure: Negative
+ * Return: Success: Non-NULL
+ * Failure: NULL
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5VL_free_wrap_ctx(const H5VL_class_t *connector, void *wrap_ctx)
+void *
+H5VL_wrap_object(const H5VL_class_t *connector, void *wrap_ctx, void *obj,
+ H5I_type_t obj_type)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ void *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_NOAPI(NULL)
/* Sanity checks */
HDassert(connector);
+ HDassert(obj);
- /* Only free wrap context, if it's non-NULL */
+ /* Only wrap object if there's a wrap context */
if(wrap_ctx) {
- /* Free the connector's object wrapping context */
- if((connector->wrap_cls.free_wrap_ctx)(wrap_ctx) < 0)
- HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "connector wrap context free request failed")
+ /* Ask the connector to wrap the object */
+ if(NULL == (ret_value = (connector->wrap_cls.wrap_object)(obj, obj_type, wrap_ctx)))
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "can't wrap object")
} /* end if */
+ else
+ ret_value = obj;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5VL_free_wrap_ctx() */
+} /* end H5VL_wrap_object() */
/*---------------------------------------------------------------------------
- * Function: H5VLfree_wrap_ctx
+ * Function: H5VLwrap_object
*
- * Purpose: Release a VOL connector's object wrapping context
+ * Purpose: Asks a connector to wrap an underlying object.
*
- * Return: Success: Non-negative
- * Failure: Negative
+ * Return: Success: Non-NULL
+ * Failure: NULL
*
*---------------------------------------------------------------------------
*/
-herr_t
-H5VLfree_wrap_ctx(void *wrap_ctx, hid_t connector_id)
+void *
+H5VLwrap_object(void *obj, H5I_type_t obj_type, hid_t connector_id, void *wrap_ctx)
{
- H5VL_class_t *cls; /* VOL connector's class struct */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5VL_class_t *cls; /* VOL connector's class struct */
+ void *ret_value = NULL; /* Return value */
FUNC_ENTER_API_NOINIT
- H5TRACE2("e", "*xi", wrap_ctx, connector_id);
+ H5TRACE4("*x", "*xIti*x", obj, obj_type, connector_id, wrap_ctx);
/* Check args and get class pointer */
+ if(NULL == obj)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object")
if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a VOL connector ID")
- /* Release the VOL connector's object wrapper */
- if(H5VL_free_wrap_ctx(cls, wrap_ctx) < 0)
- HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to release VOL connector object wrap context")
+ /* Wrap the object */
+ if(NULL == (ret_value = H5VL_wrap_object(cls, wrap_ctx, obj, obj_type)))
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "unable to wrap object")
done:
FUNC_LEAVE_API_NOINIT(ret_value)
-} /* H5VLfree_wrap_ctx() */
+} /* H5VLwrap_object */
/*-------------------------------------------------------------------------
- * Function: H5VL_wrap_object
+ * Function: H5VL_unwrap_object
*
- * Purpose: Wrap an object with connector
+ * Purpose: Unwrap an object from connector
*
- * Return: Success: Non-negative
- * Failure: Negative
+ * Return: Success: Non-NULL
+ * Failure: NULL
*
*-------------------------------------------------------------------------
*/
void *
-H5VL_wrap_object(const H5VL_class_t *connector, void *wrap_ctx, void *obj,
- H5I_type_t obj_type)
+H5VL_unwrap_object(const H5VL_class_t *connector, void *obj)
{
- void *ret_value = SUCCEED; /* Return value */
+ void *ret_value; /* Return value */
FUNC_ENTER_NOAPI(NULL)
@@ -825,24 +830,24 @@ H5VL_wrap_object(const H5VL_class_t *connector, void *wrap_ctx, void *obj,
HDassert(connector);
HDassert(obj);
- /* Only wrap object if there's a wrap context */
- if(wrap_ctx) {
- /* Ask the connector to wrap the object */
- if(NULL == (ret_value = (connector->wrap_cls.wrap_object)(obj, obj_type, wrap_ctx)))
- HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "can't wrap object")
+ /* Only unwrap object if there's an unwrap callback */
+ if(connector->wrap_cls.wrap_object) {
+ /* Ask the connector to unwrap the object */
+ if(NULL == (ret_value = (connector->wrap_cls.unwrap_object)(obj)))
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "can't unwrap object")
} /* end if */
else
ret_value = obj;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5VL_wrap_object() */
+} /* end H5VL_unwrap_object() */
/*---------------------------------------------------------------------------
- * Function: H5VLwrap_object
+ * Function: H5VLunwrap_object
*
- * Purpose: Asks a connector to wrap an underlying object.
+ * Purpose: Unwrap an object from connector
*
* Return: Success: Non-NULL
* Failure: NULL
@@ -850,13 +855,13 @@ done:
*---------------------------------------------------------------------------
*/
void *
-H5VLwrap_object(void *obj, H5I_type_t obj_type, hid_t connector_id, void *wrap_ctx)
+H5VLunwrap_object(void *obj, hid_t connector_id)
{
H5VL_class_t *cls; /* VOL connector's class struct */
void *ret_value = NULL; /* Return value */
FUNC_ENTER_API_NOINIT
- H5TRACE4("*x", "*xIti*x", obj, obj_type, connector_id, wrap_ctx);
+ H5TRACE2("*x", "*xi", obj, connector_id);
/* Check args and get class pointer */
if(NULL == obj)
@@ -864,13 +869,77 @@ H5VLwrap_object(void *obj, H5I_type_t obj_type, hid_t connector_id, void *wrap_c
if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a VOL connector ID")
- /* Wrap the object */
- if(NULL == (ret_value = H5VL_wrap_object(cls, wrap_ctx, obj, obj_type)))
- HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "unable to wrap object")
+ /* Unwrap the object */
+ if(NULL == (ret_value = H5VL_unwrap_object(cls, obj)))
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "unable to unwrap object")
done:
FUNC_LEAVE_API_NOINIT(ret_value)
-} /* H5VLwrap_object */
+} /* H5VLunwrap_object */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_free_wrap_ctx
+ *
+ * Purpose: Free object wrapping context for a connector
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_free_wrap_ctx(const H5VL_class_t *connector, void *wrap_ctx)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity checks */
+ HDassert(connector);
+
+ /* Only free wrap context, if it's non-NULL */
+ if(wrap_ctx) {
+ /* Free the connector's object wrapping context */
+ if((connector->wrap_cls.free_wrap_ctx)(wrap_ctx) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "connector wrap context free request failed")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_free_wrap_ctx() */
+
+
+/*---------------------------------------------------------------------------
+ * Function: H5VLfree_wrap_ctx
+ *
+ * Purpose: Release a VOL connector's object wrapping context
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *---------------------------------------------------------------------------
+ */
+herr_t
+H5VLfree_wrap_ctx(void *wrap_ctx, hid_t connector_id)
+{
+ H5VL_class_t *cls; /* VOL connector's class struct */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API_NOINIT
+ H5TRACE2("e", "*xi", wrap_ctx, connector_id);
+
+ /* Check args and get class pointer */
+ if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID")
+
+ /* Release the VOL connector's object wrapper */
+ if(H5VL_free_wrap_ctx(cls, wrap_ctx) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to release VOL connector object wrap context")
+
+done:
+ FUNC_LEAVE_API_NOINIT(ret_value)
+} /* H5VLfree_wrap_ctx() */
/*-------------------------------------------------------------------------
diff --git a/src/H5VLint.c b/src/H5VLint.c
index fda4443..1b735f5 100644
--- a/src/H5VLint.c
+++ b/src/H5VLint.c
@@ -1358,6 +1358,32 @@ H5VL_object_data(const H5VL_object_t *vol_obj)
/*-------------------------------------------------------------------------
+ * Function: H5VL_object_unwrap
+ *
+ * Purpose: Correctly unwrap the 'data' field for a VOL object (H5VL_object),
+ * even for nested / stacked VOL connectors.
+ *
+ * Return: Success: Object pointer
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5VL_object_unwrap(const H5VL_object_t *vol_obj)
+{
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI(NULL)
+
+ if(NULL == (ret_value = H5VL_unwrap_object(vol_obj->connector->cls, vol_obj->data)))
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "can't unwrap object")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_object_unwrap() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5VL__object
*
* Purpose: Internal function to return the VOL object pointer associated
@@ -1444,7 +1470,7 @@ H5VL_object(hid_t id)
/* Get the underlying object */
if(NULL == (ret_value = H5VL__object(id, H5I_get_type(id))))
- HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, NULL, "can't retrieve object for ID")
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "can't retrieve object for ID")
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5VLnative.c b/src/H5VLnative.c
index f4f3b5f..7848c5d 100644
--- a/src/H5VLnative.c
+++ b/src/H5VLnative.c
@@ -50,6 +50,7 @@ static H5VL_class_t H5VL_native_cls_g = {
NULL, /* get_object */
NULL, /* get_wrap_ctx */
NULL, /* wrap_object */
+ NULL, /* unwrap_object */
NULL /* free_wrap_ctx */
},
{ /* attribute_cls */
diff --git a/src/H5VLpassthru.c b/src/H5VLpassthru.c
index a4c85cc..85a9346 100644
--- a/src/H5VLpassthru.c
+++ b/src/H5VLpassthru.c
@@ -98,9 +98,10 @@ static herr_t H5VL_pass_through_str_to_info(const char *str, void **info);
/* VOL object wrap / retrieval callbacks */
static void *H5VL_pass_through_get_object(const void *obj);
static herr_t H5VL_pass_through_get_wrap_ctx(const void *obj, void **wrap_ctx);
-static herr_t H5VL_pass_through_free_wrap_ctx(void *obj);
static void *H5VL_pass_through_wrap_object(void *obj, H5I_type_t obj_type,
void *wrap_ctx);
+static void *H5VL_pass_through_unwrap_object(void *obj);
+static herr_t H5VL_pass_through_free_wrap_ctx(void *obj);
/* Attribute callbacks */
static void *H5VL_pass_through_attr_create(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id, void **req);
@@ -194,6 +195,7 @@ static const H5VL_class_t H5VL_pass_through_g = {
H5VL_pass_through_get_object, /* get_object */
H5VL_pass_through_get_wrap_ctx, /* get_wrap_ctx */
H5VL_pass_through_wrap_object, /* wrap_object */
+ H5VL_pass_through_unwrap_object, /* unwrap_object */
H5VL_pass_through_free_wrap_ctx, /* free_wrap_ctx */
},
{ /* attribute_cls */
@@ -683,8 +685,8 @@ H5VL_pass_through_get_wrap_ctx(const void *obj, void **wrap_ctx)
*
* Purpose: Use a "wrapper context" to wrap a data object
*
- * Return: Success: 0
- * Failure: -1
+ * Return: Success: Pointer to wrapped object
+ * Failure: NULL
*
*---------------------------------------------------------------------------
*/
@@ -711,6 +713,37 @@ H5VL_pass_through_wrap_object(void *obj, H5I_type_t obj_type, void *_wrap_ctx)
/*---------------------------------------------------------------------------
+ * Function: H5VL_pass_through_unwrap_object
+ *
+ * Purpose: Unwrap a wrapped object, discarding the wrapper, but returning
+ * underlying object.
+ *
+ * Return: Success: Pointer to unwrapped object
+ * Failure: NULL
+ *
+ *---------------------------------------------------------------------------
+ */
+static void *
+H5VL_pass_through_unwrap_object(void *obj)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ void *under;
+
+#ifdef ENABLE_PASSTHRU_LOGGING
+ printf("------- PASS THROUGH VOL UNWRAP Object\n");
+#endif
+
+ /* Unrap the object with the underlying VOL */
+ under = H5VLunwrap_object(o->under_object, o->under_vol_id);
+
+ if(under)
+ H5VL_pass_through_free_obj(o);
+
+ return under;
+} /* end H5VL_pass_through_unwrap_object() */
+
+
+/*---------------------------------------------------------------------------
* Function: H5VL_pass_through_free_wrap_ctx
*
* Purpose: Release a "wrapper context" for an object
@@ -1194,17 +1227,22 @@ H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_t specific_t
hid_t dxpl_id, void **req, va_list arguments)
{
H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ hid_t under_vol_id;
herr_t ret_value;
#ifdef ENABLE_PASSTHRU_LOGGING
printf("------- PASS THROUGH VOL H5Dspecific\n");
#endif
+ // Save copy of underlying VOL connector ID and prov helper, in case of
+ // refresh destroying the current object
+ under_vol_id = o->under_vol_id;
+
ret_value = H5VLdataset_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments);
/* Check for async request */
if(req && *req)
- *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+ *req = H5VL_pass_through_new_obj(*req, under_vol_id);
return ret_value;
} /* end H5VL_pass_through_dataset_specific() */
@@ -1396,17 +1434,22 @@ H5VL_pass_through_datatype_specific(void *obj, H5VL_datatype_specific_t specific
hid_t dxpl_id, void **req, va_list arguments)
{
H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ hid_t under_vol_id;
herr_t ret_value;
#ifdef ENABLE_PASSTHRU_LOGGING
printf("------- PASS THROUGH VOL DATATYPE Specific\n");
#endif
+ // Save copy of underlying VOL connector ID and prov helper, in case of
+ // refresh destroying the current object
+ under_vol_id = o->under_vol_id;
+
ret_value = H5VLdatatype_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments);
/* Check for async request */
if(req && *req)
- *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+ *req = H5VL_pass_through_new_obj(*req, under_vol_id);
return ret_value;
} /* end H5VL_pass_through_datatype_specific() */
@@ -1936,17 +1979,22 @@ H5VL_pass_through_group_specific(void *obj, H5VL_group_specific_t specific_type,
hid_t dxpl_id, void **req, va_list arguments)
{
H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ hid_t under_vol_id;
herr_t ret_value;
#ifdef ENABLE_PASSTHRU_LOGGING
printf("------- PASS THROUGH VOL GROUP Specific\n");
#endif
+ // Save copy of underlying VOL connector ID and prov helper, in case of
+ // refresh destroying the current object
+ under_vol_id = o->under_vol_id;
+
ret_value = H5VLgroup_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments);
/* Check for async request */
if(req && *req)
- *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+ *req = H5VL_pass_through_new_obj(*req, under_vol_id);
return ret_value;
} /* end H5VL_pass_through_group_specific() */
@@ -2372,17 +2420,22 @@ H5VL_pass_through_object_specific(void *obj, const H5VL_loc_params_t *loc_params
va_list arguments)
{
H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ hid_t under_vol_id;
herr_t ret_value;
#ifdef ENABLE_PASSTHRU_LOGGING
printf("------- PASS THROUGH VOL OBJECT Specific\n");
#endif
+ // Save copy of underlying VOL connector ID and prov helper, in case of
+ // refresh destroying the current object
+ under_vol_id = o->under_vol_id;
+
ret_value = H5VLobject_specific(o->under_object, loc_params, o->under_vol_id, specific_type, dxpl_id, req, arguments);
/* Check for async request */
if(req && *req)
- *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+ *req = H5VL_pass_through_new_obj(*req, under_vol_id);
return ret_value;
} /* end H5VL_pass_through_object_specific() */
diff --git a/src/H5VLprivate.h b/src/H5VLprivate.h
index dc4f9c5..04cc982 100644
--- a/src/H5VLprivate.h
+++ b/src/H5VLprivate.h
@@ -86,6 +86,7 @@ H5_DLL hid_t H5VL_register_connector(const void *cls, hbool_t app_ref, hid_t vip
/* Functions that manipulate VOL objects */
H5_DLL void *H5VL_object(hid_t id);
H5_DLL void *H5VL_object_data(const H5VL_object_t *vol_obj);
+H5_DLL void *H5VL_object_unwrap(const H5VL_object_t *vol_obj);
H5_DLL void *H5VL_object_verify(hid_t id, H5I_type_t obj_type);
H5_DLL H5VL_object_t *H5VL_vol_object(hid_t id);
H5_DLL herr_t H5VL_free_object(H5VL_object_t *obj);
@@ -93,13 +94,14 @@ H5_DLL herr_t H5VL_free_object(H5VL_object_t *obj);
/* Functions that wrap / unwrap VOL objects */
H5_DLL herr_t H5VL_get_wrap_ctx(const H5VL_class_t *connector, void *obj,
void **wrap_ctx);
+H5_DLL void * H5VL_wrap_object(const H5VL_class_t *connector, void *wrap_ctx,
+ void *obj, H5I_type_t obj_type);
+H5_DLL void * H5VL_unwrap_object(const H5VL_class_t *connector, void *obj);
H5_DLL herr_t H5VL_free_wrap_ctx(const H5VL_class_t *connector, void *wrap_ctx);
H5_DLL herr_t H5VL_set_vol_wrapper(void *obj, H5VL_t *vol_connector);
H5_DLL herr_t H5VL_inc_vol_wrapper(void *vol_wrap_ctx);
H5_DLL herr_t H5VL_dec_vol_wrapper(void *vol_wrap_ctx);
H5_DLL herr_t H5VL_reset_vol_wrapper(void);
-H5_DLL void * H5VL_wrap_object(const H5VL_class_t *connector, void *wrap_ctx,
- void *obj, H5I_type_t obj_type);
/* Library state functions */
H5_DLL herr_t H5VL_retrieve_lib_state(void **state);
diff --git a/src/H5VLpublic.h b/src/H5VLpublic.h
index da31a97..56e703c 100644
--- a/src/H5VLpublic.h
+++ b/src/H5VLpublic.h
@@ -253,6 +253,7 @@ typedef struct H5VL_wrap_class_t {
void * (*get_object)(const void *obj); /* Callback to retrieve underlying object */
herr_t (*get_wrap_ctx)(const void *obj, void **wrap_ctx); /* Callback to retrieve the object wrapping context for the connector */
void * (*wrap_object)(void *obj, H5I_type_t obj_type, void *wrap_ctx); /* Callback to wrap a library object */
+ void * (*unwrap_object)(void *obj); /* Callback to unwrap a library object */
herr_t (*free_wrap_ctx)(void *wrap_ctx); /* Callback to release the object wrapping context for the connector */
} H5VL_wrap_class_t;
@@ -472,6 +473,7 @@ H5_DLL void *H5VLget_object(void *obj, hid_t connector_id);
H5_DLL herr_t H5VLget_wrap_ctx(void *obj, hid_t connector_id, void **wrap_ctx);
H5_DLL void *H5VLwrap_object(void *obj, H5I_type_t obj_type, hid_t connector_id,
void *wrap_ctx);
+H5_DLL void *H5VLunwrap_object(void *obj, hid_t connector_id);
H5_DLL herr_t H5VLfree_wrap_ctx(void *wrap_ctx, hid_t connector_id);
/* Public wrappers for attribute callbacks */