Skip to content

Commit

Permalink
[ORC] Propagate errors to handlers when sendMessage fails.
Browse files Browse the repository at this point in the history
In SimpleRemoteEPC, calls to from callWrapperAsync to sendMessage may fail.
The handlers may or may not be sent failure messages by handleDisconnect,
depending on when that method is run. This patch adds a check for an un-failed
handler, and if it finds one sends it a failure message.
  • Loading branch information
lhames committed Oct 11, 2021
1 parent 4fc2a4c commit 17a0858
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 0 deletions.
Expand Up @@ -49,6 +49,7 @@ class ExecutorProcessControl {
friend class ExecutorProcessControl;
public:
IncomingWFRHandler() = default;
explicit operator bool() const { return !!H; }
void operator()(shared::WrapperFunctionResult WFR) { H(std::move(WFR)); }
private:
template <typename FnT> IncomingWFRHandler(FnT &&Fn)
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.cpp
Expand Up @@ -238,6 +238,11 @@ void FDSimpleRemoteEPCTransport::listenLoop() {
}
} while (true);

// Attempt to close FDs, set Disconnected to true so that subsequent
// sendMessage calls fail.
disconnect();

// Call up to the client to handle the disconnection.
C.handleDisconnect(std::move(Err));
}

Expand Down
19 changes: 19 additions & 0 deletions llvm/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp
Expand Up @@ -67,6 +67,25 @@ void SimpleRemoteEPC::callWrapperAsync(ExecutorAddr WrapperFnAddr,

if (auto Err = sendMessage(SimpleRemoteEPCOpcode::CallWrapper, SeqNo,
WrapperFnAddr, ArgBuffer)) {
IncomingWFRHandler H;

// We just registered OnComplete, but there may be a race between this
// thread returning from sendMessage and handleDisconnect being called from
// the transport's listener thread. If handleDisconnect gets there first
// then it will have failed 'H' for us. If we get there first (or if
// handleDisconnect already ran) then we need to take care of it.
{
std::lock_guard<std::mutex> Lock(SimpleRemoteEPCMutex);
auto I = PendingCallWrapperResults.find(SeqNo);
if (I != PendingCallWrapperResults.end()) {
H = std::move(I->second);
PendingCallWrapperResults.erase(I);
}
}

if (H)
H(shared::WrapperFunctionResult::createOutOfBandError("disconnecting"));

getExecutionSession().reportError(std::move(Err));
}
}
Expand Down

0 comments on commit 17a0858

Please sign in to comment.