LCOV - code coverage report
Current view: top level - include/llvm/ExecutionEngine/Orc - RPCUtils.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 227 316 71.8 %
Date: 2017-09-14 15:23:50 Functions: 383 574 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===------- RPCUTils.h - Utilities for building RPC APIs -------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // Utilities to support construction of simple RPC APIs.
      11             : //
      12             : // The RPC utilities aim for ease of use (minimal conceptual overhead) for C++
      13             : // programmers, high performance, low memory overhead, and efficient use of the
      14             : // communications channel.
      15             : //
      16             : //===----------------------------------------------------------------------===//
      17             : 
      18             : #ifndef LLVM_EXECUTIONENGINE_ORC_RPCUTILS_H
      19             : #define LLVM_EXECUTIONENGINE_ORC_RPCUTILS_H
      20             : 
      21             : #include <map>
      22             : #include <thread>
      23             : #include <vector>
      24             : 
      25             : #include "llvm/ADT/STLExtras.h"
      26             : #include "llvm/ExecutionEngine/Orc/OrcError.h"
      27             : #include "llvm/ExecutionEngine/Orc/RPCSerialization.h"
      28             : 
      29             : #include <future>
      30             : 
      31             : namespace llvm {
      32             : namespace orc {
      33             : namespace rpc {
      34             : 
      35             : /// Base class of all fatal RPC errors (those that necessarily result in the
      36             : /// termination of the RPC session).
      37           0 : class RPCFatalError : public ErrorInfo<RPCFatalError> {
      38             : public:
      39             :   static char ID;
      40             : };
      41             : 
      42             : /// RPCConnectionClosed is returned from RPC operations if the RPC connection
      43             : /// has already been closed due to either an error or graceful disconnection.
      44           0 : class ConnectionClosed : public ErrorInfo<ConnectionClosed> {
      45             : public:
      46             :   static char ID;
      47             :   std::error_code convertToErrorCode() const override;
      48             :   void log(raw_ostream &OS) const override;
      49             : };
      50             : 
      51             : /// BadFunctionCall is returned from handleOne when the remote makes a call with
      52             : /// an unrecognized function id.
      53             : ///
      54             : /// This error is fatal because Orc RPC needs to know how to parse a function
      55             : /// call to know where the next call starts, and if it doesn't recognize the
      56             : /// function id it cannot parse the call.
      57             : template <typename FnIdT, typename SeqNoT>
      58           0 : class BadFunctionCall
      59             :   : public ErrorInfo<BadFunctionCall<FnIdT, SeqNoT>, RPCFatalError> {
      60             : public:
      61             :   static char ID;
      62             : 
      63           0 :   BadFunctionCall(FnIdT FnId, SeqNoT SeqNo)
      64           0 :       : FnId(std::move(FnId)), SeqNo(std::move(SeqNo)) {}
      65             : 
      66           0 :   std::error_code convertToErrorCode() const override {
      67           0 :     return orcError(OrcErrorCode::UnexpectedRPCCall);
      68             :   }
      69             : 
      70           0 :   void log(raw_ostream &OS) const override {
      71           0 :     OS << "Call to invalid RPC function id '" << FnId << "' with "
      72           0 :           "sequence number " << SeqNo;
      73           0 :   }
      74             : 
      75             : private:
      76             :   FnIdT FnId;
      77             :   SeqNoT SeqNo;
      78             : };
      79             : 
      80             : template <typename FnIdT, typename SeqNoT>
      81             : char BadFunctionCall<FnIdT, SeqNoT>::ID = 0;
      82             : 
      83             : /// InvalidSequenceNumberForResponse is returned from handleOne when a response
      84             : /// call arrives with a sequence number that doesn't correspond to any in-flight
      85             : /// function call.
      86             : ///
      87             : /// This error is fatal because Orc RPC needs to know how to parse the rest of
      88             : /// the response call to know where the next call starts, and if it doesn't have
      89             : /// a result parser for this sequence number it can't do that.
      90             : template <typename SeqNoT>
      91           0 : class InvalidSequenceNumberForResponse
      92             :     : public ErrorInfo<InvalidSequenceNumberForResponse<SeqNoT>, RPCFatalError> {
      93             : public:
      94             :   static char ID;
      95             : 
      96           0 :   InvalidSequenceNumberForResponse(SeqNoT SeqNo)
      97           0 :       : SeqNo(std::move(SeqNo)) {}
      98             : 
      99           0 :   std::error_code convertToErrorCode() const override {
     100           0 :     return orcError(OrcErrorCode::UnexpectedRPCCall);
     101             :   };
     102             : 
     103           0 :   void log(raw_ostream &OS) const override {
     104           0 :     OS << "Response has unknown sequence number " << SeqNo;
     105           0 :   }
     106             : private:
     107             :   SeqNoT SeqNo;
     108             : };
     109             : 
     110             : template <typename SeqNoT>
     111             : char InvalidSequenceNumberForResponse<SeqNoT>::ID = 0;
     112             : 
     113             : /// This non-fatal error will be passed to asynchronous result handlers in place
     114             : /// of a result if the connection goes down before a result returns, or if the
     115             : /// function to be called cannot be negotiated with the remote.
     116           0 : class ResponseAbandoned : public ErrorInfo<ResponseAbandoned> {
     117             : public:
     118             :   static char ID;
     119             : 
     120             :   std::error_code convertToErrorCode() const override;
     121             :   void log(raw_ostream &OS) const override;
     122             : };
     123             : 
     124             : /// This error is returned if the remote does not have a handler installed for
     125             : /// the given RPC function.
     126           3 : class CouldNotNegotiate : public ErrorInfo<CouldNotNegotiate> {
     127             : public:
     128             :   static char ID;
     129             : 
     130             :   CouldNotNegotiate(std::string Signature);
     131             :   std::error_code convertToErrorCode() const override;
     132             :   void log(raw_ostream &OS) const override;
     133             :   const std::string &getSignature() const { return Signature; }
     134             : private:
     135             :   std::string Signature;
     136             : };
     137             : 
     138             : template <typename DerivedFunc, typename FnT> class Function;
     139             : 
     140             : // RPC Function class.
     141             : // DerivedFunc should be a user defined class with a static 'getName()' method
     142             : // returning a const char* representing the function's name.
     143             : template <typename DerivedFunc, typename RetT, typename... ArgTs>
     144             : class Function<DerivedFunc, RetT(ArgTs...)> {
     145             : public:
     146             :   /// User defined function type.
     147             :   using Type = RetT(ArgTs...);
     148             : 
     149             :   /// Return type.
     150             :   using ReturnType = RetT;
     151             : 
     152             :   /// Returns the full function prototype as a string.
     153        1923 :   static const char *getPrototype() {
     154        3846 :     std::lock_guard<std::mutex> Lock(NameMutex);
     155        1923 :     if (Name.empty())
     156         954 :       raw_string_ostream(Name)
     157        1908 :           << RPCTypeName<RetT>::getName() << " " << DerivedFunc::getName()
     158        1400 :           << "(" << llvm::orc::rpc::RPCTypeNameSequence<ArgTs...>() << ")";
     159        3846 :     return Name.data();
     160             :   }
     161             : 
     162             : private:
     163             :   static std::mutex NameMutex;
     164             :   static std::string Name;
     165             : };
     166             : 
     167             : template <typename DerivedFunc, typename RetT, typename... ArgTs>
     168             : std::mutex Function<DerivedFunc, RetT(ArgTs...)>::NameMutex;
     169             : 
     170             : template <typename DerivedFunc, typename RetT, typename... ArgTs>
     171        5790 : std::string Function<DerivedFunc, RetT(ArgTs...)>::Name;
     172             : 
     173             : /// Allocates RPC function ids during autonegotiation.
     174             : /// Specializations of this class must provide four members:
     175             : ///
     176             : /// static T getInvalidId():
     177             : ///   Should return a reserved id that will be used to represent missing
     178             : /// functions during autonegotiation.
     179             : ///
     180             : /// static T getResponseId():
     181             : ///   Should return a reserved id that will be used to send function responses
     182             : /// (return values).
     183             : ///
     184             : /// static T getNegotiateId():
     185             : ///   Should return a reserved id for the negotiate function, which will be used
     186             : /// to negotiate ids for user defined functions.
     187             : ///
     188             : /// template <typename Func> T allocate():
     189             : ///   Allocate a unique id for function Func.
     190             : template <typename T, typename = void> class RPCFunctionIdAllocator;
     191             : 
     192             : /// This specialization of RPCFunctionIdAllocator provides a default
     193             : /// implementation for integral types.
     194             : template <typename T>
     195          97 : class RPCFunctionIdAllocator<
     196             :     T, typename std::enable_if<std::is_integral<T>::value>::type> {
     197             : public:
     198             :   static T getInvalidId() { return T(0); }
     199             :   static T getResponseId() { return T(1); }
     200             :   static T getNegotiateId() { return T(2); }
     201             : 
     202         620 :   template <typename Func> T allocate() { return NextId++; }
     203             : 
     204             : private:
     205             :   T NextId = 3;
     206             : };
     207             : 
     208             : namespace detail {
     209             : 
     210             : // FIXME: Remove MSVCPError/MSVCPExpected once MSVC's future implementation
     211             : //        supports classes without default constructors.
     212             : #ifdef _MSC_VER
     213             : 
     214             : namespace msvc_hacks {
     215             : 
     216             : // Work around MSVC's future implementation's use of default constructors:
     217             : // A default constructed value in the promise will be overwritten when the
     218             : // real error is set - so the default constructed Error has to be checked
     219             : // already.
     220             : class MSVCPError : public Error {
     221             : public:
     222             :   MSVCPError() { (void)!!*this; }
     223             : 
     224             :   MSVCPError(MSVCPError &&Other) : Error(std::move(Other)) {}
     225             : 
     226             :   MSVCPError &operator=(MSVCPError Other) {
     227             :     Error::operator=(std::move(Other));
     228             :     return *this;
     229             :   }
     230             : 
     231             :   MSVCPError(Error Err) : Error(std::move(Err)) {}
     232             : };
     233             : 
     234             : // Work around MSVC's future implementation, similar to MSVCPError.
     235             : template <typename T> class MSVCPExpected : public Expected<T> {
     236             : public:
     237             :   MSVCPExpected()
     238             :       : Expected<T>(make_error<StringError>("", inconvertibleErrorCode())) {
     239             :     consumeError(this->takeError());
     240             :   }
     241             : 
     242             :   MSVCPExpected(MSVCPExpected &&Other) : Expected<T>(std::move(Other)) {}
     243             : 
     244             :   MSVCPExpected &operator=(MSVCPExpected &&Other) {
     245             :     Expected<T>::operator=(std::move(Other));
     246             :     return *this;
     247             :   }
     248             : 
     249             :   MSVCPExpected(Error Err) : Expected<T>(std::move(Err)) {}
     250             : 
     251             :   template <typename OtherT>
     252             :   MSVCPExpected(
     253             :       OtherT &&Val,
     254             :       typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
     255             :           nullptr)
     256             :       : Expected<T>(std::move(Val)) {}
     257             : 
     258             :   template <class OtherT>
     259             :   MSVCPExpected(
     260             :       Expected<OtherT> &&Other,
     261             :       typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
     262             :           nullptr)
     263             :       : Expected<T>(std::move(Other)) {}
     264             : 
     265             :   template <class OtherT>
     266             :   explicit MSVCPExpected(
     267             :       Expected<OtherT> &&Other,
     268             :       typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * =
     269             :           nullptr)
     270             :       : Expected<T>(std::move(Other)) {}
     271             : };
     272             : 
     273             : } // end namespace msvc_hacks
     274             : 
     275             : #endif // _MSC_VER
     276             : 
     277             : /// Provides a typedef for a tuple containing the decayed argument types.
     278             : template <typename T> class FunctionArgsTuple;
     279             : 
     280             : template <typename RetT, typename... ArgTs>
     281             : class FunctionArgsTuple<RetT(ArgTs...)> {
     282             : public:
     283             :   using Type = std::tuple<typename std::decay<
     284             :       typename std::remove_reference<ArgTs>::type>::type...>;
     285             : };
     286             : 
     287             : // ResultTraits provides typedefs and utilities specific to the return type
     288             : // of functions.
     289             : template <typename RetT> class ResultTraits {
     290             : public:
     291             :   // The return type wrapped in llvm::Expected.
     292             :   using ErrorReturnType = Expected<RetT>;
     293             : 
     294             : #ifdef _MSC_VER
     295             :   // The ErrorReturnType wrapped in a std::promise.
     296             :   using ReturnPromiseType = std::promise<msvc_hacks::MSVCPExpected<RetT>>;
     297             : 
     298             :   // The ErrorReturnType wrapped in a std::future.
     299             :   using ReturnFutureType = std::future<msvc_hacks::MSVCPExpected<RetT>>;
     300             : #else
     301             :   // The ErrorReturnType wrapped in a std::promise.
     302             :   using ReturnPromiseType = std::promise<ErrorReturnType>;
     303             : 
     304             :   // The ErrorReturnType wrapped in a std::future.
     305             :   using ReturnFutureType = std::future<ErrorReturnType>;
     306             : #endif
     307             : 
     308             :   // Create a 'blank' value of the ErrorReturnType, ready and safe to
     309             :   // overwrite.
     310             :   static ErrorReturnType createBlankErrorReturnValue() {
     311         792 :     return ErrorReturnType(RetT());
     312             :   }
     313             : 
     314             :   // Consume an abandoned ErrorReturnType.
     315           0 :   static void consumeAbandoned(ErrorReturnType RetOrErr) {
     316           0 :     consumeError(RetOrErr.takeError());
     317           0 :   }
     318             : };
     319             : 
     320             : // ResultTraits specialization for void functions.
     321             : template <> class ResultTraits<void> {
     322             : public:
     323             :   // For void functions, ErrorReturnType is llvm::Error.
     324             :   using ErrorReturnType = Error;
     325             : 
     326             : #ifdef _MSC_VER
     327             :   // The ErrorReturnType wrapped in a std::promise.
     328             :   using ReturnPromiseType = std::promise<msvc_hacks::MSVCPError>;
     329             : 
     330             :   // The ErrorReturnType wrapped in a std::future.
     331             :   using ReturnFutureType = std::future<msvc_hacks::MSVCPError>;
     332             : #else
     333             :   // The ErrorReturnType wrapped in a std::promise.
     334             :   using ReturnPromiseType = std::promise<ErrorReturnType>;
     335             : 
     336             :   // The ErrorReturnType wrapped in a std::future.
     337             :   using ReturnFutureType = std::future<ErrorReturnType>;
     338             : #endif
     339             : 
     340             :   // Create a 'blank' value of the ErrorReturnType, ready and safe to
     341             :   // overwrite.
     342             :   static ErrorReturnType createBlankErrorReturnValue() {
     343         642 :     return ErrorReturnType::success();
     344             :   }
     345             : 
     346             :   // Consume an abandoned ErrorReturnType.
     347           0 :   static void consumeAbandoned(ErrorReturnType Err) {
     348           0 :     consumeError(std::move(Err));
     349           0 :   }
     350             : };
     351             : 
     352             : // ResultTraits<Error> is equivalent to ResultTraits<void>. This allows
     353             : // handlers for void RPC functions to return either void (in which case they
     354             : // implicitly succeed) or Error (in which case their error return is
     355             : // propagated). See usage in HandlerTraits::runHandlerHelper.
     356             : template <> class ResultTraits<Error> : public ResultTraits<void> {};
     357             : 
     358             : // ResultTraits<Expected<T>> is equivalent to ResultTraits<T>. This allows
     359             : // handlers for RPC functions returning a T to return either a T (in which
     360             : // case they implicitly succeed) or Expected<T> (in which case their error
     361             : // return is propagated). See usage in HandlerTraits::runHandlerHelper.
     362             : template <typename RetT>
     363             : class ResultTraits<Expected<RetT>> : public ResultTraits<RetT> {};
     364             : 
     365             : // Determines whether an RPC function's defined error return type supports
     366             : // error return value.
     367             : template <typename T>
     368             : class SupportsErrorReturn {
     369             : public:
     370             :   static const bool value = false;
     371             : };
     372             : 
     373             : template <>
     374             : class SupportsErrorReturn<Error> {
     375             : public:
     376             :   static const bool value = true;
     377             : };
     378             : 
     379             : template <typename T>
     380             : class SupportsErrorReturn<Expected<T>> {
     381             : public:
     382             :   static const bool value = true;
     383             : };
     384             : 
     385             : // RespondHelper packages return values based on whether or not the declared
     386             : // RPC function return type supports error returns.
     387             : template <bool FuncSupportsErrorReturn>
     388             : class RespondHelper;
     389             : 
     390             : // RespondHelper specialization for functions that support error returns.
     391             : template <>
     392             : class RespondHelper<true> {
     393             : public:
     394             : 
     395             :   // Send Expected<T>.
     396             :   template <typename WireRetT, typename HandlerRetT, typename ChannelT,
     397             :             typename FunctionIdT, typename SequenceNumberT>
     398          17 :   static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
     399             :                           SequenceNumberT SeqNo,
     400             :                           Expected<HandlerRetT> ResultOrErr) {
     401          17 :     if (!ResultOrErr && ResultOrErr.template errorIsA<RPCFatalError>())
     402             :       return ResultOrErr.takeError();
     403             : 
     404             :     // Open the response message.
     405          51 :     if (auto Err = C.startSendMessage(ResponseId, SeqNo))
     406           0 :       return Err;
     407             : 
     408             :     // Serialize the result.
     409          51 :     if (auto Err =
     410             :         SerializationTraits<ChannelT, WireRetT,
     411             :                             Expected<HandlerRetT>>::serialize(
     412          17 :                                                      C, std::move(ResultOrErr)))
     413           0 :       return Err;
     414             : 
     415             :     // Close the response message.
     416           2 :     return C.endSendMessage();
     417             :   }
     418             : 
     419             :   template <typename ChannelT, typename FunctionIdT, typename SequenceNumberT>
     420           6 :   static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
     421             :                           SequenceNumberT SeqNo, Error Err) {
     422           6 :     if (Err && Err.isA<RPCFatalError>())
     423             :       return Err;
     424          18 :     if (auto Err2 = C.startSendMessage(ResponseId, SeqNo))
     425           0 :       return Err2;
     426          24 :     if (auto Err2 = serializeSeq(C, std::move(Err)))
     427           0 :       return Err2;
     428           2 :     return C.endSendMessage();
     429             :   }
     430             : 
     431             : };
     432             : 
     433             : // RespondHelper specialization for functions that do not support error returns.
     434             : template <>
     435             : class RespondHelper<false> {
     436             : public:
     437             : 
     438             :   template <typename WireRetT, typename HandlerRetT, typename ChannelT,
     439             :             typename FunctionIdT, typename SequenceNumberT>
     440         375 :   static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
     441             :                           SequenceNumberT SeqNo,
     442             :                           Expected<HandlerRetT> ResultOrErr) {
     443        1125 :     if (auto Err = ResultOrErr.takeError())
     444           0 :       return Err;
     445             : 
     446             :     // Open the response message.
     447        1125 :     if (auto Err = C.startSendMessage(ResponseId, SeqNo))
     448           0 :       return Err;
     449             : 
     450             :     // Serialize the result.
     451        1476 :     if (auto Err =
     452             :         SerializationTraits<ChannelT, WireRetT, HandlerRetT>::serialize(
     453         375 :                                                                C, *ResultOrErr))
     454           0 :       return Err;
     455             : 
     456             :     // Close the response message.
     457          24 :     return C.endSendMessage();
     458             :   }
     459             : 
     460             :   template <typename ChannelT, typename FunctionIdT, typename SequenceNumberT>
     461         215 :   static Error sendResult(ChannelT &C, const FunctionIdT &ResponseId,
     462             :                           SequenceNumberT SeqNo, Error Err) {
     463         215 :     if (Err)
     464             :       return Err;
     465         645 :     if (auto Err2 = C.startSendMessage(ResponseId, SeqNo))
     466           0 :       return Err2;
     467           8 :     return C.endSendMessage();
     468             :   }
     469             : 
     470             : };
     471             : 
     472             : 
     473             : // Send a response of the given wire return type (WireRetT) over the
     474             : // channel, with the given sequence number.
     475             : template <typename WireRetT, typename HandlerRetT, typename ChannelT,
     476             :           typename FunctionIdT, typename SequenceNumberT>
     477         392 : Error respond(ChannelT &C, const FunctionIdT &ResponseId,
     478             :               SequenceNumberT SeqNo, Expected<HandlerRetT> ResultOrErr) {
     479             :   return RespondHelper<SupportsErrorReturn<WireRetT>::value>::
     480        1152 :     template sendResult<WireRetT>(C, ResponseId, SeqNo, std::move(ResultOrErr));
     481             : }
     482             : 
     483             : // Send an empty response message on the given channel to indicate that
     484             : // the handler ran.
     485             : template <typename WireRetT, typename ChannelT, typename FunctionIdT,
     486             :           typename SequenceNumberT>
     487         221 : Error respond(ChannelT &C, const FunctionIdT &ResponseId, SequenceNumberT SeqNo,
     488             :               Error Err) {
     489             :   return RespondHelper<SupportsErrorReturn<WireRetT>::value>::
     490         663 :     sendResult(C, ResponseId, SeqNo, std::move(Err));
     491             : }
     492             : 
     493             : // Converts a given type to the equivalent error return type.
     494             : template <typename T> class WrappedHandlerReturn {
     495             : public:
     496             :   using Type = Expected<T>;
     497             : };
     498             : 
     499             : template <typename T> class WrappedHandlerReturn<Expected<T>> {
     500             : public:
     501             :   using Type = Expected<T>;
     502             : };
     503             : 
     504             : template <> class WrappedHandlerReturn<void> {
     505             : public:
     506             :   using Type = Error;
     507             : };
     508             : 
     509             : template <> class WrappedHandlerReturn<Error> {
     510             : public:
     511             :   using Type = Error;
     512             : };
     513             : 
     514             : template <> class WrappedHandlerReturn<ErrorSuccess> {
     515             : public:
     516             :   using Type = Error;
     517             : };
     518             : 
     519             : // Traits class that strips the response function from the list of handler
     520             : // arguments.
     521             : template <typename FnT> class AsyncHandlerTraits;
     522             : 
     523             : template <typename ResultT, typename... ArgTs>
     524             : class AsyncHandlerTraits<Error(std::function<Error(Expected<ResultT>)>, ArgTs...)> {
     525             : public:
     526             :   using Type = Error(ArgTs...);
     527             :   using ResultType = Expected<ResultT>;
     528             : };
     529             : 
     530             : template <typename... ArgTs>
     531             : class AsyncHandlerTraits<Error(std::function<Error(Error)>, ArgTs...)> {
     532             : public:
     533             :   using Type = Error(ArgTs...);
     534             :   using ResultType = Error;
     535             : };
     536             : 
     537             : template <typename... ArgTs>
     538             : class AsyncHandlerTraits<ErrorSuccess(std::function<Error(Error)>, ArgTs...)> {
     539             : public:
     540             :   using Type = Error(ArgTs...);
     541             :   using ResultType = Error;
     542             : };
     543             : 
     544             : template <typename... ArgTs>
     545             : class AsyncHandlerTraits<void(std::function<Error(Error)>, ArgTs...)> {
     546             : public:
     547             :   using Type = Error(ArgTs...);
     548             :   using ResultType = Error;
     549             : };
     550             : 
     551             : template <typename ResponseHandlerT, typename... ArgTs>
     552             : class AsyncHandlerTraits<Error(ResponseHandlerT, ArgTs...)> :
     553             :     public AsyncHandlerTraits<Error(typename std::decay<ResponseHandlerT>::type,
     554             :                                     ArgTs...)> {};
     555             : 
     556             : // This template class provides utilities related to RPC function handlers.
     557             : // The base case applies to non-function types (the template class is
     558             : // specialized for function types) and inherits from the appropriate
     559             : // speciilization for the given non-function type's call operator.
     560             : template <typename HandlerT>
     561             : class HandlerTraits : public HandlerTraits<decltype(
     562             :                           &std::remove_reference<HandlerT>::type::operator())> {
     563             : };
     564             : 
     565             : // Traits for handlers with a given function type.
     566             : template <typename RetT, typename... ArgTs>
     567             : class HandlerTraits<RetT(ArgTs...)> {
     568             : public:
     569             :   // Function type of the handler.
     570             :   using Type = RetT(ArgTs...);
     571             : 
     572             :   // Return type of the handler.
     573             :   using ReturnType = RetT;
     574             : 
     575             :   // Call the given handler with the given arguments.
     576             :   template <typename HandlerT, typename... TArgTs>
     577             :   static typename WrappedHandlerReturn<RetT>::Type
     578             :   unpackAndRun(HandlerT &Handler, std::tuple<TArgTs...> &Args) {
     579             :     return unpackAndRunHelper(Handler, Args,
     580         757 :                               llvm::index_sequence_for<TArgTs...>());
     581             :   }
     582             : 
     583             :   // Call the given handler with the given arguments.
     584             :   template <typename HandlerT, typename ResponderT, typename... TArgTs>
     585             :   static Error unpackAndRunAsync(HandlerT &Handler, ResponderT &Responder,
     586             :                                  std::tuple<TArgTs...> &Args) {
     587             :     return unpackAndRunAsyncHelper(Handler, Responder, Args,
     588           6 :                                    llvm::index_sequence_for<TArgTs...>());
     589             :   }
     590             : 
     591             :   // Call the given handler with the given arguments.
     592             :   template <typename HandlerT>
     593             :   static typename std::enable_if<
     594             :       std::is_void<typename HandlerTraits<HandlerT>::ReturnType>::value,
     595             :       Error>::type
     596             :   run(HandlerT &Handler, ArgTs &&... Args) {
     597          14 :     Handler(std::move(Args)...);
     598          42 :     return Error::success();
     599             :   }
     600             : 
     601             :   template <typename HandlerT, typename... TArgTs>
     602             :   static typename std::enable_if<
     603             :       !std::is_void<typename HandlerTraits<HandlerT>::ReturnType>::value,
     604             :       typename HandlerTraits<HandlerT>::ReturnType>::type
     605           4 :   run(HandlerT &Handler, TArgTs... Args) {
     606        1143 :     return Handler(std::move(Args)...);
     607             :   }
     608             : 
     609             :   // Serialize arguments to the channel.
     610             :   template <typename ChannelT, typename... CArgTs>
     611             :   static Error serializeArgs(ChannelT &C, const CArgTs... CArgs) {
     612         943 :     return SequenceSerialization<ChannelT, ArgTs...>::serialize(C, CArgs...);
     613             :   }
     614             : 
     615             :   // Deserialize arguments from the channel.
     616             :   template <typename ChannelT, typename... CArgTs>
     617             :   static Error deserializeArgs(ChannelT &C, std::tuple<CArgTs...> &Args) {
     618             :     return deserializeArgsHelper(C, Args,
     619        1163 :                                  llvm::index_sequence_for<CArgTs...>());
     620             :   }
     621             : 
     622             : private:
     623             :   template <typename ChannelT, typename... CArgTs, size_t... Indexes>
     624           1 :   static Error deserializeArgsHelper(ChannelT &C, std::tuple<CArgTs...> &Args,
     625             :                                      llvm::index_sequence<Indexes...> _) {
     626             :     return SequenceSerialization<ChannelT, ArgTs...>::deserialize(
     627        1291 :         C, std::get<Indexes>(Args)...);
     628             :   }
     629             : 
     630             :   template <typename HandlerT, typename ArgTuple, size_t... Indexes>
     631             :   static typename WrappedHandlerReturn<
     632             :       typename HandlerTraits<HandlerT>::ReturnType>::Type
     633         457 :   unpackAndRunHelper(HandlerT &Handler, ArgTuple &Args,
     634             :                      llvm::index_sequence<Indexes...>) {
     635        2221 :     return run(Handler, std::move(std::get<Indexes>(Args))...);
     636             :   }
     637             : 
     638             : 
     639             :   template <typename HandlerT, typename ResponderT, typename ArgTuple,
     640             :             size_t... Indexes>
     641             :   static typename WrappedHandlerReturn<
     642             :       typename HandlerTraits<HandlerT>::ReturnType>::Type
     643             :   unpackAndRunAsyncHelper(HandlerT &Handler, ResponderT &Responder,
     644             :                           ArgTuple &Args,
     645             :                           llvm::index_sequence<Indexes...>) {
     646           5 :     return run(Handler, Responder, std::move(std::get<Indexes>(Args))...);
     647             :   }
     648             : };
     649             : 
     650             : // Handler traits for free functions.
     651             : template <typename RetT, typename... ArgTs>
     652             : class HandlerTraits<RetT(*)(ArgTs...)>
     653             :   : public HandlerTraits<RetT(ArgTs...)> {};
     654             : 
     655             : // Handler traits for class methods (especially call operators for lambdas).
     656             : template <typename Class, typename RetT, typename... ArgTs>
     657             : class HandlerTraits<RetT (Class::*)(ArgTs...)>
     658             :     : public HandlerTraits<RetT(ArgTs...)> {};
     659             : 
     660             : // Handler traits for const class methods (especially call operators for
     661             : // lambdas).
     662             : template <typename Class, typename RetT, typename... ArgTs>
     663             : class HandlerTraits<RetT (Class::*)(ArgTs...) const>
     664             :     : public HandlerTraits<RetT(ArgTs...)> {};
     665             : 
     666             : // Utility to peel the Expected wrapper off a response handler error type.
     667             : template <typename HandlerT> class ResponseHandlerArg;
     668             : 
     669             : template <typename ArgT> class ResponseHandlerArg<Error(Expected<ArgT>)> {
     670             : public:
     671             :   using ArgType = Expected<ArgT>;
     672             :   using UnwrappedArgType = ArgT;
     673             : };
     674             : 
     675             : template <typename ArgT>
     676             : class ResponseHandlerArg<ErrorSuccess(Expected<ArgT>)> {
     677             : public:
     678             :   using ArgType = Expected<ArgT>;
     679             :   using UnwrappedArgType = ArgT;
     680             : };
     681             : 
     682             : template <> class ResponseHandlerArg<Error(Error)> {
     683             : public:
     684             :   using ArgType = Error;
     685             : };
     686             : 
     687             : template <> class ResponseHandlerArg<ErrorSuccess(Error)> {
     688             : public:
     689             :   using ArgType = Error;
     690             : };
     691             : 
     692             : // ResponseHandler represents a handler for a not-yet-received function call
     693             : // result.
     694             : template <typename ChannelT> class ResponseHandler {
     695             : public:
     696             :   virtual ~ResponseHandler() {}
     697             : 
     698             :   // Reads the function result off the wire and acts on it. The meaning of
     699             :   // "act" will depend on how this method is implemented in any given
     700             :   // ResponseHandler subclass but could, for example, mean running a
     701             :   // user-specified handler or setting a promise value.
     702             :   virtual Error handleResponse(ChannelT &C) = 0;
     703             : 
     704             :   // Abandons this outstanding result.
     705             :   virtual void abandon() = 0;
     706             : 
     707             :   // Create an error instance representing an abandoned response.
     708             :   static Error createAbandonedResponseError() {
     709             :     return make_error<ResponseAbandoned>();
     710             :   }
     711             : };
     712             : 
     713             : // ResponseHandler subclass for RPC functions with non-void returns.
     714             : template <typename ChannelT, typename FuncRetT, typename HandlerT>
     715         377 : class ResponseHandlerImpl : public ResponseHandler<ChannelT> {
     716             : public:
     717         377 :   ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
     718             : 
     719             :   // Handle the result by deserializing it from the channel then passing it
     720             :   // to the user defined handler.
     721         377 :   Error handleResponse(ChannelT &C) override {
     722             :     using UnwrappedArgType = typename ResponseHandlerArg<
     723             :         typename HandlerTraits<HandlerT>::Type>::UnwrappedArgType;
     724          48 :     UnwrappedArgType Result;
     725        1133 :     if (auto Err =
     726             :             SerializationTraits<ChannelT, FuncRetT,
     727             :                                 UnwrappedArgType>::deserialize(C, Result))
     728           0 :       return Err;
     729        1157 :     if (auto Err = C.endReceiveMessage())
     730             :       return Err;
     731        2230 :     return Handler(std::move(Result));
     732             :   }
     733             : 
     734             :   // Abandon this response by calling the handler with an 'abandoned response'
     735             :   // error.
     736           0 :   void abandon() override {
     737           0 :     if (auto Err = Handler(this->createAbandonedResponseError())) {
     738             :       // Handlers should not fail when passed an abandoned response error.
     739           0 :       report_fatal_error(std::move(Err));
     740             :     }
     741           0 :   }
     742             : 
     743             : private:
     744             :   HandlerT Handler;
     745             : };
     746             : 
     747             : // ResponseHandler subclass for RPC functions with void returns.
     748             : template <typename ChannelT, typename HandlerT>
     749         213 : class ResponseHandlerImpl<ChannelT, void, HandlerT>
     750             :     : public ResponseHandler<ChannelT> {
     751             : public:
     752         213 :   ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
     753             : 
     754             :   // Handle the result (no actual value, just a notification that the function
     755             :   // has completed on the remote end) by calling the user-defined handler with
     756             :   // Error::success().
     757         213 :   Error handleResponse(ChannelT &C) override {
     758         645 :     if (auto Err = C.endReceiveMessage())
     759             :       return Err;
     760        1701 :     return Handler(Error::success());
     761             :   }
     762             : 
     763             :   // Abandon this response by calling the handler with an 'abandoned response'
     764             :   // error.
     765           0 :   void abandon() override {
     766           0 :     if (auto Err = Handler(this->createAbandonedResponseError())) {
     767             :       // Handlers should not fail when passed an abandoned response error.
     768           0 :       report_fatal_error(std::move(Err));
     769             :     }
     770           0 :   }
     771             : 
     772             : private:
     773             :   HandlerT Handler;
     774             : };
     775             : 
     776             : template <typename ChannelT, typename FuncRetT, typename HandlerT>
     777          17 : class ResponseHandlerImpl<ChannelT, Expected<FuncRetT>, HandlerT>
     778             :     : public ResponseHandler<ChannelT> {
     779             : public:
     780          17 :   ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
     781             : 
     782             :   // Handle the result by deserializing it from the channel then passing it
     783             :   // to the user defined handler.
     784          17 :   Error handleResponse(ChannelT &C) override {
     785             :     using HandlerArgType = typename ResponseHandlerArg<
     786             :         typename HandlerTraits<HandlerT>::Type>::ArgType;
     787          51 :     HandlerArgType Result((typename HandlerArgType::value_type()));
     788             : 
     789          51 :     if (auto Err =
     790             :             SerializationTraits<ChannelT, Expected<FuncRetT>,
     791             :                                 HandlerArgType>::deserialize(C, Result))
     792           0 :       return Err;
     793          53 :     if (auto Err = C.endReceiveMessage())
     794             :       return Err;
     795          98 :     return Handler(std::move(Result));
     796             :   }
     797             : 
     798             :   // Abandon this response by calling the handler with an 'abandoned response'
     799             :   // error.
     800           0 :   void abandon() override {
     801           0 :     if (auto Err = Handler(this->createAbandonedResponseError())) {
     802             :       // Handlers should not fail when passed an abandoned response error.
     803           0 :       report_fatal_error(std::move(Err));
     804             :     }
     805           0 :   }
     806             : 
     807             : private:
     808             :   HandlerT Handler;
     809             : };
     810             : 
     811             : template <typename ChannelT, typename HandlerT>
     812           6 : class ResponseHandlerImpl<ChannelT, Error, HandlerT>
     813             :     : public ResponseHandler<ChannelT> {
     814             : public:
     815           6 :   ResponseHandlerImpl(HandlerT Handler) : Handler(std::move(Handler)) {}
     816             : 
     817             :   // Handle the result by deserializing it from the channel then passing it
     818             :   // to the user defined handler.
     819           6 :   Error handleResponse(ChannelT &C) override {
     820          18 :     Error Result = Error::success();
     821          18 :     if (auto Err =
     822             :             SerializationTraits<ChannelT, Error, Error>::deserialize(C, Result))
     823           0 :       return Err;
     824          20 :     if (auto Err = C.endReceiveMessage())
     825             :       return Err;
     826          32 :     return Handler(std::move(Result));
     827             :   }
     828             : 
     829             :   // Abandon this response by calling the handler with an 'abandoned response'
     830             :   // error.
     831           0 :   void abandon() override {
     832           0 :     if (auto Err = Handler(this->createAbandonedResponseError())) {
     833             :       // Handlers should not fail when passed an abandoned response error.
     834           0 :       report_fatal_error(std::move(Err));
     835             :     }
     836           0 :   }
     837             : 
     838             : private:
     839             :   HandlerT Handler;
     840             : };
     841             : 
     842             : // Create a ResponseHandler from a given user handler.
     843             : template <typename ChannelT, typename FuncRetT, typename HandlerT>
     844             : std::unique_ptr<ResponseHandler<ChannelT>> createResponseHandler(HandlerT H) {
     845             :   return llvm::make_unique<ResponseHandlerImpl<ChannelT, FuncRetT, HandlerT>>(
     846        2452 :       std::move(H));
     847             : }
     848             : 
     849             : // Helper for wrapping member functions up as functors. This is useful for
     850             : // installing methods as result handlers.
     851             : template <typename ClassT, typename RetT, typename... ArgTs>
     852             : class MemberFnWrapper {
     853             : public:
     854             :   using MethodT = RetT (ClassT::*)(ArgTs...);
     855             :   MemberFnWrapper(ClassT &Instance, MethodT Method)
     856             :       : Instance(Instance), Method(Method) {}
     857           9 :   RetT operator()(ArgTs &&... Args) {
     858         363 :     return (Instance.*Method)(std::move(Args)...);
     859             :   }
     860             : 
     861             : private:
     862             :   ClassT &Instance;
     863             :   MethodT Method;
     864             : };
     865             : 
     866             : // Helper that provides a Functor for deserializing arguments.
     867             : template <typename... ArgTs> class ReadArgs {
     868             : public:
     869             :   Error operator()() { return Error::success(); }
     870             : };
     871             : 
     872             : template <typename ArgT, typename... ArgTs>
     873             : class ReadArgs<ArgT, ArgTs...> : public ReadArgs<ArgTs...> {
     874             : public:
     875             :   ReadArgs(ArgT &Arg, ArgTs &... Args)
     876             :       : ReadArgs<ArgTs...>(Args...), Arg(Arg) {}
     877             : 
     878             :   Error operator()(ArgT &ArgVal, ArgTs &... ArgVals) {
     879             :     this->Arg = std::move(ArgVal);
     880             :     return ReadArgs<ArgTs...>::operator()(ArgVals...);
     881             :   }
     882             : 
     883             : private:
     884             :   ArgT &Arg;
     885             : };
     886             : 
     887             : // Manage sequence numbers.
     888         485 : template <typename SequenceNumberT> class SequenceNumberManager {
     889             : public:
     890             :   // Reset, making all sequence numbers available.
     891             :   void reset() {
     892           0 :     std::lock_guard<std::mutex> Lock(SeqNoLock);
     893           0 :     NextSequenceNumber = 0;
     894           0 :     FreeSequenceNumbers.clear();
     895             :   }
     896             : 
     897             :   // Get the next available sequence number. Will re-use numbers that have
     898             :   // been released.
     899         613 :   SequenceNumberT getSequenceNumber() {
     900        1839 :     std::lock_guard<std::mutex> Lock(SeqNoLock);
     901        1226 :     if (FreeSequenceNumbers.empty())
     902          49 :       return NextSequenceNumber++;
     903        1128 :     auto SequenceNumber = FreeSequenceNumbers.back();
     904         564 :     FreeSequenceNumbers.pop_back();
     905         564 :     return SequenceNumber;
     906             :   }
     907             : 
     908             :   // Release a sequence number, making it available for re-use.
     909         613 :   void releaseSequenceNumber(SequenceNumberT SequenceNumber) {
     910        1839 :     std::lock_guard<std::mutex> Lock(SeqNoLock);
     911         613 :     FreeSequenceNumbers.push_back(SequenceNumber);
     912         613 :   }
     913             : 
     914             : private:
     915             :   std::mutex SeqNoLock;
     916             :   SequenceNumberT NextSequenceNumber = 0;
     917             :   std::vector<SequenceNumberT> FreeSequenceNumbers;
     918             : };
     919             : 
     920             : // Checks that predicate P holds for each corresponding pair of type arguments
     921             : // from T1 and T2 tuple.
     922             : template <template <class, class> class P, typename T1Tuple, typename T2Tuple>
     923             : class RPCArgTypeCheckHelper;
     924             : 
     925             : template <template <class, class> class P>
     926             : class RPCArgTypeCheckHelper<P, std::tuple<>, std::tuple<>> {
     927             : public:
     928             :   static const bool value = true;
     929             : };
     930             : 
     931             : template <template <class, class> class P, typename T, typename... Ts,
     932             :           typename U, typename... Us>
     933             : class RPCArgTypeCheckHelper<P, std::tuple<T, Ts...>, std::tuple<U, Us...>> {
     934             : public:
     935             :   static const bool value =
     936             :       P<T, U>::value &&
     937             :       RPCArgTypeCheckHelper<P, std::tuple<Ts...>, std::tuple<Us...>>::value;
     938             : };
     939             : 
     940             : template <template <class, class> class P, typename T1Sig, typename T2Sig>
     941             : class RPCArgTypeCheck {
     942             : public:
     943             :   using T1Tuple = typename FunctionArgsTuple<T1Sig>::Type;
     944             :   using T2Tuple = typename FunctionArgsTuple<T2Sig>::Type;
     945             : 
     946             :   static_assert(std::tuple_size<T1Tuple>::value >=
     947             :                     std::tuple_size<T2Tuple>::value,
     948             :                 "Too many arguments to RPC call");
     949             :   static_assert(std::tuple_size<T1Tuple>::value <=
     950             :                     std::tuple_size<T2Tuple>::value,
     951             :                 "Too few arguments to RPC call");
     952             : 
     953             :   static const bool value = RPCArgTypeCheckHelper<P, T1Tuple, T2Tuple>::value;
     954             : };
     955             : 
     956             : template <typename ChannelT, typename WireT, typename ConcreteT>
     957             : class CanSerialize {
     958             : private:
     959             :   using S = SerializationTraits<ChannelT, WireT, ConcreteT>;
     960             : 
     961             :   template <typename T>
     962             :   static std::true_type
     963             :   check(typename std::enable_if<
     964             :         std::is_same<decltype(T::serialize(std::declval<ChannelT &>(),
     965             :                                            std::declval<const ConcreteT &>())),
     966             :                      Error>::value,
     967             :         void *>::type);
     968             : 
     969             :   template <typename> static std::false_type check(...);
     970             : 
     971             : public:
     972             :   static const bool value = decltype(check<S>(0))::value;
     973             : };
     974             : 
     975             : template <typename ChannelT, typename WireT, typename ConcreteT>
     976             : class CanDeserialize {
     977             : private:
     978             :   using S = SerializationTraits<ChannelT, WireT, ConcreteT>;
     979             : 
     980             :   template <typename T>
     981             :   static std::true_type
     982             :   check(typename std::enable_if<
     983             :         std::is_same<decltype(T::deserialize(std::declval<ChannelT &>(),
     984             :                                              std::declval<ConcreteT &>())),
     985             :                      Error>::value,
     986             :         void *>::type);
     987             : 
     988             :   template <typename> static std::false_type check(...);
     989             : 
     990             : public:
     991             :   static const bool value = decltype(check<S>(0))::value;
     992             : };
     993             : 
     994             : /// Contains primitive utilities for defining, calling and handling calls to
     995             : /// remote procedures. ChannelT is a bidirectional stream conforming to the
     996             : /// RPCChannel interface (see RPCChannel.h), FunctionIdT is a procedure
     997             : /// identifier type that must be serializable on ChannelT, and SequenceNumberT
     998             : /// is an integral type that will be used to number in-flight function calls.
     999             : ///
    1000             : /// These utilities support the construction of very primitive RPC utilities.
    1001             : /// Their intent is to ensure correct serialization and deserialization of
    1002             : /// procedure arguments, and to keep the client and server's view of the API in
    1003             : /// sync.
    1004             : template <typename ImplT, typename ChannelT, typename FunctionIdT,
    1005             :           typename SequenceNumberT>
    1006         582 : class RPCEndpointBase {
    1007             : protected:
    1008             :   class OrcRPCInvalid : public Function<OrcRPCInvalid, void()> {
    1009             :   public:
    1010             :     static const char *getName() { return "__orc_rpc$invalid"; }
    1011             :   };
    1012             : 
    1013             :   class OrcRPCResponse : public Function<OrcRPCResponse, void()> {
    1014             :   public:
    1015             :     static const char *getName() { return "__orc_rpc$response"; }
    1016             :   };
    1017             : 
    1018             :   class OrcRPCNegotiate
    1019             :       : public Function<OrcRPCNegotiate, FunctionIdT(std::string)> {
    1020             :   public:
    1021             :     static const char *getName() { return "__orc_rpc$negotiate"; }
    1022             :   };
    1023             : 
    1024             :   // Helper predicate for testing for the presence of SerializeTraits
    1025             :   // serializers.
    1026             :   template <typename WireT, typename ConcreteT>
    1027             :   class CanSerializeCheck : detail::CanSerialize<ChannelT, WireT, ConcreteT> {
    1028             :   public:
    1029             :     using detail::CanSerialize<ChannelT, WireT, ConcreteT>::value;
    1030             : 
    1031             :     static_assert(value, "Missing serializer for argument (Can't serialize the "
    1032             :                          "first template type argument of CanSerializeCheck "
    1033             :                          "from the second)");
    1034             :   };
    1035             : 
    1036             :   // Helper predicate for testing for the presence of SerializeTraits
    1037             :   // deserializers.
    1038             :   template <typename WireT, typename ConcreteT>
    1039             :   class CanDeserializeCheck
    1040             :       : detail::CanDeserialize<ChannelT, WireT, ConcreteT> {
    1041             :   public:
    1042             :     using detail::CanDeserialize<ChannelT, WireT, ConcreteT>::value;
    1043             : 
    1044             :     static_assert(value, "Missing deserializer for argument (Can't deserialize "
    1045             :                          "the second template type argument of "
    1046             :                          "CanDeserializeCheck from the first)");
    1047             :   };
    1048             : 
    1049             : public:
    1050             :   /// Construct an RPC instance on a channel.
    1051          97 :   RPCEndpointBase(ChannelT &C, bool LazyAutoNegotiation)
    1052         776 :       : C(C), LazyAutoNegotiation(LazyAutoNegotiation) {
    1053             :     // Hold ResponseId in a special variable, since we expect Response to be
    1054             :     // called relatively frequently, and want to avoid the map lookup.
    1055          97 :     ResponseId = FnIdAllocator.getResponseId();
    1056          97 :     RemoteFunctionIds[OrcRPCResponse::getPrototype()] = ResponseId;
    1057             : 
    1058             :     // Register the negotiate function id and handler.
    1059          97 :     auto NegotiateId = FnIdAllocator.getNegotiateId();
    1060          97 :     RemoteFunctionIds[OrcRPCNegotiate::getPrototype()] = NegotiateId;
    1061         291 :     Handlers[NegotiateId] = wrapHandler<OrcRPCNegotiate>(
    1062         486 :         [this](const std::string &Name) { return handleNegotiate(Name); });
    1063          97 :   }
    1064             : 
    1065             : 
    1066             :   /// Negotiate a function id for Func with the other end of the channel.
    1067           8 :   template <typename Func> Error negotiateFunction(bool Retry = false) {
    1068          24 :     return getRemoteFunctionId<Func>(true, Retry).takeError();
    1069             :   }
    1070             : 
    1071             :   /// Append a call Func, does not call send on the channel.
    1072             :   /// The first argument specifies a user-defined handler to be run when the
    1073             :   /// function returns. The handler should take an Expected<Func::ReturnType>,
    1074             :   /// or an Error (if Func::ReturnType is void). The handler will be called
    1075             :   /// with an error if the return value is abandoned due to a channel error.
    1076             :   template <typename Func, typename HandlerT, typename... ArgTs>
    1077         613 :   Error appendCallAsync(HandlerT Handler, const ArgTs &... Args) {
    1078             : 
    1079             :     static_assert(
    1080             :         detail::RPCArgTypeCheck<CanSerializeCheck, typename Func::Type,
    1081             :                                 void(ArgTs...)>::value,
    1082             :         "");
    1083             : 
    1084             :     // Look up the function ID.
    1085             :     FunctionIdT FnId;
    1086        1839 :     if (auto FnIdOrErr = getRemoteFunctionId<Func>(LazyAutoNegotiation, false))
    1087         613 :       FnId = *FnIdOrErr;
    1088             :     else {
    1089             :       // Negotiation failed. Notify the handler then return the negotiate-failed
    1090             :       // error.
    1091           0 :       cantFail(Handler(make_error<ResponseAbandoned>()));
    1092           0 :       return FnIdOrErr.takeError();
    1093             :     }
    1094             : 
    1095             :     SequenceNumberT SeqNo; // initialized in locked scope below.
    1096             :     {
    1097             :       // Lock the pending responses map and sequence number manager.
    1098        1839 :       std::lock_guard<std::mutex> Lock(ResponsesMutex);
    1099             : 
    1100             :       // Allocate a sequence number.
    1101         613 :       SeqNo = SequenceNumberMgr.getSequenceNumber();
    1102             :       assert(!PendingResponses.count(SeqNo) &&
    1103             :              "Sequence number already allocated");
    1104             : 
    1105             :       // Install the user handler.
    1106        1851 :       PendingResponses[SeqNo] =
    1107             :         detail::createResponseHandler<ChannelT, typename Func::ReturnType>(
    1108         613 :             std::move(Handler));
    1109             :     }
    1110             : 
    1111             :     // Open the function call message.
    1112        1839 :     if (auto Err = C.startSendMessage(FnId, SeqNo)) {
    1113           0 :       abandonPendingResponses();
    1114           0 :       return Err;
    1115             :     }
    1116             : 
    1117             :     // Serialize the call arguments.
    1118        2456 :     if (auto Err = detail::HandlerTraits<typename Func::Type>::serializeArgs(
    1119             :             C, Args...)) {
    1120           0 :       abandonPendingResponses();
    1121           0 :       return Err;
    1122             :     }
    1123             : 
    1124             :     // Close the function call messagee.
    1125        2452 :     if (auto Err = C.endSendMessage()) {
    1126             :       abandonPendingResponses();
    1127             :       return Err;
    1128             :     }
    1129             : 
    1130        1839 :     return Error::success();
    1131             :   }
    1132             : 
    1133             :   Error sendAppendedCalls() { return C.send(); };
    1134             : 
    1135             :   template <typename Func, typename HandlerT, typename... ArgTs>
    1136          12 :   Error callAsync(HandlerT Handler, const ArgTs &... Args) {
    1137          36 :     if (auto Err = appendCallAsync<Func>(std::move(Handler), Args...))
    1138           0 :       return Err;
    1139          12 :     return C.send();
    1140             :   }
    1141             : 
    1142             :   /// Handle one incoming call.
    1143        1226 :   Error handleOne() {
    1144             :     FunctionIdT FnId;
    1145             :     SequenceNumberT SeqNo;
    1146        3678 :     if (auto Err = C.startReceiveMessage(FnId, SeqNo)) {
    1147           0 :       abandonPendingResponses();
    1148           0 :       return Err;
    1149             :     }
    1150        1226 :     if (FnId == ResponseId)
    1151         613 :       return handleResponse(SeqNo);
    1152        1226 :     auto I = Handlers.find(FnId);
    1153        1226 :     if (I != Handlers.end())
    1154         613 :       return I->second(C, SeqNo);
    1155             : 
    1156             :     // else: No handler found. Report error to client?
    1157             :     return make_error<BadFunctionCall<FunctionIdT, SequenceNumberT>>(FnId,
    1158           0 :                                                                      SeqNo);
    1159             :   }
    1160             : 
    1161             :   /// Helper for handling setter procedures - this method returns a functor that
    1162             :   /// sets the variables referred to by Args... to values deserialized from the
    1163             :   /// channel.
    1164             :   /// E.g.
    1165             :   ///
    1166             :   ///   typedef Function<0, bool, int> Func1;
    1167             :   ///
    1168             :   ///   ...
    1169             :   ///   bool B;
    1170             :   ///   int I;
    1171             :   ///   if (auto Err = expect<Func1>(Channel, readArgs(B, I)))
    1172             :   ///     /* Handle Args */ ;
    1173             :   ///
    1174             :   template <typename... ArgTs>
    1175             :   static detail::ReadArgs<ArgTs...> readArgs(ArgTs &... Args) {
    1176             :     return detail::ReadArgs<ArgTs...>(Args...);
    1177             :   }
    1178             : 
    1179             :   /// Abandon all outstanding result handlers.
    1180             :   ///
    1181             :   /// This will call all currently registered result handlers to receive an
    1182             :   /// "abandoned" error as their argument. This is used internally by the RPC
    1183             :   /// in error situations, but can also be called directly by clients who are
    1184             :   /// disconnecting from the remote and don't or can't expect responses to their
    1185             :   /// outstanding calls. (Especially for outstanding blocking calls, calling
    1186             :   /// this function may be necessary to avoid dead threads).
    1187           0 :   void abandonPendingResponses() {
    1188             :     // Lock the pending responses map and sequence number manager.
    1189           0 :     std::lock_guard<std::mutex> Lock(ResponsesMutex);
    1190             : 
    1191           0 :     for (auto &KV : PendingResponses)
    1192           0 :       KV.second->abandon();
    1193           0 :     PendingResponses.clear();
    1194           0 :     SequenceNumberMgr.reset();
    1195           0 :   }
    1196             : 
    1197             :   /// Remove the handler for the given function.
    1198             :   /// A handler must currently be registered for this function.
    1199             :   template <typename Func>
    1200           1 :   void removeHandler() {
    1201           4 :     auto IdItr = LocalFunctionIds.find(Func::getPrototype());
    1202             :     assert(IdItr != LocalFunctionIds.end() &&
    1203             :            "Function does not have a registered handler");
    1204           3 :     auto HandlerItr = Handlers.find(IdItr->second);
    1205             :     assert(HandlerItr != Handlers.end() &&
    1206             :            "Function does not have a registered handler");
    1207           2 :     Handlers.erase(HandlerItr);
    1208           1 :   }
    1209             : 
    1210             :   /// Clear all handlers.
    1211             :   void clearHandlers() {
    1212           2 :     Handlers.clear();
    1213             :   }
    1214             : 
    1215             : protected:
    1216             : 
    1217             :   FunctionIdT getInvalidFunctionId() const {
    1218             :     return FnIdAllocator.getInvalidId();
    1219             :   }
    1220             : 
    1221             :   /// Add the given handler to the handler map and make it available for
    1222             :   /// autonegotiation and execution.
    1223             :   template <typename Func, typename HandlerT>
    1224         617 :   void addHandlerImpl(HandlerT Handler) {
    1225             : 
    1226             :     static_assert(detail::RPCArgTypeCheck<
    1227             :                       CanDeserializeCheck, typename Func::Type,
    1228             :                       typename detail::HandlerTraits<HandlerT>::Type>::value,
    1229             :                   "");
    1230             : 
    1231        1234 :     FunctionIdT NewFnId = FnIdAllocator.template allocate<Func>();
    1232        2468 :     LocalFunctionIds[Func::getPrototype()] = NewFnId;
    1233        1851 :     Handlers[NewFnId] = wrapHandler<Func>(std::move(Handler));
    1234         617 :   }
    1235             : 
    1236             :   template <typename Func, typename HandlerT>
    1237           3 :   void addAsyncHandlerImpl(HandlerT Handler) {
    1238             : 
    1239             :     static_assert(detail::RPCArgTypeCheck<
    1240             :                       CanDeserializeCheck, typename Func::Type,
    1241             :                       typename detail::AsyncHandlerTraits<
    1242             :                         typename detail::HandlerTraits<HandlerT>::Type
    1243             :                       >::Type>::value,
    1244             :                   "");
    1245             : 
    1246           6 :     FunctionIdT NewFnId = FnIdAllocator.template allocate<Func>();
    1247          12 :     LocalFunctionIds[Func::getPrototype()] = NewFnId;
    1248           9 :     Handlers[NewFnId] = wrapAsyncHandler<Func>(std::move(Handler));
    1249           3 :   }
    1250             : 
    1251         613 :   Error handleResponse(SequenceNumberT SeqNo) {
    1252             :     using Handler = typename decltype(PendingResponses)::mapped_type;
    1253        1226 :     Handler PRHandler;
    1254             : 
    1255             :     {
    1256             :       // Lock the pending responses map and sequence number manager.
    1257        1839 :       std::unique_lock<std::mutex> Lock(ResponsesMutex);
    1258        1226 :       auto I = PendingResponses.find(SeqNo);
    1259             : 
    1260        1226 :       if (I != PendingResponses.end()) {
    1261        1226 :         PRHandler = std::move(I->second);
    1262        1226 :         PendingResponses.erase(I);
    1263         613 :         SequenceNumberMgr.releaseSequenceNumber(SeqNo);
    1264             :       } else {
    1265             :         // Unlock the pending results map to prevent recursive lock.
    1266           0 :         Lock.unlock();
    1267           0 :         abandonPendingResponses();
    1268             :         return make_error<
    1269           0 :                  InvalidSequenceNumberForResponse<SequenceNumberT>>(SeqNo);
    1270             :       }
    1271             :     }
    1272             : 
    1273             :     assert(PRHandler &&
    1274             :            "If we didn't find a response handler we should have bailed out");
    1275             : 
    1276        1839 :     if (auto Err = PRHandler->handleResponse(C)) {
    1277           0 :       abandonPendingResponses();
    1278           0 :       return Err;
    1279             :     }
    1280             : 
    1281        1839 :     return Error::success();
    1282             :   }
    1283             : 
    1284             :   FunctionIdT handleNegotiate(const std::string &Name) {
    1285         486 :     auto I = LocalFunctionIds.find(Name);
    1286         486 :     if (I == LocalFunctionIds.end())
    1287             :       return getInvalidFunctionId();
    1288         242 :     return I->second;
    1289             :   }
    1290             : 
    1291             :   // Find the remote FunctionId for the given function.
    1292             :   template <typename Func>
    1293         621 :   Expected<FunctionIdT> getRemoteFunctionId(bool NegotiateIfNotInMap,
    1294             :                                             bool NegotiateIfInvalid) {
    1295             :     bool DoNegotiate;
    1296             : 
    1297             :     // Check if we already have a function id...
    1298        1242 :     auto I = RemoteFunctionIds.find(Func::getPrototype());
    1299        1242 :     if (I != RemoteFunctionIds.end()) {
    1300             :       // If it's valid there's nothing left to do.
    1301         378 :       if (I->second != getInvalidFunctionId())
    1302         378 :         return I->second;
    1303             :       DoNegotiate = NegotiateIfInvalid;
    1304             :     } else
    1305             :       DoNegotiate = NegotiateIfNotInMap;
    1306             : 
    1307             :     // We don't have a function id for Func yet, but we're allowed to try to
    1308             :     // negotiate one.
    1309         243 :     if (DoNegotiate) {
    1310         243 :       auto &Impl = static_cast<ImplT &>(*this);
    1311         729 :       if (auto RemoteIdOrErr =
    1312         486 :           Impl.template callB<OrcRPCNegotiate>(Func::getPrototype())) {
    1313         243 :         RemoteFunctionIds[Func::getPrototype()] = *RemoteIdOrErr;
    1314         243 :         if (*RemoteIdOrErr == getInvalidFunctionId())
    1315           4 :           return make_error<CouldNotNegotiate>(Func::getPrototype());
    1316         242 :         return *RemoteIdOrErr;
    1317             :       } else
    1318           0 :         return RemoteIdOrErr.takeError();
    1319             :     }
    1320             : 
    1321             :     // No key was available in the map and we weren't allowed to try to
    1322             :     // negotiate one, so return an unknown function error.
    1323           0 :     return make_error<CouldNotNegotiate>(Func::getPrototype());
    1324             :   }
    1325             : 
    1326             :   using WrappedHandlerFn = std::function<Error(ChannelT &, SequenceNumberT)>;
    1327             : 
    1328             :   // Wrap the given user handler in the necessary argument-deserialization code,
    1329             :   // result-serialization code, and call to the launch policy (if present).
    1330             :   template <typename Func, typename HandlerT>
    1331             :   WrappedHandlerFn wrapHandler(HandlerT Handler) {
    1332             :     return [this, Handler](ChannelT &Channel,
    1333        1220 :                            SequenceNumberT SeqNo) mutable -> Error {
    1334             :       // Start by deserializing the arguments.
    1335             :       using ArgsTuple =
    1336             :           typename detail::FunctionArgsTuple<
    1337             :             typename detail::HandlerTraits<HandlerT>::Type>::Type;
    1338        1220 :       auto Args = std::make_shared<ArgsTuple>();
    1339             : 
    1340        1892 :       if (auto Err =
    1341             :               detail::HandlerTraits<typename Func::Type>::deserializeArgs(
    1342         610 :                   Channel, *Args))
    1343           0 :         return Err;
    1344             : 
    1345             :       // GCC 4.7 and 4.8 incorrectly issue a -Wunused-but-set-variable warning
    1346             :       // for RPCArgs. Void cast RPCArgs to work around this for now.
    1347             :       // FIXME: Remove this workaround once we can assume a working GCC version.
    1348             :       (void)Args;
    1349             : 
    1350             :       // End receieve message, unlocking the channel for reading.
    1351        1863 :       if (auto Err = Channel.endReceiveMessage())
    1352             :         return Err;
    1353             : 
    1354             :       using HTraits = detail::HandlerTraits<HandlerT>;
    1355             :       using FuncReturn = typename Func::ReturnType;
    1356             :       return detail::respond<FuncReturn>(Channel, ResponseId, SeqNo,
    1357        2410 :                                          HTraits::unpackAndRun(Handler, *Args));
    1358        1428 :     };
    1359             :   }
    1360             : 
    1361             :   // Wrap the given user handler in the necessary argument-deserialization code,
    1362             :   // result-serialization code, and call to the launch policy (if present).
    1363             :   template <typename Func, typename HandlerT>
    1364             :   WrappedHandlerFn wrapAsyncHandler(HandlerT Handler) {
    1365             :     return [this, Handler](ChannelT &Channel,
    1366           6 :                            SequenceNumberT SeqNo) mutable -> Error {
    1367             :       // Start by deserializing the arguments.
    1368             :       using AHTraits = detail::AsyncHandlerTraits<
    1369             :                          typename detail::HandlerTraits<HandlerT>::Type>;
    1370             :       using ArgsTuple =
    1371             :           typename detail::FunctionArgsTuple<typename AHTraits::Type>::Type;
    1372           6 :       auto Args = std::make_shared<ArgsTuple>();
    1373             : 
    1374           9 :       if (auto Err =
    1375             :               detail::HandlerTraits<typename Func::Type>::deserializeArgs(
    1376           3 :                   Channel, *Args))
    1377           0 :         return Err;
    1378             : 
    1379             :       // GCC 4.7 and 4.8 incorrectly issue a -Wunused-but-set-variable warning
    1380             :       // for RPCArgs. Void cast RPCArgs to work around this for now.
    1381             :       // FIXME: Remove this workaround once we can assume a working GCC version.
    1382             :       (void)Args;
    1383             : 
    1384             :       // End receieve message, unlocking the channel for reading.
    1385          12 :       if (auto Err = Channel.endReceiveMessage())
    1386             :         return Err;
    1387             : 
    1388             :       using HTraits = detail::HandlerTraits<HandlerT>;
    1389             :       using FuncReturn = typename Func::ReturnType;
    1390           3 :       auto Responder =
    1391           6 :         [this, SeqNo](typename AHTraits::ResultType RetVal) -> Error {
    1392             :           return detail::respond<FuncReturn>(C, ResponseId, SeqNo,
    1393          12 :                                              std::move(RetVal));
    1394             :         };
    1395             : 
    1396           3 :       return HTraits::unpackAndRunAsync(Handler, Responder, *Args);
    1397           6 :     };
    1398             :   }
    1399             : 
    1400             :   ChannelT &C;
    1401             : 
    1402             :   bool LazyAutoNegotiation;
    1403             : 
    1404             :   RPCFunctionIdAllocator<FunctionIdT> FnIdAllocator;
    1405             : 
    1406             :   FunctionIdT ResponseId;
    1407             :   std::map<std::string, FunctionIdT> LocalFunctionIds;
    1408             :   std::map<const char *, FunctionIdT> RemoteFunctionIds;
    1409             : 
    1410             :   std::map<FunctionIdT, WrappedHandlerFn> Handlers;
    1411             : 
    1412             :   std::mutex ResponsesMutex;
    1413             :   detail::SequenceNumberManager<SequenceNumberT> SequenceNumberMgr;
    1414             :   std::map<SequenceNumberT, std::unique_ptr<detail::ResponseHandler<ChannelT>>>
    1415             :       PendingResponses;
    1416             : };
    1417             : 
    1418             : } // end namespace detail
    1419             : 
    1420             : template <typename ChannelT, typename FunctionIdT = uint32_t,
    1421             :           typename SequenceNumberT = uint32_t>
    1422             : class MultiThreadedRPCEndpoint
    1423             :     : public detail::RPCEndpointBase<
    1424             :           MultiThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
    1425             :           ChannelT, FunctionIdT, SequenceNumberT> {
    1426             : private:
    1427             :   using BaseClass =
    1428             :       detail::RPCEndpointBase<
    1429             :         MultiThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
    1430             :         ChannelT, FunctionIdT, SequenceNumberT>;
    1431             : 
    1432             : public:
    1433             :   MultiThreadedRPCEndpoint(ChannelT &C, bool LazyAutoNegotiation)
    1434             :       : BaseClass(C, LazyAutoNegotiation) {}
    1435             : 
    1436             :   /// Add a handler for the given RPC function.
    1437             :   /// This installs the given handler functor for the given RPC Function, and
    1438             :   /// makes the RPC function available for negotiation/calling from the remote.
    1439             :   template <typename Func, typename HandlerT>
    1440             :   void addHandler(HandlerT Handler) {
    1441             :     return this->template addHandlerImpl<Func>(std::move(Handler));
    1442             :   }
    1443             : 
    1444             :   /// Add a class-method as a handler.
    1445             :   template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
    1446             :   void addHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
    1447             :     addHandler<Func>(
    1448             :       detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
    1449             :   }
    1450             : 
    1451             :   template <typename Func, typename HandlerT>
    1452             :   void addAsyncHandler(HandlerT Handler) {
    1453             :     return this->template addAsyncHandlerImpl<Func>(std::move(Handler));
    1454             :   }
    1455             : 
    1456             :   /// Add a class-method as a handler.
    1457             :   template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
    1458             :   void addAsyncHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
    1459             :     addAsyncHandler<Func>(
    1460             :       detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
    1461             :   }
    1462             : 
    1463             :   /// Return type for non-blocking call primitives.
    1464             :   template <typename Func>
    1465             :   using NonBlockingCallResult = typename detail::ResultTraits<
    1466             :       typename Func::ReturnType>::ReturnFutureType;
    1467             : 
    1468             :   /// Call Func on Channel C. Does not block, does not call send. Returns a pair
    1469             :   /// of a future result and the sequence number assigned to the result.
    1470             :   ///
    1471             :   /// This utility function is primarily used for single-threaded mode support,
    1472             :   /// where the sequence number can be used to wait for the corresponding
    1473             :   /// result. In multi-threaded mode the appendCallNB method, which does not
    1474             :   /// return the sequence numeber, should be preferred.
    1475             :   template <typename Func, typename... ArgTs>
    1476             :   Expected<NonBlockingCallResult<Func>> appendCallNB(const ArgTs &... Args) {
    1477             :     using RTraits = detail::ResultTraits<typename Func::ReturnType>;
    1478             :     using ErrorReturn = typename RTraits::ErrorReturnType;
    1479             :     using ErrorReturnPromise = typename RTraits::ReturnPromiseType;
    1480             : 
    1481             :     // FIXME: Stack allocate and move this into the handler once LLVM builds
    1482             :     //        with C++14.
    1483             :     auto Promise = std::make_shared<ErrorReturnPromise>();
    1484             :     auto FutureResult = Promise->get_future();
    1485             : 
    1486             :     if (auto Err = this->template appendCallAsync<Func>(
    1487             :             [Promise](ErrorReturn RetOrErr) {
    1488             :               Promise->set_value(std::move(RetOrErr));
    1489             :               return Error::success();
    1490             :             },
    1491             :             Args...)) {
    1492             :       RTraits::consumeAbandoned(FutureResult.get());
    1493             :       return std::move(Err);
    1494             :     }
    1495             :     return std::move(FutureResult);
    1496             :   }
    1497             : 
    1498             :   /// The same as appendCallNBWithSeq, except that it calls C.send() to
    1499             :   /// flush the channel after serializing the call.
    1500             :   template <typename Func, typename... ArgTs>
    1501             :   Expected<NonBlockingCallResult<Func>> callNB(const ArgTs &... Args) {
    1502             :     auto Result = appendCallNB<Func>(Args...);
    1503             :     if (!Result)
    1504             :       return Result;
    1505             :     if (auto Err = this->C.send()) {
    1506             :       this->abandonPendingResponses();
    1507             :       detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
    1508             :           std::move(Result->get()));
    1509             :       return std::move(Err);
    1510             :     }
    1511             :     return Result;
    1512             :   }
    1513             : 
    1514             :   /// Call Func on Channel C. Blocks waiting for a result. Returns an Error
    1515             :   /// for void functions or an Expected<T> for functions returning a T.
    1516             :   ///
    1517             :   /// This function is for use in threaded code where another thread is
    1518             :   /// handling responses and incoming calls.
    1519             :   template <typename Func, typename... ArgTs,
    1520             :             typename AltRetT = typename Func::ReturnType>
    1521             :   typename detail::ResultTraits<AltRetT>::ErrorReturnType
    1522             :   callB(const ArgTs &... Args) {
    1523             :     if (auto FutureResOrErr = callNB<Func>(Args...))
    1524             :       return FutureResOrErr->get();
    1525             :     else
    1526             :       return FutureResOrErr.takeError();
    1527             :   }
    1528             : 
    1529             :   /// Handle incoming RPC calls.
    1530             :   Error handlerLoop() {
    1531             :     while (true)
    1532             :       if (auto Err = this->handleOne())
    1533             :         return Err;
    1534             :     return Error::success();
    1535             :   }
    1536             : };
    1537             : 
    1538             : template <typename ChannelT, typename FunctionIdT = uint32_t,
    1539             :           typename SequenceNumberT = uint32_t>
    1540          97 : class SingleThreadedRPCEndpoint
    1541             :     : public detail::RPCEndpointBase<
    1542             :           SingleThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
    1543             :           ChannelT, FunctionIdT, SequenceNumberT> {
    1544             : private:
    1545             :   using BaseClass =
    1546             :       detail::RPCEndpointBase<
    1547             :         SingleThreadedRPCEndpoint<ChannelT, FunctionIdT, SequenceNumberT>,
    1548             :         ChannelT, FunctionIdT, SequenceNumberT>;
    1549             : 
    1550             : public:
    1551          97 :   SingleThreadedRPCEndpoint(ChannelT &C, bool LazyAutoNegotiation)
    1552          97 :       : BaseClass(C, LazyAutoNegotiation) {}
    1553             : 
    1554             :   template <typename Func, typename HandlerT>
    1555             :   void addHandler(HandlerT Handler) {
    1556         617 :     return this->template addHandlerImpl<Func>(std::move(Handler));
    1557             :   }
    1558             : 
    1559             :   template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
    1560             :   void addHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
    1561        1136 :     addHandler<Func>(
    1562             :         detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
    1563             :   }
    1564             : 
    1565             :   template <typename Func, typename HandlerT>
    1566             :   void addAsyncHandler(HandlerT Handler) {
    1567           3 :     return this->template addAsyncHandlerImpl<Func>(std::move(Handler));
    1568             :   }
    1569             : 
    1570             :   /// Add a class-method as a handler.
    1571             :   template <typename Func, typename ClassT, typename RetT, typename... ArgTs>
    1572             :   void addAsyncHandler(ClassT &Object, RetT (ClassT::*Method)(ArgTs...)) {
    1573           2 :     addAsyncHandler<Func>(
    1574             :       detail::MemberFnWrapper<ClassT, RetT, ArgTs...>(Object, Method));
    1575             :   }
    1576             : 
    1577             :   template <typename Func, typename... ArgTs,
    1578             :             typename AltRetT = typename Func::ReturnType>
    1579             :   typename detail::ResultTraits<AltRetT>::ErrorReturnType
    1580         598 :   callB(const ArgTs &... Args) {
    1581         598 :     bool ReceivedResponse = false;
    1582             :     using ResultType = typename detail::ResultTraits<AltRetT>::ErrorReturnType;
    1583        1196 :     auto Result = detail::ResultTraits<AltRetT>::createBlankErrorReturnValue();
    1584             : 
    1585             :     // We have to 'Check' result (which we know is in a success state at this
    1586             :     // point) so that it can be overwritten in the async handler.
    1587         598 :     (void)!!Result;
    1588             : 
    1589        1794 :     if (auto Err = this->template appendCallAsync<Func>(
    1590             :             [&](ResultType R) {
    1591        1196 :               Result = std::move(R);
    1592         598 :               ReceivedResponse = true;
    1593             :               return Error::success();
    1594             :             },
    1595             :             Args...)) {
    1596           0 :       detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
    1597           0 :           std::move(Result));
    1598           0 :       return std::move(Err);
    1599             :     }
    1600             : 
    1601        1196 :     while (!ReceivedResponse) {
    1602        1794 :       if (auto Err = this->handleOne()) {
    1603           0 :         detail::ResultTraits<typename Func::ReturnType>::consumeAbandoned(
    1604           0 :             std::move(Result));
    1605           0 :         return std::move(Err);
    1606             :       }
    1607             :     }
    1608             : 
    1609             :     return Result;
    1610             :   }
    1611             : };
    1612             : 
    1613             : /// Asynchronous dispatch for a function on an RPC endpoint.
    1614             : template <typename RPCClass, typename Func>
    1615             : class RPCAsyncDispatch {
    1616             : public:
    1617             :   RPCAsyncDispatch(RPCClass &Endpoint) : Endpoint(Endpoint) {}
    1618             : 
    1619             :   template <typename HandlerT, typename... ArgTs>
    1620             :   Error operator()(HandlerT Handler, const ArgTs &... Args) const {
    1621           3 :     return Endpoint.template appendCallAsync<Func>(std::move(Handler), Args...);
    1622             :   }
    1623             : 
    1624             : private:
    1625             :   RPCClass &Endpoint;
    1626             : };
    1627             : 
    1628             : /// Construct an asynchronous dispatcher from an RPC endpoint and a Func.
    1629             : template <typename Func, typename RPCEndpointT>
    1630             : RPCAsyncDispatch<RPCEndpointT, Func> rpcAsyncDispatch(RPCEndpointT &Endpoint) {
    1631           3 :   return RPCAsyncDispatch<RPCEndpointT, Func>(Endpoint);
    1632             : }
    1633             : 
    1634             : /// \brief Allows a set of asynchrounous calls to be dispatched, and then
    1635             : ///        waited on as a group.
    1636           1 : class ParallelCallGroup {
    1637             : public:
    1638             : 
    1639           2 :   ParallelCallGroup() = default;
    1640             :   ParallelCallGroup(const ParallelCallGroup &) = delete;
    1641             :   ParallelCallGroup &operator=(const ParallelCallGroup &) = delete;
    1642             : 
    1643             :   /// \brief Make as asynchronous call.
    1644             :   template <typename AsyncDispatcher, typename HandlerT, typename... ArgTs>
    1645           3 :   Error call(const AsyncDispatcher &AsyncDispatch, HandlerT Handler,
    1646             :              const ArgTs &... Args) {
    1647             :     // Increment the count of outstanding calls. This has to happen before
    1648             :     // we invoke the call, as the handler may (depending on scheduling)
    1649             :     // be run immediately on another thread, and we don't want the decrement
    1650             :     // in the wrapped handler below to run before the increment.
    1651             :     {
    1652           9 :       std::unique_lock<std::mutex> Lock(M);
    1653           3 :       ++NumOutstandingCalls;
    1654             :     }
    1655             : 
    1656             :     // Wrap the user handler in a lambda that will decrement the
    1657             :     // outstanding calls count, then poke the condition variable.
    1658             :     using ArgType = typename detail::ResponseHandlerArg<
    1659             :         typename detail::HandlerTraits<HandlerT>::Type>::ArgType;
    1660             :     // FIXME: Move handler into wrapped handler once we have C++14.
    1661          15 :     auto WrappedHandler = [this, Handler](ArgType Arg) {
    1662           9 :       auto Err = Handler(std::move(Arg));
    1663           9 :       std::unique_lock<std::mutex> Lock(M);
    1664           3 :       --NumOutstandingCalls;
    1665           3 :       CV.notify_all();
    1666           3 :       return Err;
    1667             :     };
    1668             : 
    1669           6 :     return AsyncDispatch(std::move(WrappedHandler), Args...);
    1670             :   }
    1671             : 
    1672             :   /// \brief Blocks until all calls have been completed and their return value
    1673             :   ///        handlers run.
    1674           1 :   void wait() {
    1675           2 :     std::unique_lock<std::mutex> Lock(M);
    1676           1 :     while (NumOutstandingCalls > 0)
    1677           0 :       CV.wait(Lock);
    1678           1 :   }
    1679             : 
    1680             : private:
    1681             :   std::mutex M;
    1682             :   std::condition_variable CV;
    1683             :   uint32_t NumOutstandingCalls = 0;
    1684             : };
    1685             : 
    1686             : /// @brief Convenience class for grouping RPC Functions into APIs that can be
    1687             : ///        negotiated as a block.
    1688             : ///
    1689             : template <typename... Funcs>
    1690             : class APICalls {
    1691             : public:
    1692             : 
    1693             :   /// @brief Test whether this API contains Function F.
    1694             :   template <typename F>
    1695             :   class Contains {
    1696             :   public:
    1697             :     static const bool value = false;
    1698             :   };
    1699             : 
    1700             :   /// @brief Negotiate all functions in this API.
    1701             :   template <typename RPCEndpoint>
    1702             :   static Error negotiate(RPCEndpoint &R) {
    1703          12 :     return Error::success();
    1704             :   }
    1705             : };
    1706             : 
    1707             : template <typename Func, typename... Funcs>
    1708             : class APICalls<Func, Funcs...> {
    1709             : public:
    1710             : 
    1711             :   template <typename F>
    1712             :   class Contains {
    1713             :   public:
    1714             :     static const bool value = std::is_same<F, Func>::value |
    1715             :                               APICalls<Funcs...>::template Contains<F>::value;
    1716             :   };
    1717             : 
    1718             :   template <typename RPCEndpoint>
    1719           8 :   static Error negotiate(RPCEndpoint &R) {
    1720          23 :     if (auto Err = R.template negotiateFunction<Func>())
    1721           2 :       return Err;
    1722           7 :     return APICalls<Funcs...>::negotiate(R);
    1723             :   }
    1724             : 
    1725             : };
    1726             : 
    1727             : template <typename... InnerFuncs, typename... Funcs>
    1728             : class APICalls<APICalls<InnerFuncs...>, Funcs...> {
    1729             : public:
    1730             : 
    1731             :   template <typename F>
    1732             :   class Contains {
    1733             :   public:
    1734             :     static const bool value =
    1735             :       APICalls<InnerFuncs...>::template Contains<F>::value |
    1736             :       APICalls<Funcs...>::template Contains<F>::value;
    1737             :   };
    1738             : 
    1739             :   template <typename RPCEndpoint>
    1740           3 :   static Error negotiate(RPCEndpoint &R) {
    1741           8 :     if (auto Err = APICalls<InnerFuncs...>::negotiate(R))
    1742           2 :       return Err;
    1743           2 :     return APICalls<Funcs...>::negotiate(R);
    1744             :   }
    1745             : 
    1746             : };
    1747             : 
    1748             : } // end namespace rpc
    1749             : } // end namespace orc
    1750             : } // end namespace llvm
    1751             : 
    1752             : #endif

Generated by: LCOV version 1.13