1 //===- llvm/ExecutionEngine/Orc/RawByteChannel.h ----------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H
11 #define LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H
14 #include "RPCSerialization.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/Support/Endian.h"
19 #include "llvm/Support/Error.h"
25 #include <type_traits>
32 /// Interface for byte-streams to be used with RPC.
33 class RawByteChannel {
35 virtual ~RawByteChannel() {}
37 /// Read Size bytes from the stream into *Dst.
38 virtual Error readBytes(char *Dst, unsigned Size) = 0;
40 /// Read size bytes from *Src and append them to the stream.
41 virtual Error appendBytes(const char *Src, unsigned Size) = 0;
43 /// Flush the stream if possible.
44 virtual Error send() = 0;
46 /// Notify the channel that we're starting a message send.
47 /// Locks the channel for writing.
48 template <typename FunctionIdT, typename SequenceIdT>
49 Error startSendMessage(const FunctionIdT &FnId, const SequenceIdT &SeqNo) {
51 if (auto Err = serializeSeq(*this, FnId, SeqNo))
53 return Error::success();
56 /// Notify the channel that we're ending a message send.
57 /// Unlocks the channel for writing.
58 Error endSendMessage() {
60 return Error::success();
63 /// Notify the channel that we're starting a message receive.
64 /// Locks the channel for reading.
65 template <typename FunctionIdT, typename SequenceNumberT>
66 Error startReceiveMessage(FunctionIdT &FnId, SequenceNumberT &SeqNo) {
68 return deserializeSeq(*this, FnId, SeqNo);
71 /// Notify the channel that we're ending a message receive.
72 /// Unlocks the channel for reading.
73 Error endReceiveMessage() {
75 return Error::success();
78 /// Get the lock for stream reading.
79 std::mutex &getReadLock() { return readLock; }
81 /// Get the lock for stream writing.
82 std::mutex &getWriteLock() { return writeLock; }
85 std::mutex readLock, writeLock;
88 template <typename ChannelT, typename T>
89 class SerializationTraits<
91 typename std::enable_if<
92 std::is_base_of<RawByteChannel, ChannelT>::value &&
93 (std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value ||
94 std::is_same<T, uint16_t>::value || std::is_same<T, int16_t>::value ||
95 std::is_same<T, uint32_t>::value || std::is_same<T, int32_t>::value ||
96 std::is_same<T, uint64_t>::value || std::is_same<T, int64_t>::value ||
97 std::is_same<T, char>::value)>::type> {
99 static Error serialize(ChannelT &C, T V) {
100 support::endian::byte_swap<T, support::big>(V);
101 return C.appendBytes(reinterpret_cast<const char *>(&V), sizeof(T));
104 static Error deserialize(ChannelT &C, T &V) {
105 if (auto Err = C.readBytes(reinterpret_cast<char *>(&V), sizeof(T)))
107 support::endian::byte_swap<T, support::big>(V);
108 return Error::success();
112 template <typename ChannelT>
113 class SerializationTraits<ChannelT, bool, bool,
114 typename std::enable_if<std::is_base_of<
115 RawByteChannel, ChannelT>::value>::type> {
117 static Error serialize(ChannelT &C, bool V) {
118 return C.appendBytes(reinterpret_cast<const char *>(&V), 1);
121 static Error deserialize(ChannelT &C, bool &V) {
122 return C.readBytes(reinterpret_cast<char *>(&V), 1);
126 template <typename ChannelT>
127 class SerializationTraits<ChannelT, std::string, StringRef,
128 typename std::enable_if<std::is_base_of<
129 RawByteChannel, ChannelT>::value>::type> {
131 /// RPC channel serialization for std::strings.
132 static Error serialize(RawByteChannel &C, StringRef S) {
133 if (auto Err = serializeSeq(C, static_cast<uint64_t>(S.size())))
135 return C.appendBytes((const char *)S.data(), S.size());
139 template <typename ChannelT>
140 class SerializationTraits<ChannelT, std::string, const char *,
141 typename std::enable_if<std::is_base_of<
142 RawByteChannel, ChannelT>::value>::type> {
144 static Error serialize(RawByteChannel &C, const char *S) {
145 return SerializationTraits<ChannelT, std::string, StringRef>::serialize(C,
150 template <typename ChannelT>
151 class SerializationTraits<ChannelT, std::string, std::string,
152 typename std::enable_if<std::is_base_of<
153 RawByteChannel, ChannelT>::value>::type> {
155 /// RPC channel serialization for std::strings.
156 static Error serialize(RawByteChannel &C, const std::string &S) {
157 return SerializationTraits<ChannelT, std::string, StringRef>::serialize(C,
161 /// RPC channel deserialization for std::strings.
162 static Error deserialize(RawByteChannel &C, std::string &S) {
164 if (auto Err = deserializeSeq(C, Count))
167 return C.readBytes(&S[0], Count);
171 } // end namespace rpc
172 } // end namespace orc
173 } // end namespace llvm
175 #endif // LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H