Skip to content

Commit

Permalink
nixd/librpc: use exceptions for IO operations
Browse files Browse the repository at this point in the history
  • Loading branch information
inclyc committed Mar 11, 2024
1 parent a575800 commit 13ea74d
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 28 deletions.
8 changes: 4 additions & 4 deletions nixd/librpc/include/nixd/rpc/IO.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#pragma once

#include <cstdint>
#include <string>
#include <cstddef>

#include <sys/types.h>

namespace nixd::rpc {

/// \brief Read N bytes from FD into Buf, block until N bytes are read.
/// \returns the number of bytes read, or -1 on error. (errno is set)
long readBytes(int FD, void *Buf, std::size_t N);
size_t readBytes(int FD, void *Buf, std::size_t N);

} // namespace nixd::rpc
23 changes: 21 additions & 2 deletions nixd/librpc/include/nixd/rpc/Transport.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include "nixd/rpc/Protocol.h"

#include <string_view>
#include <vector>

Expand All @@ -10,9 +12,26 @@ class Transport {
int OutboundFD;

protected:
[[nodiscard]] int send(std::string_view Msg) const;
/// \brief Wraps a message with it's length, and then send it.
void send(std::string_view Msg) const;

/// \brief Read a message and then forms a packet.
[[nodiscard]] std::vector<char> recv() const;

template <class T> T recvPacket() const {
std::vector<char> Buf = recv();
T Data;
std::string_view D = {Buf.begin(), Buf.end()};
readBytecode(D, Data);
return Data;
}

template <class T> void sendPacket(const T &Data) {
auto Str = bc::toBytecode(Data);
send(Str);
}

[[nodiscard]] virtual int handleInbound(const std::vector<char> &Buf) = 0;
virtual void handleInbound(const std::vector<char> &Buf) = 0;

public:
[[nodiscard]] int run();
Expand Down
12 changes: 7 additions & 5 deletions nixd/librpc/src/IO.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
#include "nixd/rpc/IO.h"

#include <system_error>

#include <unistd.h>

namespace nixd::rpc {

long readBytes(int FD, void *Buf, std::size_t N) {
std::size_t Read = 0;
size_t readBytes(int FD, void *Buf, std::size_t N) {
size_t Read = 0;
while (Read < N) {
auto BytesRead = read(FD, static_cast<char *>(Buf) + Read, N - Read);
size_t BytesRead = read(FD, static_cast<char *>(Buf) + Read, N - Read);
if (BytesRead <= 0)
return BytesRead;
throw std::system_error(std::make_error_code(std::errc(errno)));
Read += BytesRead;
}
return static_cast<long>(Read);
return Read;
}

} // namespace nixd::rpc
35 changes: 18 additions & 17 deletions nixd/librpc/src/Transport.cpp
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
#include "nixd/rpc/Transport.h"
#include "nixd/rpc/IO.h"

#include <unistd.h>
#include <system_error>
#include <vector>

#include <unistd.h>

namespace nixd::rpc {

using MessageSizeT = std::size_t;

int Transport::send(std::string_view Msg) const {
void Transport::send(std::string_view Msg) const {
MessageSizeT Size = Msg.size();
if (write(OutboundFD, &Size, sizeof(MessageSizeT)) < 0)
return -1;
throw std::system_error(std::make_error_code(std::errc(errno)));
if (write(OutboundFD, Msg.data(), Msg.size()) < 0)
return -1;
return 0;
throw std::system_error(std::make_error_code(std::errc(errno)));
}

std::vector<char> Transport::recv() const {
MessageSizeT Size;
readBytes(InboundFD, &Size, sizeof(Size));

// Collect a message
std::vector<char> Buf(Size);
readBytes(InboundFD, Buf.data(), Size);
return Buf;
}

int Transport::run() {
for (;;) {
MessageSizeT Size;
if (readBytes(InboundFD, &Size, sizeof(Size)) <= 0) {
// Handle error
}

// Then read the message
// Collect a message
std::vector<char> Buf(Size);
if (readBytes(InboundFD, Buf.data(), Size) <= 0)
return -1;
if (handleInbound(Buf) != 0)
return -1;
std::vector<char> Buf = recv();
handleInbound(Buf);
}
return 0;
}
Expand Down

0 comments on commit 13ea74d

Please sign in to comment.