From 5461414ea2e84a05d29f095ca359e0ba874ef118 Mon Sep 17 00:00:00 2001 From: Anida Khizar Date: Wed, 8 Oct 2025 17:18:23 +0200 Subject: [PATCH 1/9] Ensuring the use of a compatible HDF5 API versions during errors handling --- plugins/decl_hdf5/hdf5_wrapper.h | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/plugins/decl_hdf5/hdf5_wrapper.h b/plugins/decl_hdf5/hdf5_wrapper.h index 4caf5e48e..b471c462c 100644 --- a/plugins/decl_hdf5/hdf5_wrapper.h +++ b/plugins/decl_hdf5/hdf5_wrapper.h @@ -57,7 +57,9 @@ class Hdf5_error_handler { /// The original handler H5E_auto2_t m_old_func; - + /// Original handler to use with old HDF5 API + H5E_auto1_t m_old_func_V16; + /// The original handler data void* m_old_data; @@ -66,15 +68,36 @@ class Hdf5_error_handler */ Hdf5_error_handler() { - if (0 > H5Eget_auto2(H5E_DEFAULT, &m_old_func, &m_old_data)) handle_hdf5_err(); - if (0 > H5Eset_auto2(H5E_DEFAULT, NULL, NULL)) handle_hdf5_err(); + unsigned is_v2; + hid_t stack = H5Eget_current_stack(); + H5Eauto_is_v2(stack, &is_v2); + if(is_v2) + { + if (0 > H5Eget_auto2(H5E_DEFAULT, &m_old_func, &m_old_data)) handle_hdf5_err(); + if (0 > H5Eset_auto2(H5E_DEFAULT, NULL, NULL)) handle_hdf5_err(); + } + else + { + if (0 > H5Eget_auto1(&m_old_func_V16, &m_old_data)) handle_hdf5_err(); + if (0 > H5Eset_auto1(NULL, NULL)) handle_hdf5_err(); + } } /** The destructor */ ~Hdf5_error_handler() { - if (0 > H5Eset_auto2(H5E_DEFAULT, m_old_func, m_old_data)) handle_hdf5_err(); + unsigned is_v2; + hid_t stack = H5Eget_current_stack(); + H5Eauto_is_v2(stack, &is_v2); + if(is_v2) + { + if (0 > H5Eset_auto2(H5E_DEFAULT, m_old_func, m_old_data)) handle_hdf5_err(); + } + else + { + if (0 > H5Eset_auto1(m_old_func_V16, m_old_data)) handle_hdf5_err(); + } } }; From aecd85b45220c1243c6e78ce3dc87767a8cd43d1 Mon Sep 17 00:00:00 2001 From: Anida Khizar Date: Thu, 9 Oct 2025 15:09:01 +0200 Subject: [PATCH 2/9] Factorizing code --- plugins/decl_hdf5/hdf5_wrapper.h | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/plugins/decl_hdf5/hdf5_wrapper.h b/plugins/decl_hdf5/hdf5_wrapper.h index b471c462c..3f54aa082 100644 --- a/plugins/decl_hdf5/hdf5_wrapper.h +++ b/plugins/decl_hdf5/hdf5_wrapper.h @@ -56,21 +56,30 @@ namespace decl_hdf5 { class Hdf5_error_handler { /// The original handler - H5E_auto2_t m_old_func; - /// Original handler to use with old HDF5 API - H5E_auto1_t m_old_func_V16; - + union { + // handler to use with the HDF5 API version 2 + H5E_auto2_t m_old_func; + ///handler to use with old HDF5 API + H5E_auto1_t m_old_func_V16; + }; /// The original handler data void* m_old_data; + unsigned get_api_version() + { + hid_t stack = H5Eget_current_stack(); + if (0 > stack) handle_hdf5_err(); + unsigned result; + if (0 > H5Eauto_is_v2(stack, &result)) handle_hdf5_err(); + if (0 > H5Eclose_stack(stack)) handle_hdf5_err(); + return result; + } public: /** The default (and only) constructor, installs the handler */ Hdf5_error_handler() { - unsigned is_v2; - hid_t stack = H5Eget_current_stack(); - H5Eauto_is_v2(stack, &is_v2); + static unsigned is_v2 = get_api_version(); if(is_v2) { if (0 > H5Eget_auto2(H5E_DEFAULT, &m_old_func, &m_old_data)) handle_hdf5_err(); @@ -87,9 +96,7 @@ class Hdf5_error_handler */ ~Hdf5_error_handler() { - unsigned is_v2; - hid_t stack = H5Eget_current_stack(); - H5Eauto_is_v2(stack, &is_v2); + static unsigned is_v2 = get_api_version(); if(is_v2) { if (0 > H5Eset_auto2(H5E_DEFAULT, m_old_func, m_old_data)) handle_hdf5_err(); From 1cb22f1021266b43b01fed4c650218d8fa2a2320 Mon Sep 17 00:00:00 2001 From: Julien Bigot Date: Thu, 9 Oct 2025 15:37:58 +0200 Subject: [PATCH 3/9] Indent --- plugins/decl_hdf5/hdf5_wrapper.h | 66 +++++++++++++++----------------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/plugins/decl_hdf5/hdf5_wrapper.h b/plugins/decl_hdf5/hdf5_wrapper.h index 3f54aa082..3281b7194 100644 --- a/plugins/decl_hdf5/hdf5_wrapper.h +++ b/plugins/decl_hdf5/hdf5_wrapper.h @@ -56,55 +56,51 @@ namespace decl_hdf5 { class Hdf5_error_handler { /// The original handler - union { - // handler to use with the HDF5 API version 2 - H5E_auto2_t m_old_func; - ///handler to use with old HDF5 API - H5E_auto1_t m_old_func_V16; - }; + union { + // handler to use with the HDF5 API version 2 + H5E_auto2_t m_old_func; + ///handler to use with old HDF5 API + H5E_auto1_t m_old_func_V16; + }; + /// The original handler data void* m_old_data; - unsigned get_api_version() - { - hid_t stack = H5Eget_current_stack(); - if (0 > stack) handle_hdf5_err(); - unsigned result; - if (0 > H5Eauto_is_v2(stack, &result)) handle_hdf5_err(); - if (0 > H5Eclose_stack(stack)) handle_hdf5_err(); - return result; - } + unsigned get_api_version() + { + hid_t stack = H5Eget_current_stack(); + if (0 > stack) handle_hdf5_err(); + unsigned result; + if (0 > H5Eauto_is_v2(stack, &result)) handle_hdf5_err(); + if (0 > H5Eclose_stack(stack)) handle_hdf5_err(); + return result; + } + public: /** The default (and only) constructor, installs the handler */ Hdf5_error_handler() { - static unsigned is_v2 = get_api_version(); - if(is_v2) - { - if (0 > H5Eget_auto2(H5E_DEFAULT, &m_old_func, &m_old_data)) handle_hdf5_err(); - if (0 > H5Eset_auto2(H5E_DEFAULT, NULL, NULL)) handle_hdf5_err(); - } - else - { - if (0 > H5Eget_auto1(&m_old_func_V16, &m_old_data)) handle_hdf5_err(); - if (0 > H5Eset_auto1(NULL, NULL)) handle_hdf5_err(); - } + static unsigned is_v2 = get_api_version(); + if (is_v2) { + if (0 > H5Eget_auto2(H5E_DEFAULT, &m_old_func, &m_old_data)) handle_hdf5_err(); + if (0 > H5Eset_auto2(H5E_DEFAULT, NULL, NULL)) handle_hdf5_err(); + } else { + if (0 > H5Eget_auto1(&m_old_func_V16, &m_old_data)) handle_hdf5_err(); + if (0 > H5Eset_auto1(NULL, NULL)) handle_hdf5_err(); + } } /** The destructor */ ~Hdf5_error_handler() { - static unsigned is_v2 = get_api_version(); - if(is_v2) - { - if (0 > H5Eset_auto2(H5E_DEFAULT, m_old_func, m_old_data)) handle_hdf5_err(); - } - else - { - if (0 > H5Eset_auto1(m_old_func_V16, m_old_data)) handle_hdf5_err(); - } + static unsigned is_v2 = get_api_version(); + if (is_v2) { + if (0 > H5Eset_auto2(H5E_DEFAULT, m_old_func, m_old_data)) handle_hdf5_err(); + } else { + if (0 > H5Eset_auto1(m_old_func_V16, m_old_data)) handle_hdf5_err(); + } } }; From 11b6bd7f2e5277cd27842074171b47c0ad9b2354 Mon Sep 17 00:00:00 2001 From: Anida Khizar Date: Thu, 9 Oct 2025 15:47:53 +0200 Subject: [PATCH 4/9] Using Raii_hid to retrieve stack --- plugins/decl_hdf5/hdf5_wrapper.h | 111 +++++++++++++++---------------- 1 file changed, 55 insertions(+), 56 deletions(-) diff --git a/plugins/decl_hdf5/hdf5_wrapper.h b/plugins/decl_hdf5/hdf5_wrapper.h index 3281b7194..461bc255f 100644 --- a/plugins/decl_hdf5/hdf5_wrapper.h +++ b/plugins/decl_hdf5/hdf5_wrapper.h @@ -48,62 +48,6 @@ namespace decl_hdf5 { */ [[noreturn]] void handle_hdf5_err(const char* message = NULL); -/** A RAII-style HDF5 error handler. - * - * Creating an instance of this class removes any HDF5 error handler. - * The original handler is reinstalled when the instance is destroyed. - */ -class Hdf5_error_handler -{ - /// The original handler - union { - // handler to use with the HDF5 API version 2 - H5E_auto2_t m_old_func; - ///handler to use with old HDF5 API - H5E_auto1_t m_old_func_V16; - }; - - /// The original handler data - void* m_old_data; - - unsigned get_api_version() - { - hid_t stack = H5Eget_current_stack(); - if (0 > stack) handle_hdf5_err(); - unsigned result; - if (0 > H5Eauto_is_v2(stack, &result)) handle_hdf5_err(); - if (0 > H5Eclose_stack(stack)) handle_hdf5_err(); - return result; - } - -public: - /** The default (and only) constructor, installs the handler - */ - Hdf5_error_handler() - { - static unsigned is_v2 = get_api_version(); - if (is_v2) { - if (0 > H5Eget_auto2(H5E_DEFAULT, &m_old_func, &m_old_data)) handle_hdf5_err(); - if (0 > H5Eset_auto2(H5E_DEFAULT, NULL, NULL)) handle_hdf5_err(); - } else { - if (0 > H5Eget_auto1(&m_old_func_V16, &m_old_data)) handle_hdf5_err(); - if (0 > H5Eset_auto1(NULL, NULL)) handle_hdf5_err(); - } - } - - /** The destructor - */ - ~Hdf5_error_handler() - { - static unsigned is_v2 = get_api_version(); - if (is_v2) { - if (0 > H5Eset_auto2(H5E_DEFAULT, m_old_func, m_old_data)) handle_hdf5_err(); - } else { - if (0 > H5Eset_auto1(m_old_func_V16, m_old_data)) handle_hdf5_err(); - } - } -}; - /** A RAII-style wrapper for HDF5 hid_t. * * This calls the provided destroyer function when the hid_t goes out of scope. @@ -209,6 +153,61 @@ Raii_hid make_raii_hid(hid_t value, Destroyer&& dst, const char* message = NULL) */ std::tuple space(PDI::Datatype_sptr type, bool dense = false); +/** A RAII-style HDF5 error handler. + * + * Creating an instance of this class removes any HDF5 error handler. + * The original handler is reinstalled when the instance is destroyed. + */ +class Hdf5_error_handler +{ + /// The original handler + union + { + // handler to use with the HDF5 API version 2 + H5E_auto2_t m_old_func; + ///handler to use with old HDF5 API + H5E_auto1_t m_old_func_V16; + }; + + /// The original handler data + void* m_old_data; + + static unsigned get_api_version() + { + Raii_hid stack = make_raii_hid(H5Eget_current_stack(), H5Eclose_stack, "unable to retrieve HDF5 stack to check API version"); + unsigned result; + if (0 > H5Eauto_is_v2(stack, &result)) handle_hdf5_err("unable to retrieve HDF5 stack to check API version"); + return result; + } + +public: + /** The default (and only) constructor, installs the handler + */ + Hdf5_error_handler() + { + static unsigned is_v2 = get_api_version(); + if (is_v2) { + if (0 > H5Eget_auto2(H5E_DEFAULT, &m_old_func, &m_old_data)) handle_hdf5_err(); + if (0 > H5Eset_auto2(H5E_DEFAULT, NULL, NULL)) handle_hdf5_err(); + } else { + if (0 > H5Eget_auto1(&m_old_func_V16, &m_old_data)) handle_hdf5_err(); + if (0 > H5Eset_auto1(NULL, NULL)) handle_hdf5_err(); + } + } + + /** The destructor + */ + ~Hdf5_error_handler() + { + static unsigned is_v2 = get_api_version(); + if (is_v2) { + if (0 > H5Eset_auto2(H5E_DEFAULT, m_old_func, m_old_data)) handle_hdf5_err(); + } else { + if (0 > H5Eset_auto1(m_old_func_V16, m_old_data)) handle_hdf5_err(); + } + } +}; + } // namespace decl_hdf5 #endif // DECL_HDF5_HDF5_WRAPPER_H_ From 2e8614dc8caea9cb13ddf326bd3b1399ef154b92 Mon Sep 17 00:00:00 2001 From: yushan wang Date: Tue, 14 Oct 2025 14:41:18 +0200 Subject: [PATCH 5/9] fix indent --- plugins/decl_hdf5/hdf5_wrapper.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/decl_hdf5/hdf5_wrapper.h b/plugins/decl_hdf5/hdf5_wrapper.h index 461bc255f..821851729 100644 --- a/plugins/decl_hdf5/hdf5_wrapper.h +++ b/plugins/decl_hdf5/hdf5_wrapper.h @@ -161,8 +161,7 @@ std::tuple space(PDI::Datatype_sptr type, bool dense = false class Hdf5_error_handler { /// The original handler - union - { + union { // handler to use with the HDF5 API version 2 H5E_auto2_t m_old_func; ///handler to use with old HDF5 API From 6023697ac5b496c6fc09b57f6af64ba3dbcbb8a6 Mon Sep 17 00:00:00 2001 From: yushan wang Date: Tue, 14 Oct 2025 15:13:39 +0200 Subject: [PATCH 6/9] update copyright date --- plugins/decl_hdf5/hdf5_wrapper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/decl_hdf5/hdf5_wrapper.h b/plugins/decl_hdf5/hdf5_wrapper.h index 821851729..29b07db28 100644 --- a/plugins/decl_hdf5/hdf5_wrapper.h +++ b/plugins/decl_hdf5/hdf5_wrapper.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (C) 2015-2021 Commissariat a l'energie atomique et aux energies alternatives (CEA) + * Copyright (C) 2015-2025 Commissariat a l'energie atomique et aux energies alternatives (CEA) * All rights reserved. * * Redistribution and use in source and binary forms, with or without From 7f20f45ee5781fe8d2ac92a53f3c0e8e283c68ee Mon Sep 17 00:00:00 2001 From: yushan wang Date: Tue, 14 Oct 2025 15:18:52 +0200 Subject: [PATCH 7/9] update AUTHORS --- plugins/decl_hdf5/AUTHORS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/decl_hdf5/AUTHORS b/plugins/decl_hdf5/AUTHORS index 23cda70a1..5e31daec4 100644 --- a/plugins/decl_hdf5/AUTHORS +++ b/plugins/decl_hdf5/AUTHORS @@ -11,6 +11,9 @@ Julien Bigot - CEA (julien.bigot@cea.fr) * Run tests that depend on the filesystem in their own temporary directory * Buildsystem +Anida Khizar - CEA (anida.khizar@cea.fr) +* fix HDF5 API version compatibility issue [#567](https://github.com/pdidev/pdi/issues/567) + Jacques Morice - CEA (jacques.morice@cea.fr) * contribution to feature improvement, validation * fix issue [#55](https://github.com/pdidev/pkgs/issues/55) From fdc65b138f13a6668549a30f4f60ce5d21a07d9a Mon Sep 17 00:00:00 2001 From: yushan wang Date: Tue, 14 Oct 2025 15:21:43 +0200 Subject: [PATCH 8/9] update CHANGELOG --- plugins/decl_hdf5/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/decl_hdf5/CHANGELOG.md b/plugins/decl_hdf5/CHANGELOG.md index 8d393171d..551a4dcdc 100644 --- a/plugins/decl_hdf5/CHANGELOG.md +++ b/plugins/decl_hdf5/CHANGELOG.md @@ -17,6 +17,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Removed ### Fixed +* fix HDF5 API version compatibility issue during error handling + [#567](https://github.com/pdidev/pdi/issues/567) ### Security From d18bd844e22dabd695693d30d354fa8081b508de Mon Sep 17 00:00:00 2001 From: Anida Khizar Date: Thu, 23 Oct 2025 17:22:12 +0200 Subject: [PATCH 9/9] comment --- plugins/decl_hdf5/hdf5_wrapper.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/decl_hdf5/hdf5_wrapper.h b/plugins/decl_hdf5/hdf5_wrapper.h index 29b07db28..5c9e77225 100644 --- a/plugins/decl_hdf5/hdf5_wrapper.h +++ b/plugins/decl_hdf5/hdf5_wrapper.h @@ -171,6 +171,10 @@ class Hdf5_error_handler /// The original handler data void* m_old_data; + /** Retrieves the HDF5 API version that is being used by the current error stack + * + * \return 1 if the error stack conforms to the API version 2, 0 otherwise + */ static unsigned get_api_version() { Raii_hid stack = make_raii_hid(H5Eget_current_stack(), H5Eclose_stack, "unable to retrieve HDF5 stack to check API version");