[Orc] Handle hangup messages in SimpleRemoteEPC

On the controller-side, handle `Hangup` messages from the executor. The executor passed `Error::success()` or a failure message as payload.

Hangups cause an immediate disconnect of the transport layer. The disconnect function may be called later again and so implementations should be prepared. `FDSimpleRemoteEPCTransport::disconnect()` already has a flag to check that:
cd1bd95d87/llvm/lib/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.cpp (L112)

Reviewed By: lhames

Differential Revision: https://reviews.llvm.org/D111527
This commit is contained in:
Stefan Gränitz 2021-10-11 20:37:47 +02:00
parent ec2d0ded1b
commit a6c9506365
3 changed files with 20 additions and 3 deletions

View File

@ -94,7 +94,7 @@ public:
/// Trigger disconnection from the transport. The implementation should
/// respond by calling handleDisconnect on the client once disconnection
/// is complete.
/// is complete. May be called more than once and from different threads.
virtual void disconnect() = 0;
};

View File

@ -96,6 +96,7 @@ private:
SimpleRemoteEPCArgBytesVector ArgBytes);
void handleCallWrapper(uint64_t RemoteSeqNo, ExecutorAddr TagAddr,
SimpleRemoteEPCArgBytesVector ArgBytes);
Error handleHangup(SimpleRemoteEPCArgBytesVector ArgBytes);
uint64_t getNextSeqNo() { return NextSeqNo++; }
void releaseSeqNo(uint64_t SeqNo) {}

View File

@ -121,8 +121,10 @@ SimpleRemoteEPC::handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
return std::move(Err);
break;
case SimpleRemoteEPCOpcode::Hangup:
return make_error<StringError>("Unexpected Hangup opcode",
inconvertibleErrorCode());
T->disconnect();
if (auto Err = handleHangup(std::move(ArgBytes)))
return std::move(Err);
return EndSession;
case SimpleRemoteEPCOpcode::Result:
if (auto Err = handleResult(SeqNo, TagAddr, std::move(ArgBytes)))
return std::move(Err);
@ -354,5 +356,19 @@ void SimpleRemoteEPC::handleCallWrapper(
TagAddr.getValue(), ArgBytes);
}
Error SimpleRemoteEPC::handleHangup(SimpleRemoteEPCArgBytesVector ArgBytes) {
using namespace llvm::orc::shared;
auto WFR = WrapperFunctionResult::copyFrom(ArgBytes.data(), ArgBytes.size());
if (const char *ErrMsg = WFR.getOutOfBandError())
return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
detail::SPSSerializableError Info;
SPSInputBuffer IB(WFR.data(), WFR.size());
if (!SPSArgList<SPSError>::deserialize(IB, Info))
return make_error<StringError>("Could not deserialize hangup info",
inconvertibleErrorCode());
return fromSPSSerializable(std::move(Info));
}
} // end namespace orc
} // end namespace llvm