Skip to content

Commit 591cd13

Browse files
authored
Merge exception-safe array::resize_and_reset
Previously arrays were resized before reallocating memory, now the order is reversed, which means that if an allocation exception is caught, the array is still unchanged. Related PR: #1963
2 parents 03704c4 + ea929b0 commit 591cd13

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

core/test/base/array.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// SPDX-License-Identifier: BSD-3-Clause
44

55
#include <algorithm>
6+
#include <stdexcept>
67
#include <type_traits>
78

89
#include <gtest/gtest.h>
@@ -36,7 +37,7 @@ class Array : public ::testing::Test {
3637
EXPECT_EQ(a.get_const_data()[1], T{2});
3738
}
3839

39-
std::shared_ptr<const gko::Executor> exec;
40+
std::shared_ptr<gko::Executor> exec;
4041
gko::array<T> x;
4142
};
4243

@@ -431,6 +432,37 @@ TYPED_TEST(Array, CanBeResized)
431432
}
432433

433434

435+
class ThrowOnAllocationLogger : public gko::log::Logger {
436+
public:
437+
void on_allocation_started(const gko::Executor* exec,
438+
const gko::size_type& num_bytes) const override
439+
{
440+
throw std::runtime_error{""};
441+
}
442+
443+
ThrowOnAllocationLogger()
444+
: Logger(gko::log::Logger::allocation_started_mask)
445+
{}
446+
};
447+
448+
449+
TYPED_TEST(Array, ResizeIsExceptionSafe)
450+
{
451+
this->exec->add_logger(std::make_unique<ThrowOnAllocationLogger>());
452+
gko::array<TypeParam> a{this->exec};
453+
bool thrown = false;
454+
455+
try {
456+
a.resize_and_reset(1);
457+
} catch (const std::runtime_error&) {
458+
thrown = true;
459+
}
460+
461+
ASSERT_EQ(a.get_size(), 0);
462+
ASSERT_TRUE(thrown);
463+
}
464+
465+
434466
TYPED_TEST(Array, ViewCannotBeResized)
435467
{
436468
TypeParam data[] = {1, 2, 3};

include/ginkgo/core/base/array.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,8 +634,8 @@ class array {
634634
}
635635

636636
if (size > 0 && this->is_owning()) {
637-
size_ = size;
638637
data_.reset(exec_->alloc<value_type>(size));
638+
size_ = size;
639639
} else {
640640
this->clear();
641641
}

0 commit comments

Comments
 (0)