15#include "llvm/Config/llvm-config.h"
18#if !defined(_MSC_VER) && !defined(__MINGW32__)
24#include <sys/socket.h>
30 static constexpr unsigned MsgSizeOffset = 0;
31 static constexpr unsigned OpCOffset = MsgSizeOffset +
sizeof(
uint64_t);
32 static constexpr unsigned SeqNoOffset = OpCOffset +
sizeof(
uint64_t);
33 static constexpr unsigned TagAddrOffset = SeqNoOffset +
sizeof(
uint64_t);
34 static constexpr unsigned Size = TagAddrOffset +
sizeof(
uint64_t);
44 "__llvm_orc_SimpleRemoteEPC_dispatch_ctx";
55 bool Success = SPSSerialize::serialize(OB, SE);
57 assert(
Success &&
"Hangup payload serialization should not fail");
63 "Hangup payload should not be an out-of-band error buffer");
73std::pair<ExecutorAddr, shared::WrapperFunctionBuffer>
87 bool Success = SPSSerialize::serialize(OB, M);
89 assert(
Success &&
"Out-of-band error serialization should not fail");
96 using UT = std::underlying_type_t<SimpleRemoteEPCResultKind>;
100 " in result message",
105 return std::move(Payload);
114 "Could not deserialize out-of-band error message");
127#if LLVM_ENABLE_THREADS
136 std::unique_ptr<FDSimpleRemoteEPCTransport> FDT(
137 new FDSimpleRemoteEPCTransport(C, InFD, OutFD));
138 return std::move(FDT);
141 "thread support, but llvm was built with "
142 "LLVM_ENABLE_THREADS=Off",
148#if LLVM_ENABLE_THREADS
149 ListenerThread.join();
154#if LLVM_ENABLE_THREADS
155 ListenerThread = std::thread([
this]() { listenLoop(); });
165 char HeaderBuffer[FDMsgHeader::Size];
168 FDMsgHeader::Size + ArgBytes.
size();
175 std::lock_guard<std::mutex> Lock(M);
179 if (
int ErrNo = writeBytes(HeaderBuffer, FDMsgHeader::Size))
181 if (
int ErrNo = writeBytes(ArgBytes.
data(), ArgBytes.
size()))
191 bool CloseOutFD = InFD != OutFD;
198 ::shutdown(InFD, CloseOutFD ? SHUT_RD : SHUT_RDWR);
201 while (close(InFD) == -1) {
210 ::shutdown(OutFD, SHUT_WR);
212 while (close(OutFD) == -1) {
224Error FDSimpleRemoteEPCTransport::readBytes(
char *Dst,
size_t Size,
226 assert((
Size == 0 || Dst) &&
"Attempt to read into null.");
227 ssize_t Completed = 0;
228 while (Completed <
static_cast<ssize_t
>(
Size)) {
229 ssize_t
Read = ::read(InFD, Dst + Completed,
Size - Completed);
233 if (Completed == 0 && IsEOF) {
238 }
else if (ErrNo == EAGAIN || ErrNo == EINTR)
241 std::lock_guard<std::mutex> Lock(M);
242 if (Disconnected && IsEOF) {
247 std::error_code(ErrNo, std::generic_category()));
255int FDSimpleRemoteEPCTransport::writeBytes(
const char *Src,
size_t Size) {
256 assert((
Size == 0 || Src) &&
"Attempt to append from null.");
257 ssize_t Completed = 0;
258 while (Completed <
static_cast<ssize_t
>(
Size)) {
259 ssize_t Written =
::write(OutFD, Src + Completed,
Size - Completed);
262 if (ErrNo == EAGAIN || ErrNo == EINTR)
267 Completed += Written;
272void FDSimpleRemoteEPCTransport::listenLoop() {
276 char HeaderBuffer[FDMsgHeader::Size];
280 if (
auto Err2 = readBytes(HeaderBuffer, FDMsgHeader::Size, &IsEOF)) {
281 Err =
joinErrors(std::move(Err), std::move(Err2));
292 ExecutorAddr TagAddr;
303 if (MsgSize < FDMsgHeader::Size) {
313 if (
auto Err2 = readBytes(ArgBytes.data(), ArgBytes.size())) {
314 Err =
joinErrors(std::move(Err), std::move(Err2));
319 C.handleMessage(OpC, SeqNo, TagAddr, std::move(ArgBytes))) {
323 Err =
joinErrors(std::move(Err), Action.takeError());
333 C.handleDisconnect(std::move(Err));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Represent a constant reference to a string, i.e.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Represents an address in the executor process.
uint64_t getValue() const
void disconnect() override
Trigger disconnection from the transport.
static Expected< std::unique_ptr< FDSimpleRemoteEPCTransport > > Create(SimpleRemoteEPCTransportClient &C, int InFD, int OutFD)
Create a FDSimpleRemoteEPCTransport using the given FDs for reading (InFD) and writing (OutFD).
Error start() override
Called during setup of the client to indicate that the client is ready to receive messages.
Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr, ArrayRef< char > ArgBytes) override
Send a SimpleRemoteEPC message.
~FDSimpleRemoteEPCTransport() override
virtual ~SimpleRemoteEPCTransportClient()
virtual ~SimpleRemoteEPCTransport()
A utility class for serializing to a blob from a variadic list.
Output char buffer with overflow check.
C++ wrapper function buffer: Same as CWrapperFunctionBuffer but auto-releases memory.
const char * getOutOfBandError() const
If this value is an out-of-band error then this returns the error message, otherwise returns nullptr.
size_t size() const
Returns the size of the data contained in this instance.
static WrapperFunctionBuffer createOutOfBandError(const char *Msg)
Create an out-of-band error by copying the given string.
char * data()
Get a pointer to the data contained in this instance.
static WrapperFunctionBuffer allocate(size_t Size)
Create a WrapperFunctionBuffer with the given size and return a pointer to the underlying memory.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI const char * DispatchFnName
LLVM_ABI const char * ExecutorSessionObjectName
SPSSerializableError toSPSSerializable(Error Err)
Error fromSPSSerializable(SPSSerializableError BSE)
LLVM_ABI shared::WrapperFunctionBuffer encodeHangupPayload(Error Err)
Encode an Error as the payload of a Hangup message.
LLVM_ABI std::pair< ExecutorAddr, shared::WrapperFunctionBuffer > encodeResultMessage(shared::WrapperFunctionBuffer ResultBytes)
Encode a wrapper function result as the TagAddr and payload of a Result message.
SimpleRemoteEPCResultKind
Result message kind: either a value, or an out-of-band error.
LLVM_ABI Error decodeHangupPayload(shared::WrapperFunctionBuffer Payload)
Decode a Hangup payload produced by encodeHangupPayload.
LLVM_ABI Expected< shared::WrapperFunctionBuffer > decodeResultMessage(ExecutorAddr TagAddr, shared::WrapperFunctionBuffer Payload)
Decode a Result message produced by encodeResultMessage, returning the result to complete the pending...
static Error makeUnexpectedEOFError()
detail::packed_endian_specific_integral< uint64_t, llvm::endianness::little, unaligned > ulittle64_t
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Error joinErrors(Error E1, Error E2)
Concatenate errors.
@ Success
The lock was released successfully.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
LLVM_ABI Error write(DWPWriter &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue, Dwarf64StrOffsetsPromotion StrOffsetsOptValue, raw_pwrite_stream *OS=nullptr)
Helper type for serializing Errors.