Skip to content

Commit

Permalink
[Orc][RPC] Add a AsyncHandlerTraits specialization for non-value-type…
Browse files Browse the repository at this point in the history
… 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.

llvm-svn: 295151
  • Loading branch information
lhames committed Feb 15, 2017
1 parent 6697eff commit 56b3d6b
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
7 changes: 7 additions & 0 deletions llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ template <> class WrappedHandlerReturn<ErrorSuccess> {
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>
Expand All @@ -355,6 +357,11 @@ class AsyncHandlerTraits<Error(std::function<Error(Error)>, ArgTs...)> {
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
Expand Down
51 changes: 51 additions & 0 deletions llvm/unittests/ExecutionEngine/Orc/RPCUtilsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 56b3d6b

Please sign in to comment.