[llvm] [orc-rt] Make more Session callbacks noexcept. (PR #226385)
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 25 01:54:05 PDT 2026
https://github.com/lhames updated https://github.com/llvm/llvm-project/pull/226385
>From 2f539a4452a3d5a886499be7662643da83cc4e9a Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Fri, 25 Sep 2026 17:13:59 +1000
Subject: [PATCH] [orc-rt] Make more Session callbacks noexcept.
Session's OnDisconnectFn, OnDetachFn, and OnShutdownFn callbacks should
not throw exceptions.
---
orc-rt/include/orc-rt/bedrock/Session.h | 6 +--
orc-rt/lib/bedrock/NativeDylibManager.cpp | 2 +-
orc-rt/test/unit/CommonTestUtils.h | 11 +++--
orc-rt/test/unit/bedrock/SessionTest.cpp | 43 ++++++++++---------
.../sps/SimpleRemoteCAOverSocketTest.cpp | 2 +-
.../unit/bedrock/sps/SimpleRemoteCATest.cpp | 10 ++---
orc-rt/tools/ogre/ogre.cpp | 2 +-
7 files changed, 41 insertions(+), 35 deletions(-)
diff --git a/orc-rt/include/orc-rt/bedrock/Session.h b/orc-rt/include/orc-rt/bedrock/Session.h
index 66128643d3f0ca..d9bc61359ccc6d 100644
--- a/orc-rt/include/orc-rt/bedrock/Session.h
+++ b/orc-rt/include/orc-rt/bedrock/Session.h
@@ -72,9 +72,9 @@ class Session {
public:
using ErrorReporterFn = move_only_function<void(Error) noexcept>;
- using OnDisconnectFn = move_only_function<void(Error)>;
- using OnDetachFn = move_only_function<void()>;
- using OnShutdownFn = move_only_function<void()>;
+ using OnDisconnectFn = move_only_function<void(Error) noexcept>;
+ using OnDetachFn = move_only_function<void() noexcept>;
+ using OnShutdownFn = move_only_function<void() noexcept>;
/// Return value callback used to return results from callController.
using OnControllerCallReturnFn =
diff --git a/orc-rt/lib/bedrock/NativeDylibManager.cpp b/orc-rt/lib/bedrock/NativeDylibManager.cpp
index d26f92e24851ec..72201d3866dafe 100644
--- a/orc-rt/lib/bedrock/NativeDylibManager.cpp
+++ b/orc-rt/lib/bedrock/NativeDylibManager.cpp
@@ -50,7 +50,7 @@ void NativeDylibManager::load(OnLoadCompleteFn &&OnComplete, std::string Path) {
// Capture S by reference, rather than this, so that the callback remains
// valid even if the NativeDylibManager is destroyed prior to shutdown.
- S.addOnShutdown([&S = this->S, Handle = *H]() {
+ S.addOnShutdown([&S = this->S, Handle = *H]() noexcept {
if (auto Err = sys::unloadLibrary(Handle))
S.reportError(std::move(Err));
});
diff --git a/orc-rt/test/unit/CommonTestUtils.h b/orc-rt/test/unit/CommonTestUtils.h
index 7bbe91d982a22a..a54a2055c29e15 100644
--- a/orc-rt/test/unit/CommonTestUtils.h
+++ b/orc-rt/test/unit/CommonTestUtils.h
@@ -100,16 +100,19 @@ template <size_t Idx> size_t OpCounter<Idx>::MoveConstructions = 0;
template <size_t Idx> size_t OpCounter<Idx>::MoveAssignments = 0;
template <size_t Idx> size_t OpCounter<Idx>::Destructions = 0;
-template <typename T> move_only_function<void(T)> waitFor(std::future<T> &F) {
+template <typename T>
+move_only_function<void(T) noexcept> waitFor(std::future<T> &F) {
std::promise<T> P;
F = P.get_future();
- return [P = std::move(P)](T Val) mutable { P.set_value(std::move(Val)); };
+ return [P = std::move(P)](T Val) mutable noexcept {
+ P.set_value(std::move(Val));
+ };
}
-inline move_only_function<void()> waitFor(std::future<void> &F) {
+inline move_only_function<void() noexcept> waitFor(std::future<void> &F) {
std::promise<void> P;
F = P.get_future();
- return [P = std::move(P)]() mutable { P.set_value(); };
+ return [P = std::move(P)]() mutable noexcept { P.set_value(); };
}
} // namespace orc_rt::test
diff --git a/orc-rt/test/unit/bedrock/SessionTest.cpp b/orc-rt/test/unit/bedrock/SessionTest.cpp
index 41fc8738696e0a..493249ad556896 100644
--- a/orc-rt/test/unit/bedrock/SessionTest.cpp
+++ b/orc-rt/test/unit/bedrock/SessionTest.cpp
@@ -327,7 +327,7 @@ inline MockControllerAccess::PostFn postOnto(QueueingRunner<>::WorkQueue &Q) {
void waitForShutdown(Session &S) {
std::promise<void> P;
auto F = P.get_future();
- S.shutdown([P = std::move(P)]() mutable { P.set_value(); });
+ S.shutdown([P = std::move(P)]() mutable noexcept { P.set_value(); });
F.get();
}
@@ -404,10 +404,10 @@ TEST(SessionTest, ScheduleShutdownFromOnDetachHandler) {
int OnDetachHandlersRun = 0;
bool OnShutdownHandlerRun = false;
- S.addOnDetach([&]() { ++OnDetachHandlersRun; });
- S.addOnDetach([&]() { S.shutdown(); });
- S.addOnDetach([&]() { ++OnDetachHandlersRun; });
- S.addOnShutdown([&]() {
+ S.addOnDetach([&]() noexcept { ++OnDetachHandlersRun; });
+ S.addOnDetach([&]() noexcept { S.shutdown(); });
+ S.addOnDetach([&]() noexcept { ++OnDetachHandlersRun; });
+ S.addOnShutdown([&]() noexcept {
EXPECT_EQ(OnDetachHandlersRun, 2);
OnShutdownHandlerRun = true;
});
@@ -428,7 +428,7 @@ TEST(SessionTest, RedundantAsyncShutdown) {
// Now try to add a new on-shutdown callback and verify that it runs.
bool RedundantCallbackRan = false;
- S.shutdown([&]() { RedundantCallbackRan = true; });
+ S.shutdown([&]() noexcept { RedundantCallbackRan = true; });
EXPECT_TRUE(RedundantCallbackRan);
}
@@ -448,7 +448,7 @@ TEST(SessionTest, ExpectedShutdownSequenceWithNoOutstandingKeepalives) {
S.addService(
std::make_unique<MockService>(DetachOpIdx, ShutdownOpIdx, OpIdx));
- S.shutdown([&]() {
+ S.shutdown([&]() noexcept {
EXPECT_TRUE(ShutdownOpIdx);
EXPECT_EQ(*ShutdownOpIdx, 1);
SessionShutdownComplete = true;
@@ -476,7 +476,7 @@ TEST(SessionTest, OutstandingKeepalivesDelayShutdown) {
// We expect shutdown to wait for any outstanding keepalives to be released.
bool ShutdownComplete = false;
- S.shutdown([&]() { ShutdownComplete = true; });
+ S.shutdown([&]() noexcept { ShutdownComplete = true; });
// Detach should have happened, but shutdown should be waiting on token.
EXPECT_EQ(DetachOpIdx, 0U);
@@ -846,7 +846,7 @@ TEST(ControllerAccessTest, WrapperCallTokenReleasedWhenFnReturns) {
// drain phase should therefore complete without waiting on the deferred
// Return call.
bool ShutdownComplete = false;
- S.shutdown([&] { ShutdownComplete = true; });
+ S.shutdown([&]() noexcept { ShutdownComplete = true; });
EXPECT_TRUE(ShutdownComplete);
}
@@ -1008,7 +1008,7 @@ TEST(ControllerAccessTest, OnDisconnectReportsOrderlyDisconnect) {
size_t HandlerRuns = 0;
std::string ErrMsg = "<not run>";
Session S(mockExecutorProcessInfo(), noDispatch, noErrors);
- S.setOnDisconnect([&](Error Err) {
+ S.setOnDisconnect([&](Error Err) noexcept {
++HandlerRuns;
ErrMsg = errMsgOrEmpty(std::move(Err));
});
@@ -1024,7 +1024,8 @@ TEST(ControllerAccessTest, OnDisconnectReportsAbnormalDisconnect) {
// An abnormal disconnection reports the ControllerAccess's Error unchanged.
std::optional<std::string> ErrMsg;
Session S(mockExecutorProcessInfo(), noDispatch, noErrors);
- S.setOnDisconnect([&](Error Err) { ErrMsg = errMsgOrEmpty(std::move(Err)); });
+ S.setOnDisconnect(
+ [&](Error Err) noexcept { ErrMsg = errMsgOrEmpty(std::move(Err)); });
S.attach<DisconnectingControllerAccess>(BootstrapInfo(S),
"connection closed without hangup");
@@ -1065,8 +1066,9 @@ TEST(ControllerAccessTest, OnDisconnectSuppressesErrorReporterRouting) {
std::vector<std::string> ErrMsgs;
std::optional<std::string> HandlerErrMsg;
Session S(mockExecutorProcessInfo(), noDispatch, AccumulateErrors(ErrMsgs));
- S.setOnDisconnect(
- [&](Error Err) { HandlerErrMsg = errMsgOrEmpty(std::move(Err)); });
+ S.setOnDisconnect([&](Error Err) noexcept {
+ HandlerErrMsg = errMsgOrEmpty(std::move(Err));
+ });
S.attach<DisconnectingControllerAccess>(BootstrapInfo(S),
"connection closed without hangup");
@@ -1088,7 +1090,8 @@ TEST(ControllerAccessTest, OnDisconnectReportsConnectFailure) {
// would still pass if a failed connect were reported as success.
std::optional<std::string> ErrMsg;
Session S(mockExecutorProcessInfo(), noDispatch, noErrors);
- S.setOnDisconnect([&](Error Err) { ErrMsg = errMsgOrEmpty(std::move(Err)); });
+ S.setOnDisconnect(
+ [&](Error Err) noexcept { ErrMsg = errMsgOrEmpty(std::move(Err)); });
S.attach<MockControllerAccess>(
BootstrapInfo(S), MockControllerAccess::PostFn{},
@@ -1110,7 +1113,7 @@ TEST(ControllerAccessTest, OnDisconnectReportsSuccessWithoutAttach) {
std::string ErrMsg = "<not run>";
{
Session S(mockExecutorProcessInfo(), noDispatch, noErrors);
- S.setOnDisconnect([&](Error Err) {
+ S.setOnDisconnect([&](Error Err) noexcept {
++HandlerRuns;
ErrMsg = errMsgOrEmpty(std::move(Err));
});
@@ -1130,7 +1133,7 @@ TEST(ControllerAccessTest, OnDisconnectRunsBeforeDetachAndShutdown) {
{
Session S(mockExecutorProcessInfo(), noDispatch, noErrors);
- S.setOnDisconnect([&](Error Err) {
+ S.setOnDisconnect([&](Error Err) noexcept {
DisconnectOpIdx = OpIdx++;
cantFail(std::move(Err));
});
@@ -1161,9 +1164,9 @@ TEST(ControllerAccessTest, ShutdownFromOnDisconnectHandler) {
Session S(mockExecutorProcessInfo(), noDispatch, noErrors);
S.addService(
std::make_unique<MockService>(DetachOpIdx, ShutdownOpIdx, OpIdx));
- S.setOnDisconnect([&](Error Err) {
+ S.setOnDisconnect([&](Error Err) noexcept {
cantFail(std::move(Err));
- S.shutdown([&]() { OnShutdownRan = true; });
+ S.shutdown([&]() noexcept { OnShutdownRan = true; });
});
S.attach<DisconnectingControllerAccess>(BootstrapInfo(S));
@@ -1192,9 +1195,9 @@ TEST(ControllerAccessTest, ShutdownFromOnDisconnectHandlerAfterRemoteHangup) {
Session S(mockExecutorProcessInfo(), noDispatch, noErrors);
S.addService(
std::make_unique<MockService>(DetachOpIdx, ShutdownOpIdx, OpIdx));
- S.setOnDisconnect([&](Error Err) {
+ S.setOnDisconnect([&](Error Err) noexcept {
cantFail(std::move(Err));
- S.shutdown([&]() { OnShutdownRan = true; });
+ S.shutdown([&]() noexcept { OnShutdownRan = true; });
});
S.attach<DisconnectingControllerAccess>(BootstrapInfo(S), "", &CA);
ASSERT_TRUE(CA);
diff --git a/orc-rt/test/unit/bedrock/sps/SimpleRemoteCAOverSocketTest.cpp b/orc-rt/test/unit/bedrock/sps/SimpleRemoteCAOverSocketTest.cpp
index 48b5214ecd5939..aece4eac1c647c 100644
--- a/orc-rt/test/unit/bedrock/sps/SimpleRemoteCAOverSocketTest.cpp
+++ b/orc-rt/test/unit/bedrock/sps/SimpleRemoteCAOverSocketTest.cpp
@@ -539,7 +539,7 @@ TEST_F(SimpleRemoteCAOverSocketTest, NothingIsQueuedBehindTheHangup) {
// Queues the hang-up and latches the queue. Returns without waiting for the
// reactor, which is still stalled.
- S.detach([] {});
+ S.detach();
// Too late: this must not reach the wire.
DeferredReturn(Deferred.S, Deferred.ArgBytes, Deferred.CallId);
diff --git a/orc-rt/test/unit/bedrock/sps/SimpleRemoteCATest.cpp b/orc-rt/test/unit/bedrock/sps/SimpleRemoteCATest.cpp
index f434575b10b307..4f4d6c253d72bf 100644
--- a/orc-rt/test/unit/bedrock/sps/SimpleRemoteCATest.cpp
+++ b/orc-rt/test/unit/bedrock/sps/SimpleRemoteCATest.cpp
@@ -133,7 +133,7 @@ TEST(SimpleRemoteCATest, SetupMessageRoundTrips) {
// controller would be left to interpret.
EXPECT_EQ(static_cast<size_t>(IB.data() - Payload.data()), Payload.size());
- S.detach([] {});
+ S.detach();
}
TEST(SimpleRemoteCATest, MessageHeaderRoundTrips) {
@@ -245,7 +245,7 @@ TEST(SimpleRemoteCATest, ResultWithAnUnknownKindIsRejected) {
EXPECT_EQ(toString(A.takeError()),
"Malformed result message: invalid kind 2");
- S.detach([] {});
+ S.detach();
}
TEST(SimpleRemoteCATest, DecodeResultOfMalformedOutOfBandErrorIsNotTerminal) {
@@ -274,7 +274,7 @@ TEST(SimpleRemoteCATest, RegisterCallReturnsDistinctNonZeroSequenceNumbers) {
EXPECT_NE(Second, 0u);
EXPECT_NE(First, Second);
- S.detach([] {});
+ S.detach();
}
TEST(SimpleRemoteCATest, TakeCallYieldsTheHandlerExactlyOnce) {
@@ -293,7 +293,7 @@ TEST(SimpleRemoteCATest, TakeCallYieldsTheHandlerExactlyOnce) {
EXPECT_FALSE(!!CA->takeCall(/*SeqNo=*/9999)) << "never registered";
CA->failPendingControllerCall(std::move(Taken));
- S.detach([] {});
+ S.detach();
}
TEST(SimpleRemoteCATest, TakeAllCallsEmptiesTheTable) {
@@ -316,5 +316,5 @@ TEST(SimpleRemoteCATest, TakeAllCallsEmptiesTheTable) {
for (auto &[SeqNo, OnComplete] : All)
CA->failPendingControllerCall(std::move(OnComplete));
- S.detach([] {});
+ S.detach();
}
diff --git a/orc-rt/tools/ogre/ogre.cpp b/orc-rt/tools/ogre/ogre.cpp
index 1fbef3087e79c9..c98da66fba3194 100644
--- a/orc-rt/tools/ogre/ogre.cpp
+++ b/orc-rt/tools/ogre/ogre.cpp
@@ -140,7 +140,7 @@ Expected<int> runOgre(const Options &Opts) noexcept {
std::promise<void> StopP;
auto StopF = StopP.get_future();
- S.setOnDisconnect([StopP = std::move(StopP)](Error Err) mutable {
+ S.setOnDisconnect([StopP = std::move(StopP)](Error Err) mutable noexcept {
if (Err)
reportError(std::move(Err));
StopP.set_value();
More information about the llvm-commits
mailing list