1 //===- llvm/ExecutionEngine/Orc/RawByteChannel.h ----------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H
10 #define LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/ExecutionEngine/Orc/RPCSerialization.h"
14 #include "llvm/Support/Endian.h"
15 #include "llvm/Support/Error.h"
19 #include <type_traits>
25 /// Interface for byte-streams to be used with RPC.
26 class RawByteChannel
{
28 virtual ~RawByteChannel() = default;
30 /// Read Size bytes from the stream into *Dst.
31 virtual Error
readBytes(char *Dst
, unsigned Size
) = 0;
33 /// Read size bytes from *Src and append them to the stream.
34 virtual Error
appendBytes(const char *Src
, unsigned Size
) = 0;
36 /// Flush the stream if possible.
37 virtual Error
send() = 0;
39 /// Notify the channel that we're starting a message send.
40 /// Locks the channel for writing.
41 template <typename FunctionIdT
, typename SequenceIdT
>
42 Error
startSendMessage(const FunctionIdT
&FnId
, const SequenceIdT
&SeqNo
) {
44 if (auto Err
= serializeSeq(*this, FnId
, SeqNo
)) {
48 return Error::success();
51 /// Notify the channel that we're ending a message send.
52 /// Unlocks the channel for writing.
53 Error
endSendMessage() {
55 return Error::success();
58 /// Notify the channel that we're starting a message receive.
59 /// Locks the channel for reading.
60 template <typename FunctionIdT
, typename SequenceNumberT
>
61 Error
startReceiveMessage(FunctionIdT
&FnId
, SequenceNumberT
&SeqNo
) {
63 if (auto Err
= deserializeSeq(*this, FnId
, SeqNo
)) {
67 return Error::success();
70 /// Notify the channel that we're ending a message receive.
71 /// Unlocks the channel for reading.
72 Error
endReceiveMessage() {
74 return Error::success();
77 /// Get the lock for stream reading.
78 std::mutex
&getReadLock() { return readLock
; }
80 /// Get the lock for stream writing.
81 std::mutex
&getWriteLock() { return writeLock
; }
84 std::mutex readLock
, writeLock
;
87 template <typename ChannelT
, typename T
>
88 class SerializationTraits
<
90 typename
std::enable_if
<
91 std::is_base_of
<RawByteChannel
, ChannelT
>::value
&&
92 (std::is_same
<T
, uint8_t>::value
|| std::is_same
<T
, int8_t>::value
||
93 std::is_same
<T
, uint16_t>::value
|| std::is_same
<T
, int16_t>::value
||
94 std::is_same
<T
, uint32_t>::value
|| std::is_same
<T
, int32_t>::value
||
95 std::is_same
<T
, uint64_t>::value
|| std::is_same
<T
, int64_t>::value
||
96 std::is_same
<T
, char>::value
)>::type
> {
98 static Error
serialize(ChannelT
&C
, T V
) {
99 support::endian::byte_swap
<T
, support::big
>(V
);
100 return C
.appendBytes(reinterpret_cast<const char *>(&V
), sizeof(T
));
103 static Error
deserialize(ChannelT
&C
, T
&V
) {
104 if (auto Err
= C
.readBytes(reinterpret_cast<char *>(&V
), sizeof(T
)))
106 support::endian::byte_swap
<T
, support::big
>(V
);
107 return Error::success();
111 template <typename ChannelT
>
112 class SerializationTraits
<ChannelT
, bool, bool,
113 typename
std::enable_if
<std::is_base_of
<
114 RawByteChannel
, ChannelT
>::value
>::type
> {
116 static Error
serialize(ChannelT
&C
, bool V
) {
117 uint8_t Tmp
= V
? 1 : 0;
119 C
.appendBytes(reinterpret_cast<const char *>(&Tmp
), 1))
121 return Error::success();
124 static Error
deserialize(ChannelT
&C
, bool &V
) {
126 if (auto Err
= C
.readBytes(reinterpret_cast<char *>(&Tmp
), 1))
129 return Error::success();
133 template <typename ChannelT
>
134 class SerializationTraits
<ChannelT
, std::string
, StringRef
,
135 typename
std::enable_if
<std::is_base_of
<
136 RawByteChannel
, ChannelT
>::value
>::type
> {
138 /// RPC channel serialization for std::strings.
139 static Error
serialize(RawByteChannel
&C
, StringRef S
) {
140 if (auto Err
= serializeSeq(C
, static_cast<uint64_t>(S
.size())))
142 return C
.appendBytes((const char *)S
.data(), S
.size());
146 template <typename ChannelT
, typename T
>
147 class SerializationTraits
<ChannelT
, std::string
, T
,
148 typename
std::enable_if
<
149 std::is_base_of
<RawByteChannel
, ChannelT
>::value
&&
150 (std::is_same
<T
, const char*>::value
||
151 std::is_same
<T
, char*>::value
)>::type
> {
153 static Error
serialize(RawByteChannel
&C
, const char *S
) {
154 return SerializationTraits
<ChannelT
, std::string
, StringRef
>::serialize(C
,
159 template <typename ChannelT
>
160 class SerializationTraits
<ChannelT
, std::string
, std::string
,
161 typename
std::enable_if
<std::is_base_of
<
162 RawByteChannel
, ChannelT
>::value
>::type
> {
164 /// RPC channel serialization for std::strings.
165 static Error
serialize(RawByteChannel
&C
, const std::string
&S
) {
166 return SerializationTraits
<ChannelT
, std::string
, StringRef
>::serialize(C
,
170 /// RPC channel deserialization for std::strings.
171 static Error
deserialize(RawByteChannel
&C
, std::string
&S
) {
173 if (auto Err
= deserializeSeq(C
, Count
))
176 return C
.readBytes(&S
[0], Count
);
180 } // end namespace rpc
181 } // end namespace orc
182 } // end namespace llvm
184 #endif // LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H