diff --git a/src/H5T.c b/src/H5T.c index 811323e2d58..09eeff8c2f1 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -348,6 +348,8 @@ static herr_t H5T__set_size(H5T_t *dt, size_t size); static herr_t H5T__close_cb(H5T_t *dt, void **request); static H5T_path_t *H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name, H5T_conv_func_t *conv); +static bool H5T_path_match(H5T_path_t *path, H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, + H5VL_object_t *owned_vol_obj, H5T_conv_t func); static bool H5T__detect_vlen_ref(const H5T_t *dt); static H5T_t *H5T__initiate_copy(const H5T_t *old_dt); static H5T_t *H5T__copy_transient(H5T_t *old_dt); @@ -2693,8 +2695,22 @@ H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5VL_o FUNC_ENTER_NOAPI_NOERR - /* Remove matching entries from the soft list */ - if (H5T_PERS_DONTCARE == pers || H5T_PERS_SOFT == pers) { + /* + * Remove matching entries from the soft list if: + * + * - The caller didn't specify a particular type (soft or hard) + * of conversion path to match against or specified that soft + * conversion paths should be matched against + * + * AND + * + * - The caller didn't provide the `owned_vol_obj` parameter; + * if this parameter is provided, we want to leave the soft + * list untouched and only remove cached conversion paths + * below where the file VOL object associated with the path's + * source or destination types matches the given VOL object. + */ + if ((H5T_PERS_DONTCARE == pers || H5T_PERS_SOFT == pers) && !owned_vol_obj) { for (i = H5T_g.nsoft - 1; i >= 0; --i) { soft = H5T_g.soft + i; assert(soft); @@ -2704,8 +2720,6 @@ H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5VL_o continue; if (dst && dst->shared->type != soft->dst) continue; - if (owned_vol_obj) - continue; if (func && func != soft->conv.u.app_func) continue; @@ -2721,12 +2735,7 @@ H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5VL_o path = H5T_g.path[i]; assert(path); - nomatch = ((H5T_PERS_SOFT == pers && path->is_hard) || (H5T_PERS_HARD == pers && !path->is_hard)) || - (name && *name && strcmp(name, path->name) != 0) || - (src && H5T_cmp(src, path->src, false)) || (dst && H5T_cmp(dst, path->dst, false)) || - (owned_vol_obj && (owned_vol_obj != path->src->shared->owned_vol_obj) && - (owned_vol_obj != path->dst->shared->owned_vol_obj)) || - (func && func != path->conv.u.app_func); + nomatch = !H5T_path_match(path, pers, name, src, dst, owned_vol_obj, func); /* Not a match */ if (nomatch) { @@ -5158,6 +5167,53 @@ H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name, H5T_co FUNC_LEAVE_NOAPI(ret_value) } /* end H5T__path_find_real() */ +/*------------------------------------------------------------------------- + * Function: H5T_path_match + * + * Purpose: Helper function to determine whether a datatype conversion + * path object matches against a given set of criteria. + * + * Return: true/false (can't fail) + * + *------------------------------------------------------------------------- + */ +static bool +H5T_path_match(H5T_path_t *path, H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, + H5VL_object_t *owned_vol_obj, H5T_conv_t func) +{ + bool ret_value = true; + + assert(path); + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + if ( + /* Check that the specified conversion function persistence matches */ + ((H5T_PERS_SOFT == pers && path->is_hard) || (H5T_PERS_HARD == pers && !path->is_hard)) || + + /* Check that the specified conversion path name matches */ + (name && *name && strcmp(name, path->name) != 0) || + + /* + * Check that the specified source and destination datatypes match + * the source and destination datatypes in the conversion path + */ + (src && H5T_cmp(src, path->src, false)) || (dst && H5T_cmp(dst, path->dst, false)) || + + /* + * Check that the specified VOL object matches the VOL object + * in the conversion path + */ + (owned_vol_obj && (owned_vol_obj != path->src->shared->owned_vol_obj) && + (owned_vol_obj != path->dst->shared->owned_vol_obj)) || + + /* Check that the specified conversion function matches */ + (func && func != path->conv.u.app_func)) + ret_value = false; + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5T_path_match() */ + /*------------------------------------------------------------------------- * Function: H5T_path_noop *