From: Lang Hames Date: Wed, 15 Feb 2017 05:39:35 +0000 (+0000) Subject: [Orc][RPC] Add a AsyncHandlerTraits specialization for non-value-type response X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=200c66b2e08ab58fcc5d3fdfdc3af5a873cb99bf;p=llvm [Orc][RPC] Add a AsyncHandlerTraits specialization for non-value-type response 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 --- diff --git a/include/llvm/ExecutionEngine/Orc/RPCUtils.h b/include/llvm/ExecutionEngine/Orc/RPCUtils.h index 8119494b571..38ebd5dd3b2 100644 --- a/include/llvm/ExecutionEngine/Orc/RPCUtils.h +++ b/include/llvm/ExecutionEngine/Orc/RPCUtils.h @@ -339,6 +339,8 @@ public: using Type = Error; }; +// Traits class that strips the response function from the list of handler +// arguments. template class AsyncHandlerTraits; template @@ -355,6 +357,11 @@ public: using ResultType = Error; }; +template +class AsyncHandlerTraits : + public AsyncHandlerTraits::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 diff --git a/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp b/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp index 91cec1c1ede..f1fce9d6f21 100644 --- a/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp +++ b/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp @@ -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)> 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(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( + [](Expected 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);