diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h --- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h @@ -94,7 +94,7 @@ /// 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; }; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h b/llvm/include/llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h --- a/llvm/include/llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h @@ -96,6 +96,7 @@ 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) {} diff --git a/llvm/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp b/llvm/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp --- a/llvm/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp +++ b/llvm/lib/ExecutionEngine/Orc/SimpleRemoteEPC.cpp @@ -121,8 +121,10 @@ return std::move(Err); break; case SimpleRemoteEPCOpcode::Hangup: - return make_error("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 @@ 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(ErrMsg, inconvertibleErrorCode()); + + detail::SPSSerializableError Info; + SPSInputBuffer IB(WFR.data(), WFR.size()); + if (!SPSArgList::deserialize(IB, Info)) + return make_error("Could not deserialize hangup info", + inconvertibleErrorCode()); + return fromSPSSerializable(std::move(Info)); +} + } // end namespace orc } // end namespace llvm