CIRCT 23.0.0git
Loading...
Searching...
No Matches
RpcWire.h
Go to the documentation of this file.
1//===- RpcWire.h - Shared cosim wire-format helpers -------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Small inline helpers for encoding/decoding the cosim binary data-frame
10// layout (`[u64 LE channel_id][payload]`). Used by both RpcServer.cpp and
11// RpcClient.cpp so the two ends can't drift apart on wire format. Header is
12// private to the CosimRpc library; not installed.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef ESI_BACKENDS_RPC_WIRE_H
17#define ESI_BACKENDS_RPC_WIRE_H
18
19#include <cstddef>
20#include <cstdint>
21#include <exception>
22#include <mutex>
23#include <string>
24
25namespace esi {
26namespace cosim {
27
28/// Pack a cosim binary data frame: `[u64 LE channel_id][payload]`.
29inline std::string buildDataFrame(uint64_t channelId, const uint8_t *bytes,
30 size_t size) {
31 std::string frame;
32 frame.reserve(8 + size);
33 uint8_t hdr[8];
34 for (int i = 0; i < 8; ++i)
35 hdr[i] = static_cast<uint8_t>((channelId >> (8 * i)) & 0xFF);
36 frame.append(reinterpret_cast<const char *>(hdr), 8);
37 frame.append(reinterpret_cast<const char *>(bytes), size);
38 return frame;
39}
40
41/// Size of the binary data-frame header (LE channel_id).
42inline constexpr size_t kDataFrameHeaderSize = 8;
43
44/// Parse a cosim binary data frame. On success returns true and sets
45/// `channelId` to the decoded id; `payload` / `payloadSize` point into
46/// `data` past the header. Returns false if `data` is too short to contain
47/// the header.
48inline bool parseDataFrame(const std::string &data, uint64_t &channelId,
49 const uint8_t *&payload, size_t &payloadSize) {
50 if (data.size() < kDataFrameHeaderSize)
51 return false;
52 uint64_t id = 0;
53 for (int i = 0; i < 8; ++i)
54 id |= static_cast<uint64_t>(static_cast<uint8_t>(data[i])) << (8 * i);
55 channelId = id;
56 payload =
57 reinterpret_cast<const uint8_t *>(data.data()) + kDataFrameHeaderSize;
58 payloadSize = data.size() - kDataFrameHeaderSize;
59 return true;
60}
61
62/// Cross-thread error channel for the IXWebSocket network thread.
63///
64/// IXWebSocket invokes user callbacks from its internal network thread; any
65/// exception escaping that callback kills the process. Call sites catch and
66/// `record()` the first fault; the next public method on the owning
67/// RpcServer/RpcClient calls `check()`, which consumes the stash and rethrows
68/// on the user's thread.
70public:
71 /// Stash the first exception we see (subsequent ones are dropped -- the
72 /// first is the most informative). Safe to call from any thread.
73 void record(std::exception_ptr ep) noexcept {
74 std::lock_guard<std::mutex> lock(mutex);
75 if (!fault)
76 fault = ep;
77 }
78
79 /// Consume and rethrow the stored fault on the caller's thread, if any.
80 void check() {
81 std::exception_ptr ep;
82 {
83 std::lock_guard<std::mutex> lock(mutex);
84 // `std::exception_ptr` has no member `swap()`; use the free function.
85 std::swap(ep, fault);
86 }
87 if (ep)
88 std::rethrow_exception(ep);
89 }
90
91private:
92 std::mutex mutex;
93 std::exception_ptr fault;
94};
95
96} // namespace cosim
97} // namespace esi
98
99#endif // ESI_BACKENDS_RPC_WIRE_H
Cross-thread error channel for the IXWebSocket network thread.
Definition RpcWire.h:69
std::exception_ptr fault
Definition RpcWire.h:93
void record(std::exception_ptr ep) noexcept
Stash the first exception we see (subsequent ones are dropped – the first is the most informative).
Definition RpcWire.h:73
void check()
Consume and rethrow the stored fault on the caller's thread, if any.
Definition RpcWire.h:80
std::string buildDataFrame(uint64_t channelId, const uint8_t *bytes, size_t size)
Pack a cosim binary data frame: [u64 LE channel_id][payload].
Definition RpcWire.h:29
bool parseDataFrame(const std::string &data, uint64_t &channelId, const uint8_t *&payload, size_t &payloadSize)
Parse a cosim binary data frame.
Definition RpcWire.h:48
constexpr size_t kDataFrameHeaderSize
Size of the binary data-frame header (LE channel_id).
Definition RpcWire.h:42
Definition esi.py:1