//===- RawByteChannel.h -----------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_RAWBYTECHANNEL_H #define LLVM_EXECUTIONENGINE_ORC_SHARED_RAWBYTECHANNEL_H #include "llvm/ADT/StringRef.h" #include "llvm/ExecutionEngine/Orc/Shared/Serialization.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include #include #include #include namespace llvm { namespace orc { namespace shared { /// Interface for byte-streams to be used with ORC Serialization. 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, std::enable_if_t< 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)>> { 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< ChannelT, bool, bool, std::enable_if_t::value>> { 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< ChannelT, std::string, StringRef, std::enable_if_t::value>> { public: /// Serialization 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< ChannelT, std::string, T, std::enable_if_t::value && (std::is_same::value || std::is_same::value)>> { public: static Error serialize(RawByteChannel &C, const char *S) { return SerializationTraits::serialize(C, S); } }; template class SerializationTraits< ChannelT, std::string, std::string, std::enable_if_t::value>> { public: /// Serialization channel serialization for std::strings. static Error serialize(RawByteChannel &C, const std::string &S) { return SerializationTraits::serialize(C, S); } /// Serialization 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 shared } // end namespace orc } // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_RAWBYTECHANNEL_H