Skip to content

Commit aef11db

Browse files
authored
[orc-rt] Add a make_scope_exit utility. (llvm#157094)
make_scoped_exit takes a function object and returns an object that will run the given function object at destruction time (unless the scope-exit object's `release` method is called to disable it). This can be useful when a function needs to conditionally perform some cleanup, but may exit along multiple pathways. E.g. ``` // Allocate resource here. auto DoCleanup = make_scope_exit([]() { // release resource here. }); // various conditional error return paths. if (...) return make_error<...>(...); // successful return: cancel cleanup. DoCleanup.release(); return Error::success(); ```
1 parent 2e6685c commit aef11db

File tree

4 files changed

+94
-0
lines changed

4 files changed

+94
-0
lines changed

orc-rt/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ set(ORC_RT_HEADERS
1313
orc-rt/MemoryFlags.h
1414
orc-rt/RTTI.h
1515
orc-rt/WrapperFunction.h
16+
orc-rt/ScopeExit.h
1617
orc-rt/SimplePackedSerialization.h
1718
orc-rt/SPSWrapperFunction.h
1819
orc-rt/bind.h

orc-rt/include/orc-rt/ScopeExit.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//===---------- ScopeExit.h - Execute code at scope exit --------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// make_scope_exit and related APIs.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef ORC_RT_SCOPEEXIT_H
14+
#define ORC_RT_SCOPEEXIT_H
15+
16+
#include <type_traits>
17+
#include <utility>
18+
19+
namespace orc_rt {
20+
namespace detail {
21+
22+
template <typename Fn> class ScopeExitRunner {
23+
public:
24+
ScopeExitRunner(Fn &&F) : F(F) {}
25+
ScopeExitRunner(const ScopeExitRunner &) = delete;
26+
ScopeExitRunner &operator=(const ScopeExitRunner &) = delete;
27+
ScopeExitRunner(ScopeExitRunner &&) = delete;
28+
ScopeExitRunner &operator=(ScopeExitRunner &&) = delete;
29+
~ScopeExitRunner() {
30+
if (Engaged)
31+
F();
32+
}
33+
void release() { Engaged = false; }
34+
35+
private:
36+
Fn F;
37+
bool Engaged = true;
38+
};
39+
40+
} // namespace detail
41+
42+
/// Creates an object that runs the given function object upon destruction.
43+
/// Calling the object's release method prior to destruction will prevent the
44+
/// function object from running.
45+
template <typename Fn>
46+
[[nodiscard]] detail::ScopeExitRunner<std::decay_t<Fn>>
47+
make_scope_exit(Fn &&F) {
48+
return detail::ScopeExitRunner<std::decay_t<Fn>>(std::forward<Fn>(F));
49+
}
50+
51+
} // namespace orc_rt
52+
53+
#endif // ORC_RT_SCOPEEXIT_H

orc-rt/unittests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ add_orc_rt_unittest(CoreTests
2121
MathTest.cpp
2222
MemoryFlagsTest.cpp
2323
RTTITest.cpp
24+
ScopeExitTest.cpp
2425
SimplePackedSerializationTest.cpp
2526
SPSWrapperFunctionTest.cpp
2627
WrapperFunctionBufferTest.cpp

orc-rt/unittests/ScopeExitTest.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//===- ScopeExitTest.cpp --------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Tests for orc-rt's ScopeExit.h APIs.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "orc-rt/ScopeExit.h"
14+
#include "gtest/gtest.h"
15+
16+
using namespace orc_rt;
17+
18+
TEST(ScopeExitTest, Noop) {
19+
auto _ = make_scope_exit([]() {});
20+
}
21+
22+
TEST(ScopeExitTest, OnScopeExit) {
23+
bool ScopeExitRun = false;
24+
{
25+
auto _ = make_scope_exit([&]() { ScopeExitRun = true; });
26+
EXPECT_FALSE(ScopeExitRun);
27+
}
28+
EXPECT_TRUE(ScopeExitRun);
29+
}
30+
31+
TEST(ScopeExitTest, Release) {
32+
bool ScopeExitRun = false;
33+
{
34+
auto OnExit = make_scope_exit([&]() { ScopeExitRun = true; });
35+
EXPECT_FALSE(ScopeExitRun);
36+
OnExit.release();
37+
}
38+
EXPECT_FALSE(ScopeExitRun);
39+
}

0 commit comments

Comments
 (0)