//===- llvm/ExecutionEngine/Orc/RawByteChannel.h ----------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H #define LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H #include "llvm/ADT/StringRef.h" #include "llvm/ExecutionEngine/Orc/RPCSerialization.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include #include #include #include namespace llvm { namespace orc { namespace rpc { /// Interface for byte-streams to be used with RPC. class RawByteChannel { public: virtual ~RawByteChannel() = default; /// Read Size bytes from the stream into *Dst. virtual Error readBytes(char *Dst, unsigned Size) = 0; /// Read size bytes from *Src and append them to the stream. virtual Error appendBytes(const char *Src, unsigned Size) = 0; /// Flush the stream if possible. virtual Error send() = 0; /// Notify the channel that we're starting a message send. /// Locks the channel for writing. template Error startSendMessage(const FunctionIdT &FnId, const SequenceIdT &SeqNo) { writeLock.lock(); if (auto Err = serializeSeq(*this, FnId, SeqNo)) { writeLock.unlock(); return Err; } return Error::success(); } /// Notify the channel that we're ending a message send. /// Unlocks the channel for writing. Error endSendMessage() { writeLock.unlock(); return Error::success(); } /// Notify the channel that we're starting a message receive. /// Locks the channel for reading. template Error startReceiveMessage(FunctionIdT &FnId, SequenceNumberT &SeqNo) { readLock.lock(); if (auto Err = deserializeSeq(*this, FnId, SeqNo)) { readLock.unlock(); return Err; } return Error::success(); } /// Notify the channel that we're ending a message receive. /// Unlocks the channel for reading. Error endReceiveMessage() { readLock.unlock(); return Error::success(); } /// Get the lock for stream reading. std::mutex &getReadLock() { return readLock; } /// Get the lock for stream writing. std::mutex &getWriteLock() { return writeLock; } private: std::mutex readLock, writeLock; }; template class SerializationTraits< ChannelT, T, T, typename std::enable_if< std::is_base_of::value && (std::is_same::value || std::is_same::value || std::is_same::value || std::is_same::value || std::is_same::value || std::is_same::value || std::is_same::value || std::is_same::value || std::is_same::value)>::type> { public: static Error serialize(ChannelT &C, T V) { support::endian::byte_swap(V); return C.appendBytes(reinterpret_cast(&V), sizeof(T)); }; static Error deserialize(ChannelT &C, T &V) { if (auto Err = C.readBytes(reinterpret_cast(&V), sizeof(T))) return Err; support::endian::byte_swap(V); return Error::success(); }; }; template class SerializationTraits::value>::type> { public: static Error serialize(ChannelT &C, bool V) { uint8_t Tmp = V ? 1 : 0; if (auto Err = C.appendBytes(reinterpret_cast(&Tmp), 1)) return Err; return Error::success(); } static Error deserialize(ChannelT &C, bool &V) { uint8_t Tmp = 0; if (auto Err = C.readBytes(reinterpret_cast(&Tmp), 1)) return Err; V = Tmp != 0; return Error::success(); } }; template class SerializationTraits::value>::type> { public: /// RPC channel serialization for std::strings. static Error serialize(RawByteChannel &C, StringRef S) { if (auto Err = serializeSeq(C, static_cast(S.size()))) return Err; return C.appendBytes((const char *)S.data(), S.size()); } }; template class SerializationTraits::value && (std::is_same::value || std::is_same::value)>::type> { public: static Error serialize(RawByteChannel &C, const char *S) { return SerializationTraits::serialize(C, S); } }; template class SerializationTraits::value>::type> { public: /// RPC channel serialization for std::strings. static Error serialize(RawByteChannel &C, const std::string &S) { return SerializationTraits::serialize(C, S); } /// RPC channel deserialization for std::strings. static Error deserialize(RawByteChannel &C, std::string &S) { uint64_t Count = 0; if (auto Err = deserializeSeq(C, Count)) return Err; S.resize(Count); return C.readBytes(&S[0], Count); } }; } // end namespace rpc } // end namespace orc } // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H