#ifndef LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETRPCAPI_H
#define LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETRPCAPI_H
-#include "RawByteChannel.h"
#include "RPCUtils.h"
+#include "RawByteChannel.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
namespace llvm {
namespace rpc {
-template <>
-class RPCTypeName<remote::DirectBufferWriter> {
+template <> class RPCTypeName<remote::DirectBufferWriter> {
public:
static const char *getName() { return "DirectBufferWriter"; }
};
template <typename ChannelT>
-class SerializationTraits<ChannelT, remote::DirectBufferWriter, remote::DirectBufferWriter,
- typename std::enable_if<
- std::is_base_of<RawByteChannel, ChannelT>::
- value>::type> {
+class SerializationTraits<
+ ChannelT, remote::DirectBufferWriter, remote::DirectBufferWriter,
+ typename std::enable_if<
+ std::is_base_of<RawByteChannel, ChannelT>::value>::type> {
public:
-
static Error serialize(ChannelT &C, const remote::DirectBufferWriter &DBW) {
if (auto EC = serializeSeq(C, DBW.getDst()))
return EC;
namespace remote {
class OrcRemoteTargetRPCAPI
- : public rpc::SingleThreadedRPC<rpc::RawByteChannel> {
+ : public rpc::SingleThreadedRPC<rpc::RawByteChannel> {
protected:
class ResourceIdMgr {
public:
OrcRemoteTargetRPCAPI(rpc::RawByteChannel &C)
: rpc::SingleThreadedRPC<rpc::RawByteChannel>(C, true) {}
- class CallIntVoid : public rpc::Function<CallIntVoid,
- int32_t(JITTargetAddress Addr)> {
+ class CallIntVoid
+ : public rpc::Function<CallIntVoid, int32_t(JITTargetAddress Addr)> {
public:
- static const char* getName() { return "CallIntVoid"; }
+ static const char *getName() { return "CallIntVoid"; }
};
class CallMain
- : public rpc::Function<CallMain,
- int32_t(JITTargetAddress Addr,
- std::vector<std::string> Args)> {
+ : public rpc::Function<CallMain, int32_t(JITTargetAddress Addr,
+ std::vector<std::string> Args)> {
public:
- static const char* getName() { return "CallMain"; }
+ static const char *getName() { return "CallMain"; }
};
- class CallVoidVoid : public rpc::Function<CallVoidVoid,
- void(JITTargetAddress FnAddr)> {
+ class CallVoidVoid
+ : public rpc::Function<CallVoidVoid, void(JITTargetAddress FnAddr)> {
public:
- static const char* getName() { return "CallVoidVoid"; }
+ static const char *getName() { return "CallVoidVoid"; }
};
class CreateRemoteAllocator
- : public rpc::Function<CreateRemoteAllocator,
- void(ResourceIdMgr::ResourceId AllocatorID)> {
+ : public rpc::Function<CreateRemoteAllocator,
+ void(ResourceIdMgr::ResourceId AllocatorID)> {
public:
- static const char* getName() { return "CreateRemoteAllocator"; }
+ static const char *getName() { return "CreateRemoteAllocator"; }
};
class CreateIndirectStubsOwner
- : public rpc::Function<CreateIndirectStubsOwner,
- void(ResourceIdMgr::ResourceId StubOwnerID)> {
+ : public rpc::Function<CreateIndirectStubsOwner,
+ void(ResourceIdMgr::ResourceId StubOwnerID)> {
public:
- static const char* getName() { return "CreateIndirectStubsOwner"; }
+ static const char *getName() { return "CreateIndirectStubsOwner"; }
};
class DeregisterEHFrames
- : public rpc::Function<DeregisterEHFrames,
- void(JITTargetAddress Addr, uint32_t Size)> {
+ : public rpc::Function<DeregisterEHFrames,
+ void(JITTargetAddress Addr, uint32_t Size)> {
public:
- static const char* getName() { return "DeregisterEHFrames"; }
+ static const char *getName() { return "DeregisterEHFrames"; }
};
class DestroyRemoteAllocator
- : public rpc::Function<DestroyRemoteAllocator,
- void(ResourceIdMgr::ResourceId AllocatorID)> {
+ : public rpc::Function<DestroyRemoteAllocator,
+ void(ResourceIdMgr::ResourceId AllocatorID)> {
public:
- static const char* getName() { return "DestroyRemoteAllocator"; }
+ static const char *getName() { return "DestroyRemoteAllocator"; }
};
class DestroyIndirectStubsOwner
- : public rpc::Function<DestroyIndirectStubsOwner,
- void(ResourceIdMgr::ResourceId StubsOwnerID)> {
+ : public rpc::Function<DestroyIndirectStubsOwner,
+ void(ResourceIdMgr::ResourceId StubsOwnerID)> {
public:
- static const char* getName() { return "DestroyIndirectStubsOwner"; }
+ static const char *getName() { return "DestroyIndirectStubsOwner"; }
};
/// EmitIndirectStubs result is (StubsBase, PtrsBase, NumStubsEmitted).
class EmitIndirectStubs
- : public rpc::Function<EmitIndirectStubs,
- std::tuple<JITTargetAddress, JITTargetAddress,
- uint32_t>(
- ResourceIdMgr::ResourceId StubsOwnerID,
- uint32_t NumStubsRequired)> {
+ : public rpc::Function<
+ EmitIndirectStubs,
+ std::tuple<JITTargetAddress, JITTargetAddress, uint32_t>(
+ ResourceIdMgr::ResourceId StubsOwnerID,
+ uint32_t NumStubsRequired)> {
public:
- static const char* getName() { return "EmitIndirectStubs"; }
+ static const char *getName() { return "EmitIndirectStubs"; }
};
class EmitResolverBlock : public rpc::Function<EmitResolverBlock, void()> {
public:
- static const char* getName() { return "EmitResolverBlock"; }
+ static const char *getName() { return "EmitResolverBlock"; }
};
/// EmitTrampolineBlock result is (BlockAddr, NumTrampolines).
class EmitTrampolineBlock
- : public rpc::Function<EmitTrampolineBlock,
- std::tuple<JITTargetAddress, uint32_t>()> {
+ : public rpc::Function<EmitTrampolineBlock,
+ std::tuple<JITTargetAddress, uint32_t>()> {
public:
- static const char* getName() { return "EmitTrampolineBlock"; }
+ static const char *getName() { return "EmitTrampolineBlock"; }
};
class GetSymbolAddress
- : public rpc::Function<GetSymbolAddress,
- JITTargetAddress(std::string SymbolName)> {
+ : public rpc::Function<GetSymbolAddress,
+ JITTargetAddress(std::string SymbolName)> {
public:
- static const char* getName() { return "GetSymbolAddress"; }
+ static const char *getName() { return "GetSymbolAddress"; }
};
/// GetRemoteInfo result is (Triple, PointerSize, PageSize, TrampolineSize,
/// IndirectStubsSize).
class GetRemoteInfo
- : public rpc::Function<GetRemoteInfo,
- std::tuple<std::string, uint32_t, uint32_t,
- uint32_t, uint32_t>()> {
+ : public rpc::Function<
+ GetRemoteInfo,
+ std::tuple<std::string, uint32_t, uint32_t, uint32_t, uint32_t>()> {
public:
- static const char* getName() { return "GetRemoteInfo"; }
+ static const char *getName() { return "GetRemoteInfo"; }
};
class ReadMem
- : public rpc::Function<ReadMem,
- std::vector<uint8_t>(JITTargetAddress Src,
- uint64_t Size)> {
+ : public rpc::Function<ReadMem, std::vector<uint8_t>(JITTargetAddress Src,
+ uint64_t Size)> {
public:
- static const char* getName() { return "ReadMem"; }
+ static const char *getName() { return "ReadMem"; }
};
class RegisterEHFrames
- : public rpc::Function<RegisterEHFrames,
- void(JITTargetAddress Addr, uint32_t Size)> {
+ : public rpc::Function<RegisterEHFrames,
+ void(JITTargetAddress Addr, uint32_t Size)> {
public:
- static const char* getName() { return "RegisterEHFrames"; }
+ static const char *getName() { return "RegisterEHFrames"; }
};
class ReserveMem
- : public rpc::Function<ReserveMem,
- JITTargetAddress(ResourceIdMgr::ResourceId AllocID,
- uint64_t Size, uint32_t Align)> {
+ : public rpc::Function<ReserveMem,
+ JITTargetAddress(ResourceIdMgr::ResourceId AllocID,
+ uint64_t Size, uint32_t Align)> {
public:
- static const char* getName() { return "ReserveMem"; }
+ static const char *getName() { return "ReserveMem"; }
};
class RequestCompile
- : public rpc::Function<RequestCompile,
- JITTargetAddress(JITTargetAddress TrampolineAddr)> {
+ : public rpc::Function<
+ RequestCompile, JITTargetAddress(JITTargetAddress TrampolineAddr)> {
public:
- static const char* getName() { return "RequestCompile"; }
+ static const char *getName() { return "RequestCompile"; }
};
class SetProtections
- : public rpc::Function<SetProtections,
- void(ResourceIdMgr::ResourceId AllocID,
- JITTargetAddress Dst,
- uint32_t ProtFlags)> {
+ : public rpc::Function<SetProtections,
+ void(ResourceIdMgr::ResourceId AllocID,
+ JITTargetAddress Dst, uint32_t ProtFlags)> {
public:
- static const char* getName() { return "SetProtections"; }
+ static const char *getName() { return "SetProtections"; }
};
class TerminateSession : public rpc::Function<TerminateSession, void()> {
public:
- static const char* getName() { return "TerminateSession"; }
+ static const char *getName() { return "TerminateSession"; }
};
- class WriteMem : public rpc::Function<WriteMem,
- void(remote::DirectBufferWriter DB)> {
+ class WriteMem
+ : public rpc::Function<WriteMem, void(remote::DirectBufferWriter DB)> {
public:
- static const char* getName() { return "WriteMem"; }
+ static const char *getName() { return "WriteMem"; }
};
- class WritePtr
- : public rpc::Function<WritePtr,
- void(JITTargetAddress Dst, JITTargetAddress Val)> {
+ class WritePtr : public rpc::Function<WritePtr, void(JITTargetAddress Dst,
+ JITTargetAddress Val)> {
public:
- static const char* getName() { return "WritePtr"; }
+ static const char *getName() { return "WritePtr"; }
};
-
};
} // end namespace remote
namespace orc {
namespace rpc {
-template <typename DerivedFunc, typename FnT>
-class Function;
+template <typename DerivedFunc, typename FnT> class Function;
// RPC Function class.
// DerivedFunc should be a user defined class with a static 'getName()' method
template <typename DerivedFunc, typename RetT, typename... ArgTs>
class Function<DerivedFunc, RetT(ArgTs...)> {
public:
-
/// User defined function type.
using Type = RetT(ArgTs...);
<< "(" << llvm::orc::rpc::RPCTypeNameSequence<ArgTs...>() << ")";
return Name.data();
}
+
private:
static std::mutex NameMutex;
static std::string Name;
};
-
template <typename DerivedFunc, typename RetT, typename... ArgTs>
std::mutex Function<DerivedFunc, RetT(ArgTs...)>::NameMutex;
///
/// template <typename Func> T allocate():
/// Allocate a unique id for function Func.
-template <typename T, typename = void>
-class RPCFunctionIdAllocator;
+template <typename T, typename = void> class RPCFunctionIdAllocator;
/// This specialization of RPCFunctionIdAllocator provides a default
/// implementation for integral types.
template <typename T>
-class RPCFunctionIdAllocator<T,
- typename std::enable_if<
- std::is_integral<T>::value
- >::type> {
+class RPCFunctionIdAllocator<
+ T, typename std::enable_if<std::is_integral<T>::value>::type> {
public:
-
static T getInvalidId() { return T(0); }
static T getResponseId() { return T(1); }
static T getNegotiateId() { return T(2); }
- template <typename Func>
- T allocate(){ return NextId++; }
+ template <typename Func> T allocate() { return NextId++; }
+
private:
T NextId = 3;
};
namespace msvc_hacks {
- // Work around MSVC's future implementation's use of default constructors:
- // A default constructed value in the promise will be overwritten when the
- // real error is set - so the default constructed Error has to be checked
- // already.
- class MSVCPError : public Error {
- public:
-
- MSVCPError() {
- (void)!!*this;
- }
-
- MSVCPError(MSVCPError &&Other) : Error(std::move(Other)) {}
-
- MSVCPError& operator=(MSVCPError Other) {
- Error::operator=(std::move(Other));
- return *this;
- }
-
- MSVCPError(Error Err) : Error(std::move(Err)) {}
- };
-
- // Work around MSVC's future implementation, similar to MSVCPError.
- template <typename T>
- class MSVCPExpected : public Expected<T> {
- public:
+// Work around MSVC's future implementation's use of default constructors:
+// A default constructed value in the promise will be overwritten when the
+// real error is set - so the default constructed Error has to be checked
+// already.
+class MSVCPError : public Error {
+public:
+ MSVCPError() { (void)!!*this; }
- MSVCPExpected()
- : Expected<T>(make_error<StringError>("", inconvertibleErrorCode())) {
- consumeError(this->takeError());
- }
+ MSVCPError(MSVCPError &&Other) : Error(std::move(Other)) {}
- MSVCPExpected(MSVCPExpected &&Other) : Expected<T>(std::move(Other)) {}
+ MSVCPError &operator=(MSVCPError Other) {
+ Error::operator=(std::move(Other));
+ return *this;
+ }
- MSVCPExpected& operator=(MSVCPExpected &&Other) {
- Expected<T>::operator=(std::move(Other));
- return *this;
- }
+ MSVCPError(Error Err) : Error(std::move(Err)) {}
+};
- MSVCPExpected(Error Err) : Expected<T>(std::move(Err)) {}
+// Work around MSVC's future implementation, similar to MSVCPError.
+template <typename T> class MSVCPExpected : public Expected<T> {
+public:
+ MSVCPExpected()
+ : Expected<T>(make_error<StringError>("", inconvertibleErrorCode())) {
+ consumeError(this->takeError());
+ }
- template <typename OtherT>
- MSVCPExpected(OtherT &&Val,
- typename std::enable_if<std::is_convertible<OtherT, T>::value>::type
- * = nullptr) : Expected<T>(std::move(Val)) {}
+ MSVCPExpected(MSVCPExpected &&Other) : Expected<T>(std::move(Other)) {}
- template <class OtherT>
- MSVCPExpected(
- Expected<OtherT> &&Other,
- typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
- nullptr) : Expected<T>(std::move(Other)) {}
+ MSVCPExpected &operator=(MSVCPExpected &&Other) {
+ Expected<T>::operator=(std::move(Other));
+ return *this;
+ }
- template <class OtherT>
- explicit MSVCPExpected(
- Expected<OtherT> &&Other,
- typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * =
- nullptr) : Expected<T>(std::move(Other)) {}
- };
+ MSVCPExpected(Error Err) : Expected<T>(std::move(Err)) {}
+
+ template <typename OtherT>
+ MSVCPExpected(
+ OtherT &&Val,
+ typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
+ nullptr)
+ : Expected<T>(std::move(Val)) {}
+
+ template <class OtherT>
+ MSVCPExpected(
+ Expected<OtherT> &&Other,
+ typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
+ nullptr)
+ : Expected<T>(std::move(Other)) {}
+
+ template <class OtherT>
+ explicit MSVCPExpected(
+ Expected<OtherT> &&Other,
+ typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * =
+ nullptr)
+ : Expected<T>(std::move(Other)) {}
+};
} // end namespace msvc_hacks
// ResultTraits provides typedefs and utilities specific to the return type
// of functions.
-template <typename RetT>
-class ResultTraits {
+template <typename RetT> class ResultTraits {
public:
-
// The return type wrapped in llvm::Expected.
using ErrorReturnType = Expected<RetT>;
};
// ResultTraits specialization for void functions.
-template <>
-class ResultTraits<void> {
+template <> class ResultTraits<void> {
public:
-
// For void functions, ErrorReturnType is llvm::Error.
using ErrorReturnType = Error;
// handlers for void RPC functions to return either void (in which case they
// implicitly succeed) or Error (in which case their error return is
// propagated). See usage in HandlerTraits::runHandlerHelper.
-template <>
-class ResultTraits<Error> : public ResultTraits<void> {};
+template <> class ResultTraits<Error> : public ResultTraits<void> {};
// ResultTraits<Expected<T>> is equivalent to ResultTraits<T>. This allows
// handlers for RPC functions returning a T to return either a T (in which
return Err;
// Serialize the result.
- if (auto Err = SerializationTraits<ChannelT, WireRetT, HandlerRetT>::
- serialize(C, *ResultOrErr))
+ if (auto Err =
+ SerializationTraits<ChannelT, WireRetT, HandlerRetT>::serialize(
+ C, *ResultOrErr))
return Err;
// Close the response message.
}
// Converts a given type to the equivalent error return type.
-template <typename T>
-class WrappedHandlerReturn {
+template <typename T> class WrappedHandlerReturn {
public:
using Type = Expected<T>;
};
-template <typename T>
-class WrappedHandlerReturn<Expected<T>> {
+template <typename T> class WrappedHandlerReturn<Expected<T>> {
public:
using Type = Expected<T>;
};
-template <>
-class WrappedHandlerReturn<void> {
+template <> class WrappedHandlerReturn<void> {
public:
using Type = Error;
};
-template <>
-class WrappedHandlerReturn<Error> {
+template <> class WrappedHandlerReturn<Error> {
public:
using Type = Error;
};
-template <>
-class WrappedHandlerReturn<ErrorSuccess> {
+template <> class WrappedHandlerReturn<ErrorSuccess> {
public:
using Type = Error;
};
// specialized for function types) and inherits from the appropriate
// speciilization for the given non-function type's call operator.
template <typename HandlerT>
-class HandlerTraits
- : public HandlerTraits<decltype(
- &std::remove_reference<HandlerT>::type::operator())> {};
+class HandlerTraits : public HandlerTraits<decltype(
+ &std::remove_reference<HandlerT>::type::operator())> {
+};
// Traits for handlers with a given function type.
template <typename RetT, typename... ArgTs>
class HandlerTraits<RetT(ArgTs...)> {
public:
-
// Function type of the handler.
using Type = RetT(ArgTs...);
using ReturnType = RetT;
// A std::tuple wrapping the handler arguments.
- using ArgStorage =
- std::tuple<
- typename std::decay<
- typename std::remove_reference<ArgTs>::type>::type...>;
+ using ArgStorage = std::tuple<typename std::decay<
+ typename std::remove_reference<ArgTs>::type>::type...>;
// Call the given handler with the given arguments.
template <typename HandlerT>
}
private:
-
// For non-void user handlers: unwrap the args tuple and call the handler,
// returning the result.
template <typename RetTAlt, typename HandlerT, size_t... Indexes>
}
template <typename ChannelT, typename... CArgTs, size_t... Indexes>
- static
- Error deserializeArgsHelper(ChannelT &C, std::tuple<CArgTs...> &Args,
- llvm::index_sequence<Indexes...> _) {
- return SequenceSerialization<ChannelT, ArgTs...>::
- deserialize(C, std::get<Indexes>(Args)...);
+ static Error deserializeArgsHelper(ChannelT &C, std::tuple<CArgTs...> &Args,
+ llvm::index_sequence<Indexes...> _) {
+ return SequenceSerialization<ChannelT, ArgTs...>::deserialize(
+ C, std::get<Indexes>(Args)...);
}
-
};
// Handler traits for class methods (especially call operators for lambdas).
template <typename Class, typename RetT, typename... ArgTs>
class HandlerTraits<RetT (Class::*)(ArgTs...)>
- : public HandlerTraits<RetT(ArgTs...)> {};
+ : public HandlerTraits<RetT(ArgTs...)> {};
// Handler traits for const class methods (especially call operators for
// lambdas).
template <typename Class, typename RetT, typename... ArgTs>
class HandlerTraits<RetT (Class::*)(ArgTs...) const>
- : public HandlerTraits<RetT(ArgTs...)> {};
+ : public HandlerTraits<RetT(ArgTs...)> {};
// Utility to peel the Expected wrapper off a response handler error type.
-template <typename HandlerT>
-class UnwrapResponseHandlerArg;
+template <typename HandlerT> class UnwrapResponseHandlerArg;
-template <typename ArgT>
-class UnwrapResponseHandlerArg<Error(Expected<ArgT>)> {
+template <typename ArgT> class UnwrapResponseHandlerArg<Error(Expected<ArgT>)> {
public:
using ArgType = ArgT;
};
using ArgType = ArgT;
};
-
// ResponseHandler represents a handler for a not-yet-received function call
// result.
-template <typename ChannelT>
-class ResponseHandler {
+template <typename ChannelT> class ResponseHandler {
public:
virtual ~ResponseHandler() {}
template <typename ChannelT, typename FuncRetT, typename HandlerT>
class ResponseHandlerImpl : public ResponseHandler<ChannelT> {
public:
- ResponseHandlerImpl(HandlerT Handler)
- : Handler(std::move(Handler)) {}
+ ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
// Handle the result by deserializing it from the channel then passing it
// to the user defined handler.
Error handleResponse(ChannelT &C) override {
using ArgType = typename UnwrapResponseHandlerArg<
- typename HandlerTraits<HandlerT>::Type>::ArgType;
+ typename HandlerTraits<HandlerT>::Type>::ArgType;
ArgType Result;
- if (auto Err = SerializationTraits<ChannelT, FuncRetT, ArgType>::
- deserialize(C, Result))
+ if (auto Err =
+ SerializationTraits<ChannelT, FuncRetT, ArgType>::deserialize(
+ C, Result))
return Err;
if (auto Err = C.endReceiveMessage())
return Err;
// ResponseHandler subclass for RPC functions with void returns.
template <typename ChannelT, typename HandlerT>
class ResponseHandlerImpl<ChannelT, void, HandlerT>
- : public ResponseHandler<ChannelT> {
+ : public ResponseHandler<ChannelT> {
public:
- ResponseHandlerImpl(HandlerT Handler)
- : Handler(std::move(Handler)) {}
+ ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
// Handle the result (no actual value, just a notification that the function
// has completed on the remote end) by calling the user-defined handler with
// Create a ResponseHandler from a given user handler.
template <typename ChannelT, typename FuncRetT, typename HandlerT>
-std::unique_ptr<ResponseHandler<ChannelT>>
-createResponseHandler(HandlerT H) {
- return llvm::make_unique<
- ResponseHandlerImpl<ChannelT, FuncRetT, HandlerT>>(std::move(H));
+std::unique_ptr<ResponseHandler<ChannelT>> createResponseHandler(HandlerT H) {
+ return llvm::make_unique<ResponseHandlerImpl<ChannelT, FuncRetT, HandlerT>>(
+ std::move(H));
}
// Helper for wrapping member functions up as functors. This is useful for
template <typename ClassT, typename RetT, typename... ArgTs>
class MemberFnWrapper {
public:
- using MethodT = RetT(ClassT::*)(ArgTs...);
+ using MethodT = RetT (ClassT::*)(ArgTs...);
MemberFnWrapper(ClassT &Instance, MethodT Method)
: Instance(Instance), Method(Method) {}
RetT operator()(ArgTs &&... Args) {
return (Instance.*Method)(std::move(Args)...);
}
+
private:
ClassT &Instance;
MethodT Method;
this->Arg = std::move(ArgVal);
return ReadArgs<ArgTs...>::operator()(ArgVals...);
}
+
private:
ArgT &Arg;
};
// Manage sequence numbers.
-template <typename SequenceNumberT>
-class SequenceNumberManager {
+template <typename SequenceNumberT> class SequenceNumberManager {
public:
// Reset, making all sequence numbers available.
void reset() {
typename SequenceNumberT>
class RPCBase {
protected:
-
class OrcRPCInvalid : public Function<OrcRPCInvalid, void()> {
public:
static const char *getName() { return "__orc_rpc$invalid"; }
};
class OrcRPCNegotiate
- : public Function<OrcRPCNegotiate, FunctionIdT(std::string)> {
+ : public Function<OrcRPCNegotiate, FunctionIdT(std::string)> {
public:
static const char *getName() { return "__orc_rpc$negotiate"; }
};
public:
-
/// Construct an RPC instance on a channel.
RPCBase(ChannelT &C, bool LazyAutoNegotiation)
: C(C), LazyAutoNegotiation(LazyAutoNegotiation) {
// Register the negotiate function id and handler.
auto NegotiateId = FnIdAllocator.getNegotiateId();
RemoteFunctionIds[OrcRPCNegotiate::getPrototype()] = NegotiateId;
- Handlers[NegotiateId] =
- wrapHandler<OrcRPCNegotiate>([this](const std::string &Name) {
- return handleNegotiate(Name);
- }, LaunchPolicy());
+ Handlers[NegotiateId] = wrapHandler<OrcRPCNegotiate>(
+ [this](const std::string &Name) { return handleNegotiate(Name); },
+ LaunchPolicy());
}
/// Append a call Func, does not call send on the channel.
// Install the user handler.
PendingResponses[SeqNo] =
- detail::createResponseHandler<ChannelT, typename Func::ReturnType>(
- std::move(Handler));
+ detail::createResponseHandler<ChannelT, typename Func::ReturnType>(
+ std::move(Handler));
// Open the function call message.
if (auto Err = C.startSendMessage(FnId, SeqNo)) {
}
// Serialize the call arguments.
- if (auto Err =
- detail::HandlerTraits<typename Func::Type>::
- serializeArgs(C, Args...)) {
+ if (auto Err = detail::HandlerTraits<typename Func::Type>::serializeArgs(
+ C, Args...)) {
abandonPendingResponses();
return joinErrors(std::move(Err), C.endSendMessage());
}
return Error::success();
}
-
template <typename Func, typename HandlerT, typename... ArgTs>
Error callAsync(HandlerT Handler, const ArgTs &... Args) {
if (auto Err = appendCallAsync<Func>(std::move(Handler), Args...))
void addHandlerImpl(HandlerT Handler, LaunchPolicy Launch) {
FunctionIdT NewFnId = FnIdAllocator.template allocate<Func>();
LocalFunctionIds[Func::getPrototype()] = NewFnId;
- Handlers[NewFnId] = wrapHandler<Func>(std::move(Handler),
- std::move(Launch));
+ Handlers[NewFnId] =
+ wrapHandler<Func>(std::move(Handler), std::move(Launch));
}
// Abandon all outstanding results.
// Find the remote FunctionId for the given function, which must be in the
// RemoteFunctionIds map.
- template <typename Func>
- Expected<FunctionIdT> getRemoteFunctionId() {
+ template <typename Func> Expected<FunctionIdT> getRemoteFunctionId() {
// Try to find the id for the given function.
auto I = RemoteFunctionIds.find(Func::getPrototype());
// Otherwise, if we have auto-negotiation enabled, try to negotiate it.
if (LazyAutoNegotiation) {
- auto &Impl = static_cast<ImplT&>(*this);
+ auto &Impl = static_cast<ImplT &>(*this);
if (auto RemoteIdOrErr =
- Impl.template callB<OrcRPCNegotiate>(Func::getPrototype())) {
+ Impl.template callB<OrcRPCNegotiate>(Func::getPrototype())) {
auto &RemoteId = *RemoteIdOrErr;
// If autonegotiation indicates that the remote end doesn't support this
return orcError(OrcErrorCode::UnknownRPCFunction);
}
- using WrappedHandlerFn = std::function<Error(ChannelT&, SequenceNumberT)>;
+ using WrappedHandlerFn = std::function<Error(ChannelT &, SequenceNumberT)>;
// Wrap the given user handler in the necessary argument-deserialization code,
// result-serialization code, and call to the launch policy (if present).
template <typename Func, typename HandlerT>
WrappedHandlerFn wrapHandler(HandlerT Handler, LaunchPolicy Launch) {
- return
- [this, Handler, Launch](ChannelT &Channel, SequenceNumberT SeqNo) mutable
- -> Error {
- // Start by deserializing the arguments.
- auto Args =
- std::make_shared<typename detail::HandlerTraits<HandlerT>::ArgStorage>();
- if (auto Err = detail::HandlerTraits<typename Func::Type>::
- deserializeArgs(Channel, *Args))
- return Err;
-
- // GCC 4.7 and 4.8 incorrectly issue a -Wunused-but-set-variable warning
- // for RPCArgs. Void cast RPCArgs to work around this for now.
- // FIXME: Remove this workaround once we can assume a working GCC version.
- (void)Args;
-
- // End receieve message, unlocking the channel for reading.
- if (auto Err = Channel.endReceiveMessage())
- return Err;
-
- // Build the handler/responder.
- auto Responder =
- [this, Handler, Args, &Channel, SeqNo]() mutable -> Error {
- using HTraits = detail::HandlerTraits<HandlerT>;
- using FuncReturn = typename Func::ReturnType;
- return detail::respond<FuncReturn>(Channel, ResponseId, SeqNo,
- HTraits::runHandler(Handler,
- *Args));
- };
-
- // If there is an explicit launch policy then use it to launch the
- // handler.
- if (Launch)
- return Launch(std::move(Responder));
-
- // Otherwise run the handler on the listener thread.
- return Responder();
+ return [this, Handler, Launch](ChannelT &Channel,
+ SequenceNumberT SeqNo) mutable -> Error {
+ // Start by deserializing the arguments.
+ auto Args = std::make_shared<
+ typename detail::HandlerTraits<HandlerT>::ArgStorage>();
+ if (auto Err =
+ detail::HandlerTraits<typename Func::Type>::deserializeArgs(
+ Channel, *Args))
+ return Err;
+
+ // GCC 4.7 and 4.8 incorrectly issue a -Wunused-but-set-variable warning
+ // for RPCArgs. Void cast RPCArgs to work around this for now.
+ // FIXME: Remove this workaround once we can assume a working GCC version.
+ (void)Args;
+
+ // End receieve message, unlocking the channel for reading.
+ if (auto Err = Channel.endReceiveMessage())
+ return Err;
+
+ // Build the handler/responder.
+ auto Responder = [this, Handler, Args, &Channel,
+ SeqNo]() mutable -> Error {
+ using HTraits = detail::HandlerTraits<HandlerT>;
+ using FuncReturn = typename Func::ReturnType;
+ return detail::respond<FuncReturn>(Channel, ResponseId, SeqNo,
+ HTraits::runHandler(Handler, *Args));
};
+
+ // If there is an explicit launch policy then use it to launch the
+ // handler.
+ if (Launch)
+ return Launch(std::move(Responder));
+
+ // Otherwise run the handler on the listener thread.
+ return Responder();
+ };
}
ChannelT &C;
FunctionIdT ResponseId;
std::map<std::string, FunctionIdT> LocalFunctionIds;
- std::map<const char*, FunctionIdT> RemoteFunctionIds;
+ std::map<const char *, FunctionIdT> RemoteFunctionIds;
std::map<FunctionIdT, WrappedHandlerFn> Handlers;
detail::SequenceNumberManager<SequenceNumberT> SequenceNumberMgr;
std::map<SequenceNumberT, std::unique_ptr<detail::ResponseHandler<ChannelT>>>
- PendingResponses;
+ PendingResponses;
};
} // end namespace detail
-
-template <typename ChannelT,
- typename FunctionIdT = uint32_t,
+template <typename ChannelT, typename FunctionIdT = uint32_t,
typename SequenceNumberT = uint32_t>
class MultiThreadedRPC
- : public detail::RPCBase<MultiThreadedRPC<ChannelT, FunctionIdT,
- SequenceNumberT>,
- ChannelT, FunctionIdT, SequenceNumberT> {
+ : public detail::RPCBase<
+ MultiThreadedRPC<ChannelT, FunctionIdT, SequenceNumberT>, ChannelT,
+ FunctionIdT, SequenceNumberT> {
private:
using BaseClass =
- detail::RPCBase<MultiThreadedRPC<ChannelT, FunctionIdT, SequenceNumberT>,
- ChannelT, FunctionIdT, SequenceNumberT>;
+ detail::RPCBase<MultiThreadedRPC<ChannelT, FunctionIdT, SequenceNumberT>,
+ ChannelT, FunctionIdT, SequenceNumberT>;
public:
-
MultiThreadedRPC(ChannelT &C, bool LazyAutoNegotiation)
: BaseClass(C, LazyAutoNegotiation) {}
}
/// Negotiate a function id for Func with the other end of the channel.
- template <typename Func>
- Error negotiateFunction() {
+ template <typename Func> Error negotiateFunction() {
using OrcRPCNegotiate = typename BaseClass::OrcRPCNegotiate;
if (auto RemoteIdOrErr = callB<OrcRPCNegotiate>(Func::getPrototype())) {
}
/// Convenience method for negotiating multiple functions at once.
- template <typename Func>
- Error negotiateFunctions() {
+ template <typename Func> Error negotiateFunctions() {
return negotiateFunction<Func>();
}
/// Return type for non-blocking call primitives.
template <typename Func>
- using NonBlockingCallResult =
- typename detail::ResultTraits<typename Func::ReturnType>::ReturnFutureType;
+ using NonBlockingCallResult = typename detail::ResultTraits<
+ typename Func::ReturnType>::ReturnFutureType;
/// Call Func on Channel C. Does not block, does not call send. Returns a pair
/// of a future result and the sequence number assigned to the result.
/// result. In multi-threaded mode the appendCallNB method, which does not
/// return the sequence numeber, should be preferred.
template <typename Func, typename... ArgTs>
- Expected<NonBlockingCallResult<Func>>
- appendCallNB(const ArgTs &... Args) {
+ Expected<NonBlockingCallResult<Func>> appendCallNB(const ArgTs &... Args) {
using RTraits = detail::ResultTraits<typename Func::ReturnType>;
using ErrorReturn = typename RTraits::ErrorReturnType;
using ErrorReturnPromise = typename RTraits::ReturnPromiseType;
[Promise](ErrorReturn RetOrErr) {
Promise->set_value(std::move(RetOrErr));
return Error::success();
- }, Args...)) {
+ },
+ Args...)) {
this->abandonPendingResponses();
RTraits::consumeAbandoned(FutureResult.get());
return std::move(Err);
/// The same as appendCallNBWithSeq, except that it calls C.send() to
/// flush the channel after serializing the call.
template <typename Func, typename... ArgTs>
- Expected<NonBlockingCallResult<Func>>
- callNB(const ArgTs &... Args) {
+ Expected<NonBlockingCallResult<Func>> callNB(const ArgTs &... Args) {
auto Result = appendCallNB<Func>(Args...);
if (!Result)
return Result;
if (auto Err = this->C.send()) {
this->abandonPendingResponses();
- detail::ResultTraits<typename Func::ReturnType>::
- consumeAbandoned(std::move(Result->get()));
+ detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
+ std::move(Result->get()));
return std::move(Err);
}
return Result;
if (auto FutureResOrErr = callNB<Func>(Args...)) {
if (auto Err = this->C.send()) {
this->abandonPendingResponses();
- detail::ResultTraits<typename Func::ReturnType>::
- consumeAbandoned(std::move(FutureResOrErr->get()));
+ detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
+ std::move(FutureResOrErr->get()));
return std::move(Err);
}
return FutureResOrErr->get();
return Err;
return Error::success();
}
-
};
-template <typename ChannelT,
- typename FunctionIdT = uint32_t,
+template <typename ChannelT, typename FunctionIdT = uint32_t,
typename SequenceNumberT = uint32_t>
class SingleThreadedRPC
- : public detail::RPCBase<SingleThreadedRPC<ChannelT, FunctionIdT,
- SequenceNumberT>,
- ChannelT, FunctionIdT,
- SequenceNumberT> {
+ : public detail::RPCBase<
+ SingleThreadedRPC<ChannelT, FunctionIdT, SequenceNumberT>, ChannelT,
+ FunctionIdT, SequenceNumberT> {
private:
-
- using BaseClass = detail::RPCBase<SingleThreadedRPC<ChannelT, FunctionIdT,
- SequenceNumberT>,
- ChannelT, FunctionIdT, SequenceNumberT>;
+ using BaseClass =
+ detail::RPCBase<SingleThreadedRPC<ChannelT, FunctionIdT, SequenceNumberT>,
+ ChannelT, FunctionIdT, SequenceNumberT>;
using LaunchPolicy = typename BaseClass::LaunchPolicy;
public:
-
SingleThreadedRPC(ChannelT &C, bool LazyAutoNegotiation)
: BaseClass(C, LazyAutoNegotiation) {}
}
/// Negotiate a function id for Func with the other end of the channel.
- template <typename Func>
- Error negotiateFunction() {
+ template <typename Func> Error negotiateFunction() {
using OrcRPCNegotiate = typename BaseClass::OrcRPCNegotiate;
if (auto RemoteIdOrErr = callB<OrcRPCNegotiate>(Func::getPrototype())) {
}
/// Convenience method for negotiating multiple functions at once.
- template <typename Func>
- Error negotiateFunctions() {
+ template <typename Func> Error negotiateFunctions() {
return negotiateFunction<Func>();
}
typename detail::ResultTraits<AltRetT>::ErrorReturnType
callB(const ArgTs &... Args) {
bool ReceivedResponse = false;
- using ResultType =
- typename detail::ResultTraits<AltRetT>::ErrorReturnType;
+ using ResultType = typename detail::ResultTraits<AltRetT>::ErrorReturnType;
auto Result = detail::ResultTraits<AltRetT>::createBlankErrorReturnValue();
// We have to 'Check' result (which we know is in a success state at this
(void)!!Result;
if (auto Err = this->template appendCallAsync<Func>(
- [&](ResultType R) {
- Result = std::move(R);
- ReceivedResponse = true;
- return Error::success();
- }, Args...)) {
+ [&](ResultType R) {
+ Result = std::move(R);
+ ReceivedResponse = true;
+ return Error::success();
+ },
+ Args...)) {
this->abandonPendingResponses();
- detail::ResultTraits<typename Func::ReturnType>::
- consumeAbandoned(std::move(Result));
+ detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
+ std::move(Result));
return std::move(Err);
}
while (!ReceivedResponse) {
if (auto Err = this->handleOne()) {
this->abandonPendingResponses();
- detail::ResultTraits<typename Func::ReturnType>::
- consumeAbandoned(std::move(Result));
+ detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
+ std::move(Result));
return std::move(Err);
}
}
return Result;
}
-
- //using detail::RPCBase<ChannelT, FunctionIdT, SequenceNumberT>::handleOne;
-
};
} // end namespace rpc