[llvm] r300155 - [ORC] Use native Errors rather than converted std::error_codes for ORC RPC.
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 12 18:03:07 PDT 2017
Author: lhames
Date: Wed Apr 12 20:03:06 2017
New Revision: 300155
URL: http://llvm.org/viewvc/llvm-project?rev=300155&view=rev
Log:
[ORC] Use native Errors rather than converted std::error_codes for ORC RPC.
Modified:
llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcError.h
llvm/trunk/include/llvm/ExecutionEngine/Orc/RPCUtils.h
llvm/trunk/include/llvm/Support/Error.h
llvm/trunk/lib/ExecutionEngine/Orc/CMakeLists.txt
llvm/trunk/lib/ExecutionEngine/Orc/OrcError.cpp
llvm/trunk/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp
Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcError.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcError.h?rev=300155&r1=300154&r2=300155&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcError.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcError.h Wed Apr 12 20:03:06 2017
@@ -27,26 +27,15 @@ enum class OrcErrorCode : int {
RemoteMProtectAddrUnrecognized,
RemoteIndirectStubsOwnerDoesNotExist,
RemoteIndirectStubsOwnerIdAlreadyInUse,
+ RPCConnectionClosed,
+ RPCCouldNotNegotiateFunction,
RPCResponseAbandoned,
UnexpectedRPCCall,
UnexpectedRPCResponse,
- UnknownRPCFunction
};
std::error_code orcError(OrcErrorCode ErrCode);
-class RPCFunctionNotSupported : public ErrorInfo<RPCFunctionNotSupported> {
-public:
- static char ID;
-
- RPCFunctionNotSupported(std::string RPCFunctionSignature);
- std::error_code convertToErrorCode() const override;
- void log(raw_ostream &OS) const override;
- const std::string &getFunctionSignature() const;
-private:
- std::string RPCFunctionSignature;
-};
-
} // End namespace orc.
} // End namespace llvm.
Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/RPCUtils.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/RPCUtils.h?rev=300155&r1=300154&r2=300155&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/RPCUtils.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/RPCUtils.h Wed Apr 12 20:03:06 2017
@@ -32,6 +32,109 @@ namespace llvm {
namespace orc {
namespace rpc {
+/// Base class of all fatal RPC errors (those that necessarily result in the
+/// termination of the RPC session).
+class RPCFatalError : public ErrorInfo<RPCFatalError> {
+public:
+ static char ID;
+};
+
+/// RPCConnectionClosed is returned from RPC operations if the RPC connection
+/// has already been closed due to either an error or graceful disconnection.
+class ConnectionClosed : public ErrorInfo<ConnectionClosed> {
+public:
+ static char ID;
+ std::error_code convertToErrorCode() const override;
+ void log(raw_ostream &OS) const override;
+};
+
+/// BadFunctionCall is returned from handleOne when the remote makes a call with
+/// an unrecognized function id.
+///
+/// This error is fatal because Orc RPC needs to know how to parse a function
+/// call to know where the next call starts, and if it doesn't recognize the
+/// function id it cannot parse the call.
+template <typename FnIdT, typename SeqNoT>
+class BadFunctionCall
+ : public ErrorInfo<BadFunctionCall<FnIdT, SeqNoT>, RPCFatalError> {
+public:
+ static char ID;
+
+ BadFunctionCall(FnIdT FnId, SeqNoT SeqNo)
+ : FnId(std::move(FnId)), SeqNo(std::move(SeqNo)) {}
+
+ std::error_code convertToErrorCode() const override {
+ return orcError(OrcErrorCode::UnexpectedRPCCall);
+ }
+
+ void log(raw_ostream &OS) const override {
+ OS << "Call to invalid RPC function id '" << FnId << "' with "
+ "sequence number " << SeqNo;
+ }
+
+private:
+ FnIdT FnId;
+ SeqNoT SeqNo;
+};
+
+template <typename FnIdT, typename SeqNoT>
+char BadFunctionCall<FnIdT, SeqNoT>::ID = 0;
+
+/// InvalidSequenceNumberForResponse is returned from handleOne when a response
+/// call arrives with a sequence number that doesn't correspond to any in-flight
+/// function call.
+///
+/// This error is fatal because Orc RPC needs to know how to parse the rest of
+/// the response call to know where the next call starts, and if it doesn't have
+/// a result parser for this sequence number it can't do that.
+template <typename SeqNoT>
+class InvalidSequenceNumberForResponse
+ : public ErrorInfo<InvalidSequenceNumberForResponse<SeqNoT>, RPCFatalError> {
+public:
+ static char ID;
+
+ InvalidSequenceNumberForResponse(SeqNoT SeqNo)
+ : SeqNo(std::move(SeqNo)) {}
+
+ std::error_code convertToErrorCode() const override {
+ return orcError(OrcErrorCode::UnexpectedRPCCall);
+ };
+
+ void log(raw_ostream &OS) const override {
+ OS << "Response has unknown sequence number " << SeqNo;
+ }
+private:
+ SeqNoT SeqNo;
+};
+
+template <typename SeqNoT>
+char InvalidSequenceNumberForResponse<SeqNoT>::ID = 0;
+
+/// This non-fatal error will be passed to asynchronous result handlers in place
+/// of a result if the connection goes down before a result returns, or if the
+/// function to be called cannot be negotiated with the remote.
+class ResponseAbandoned : public ErrorInfo<ResponseAbandoned> {
+public:
+ static char ID;
+
+ std::error_code convertToErrorCode() const override;
+ void log(raw_ostream &OS) const override;
+};
+
+/// This error is returned if the remote does not have a handler installed for
+/// the given RPC function.
+class CouldNotNegotiate : public ErrorInfo<CouldNotNegotiate> {
+public:
+ static char ID;
+
+ CouldNotNegotiate(std::string Signature);
+ std::error_code convertToErrorCode() const override;
+ void log(raw_ostream &OS) const override;
+ const std::string &getSignature() const { return Signature; }
+private:
+ std::string Signature;
+};
+
template <typename DerivedFunc, typename FnT> class Function;
// RPC Function class.
@@ -500,7 +603,7 @@ public:
// Create an error instance representing an abandoned response.
static Error createAbandonedResponseError() {
- return errorCodeToError(orcError(OrcErrorCode::RPCResponseAbandoned));
+ return make_error<ResponseAbandoned>();
}
};
@@ -814,12 +917,9 @@ public:
if (auto FnIdOrErr = getRemoteFunctionId<Func>(LazyAutoNegotiation, false))
FnId = *FnIdOrErr;
else {
- // This isn't a channel error so we don't want to abandon other pending
- // responses, but we still need to run the user handler with an error to
- // let them know the call failed.
- if (auto Err = Handler(errorCodeToError(
- orcError(OrcErrorCode::UnknownRPCFunction))))
- report_fatal_error(std::move(Err));
+ // Negotiation failed. Notify the handler then return the negotiate-failed
+ // error.
+ cantFail(Handler(make_error<ResponseAbandoned>()));
return FnIdOrErr.takeError();
}
@@ -885,7 +985,8 @@ public:
return I->second(C, SeqNo);
// else: No handler found. Report error to client?
- return errorCodeToError(orcError(OrcErrorCode::UnexpectedRPCCall));
+ return make_error<BadFunctionCall<FunctionIdT, SequenceNumberT>>(FnId,
+ SeqNo);
}
/// Helper for handling setter procedures - this method returns a functor that
@@ -995,7 +1096,8 @@ protected:
// Unlock the pending results map to prevent recursive lock.
Lock.unlock();
abandonPendingResponses();
- return errorCodeToError(orcError(OrcErrorCode::UnexpectedRPCResponse));
+ return make_error<
+ InvalidSequenceNumberForResponse<SequenceNumberT>>(SeqNo);
}
}
@@ -1041,7 +1143,7 @@ protected:
Impl.template callB<OrcRPCNegotiate>(Func::getPrototype())) {
RemoteFunctionIds[Func::getPrototype()] = *RemoteIdOrErr;
if (*RemoteIdOrErr == getInvalidFunctionId())
- return make_error<RPCFunctionNotSupported>(Func::getPrototype());
+ return make_error<CouldNotNegotiate>(Func::getPrototype());
return *RemoteIdOrErr;
} else
return RemoteIdOrErr.takeError();
@@ -1049,7 +1151,7 @@ protected:
// No key was available in the map and we weren't allowed to try to
// negotiate one, so return an unknown function error.
- return make_error<RPCFunctionNotSupported>(Func::getPrototype());
+ return make_error<CouldNotNegotiate>(Func::getPrototype());
}
using WrappedHandlerFn = std::function<Error(ChannelT &, SequenceNumberT)>;
Modified: llvm/trunk/include/llvm/Support/Error.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Error.h?rev=300155&r1=300154&r2=300155&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/Error.h (original)
+++ llvm/trunk/include/llvm/Support/Error.h Wed Apr 12 20:03:06 2017
@@ -64,6 +64,12 @@ public:
/// using std::error_code. It will be removed in the future.
virtual std::error_code convertToErrorCode() const = 0;
+ // Returns the class ID for this type.
+ static const void *classID() { return &ID; }
+
+ // Returns the class ID for the dynamic type of this ErrorInfoBase instance.
+ virtual const void *dynamicClassID() const = 0;
+
// Check whether this instance is a subclass of the class identified by
// ClassID.
virtual bool isA(const void *const ClassID) const {
@@ -75,9 +81,6 @@ public:
return isA(ErrorInfoT::classID());
}
- // Returns the class ID for this type.
- static const void *classID() { return &ID; }
-
private:
virtual void anchor();
@@ -316,11 +319,14 @@ template <typename ErrT, typename... Arg
template <typename ThisErrT, typename ParentErrT = ErrorInfoBase>
class ErrorInfo : public ParentErrT {
public:
+
+ static const void *classID() { return &ThisErrT::ID; }
+
+ const void *dynamicClassID() const override { return &ThisErrT::ID; }
+
bool isA(const void *const ClassID) const override {
return ClassID == classID() || ParentErrT::isA(ClassID);
}
-
- static const void *classID() { return &ThisErrT::ID; }
};
/// Special ErrorInfo subclass representing a list of ErrorInfos.
@@ -926,6 +932,8 @@ public:
void log(raw_ostream &OS) const override;
std::error_code convertToErrorCode() const override;
+ const std::string &getMessage() const { return Msg; }
+
private:
std::string Msg;
std::error_code EC;
Modified: llvm/trunk/lib/ExecutionEngine/Orc/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/CMakeLists.txt?rev=300155&r1=300154&r2=300155&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/CMakeLists.txt (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/CMakeLists.txt Wed Apr 12 20:03:06 2017
@@ -6,6 +6,7 @@ add_llvm_library(LLVMOrcJIT
OrcCBindings.cpp
OrcError.cpp
OrcMCJITReplacement.cpp
+ RPCUtils.cpp
ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm/ExecutionEngine/Orc
Modified: llvm/trunk/lib/ExecutionEngine/Orc/OrcError.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcError.cpp?rev=300155&r1=300154&r2=300155&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Orc/OrcError.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Orc/OrcError.cpp Wed Apr 12 20:03:06 2017
@@ -39,14 +39,16 @@ public:
return "Remote indirect stubs owner does not exist";
case OrcErrorCode::RemoteIndirectStubsOwnerIdAlreadyInUse:
return "Remote indirect stubs owner Id already in use";
+ case OrcErrorCode::RPCConnectionClosed:
+ return "RPC connection closed";
+ case OrcErrorCode::RPCCouldNotNegotiateFunction:
+ return "Could not negotiate RPC function";
case OrcErrorCode::RPCResponseAbandoned:
return "RPC response abandoned";
case OrcErrorCode::UnexpectedRPCCall:
return "Unexpected RPC call";
case OrcErrorCode::UnexpectedRPCResponse:
return "Unexpected RPC response";
- case OrcErrorCode::UnknownRPCFunction:
- return "Unknown RPC function";
}
llvm_unreachable("Unhandled error code");
}
@@ -58,27 +60,10 @@ static ManagedStatic<OrcErrorCategory> O
namespace llvm {
namespace orc {
-char RPCFunctionNotSupported::ID = 0;
-
std::error_code orcError(OrcErrorCode ErrCode) {
typedef std::underlying_type<OrcErrorCode>::type UT;
return std::error_code(static_cast<UT>(ErrCode), *OrcErrCat);
}
-RPCFunctionNotSupported::RPCFunctionNotSupported(std::string RPCFunctionSignature)
- : RPCFunctionSignature(std::move(RPCFunctionSignature)) {}
-
-std::error_code RPCFunctionNotSupported::convertToErrorCode() const {
- return orcError(OrcErrorCode::UnknownRPCFunction);
-}
-
-void RPCFunctionNotSupported::log(raw_ostream &OS) const {
- OS << "Could not negotiate RPC function '" << RPCFunctionSignature << "'";
-}
-
-const std::string &RPCFunctionNotSupported::getFunctionSignature() const {
- return RPCFunctionSignature;
-}
-
}
}
Modified: llvm/trunk/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp?rev=300155&r1=300154&r2=300155&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp Wed Apr 12 20:03:06 2017
@@ -604,10 +604,10 @@ TEST(DummyRPC, TestAPICalls) {
{
auto Err = DummyCallsAll::negotiate(Client);
- EXPECT_EQ(errorToErrorCode(std::move(Err)).value(),
- static_cast<int>(OrcErrorCode::UnknownRPCFunction))
- << "Expected 'UnknownRPCFunction' error for attempted negotiate of "
+ EXPECT_TRUE(Err.isA<CouldNotNegotiate>())
+ << "Expected CouldNotNegotiate error for attempted negotiate of "
"unsupported function";
+ consumeError(std::move(Err));
}
ServerThread.join();
More information about the llvm-commits
mailing list