Skip to content

Commit 08a93f1

Browse files
committed
HDF5 readAttribute: cleanup also upon failure
1 parent a307fd2 commit 08a93f1

File tree

2 files changed

+80
-54
lines changed

2 files changed

+80
-54
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
3+
#include <type_traits>
4+
#include <utility>
5+
6+
namespace openPMD::auxiliary
7+
{
8+
template <typename F>
9+
struct defer_type
10+
{
11+
F functor;
12+
~defer_type()
13+
{
14+
std::move(functor)();
15+
}
16+
};
17+
18+
template <typename F>
19+
auto defer(F &&functor) -> defer_type<std::remove_reference_t<F>>
20+
{
21+
return defer_type<std::remove_reference_t<F>>{std::forward<F>(functor)};
22+
}
23+
} // namespace openPMD::auxiliary

src/IO/HDF5/HDF5IOHandler.cpp

Lines changed: 57 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "openPMD/IO/Access.hpp"
2626
#include "openPMD/IO/FlushParametersInternal.hpp"
2727
#include "openPMD/IO/HDF5/HDF5IOHandlerImpl.hpp"
28+
#include "openPMD/auxiliary/Defer.hpp"
2829
#include "openPMD/auxiliary/Environment.hpp"
2930
#include "openPMD/auxiliary/JSON_internal.hpp"
3031
#include "openPMD/auxiliary/Variant.hpp"
@@ -2506,6 +2507,15 @@ void HDF5IOHandlerImpl::readAttribute(
25062507
H5Pset_all_coll_metadata_ops(fapl, true);
25072508
}
25082509
#endif
2510+
auto defer_close_fapl = auxiliary::defer([&]() {
2511+
status = H5Pclose(fapl);
2512+
if (status != 0)
2513+
{
2514+
std::cerr << "[HDF5] Internal error: Failed to close HDF5 "
2515+
"attribute during attribute read."
2516+
<< std::endl;
2517+
}
2518+
});
25092519

25102520
obj_id =
25112521
H5Oopen(file.id, concrete_h5_file_position(writable).c_str(), fapl);
@@ -2519,7 +2529,26 @@ void HDF5IOHandlerImpl::readAttribute(
25192529
concrete_h5_file_position(writable).c_str() +
25202530
"' during attribute read");
25212531
}
2532+
auto defer_close_obj_id = auxiliary::defer([&]() {
2533+
status = H5Oclose(obj_id);
2534+
if (status != 0)
2535+
{
2536+
std::cerr << "[HDF5] Internal error: Failed to close " +
2537+
concrete_h5_file_position(writable) +
2538+
" during attribute read."
2539+
<< std::endl;
2540+
;
2541+
}
2542+
});
25222543
std::string const &attr_name = parameters.name;
2544+
if (H5Aexists(obj_id, attr_name.c_str()) <= 0)
2545+
{
2546+
throw error::ReadError(
2547+
error::AffectedObject::Attribute,
2548+
error::Reason::NotFound,
2549+
"HDF5",
2550+
parameters.name);
2551+
}
25232552
attr_id = H5Aopen(obj_id, attr_name.c_str(), H5P_DEFAULT);
25242553
if (attr_id < 0)
25252554
{
@@ -2533,10 +2562,38 @@ void HDF5IOHandlerImpl::readAttribute(
25332562
concrete_h5_file_position(writable).c_str() +
25342563
") during attribute read");
25352564
}
2565+
auto defer_close_attr_id = auxiliary::defer([&]() {
2566+
status = H5Aclose(attr_id);
2567+
if (status != 0)
2568+
{
2569+
std::cerr << "[HDF5] Internal error: Failed to close attribute " +
2570+
attr_name + " at " + concrete_h5_file_position(writable) +
2571+
" during attribute read."
2572+
<< std::endl;
2573+
}
2574+
});
25362575

25372576
hid_t attr_type, attr_space;
25382577
attr_type = H5Aget_type(attr_id);
2578+
auto defer_close_attr_type = auxiliary::defer([&]() {
2579+
status = H5Tclose(attr_type);
2580+
if (status != 0)
2581+
{
2582+
std::cerr << "[HDF5] Internal error: Failed to close attribute "
2583+
"file space during attribute read."
2584+
<< std::endl;
2585+
}
2586+
});
25392587
attr_space = H5Aget_space(attr_id);
2588+
auto defer_close_attr_space = auxiliary::defer([&]() {
2589+
status = H5Sclose(attr_space);
2590+
if (status != 0)
2591+
{
2592+
std::cerr << "[HDF5] Internal error: Failed to close attribute "
2593+
"datatype during attribute read."
2594+
<< std::endl;
2595+
}
2596+
});
25402597

25412598
int ndims = H5Sget_simple_extent_ndims(attr_space);
25422599
std::vector<hsize_t> dims(ndims, 0);
@@ -3065,63 +3122,9 @@ void HDF5IOHandlerImpl::readAttribute(
30653122
" at " + concrete_h5_file_position(writable));
30663123
}
30673124

3068-
status = H5Tclose(attr_type);
3069-
if (status != 0)
3070-
{
3071-
throw error::ReadError(
3072-
error::AffectedObject::Attribute,
3073-
error::Reason::CannotRead,
3074-
"HDF5",
3075-
"[HDF5] Internal error: Failed to close attribute datatype during "
3076-
"attribute read");
3077-
}
3078-
status = H5Sclose(attr_space);
3079-
if (status != 0)
3080-
{
3081-
throw error::ReadError(
3082-
error::AffectedObject::Attribute,
3083-
error::Reason::CannotRead,
3084-
"HDF5",
3085-
"[HDF5] Internal error: Failed to close attribute file space "
3086-
"during "
3087-
"attribute read");
3088-
}
3089-
30903125
auto dtype = parameters.dtype;
30913126
*dtype = a.dtype;
30923127
*parameters.m_resource = a.getAny();
3093-
3094-
status = H5Aclose(attr_id);
3095-
if (status != 0)
3096-
{
3097-
throw error::ReadError(
3098-
error::AffectedObject::Attribute,
3099-
error::Reason::CannotRead,
3100-
"HDF5",
3101-
"[HDF5] Internal error: Failed to close attribute " + attr_name +
3102-
" at " + concrete_h5_file_position(writable) +
3103-
" during attribute read");
3104-
}
3105-
status = H5Oclose(obj_id);
3106-
if (status != 0)
3107-
{
3108-
throw error::ReadError(
3109-
error::AffectedObject::Attribute,
3110-
error::Reason::CannotRead,
3111-
"HDF5",
3112-
"[HDF5] Internal error: Failed to close " +
3113-
concrete_h5_file_position(writable) + " during attribute read");
3114-
}
3115-
status = H5Pclose(fapl);
3116-
if (status != 0)
3117-
{
3118-
throw error::ReadError(
3119-
error::AffectedObject::Attribute,
3120-
error::Reason::CannotRead,
3121-
"HDF5",
3122-
"[HDF5] Internal error: Failed to close HDF5 attribute during "
3123-
"attribute read");
3124-
}
31253128
}
31263129

31273130
void HDF5IOHandlerImpl::listPaths(

0 commit comments

Comments
 (0)