From bf76baef3335460fac43a77a9b5ad84c9c99a19d Mon Sep 17 00:00:00 2001 From: mattjala <124107509+mattjala@users.noreply.github.com> Date: Sat, 29 Jun 2024 15:22:35 -0500 Subject: [PATCH] Document VOL object wrapping context (#4611) --- doxygen/dox/VOLConnGuide.dox | 39 +++++++++++++++++++++++++++--------- src/H5VLcallback.c | 5 ++++- src/H5VLconnector.h | 3 ++- src/H5VLint.c | 11 +++++++++- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/doxygen/dox/VOLConnGuide.dox b/doxygen/dox/VOLConnGuide.dox index fb662a0ef5a..05219db442c 100644 --- a/doxygen/dox/VOLConnGuide.dox +++ b/doxygen/dox/VOLConnGuide.dox @@ -657,7 +657,11 @@ structure. It is the opposite of the to_str callback. \subsection subsecVOLRefWrap Object Wrap Callbacks The object wrap callbacks are used by passthrough connectors to wrap/unwrap objects and contexts when -passing them up and down the VOL chain. +passing them up and down the VOL chain. Each passthrough VOL must define an object wrapping structure and a wrap context. +The object wrapping structure should contain the information necessary to recursively unwrap the object - at a minimum, this is the object provided from and the ID of the next connector in the stack. +The wrap context should contain the information necessary to recursively wrap the object - at a minimum, this is the ID and the wrap context of the next VOL connector in the stack. + +Each callback should use H5VL<callback> to recursively invoke the same callback in all lower passthrough VOl connectors. Wrap class for object wrapping routines, H5VLconnector.h \code @@ -671,7 +675,13 @@ typedef struct H5VL_wrap_class_t { \endcode \subsubsection subsubsecVOLRefWrapobj wrap: get_object -Retrieves an underlying object. +Retrieves the underlying object from a wrapped object. Should return a pointer to the underlying object belonging to the terminal VOL connector. + +This will generally be done by unwrapping this VOL's object wrapping structure, before recursively calling H5VLget_object to invoke the get_object +callback for all lower VOL connectors which define it. H5VLget_object requires the object returned by the next VOL and the next VOL's ID. Both of +these fields should be stored by the VOL somehow, generally on the wrapped object structure. + +This callback should not cleanup or modify the provided object wrapping structure. @@ -689,7 +699,7 @@ Retrieves an underlying object. @@ -697,6 +707,9 @@ Retrieves an underlying object. \subsubsection subsubsecVOLRefWrapctx wrap: get_wrap_ctx Get a VOL connector's object wrapping context. + +The context should be returned in dynamically allocated memory under *wrap_ctx. +Any resources this callback allocates should be freed within free_wrap_ctx.
Signature:
\code - obj (IN): Object being unwrapped. + obj (IN): The object to be unwrapped. \endcode
@@ -714,7 +727,7 @@ Get a VOL connector's object wrapping context. @@ -722,7 +735,11 @@ Get a VOL connector's object wrapping context.
Signature:
\code - obj (IN): Object for which we need a context. + obj (IN): Object wrapped by this VOL connector, for which we need a context. wrap_ctx (OUT): Context. \endcode
\subsubsection subsubsecVOLRefWrapwrap wrap: wrap_object -Asks a connector to wrap an underlying object. +Asks a connector to wrap an underlying object. This callback should use H5VLwrap_object +to recursively have the object wrapped by all lower VOL connectors before performing its own wrapping. + +The wrapped object should provide the information necessary for unwrap_object to recursively +unwrap it - at a minimum, the object provided from and the ID of the next VOL connector. @@ -740,7 +757,7 @@ Asks a connector to wrap an underlying object.
Signature:
\code - obj (IN): Object being wrapped. + obj (IN): The object to be wrapped. obj_type (IN): Object type (see H5Ipublic.h). wrap_ctx (IN): Context. \endcode @@ -749,7 +766,10 @@ Asks a connector to wrap an underlying object.
\subsubsection subsubsecVOLRefWrapunwrap wrap: unwrap_object -Unwrap an object from connector. +Unwrap an object from connector. Any resources allocated during wrap_object should be released and cleaned up here. + +This callback should clean up this VOL's object wrapping structure before recursively invoking H5VLunwrap_object. + @@ -767,14 +787,15 @@ Unwrap an object from connector.
Signature:
\code - obj (IN): Object being unwrapped. + obj (IN): Object to be unwrapped. \endcode
\subsubsection subsubsecVOLRefWrapfree wrap: free_wrap_ctx -Release a VOL connector's object wrapping context. +Release a VOL connector's object wrapping context. This should free any resources allocated during get_wrap_ctx, and recursively invoke H5VLfree_wrap_ctx +to execute the free callback for the lower VOL connectors in the stack. diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c index 83ff9e92402..0d6a2d22215 100644 --- a/src/H5VLcallback.c +++ b/src/H5VLcallback.c @@ -776,7 +776,10 @@ H5VL_get_wrap_ctx(const H5VL_class_t *connector, void *obj, void **wrap_ctx) /*--------------------------------------------------------------------------- * Function: H5VLget_wrap_ctx * - * Purpose: Get a VOL connector's object wrapping context + * Purpose: Get a VOL connector's object wrapping context. The output + * wrap context is stored in memory allocated by the VOL callback + * under *wrap_ctx and must be freed by the caller through + * H5VLfree_wrap_ctx(). * * Return: Success: Non-negative * Failure: Negative diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h index 02d22314ebc..83a5b087133 100644 --- a/src/H5VLconnector.h +++ b/src/H5VLconnector.h @@ -845,7 +845,8 @@ typedef struct H5VL_info_class_t { } H5VL_info_class_t; /* VOL object wrap / retrieval callbacks */ -/* (These only need to be implemented by "pass through" VOL connectors) */ +/* (These must be implemented by "pass through" VOL connectors, and should not be implemented by terminal VOL + * connectors) */ typedef struct H5VL_wrap_class_t { void *(*get_object)(const void *obj); /* Callback to retrieve underlying object */ herr_t (*get_wrap_ctx)( diff --git a/src/H5VLint.c b/src/H5VLint.c index de52dfc4519..4337e48c91f 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -55,7 +55,16 @@ /* Local Typedefs */ /******************/ -/* Object wrapping context info */ +/* Object wrapping context info for passthrough VOL connectors. + * Passthrough VOL connectors must wrap objects returned from lower level(s) of the VOL connector stack + * so that they may be passed back up the stack to the library, and must unwrap objects + * passed down the stack before providing them to the next lower VOL connector. + * This is generally done individually within each VOL object callback. However, the library sometimes + * needs to wrap objects from places that don't pass through the VOL layer. + * In this case, the wrap callbacks defined in H5VL_wrap_class_t are used, and the VOL-defined wrap context + * (obj_wrap_ctx) provides necessary information - at a minimum, the object originally returned by the lower + * VOL connector, and the ID of the next VOL connector. + */ typedef struct H5VL_wrap_ctx_t { H5_ATOMIC(unsigned) rc; /* Ref. count for the # of times the context was set / reset */ H5VL_t *connector; /* VOL connector for "outermost" class to start wrap */
Signature: