aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/ExecutionEngine/Orc/RPCChannel.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/ExecutionEngine/Orc/RPCChannel.h')
-rw-r--r--include/llvm/ExecutionEngine/Orc/RPCChannel.h188
1 files changed, 129 insertions, 59 deletions
diff --git a/include/llvm/ExecutionEngine/Orc/RPCChannel.h b/include/llvm/ExecutionEngine/Orc/RPCChannel.h
index b97b6daf5864..c569e3cf05b4 100644
--- a/include/llvm/ExecutionEngine/Orc/RPCChannel.h
+++ b/include/llvm/ExecutionEngine/Orc/RPCChannel.h
@@ -1,13 +1,27 @@
-// -*- c++ -*-
+//===- llvm/ExecutionEngine/Orc/RPCChannel.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_RPCCHANNEL_H
#define LLVM_EXECUTIONENGINE_ORC_RPCCHANNEL_H
#include "OrcError.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Endian.h"
-
-#include <system_error>
+#include "llvm/Support/Error.h"
+#include <cstddef>
+#include <cstdint>
+#include <mutex>
+#include <string>
+#include <tuple>
+#include <vector>
namespace llvm {
namespace orc {
@@ -19,40 +33,73 @@ public:
virtual ~RPCChannel() {}
/// Read Size bytes from the stream into *Dst.
- virtual std::error_code readBytes(char *Dst, unsigned Size) = 0;
+ virtual Error readBytes(char *Dst, unsigned Size) = 0;
/// Read size bytes from *Src and append them to the stream.
- virtual std::error_code appendBytes(const char *Src, unsigned Size) = 0;
+ virtual Error appendBytes(const char *Src, unsigned Size) = 0;
/// Flush the stream if possible.
- virtual std::error_code send() = 0;
+ virtual Error send() = 0;
+
+ /// 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;
};
+/// Notify the channel that we're starting a message send.
+/// Locks the channel for writing.
+inline Error startSendMessage(RPCChannel &C) {
+ C.getWriteLock().lock();
+ return Error::success();
+}
+
+/// Notify the channel that we're ending a message send.
+/// Unlocks the channel for writing.
+inline Error endSendMessage(RPCChannel &C) {
+ C.getWriteLock().unlock();
+ return Error::success();
+}
+
+/// Notify the channel that we're starting a message receive.
+/// Locks the channel for reading.
+inline Error startReceiveMessage(RPCChannel &C) {
+ C.getReadLock().lock();
+ return Error::success();
+}
+
+/// Notify the channel that we're ending a message receive.
+/// Unlocks the channel for reading.
+inline Error endReceiveMessage(RPCChannel &C) {
+ C.getReadLock().unlock();
+ return Error::success();
+}
+
/// RPC channel serialization for a variadic list of arguments.
template <typename T, typename... Ts>
-std::error_code serialize_seq(RPCChannel &C, const T &Arg, const Ts &... Args) {
- if (auto EC = serialize(C, Arg))
- return EC;
- return serialize_seq(C, Args...);
+Error serializeSeq(RPCChannel &C, const T &Arg, const Ts &... Args) {
+ if (auto Err = serialize(C, Arg))
+ return Err;
+ return serializeSeq(C, Args...);
}
/// RPC channel serialization for an (empty) variadic list of arguments.
-inline std::error_code serialize_seq(RPCChannel &C) {
- return std::error_code();
-}
+inline Error serializeSeq(RPCChannel &C) { return Error::success(); }
/// RPC channel deserialization for a variadic list of arguments.
template <typename T, typename... Ts>
-std::error_code deserialize_seq(RPCChannel &C, T &Arg, Ts &... Args) {
- if (auto EC = deserialize(C, Arg))
- return EC;
- return deserialize_seq(C, Args...);
+Error deserializeSeq(RPCChannel &C, T &Arg, Ts &... Args) {
+ if (auto Err = deserialize(C, Arg))
+ return Err;
+ return deserializeSeq(C, Args...);
}
/// RPC channel serialization for an (empty) variadic list of arguments.
-inline std::error_code deserialize_seq(RPCChannel &C) {
- return std::error_code();
-}
+inline Error deserializeSeq(RPCChannel &C) { return Error::success(); }
/// RPC channel serialization for integer primitives.
template <typename T>
@@ -61,7 +108,7 @@ typename std::enable_if<
std::is_same<T, uint32_t>::value || std::is_same<T, int32_t>::value ||
std::is_same<T, uint16_t>::value || std::is_same<T, int16_t>::value ||
std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value,
- std::error_code>::type
+ Error>::type
serialize(RPCChannel &C, T V) {
support::endian::byte_swap<T, support::big>(V);
return C.appendBytes(reinterpret_cast<const char *>(&V), sizeof(T));
@@ -74,106 +121,129 @@ typename std::enable_if<
std::is_same<T, uint32_t>::value || std::is_same<T, int32_t>::value ||
std::is_same<T, uint16_t>::value || std::is_same<T, int16_t>::value ||
std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value,
- std::error_code>::type
+ Error>::type
deserialize(RPCChannel &C, T &V) {
- if (auto EC = C.readBytes(reinterpret_cast<char *>(&V), sizeof(T)))
- return EC;
+ if (auto Err = C.readBytes(reinterpret_cast<char *>(&V), sizeof(T)))
+ return Err;
support::endian::byte_swap<T, support::big>(V);
- return std::error_code();
+ return Error::success();
}
/// RPC channel serialization for enums.
template <typename T>
-typename std::enable_if<std::is_enum<T>::value, std::error_code>::type
+typename std::enable_if<std::is_enum<T>::value, Error>::type
serialize(RPCChannel &C, T V) {
return serialize(C, static_cast<typename std::underlying_type<T>::type>(V));
}
/// RPC channel deserialization for enums.
template <typename T>
-typename std::enable_if<std::is_enum<T>::value, std::error_code>::type
+typename std::enable_if<std::is_enum<T>::value, Error>::type
deserialize(RPCChannel &C, T &V) {
typename std::underlying_type<T>::type Tmp;
- std::error_code EC = deserialize(C, Tmp);
+ Error Err = deserialize(C, Tmp);
V = static_cast<T>(Tmp);
- return EC;
+ return Err;
}
/// RPC channel serialization for bools.
-inline std::error_code serialize(RPCChannel &C, bool V) {
+inline Error serialize(RPCChannel &C, bool V) {
uint8_t VN = V ? 1 : 0;
return C.appendBytes(reinterpret_cast<const char *>(&VN), 1);
}
/// RPC channel deserialization for bools.
-inline std::error_code deserialize(RPCChannel &C, bool &V) {
+inline Error deserialize(RPCChannel &C, bool &V) {
uint8_t VN = 0;
- if (auto EC = C.readBytes(reinterpret_cast<char *>(&VN), 1))
- return EC;
+ if (auto Err = C.readBytes(reinterpret_cast<char *>(&VN), 1))
+ return Err;
- V = (VN != 0) ? true : false;
- return std::error_code();
+ V = (VN != 0);
+ return Error::success();
}
/// RPC channel serialization for StringRefs.
/// Note: There is no corresponding deseralization for this, as StringRef
/// doesn't own its memory and so can't hold the deserialized data.
-inline std::error_code serialize(RPCChannel &C, StringRef S) {
- if (auto EC = serialize(C, static_cast<uint64_t>(S.size())))
- return EC;
+inline Error serialize(RPCChannel &C, StringRef S) {
+ if (auto Err = serialize(C, static_cast<uint64_t>(S.size())))
+ return Err;
return C.appendBytes((const char *)S.bytes_begin(), S.size());
}
/// RPC channel serialization for std::strings.
-inline std::error_code serialize(RPCChannel &C, const std::string &S) {
+inline Error serialize(RPCChannel &C, const std::string &S) {
return serialize(C, StringRef(S));
}
/// RPC channel deserialization for std::strings.
-inline std::error_code deserialize(RPCChannel &C, std::string &S) {
+inline Error deserialize(RPCChannel &C, std::string &S) {
uint64_t Count;
- if (auto EC = deserialize(C, Count))
- return EC;
+ if (auto Err = deserialize(C, Count))
+ return Err;
S.resize(Count);
return C.readBytes(&S[0], Count);
}
+// Serialization helper for std::tuple.
+template <typename TupleT, size_t... Is>
+inline Error serializeTupleHelper(RPCChannel &C, const TupleT &V,
+ llvm::index_sequence<Is...> _) {
+ return serializeSeq(C, std::get<Is>(V)...);
+}
+
+/// RPC channel serialization for std::tuple.
+template <typename... ArgTs>
+inline Error serialize(RPCChannel &C, const std::tuple<ArgTs...> &V) {
+ return serializeTupleHelper(C, V, llvm::index_sequence_for<ArgTs...>());
+}
+
+// Serialization helper for std::tuple.
+template <typename TupleT, size_t... Is>
+inline Error deserializeTupleHelper(RPCChannel &C, TupleT &V,
+ llvm::index_sequence<Is...> _) {
+ return deserializeSeq(C, std::get<Is>(V)...);
+}
+
+/// RPC channel deserialization for std::tuple.
+template <typename... ArgTs>
+inline Error deserialize(RPCChannel &C, std::tuple<ArgTs...> &V) {
+ return deserializeTupleHelper(C, V, llvm::index_sequence_for<ArgTs...>());
+}
+
/// RPC channel serialization for ArrayRef<T>.
-template <typename T>
-std::error_code serialize(RPCChannel &C, const ArrayRef<T> &A) {
- if (auto EC = serialize(C, static_cast<uint64_t>(A.size())))
- return EC;
+template <typename T> Error serialize(RPCChannel &C, const ArrayRef<T> &A) {
+ if (auto Err = serialize(C, static_cast<uint64_t>(A.size())))
+ return Err;
for (const auto &E : A)
- if (auto EC = serialize(C, E))
- return EC;
+ if (auto Err = serialize(C, E))
+ return Err;
- return std::error_code();
+ return Error::success();
}
/// RPC channel serialization for std::array<T>.
-template <typename T>
-std::error_code serialize(RPCChannel &C, const std::vector<T> &V) {
+template <typename T> Error serialize(RPCChannel &C, const std::vector<T> &V) {
return serialize(C, ArrayRef<T>(V));
}
/// RPC channel deserialization for std::array<T>.
-template <typename T>
-std::error_code deserialize(RPCChannel &C, std::vector<T> &V) {
+template <typename T> Error deserialize(RPCChannel &C, std::vector<T> &V) {
uint64_t Count = 0;
- if (auto EC = deserialize(C, Count))
- return EC;
+ if (auto Err = deserialize(C, Count))
+ return Err;
V.resize(Count);
for (auto &E : V)
- if (auto EC = deserialize(C, E))
- return EC;
+ if (auto Err = deserialize(C, E))
+ return Err;
- return std::error_code();
+ return Error::success();
}
} // end namespace remote
} // end namespace orc
} // end namespace llvm
-#endif
+#endif // LLVM_EXECUTIONENGINE_ORC_RPCCHANNEL_H