[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