OSDN Git Service

[Orc][RPC] Add a AsyncHandlerTraits specialization for non-value-type response
authorLang Hames <lhames@gmail.com>
Wed, 15 Feb 2017 05:39:35 +0000 (05:39 +0000)
committerLang Hames <lhames@gmail.com>
Wed, 15 Feb 2017 05:39:35 +0000 (05:39 +0000)
handler args.

The specialization just inherits from the std::decay'd response handler type.
This allows member functions (via MemberFunctionWrapper) to be used as async
handlers.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@295151 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ExecutionEngine/Orc/RPCUtils.h
unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp

index 8119494..38ebd5d 100644 (file)
@@ -339,6 +339,8 @@ public:
   using Type = Error;
 };
 
+// Traits class that strips the response function from the list of handler
+// arguments.
 template <typename FnT> class AsyncHandlerTraits;
 
 template <typename ResultT, typename... ArgTs>
@@ -355,6 +357,11 @@ public:
   using ResultType = Error;
 };
 
+template <typename ResponseHandlerT, typename... ArgTs>
+class AsyncHandlerTraits<Error(ResponseHandlerT, ArgTs...)> :
+    public AsyncHandlerTraits<Error(typename std::decay<ResponseHandlerT>::type,
+                                    ArgTs...)> {};
+
 // This template class provides utilities related to RPC function handlers.
 // The base case applies to non-function types (the template class is
 // specialized for function types) and inherits from the appropriate
index 91cec1c..f1fce9d 100644 (file)
@@ -289,6 +289,57 @@ TEST(DummyRPC, TestAsyncIntIntHandler) {
   ServerThread.join();
 }
 
+TEST(DummyRPC, TestAsyncIntIntHandlerMethod) {
+  Queue Q1, Q2;
+  DummyRPCEndpoint Client(Q1, Q2);
+  DummyRPCEndpoint Server(Q2, Q1);
+
+  class Dummy {
+  public:
+    Error handler(std::function<Error(Expected<int32_t>)> SendResult,
+             int32_t X) {
+      EXPECT_EQ(X, 21) << "Server int(int) receieved unexpected result";
+      return SendResult(2 * X);
+    }
+  };
+
+  std::thread ServerThread([&]() {
+      Dummy D;
+      Server.addAsyncHandler<DummyRPCAPI::IntInt>(D, &Dummy::handler);
+
+      {
+        // Poke the server to handle the negotiate call.
+        auto Err = Server.handleOne();
+        EXPECT_FALSE(!!Err) << "Server failed to handle call to negotiate";
+      }
+
+      {
+        // Poke the server to handle the VoidBool call.
+        auto Err = Server.handleOne();
+        EXPECT_FALSE(!!Err) << "Server failed to handle call to void(bool)";
+      }
+  });
+
+  {
+    auto Err = Client.callAsync<DummyRPCAPI::IntInt>(
+        [](Expected<int> Result) {
+          EXPECT_TRUE(!!Result) << "Async int(int) response handler failed";
+          EXPECT_EQ(*Result, 42)
+            << "Async int(int) response handler received incorrect result";
+          return Error::success();
+        }, 21);
+    EXPECT_FALSE(!!Err) << "Client.callAsync failed for int(int)";
+  }
+
+  {
+    // Poke the client to process the result.
+    auto Err = Client.handleOne();
+    EXPECT_FALSE(!!Err) << "Client failed to handle response from void(bool)";
+  }
+
+  ServerThread.join();
+}
+
 TEST(DummyRPC, TestSerialization) {
   Queue Q1, Q2;
   DummyRPCEndpoint Client(Q1, Q2);