mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 23:28:11 +00:00
LibIPC: Allow giving Connection a separate socket for FD passing
Our IPC protocol currently relies on the behavior of recvfd() and sendfd() on SerenityOS, which provide an out-of-band queue that can be accessed independently of the in-band data stream. To make LibIPC usable on other platforms, this patch adds a mechanism where IPC::Connection can be given a dedicated socket for FD passing. This gives us the same behavior as the syscalls on SerenityOS, without having to change the protocol implementation.
This commit is contained in:
parent
3bb25ef227
commit
ece1b7422f
2 changed files with 20 additions and 3 deletions
|
@ -20,6 +20,18 @@ ConnectionBase::ConnectionBase(IPC::Stub& local_stub, NonnullOwnPtr<Core::Stream
|
|||
m_responsiveness_timer = Core::Timer::create_single_shot(3000, [this] { may_have_become_unresponsive(); });
|
||||
}
|
||||
|
||||
void ConnectionBase::set_fd_passing_socket(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||
{
|
||||
m_fd_passing_socket = move(socket);
|
||||
}
|
||||
|
||||
Core::Stream::LocalSocket& ConnectionBase::fd_passing_socket()
|
||||
{
|
||||
if (m_fd_passing_socket)
|
||||
return *m_fd_passing_socket;
|
||||
return *m_socket;
|
||||
}
|
||||
|
||||
ErrorOr<void> ConnectionBase::post_message(Message const& message)
|
||||
{
|
||||
return post_message(message.encode());
|
||||
|
@ -38,7 +50,7 @@ ErrorOr<void> ConnectionBase::post_message(MessageBuffer buffer)
|
|||
|
||||
#ifdef __serenity__
|
||||
for (auto& fd : buffer.fds) {
|
||||
if (auto result = m_socket->send_fd(fd.value()); result.is_error()) {
|
||||
if (auto result = fd_passing_socket().send_fd(fd.value()); result.is_error()) {
|
||||
shutdown_with_error(result.error());
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ class ConnectionBase : public Core::Object {
|
|||
public:
|
||||
virtual ~ConnectionBase() override = default;
|
||||
|
||||
void set_fd_passing_socket(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||
|
||||
bool is_open() const { return m_socket->is_open(); }
|
||||
ErrorOr<void> post_message(Message const&);
|
||||
|
||||
|
@ -43,6 +45,7 @@ protected:
|
|||
explicit ConnectionBase(IPC::Stub&, NonnullOwnPtr<Core::Stream::LocalSocket>, u32 local_endpoint_magic);
|
||||
|
||||
Core::Stream::LocalSocket& socket() { return *m_socket; }
|
||||
Core::Stream::LocalSocket& fd_passing_socket();
|
||||
|
||||
virtual void may_have_become_unresponsive() { }
|
||||
virtual void did_become_responsive() { }
|
||||
|
@ -60,6 +63,8 @@ protected:
|
|||
IPC::Stub& m_local_stub;
|
||||
|
||||
NonnullOwnPtr<Core::Stream::LocalSocket> m_socket;
|
||||
OwnPtr<Core::Stream::LocalSocket> m_fd_passing_socket;
|
||||
|
||||
RefPtr<Core::Timer> m_responsiveness_timer;
|
||||
|
||||
NonnullOwnPtrVector<Message> m_unprocessed_messages;
|
||||
|
@ -123,9 +128,9 @@ protected:
|
|||
break;
|
||||
index += sizeof(message_size);
|
||||
auto remaining_bytes = ReadonlyBytes { bytes.data() + index, message_size };
|
||||
if (auto message = LocalEndpoint::decode_message(remaining_bytes, *m_socket)) {
|
||||
if (auto message = LocalEndpoint::decode_message(remaining_bytes, fd_passing_socket())) {
|
||||
m_unprocessed_messages.append(message.release_nonnull());
|
||||
} else if (auto message = PeerEndpoint::decode_message(remaining_bytes, *m_socket)) {
|
||||
} else if (auto message = PeerEndpoint::decode_message(remaining_bytes, fd_passing_socket())) {
|
||||
m_unprocessed_messages.append(message.release_nonnull());
|
||||
} else {
|
||||
dbgln("Failed to parse a message");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue