mirror of
https://github.com/SerenityOS/serenity.git
synced 2026-11-07 04:29:30 -10:00
Kernel: Make local socket descriptor allocations more efficient
Now we only track the numerical fd, whereas previously we also tracked the respective OpenFileDescription instance. This patch also gives the vector in sys$recvmsg some inline capacity to reduce allocation churn.
This commit is contained in:
1 parent
97157ad757
commit
069650b1fa
3 files changed
+9
-11
No files matched your search
@@ -535,10 +535,9 @@ ErrorOr<NonnullRefPtr<OpenFileDescription>> LocalSocket::recvfd(OpenFileDescript
|
||||
return queue.take_first();
|
||||
}
|
||||
|
||||
ErrorOr<Vector<NonnullRefPtr<OpenFileDescription>>> LocalSocket::recvfds(OpenFileDescription const& socket_description, int n)
|
||||
ErrorOr<void> LocalSocket::recvfds(OpenFileDescription const& socket_description, int n, Function<ErrorOr<void>(OpenFileDescription&)> callback)
|
||||
{
|
||||
MutexLocker locker(mutex());
|
||||
Vector<NonnullRefPtr<OpenFileDescription>> fds;
|
||||
|
||||
auto role = this->role(socket_description);
|
||||
if (role != Role::Connected && role != Role::Accepted)
|
||||
@@ -549,10 +548,10 @@ ErrorOr<Vector<NonnullRefPtr<OpenFileDescription>>> LocalSocket::recvfds(OpenFil
|
||||
if (queue.is_empty())
|
||||
break;
|
||||
|
||||
fds.append(queue.take_first());
|
||||
TRY(callback(*queue.take_first()));
|
||||
}
|
||||
|
||||
return fds;
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<void> LocalSocket::try_set_path(StringView path)
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
|
||||
ErrorOr<void> sendfd(OpenFileDescription const& socket_description, NonnullRefPtr<OpenFileDescription> passing_description);
|
||||
ErrorOr<NonnullRefPtr<OpenFileDescription>> recvfd(OpenFileDescription const& socket_description);
|
||||
ErrorOr<Vector<NonnullRefPtr<OpenFileDescription>>> recvfds(OpenFileDescription const& socket_description, int n);
|
||||
ErrorOr<void> recvfds(OpenFileDescription const& socket_description, int n, Function<ErrorOr<void>(OpenFileDescription&)> callback);
|
||||
|
||||
static void for_each(Function<void(LocalSocket const&)>);
|
||||
static ErrorOr<void> try_for_each(Function<ErrorOr<void>(LocalSocket const&)>);
|
||||
|
||||
@@ -317,13 +317,12 @@ ErrorOr<FlatPtr> Process::sys$recvmsg(int sockfd, Userspace<struct msghdr*> user
|
||||
int space_for_fds = (msg.msg_controllen - current_cmsg_len - sizeof(struct cmsghdr)) / sizeof(int);
|
||||
if (space_for_fds > 0 && socket.is_local()) {
|
||||
auto& local_socket = static_cast<LocalSocket&>(socket);
|
||||
auto descriptions = TRY(local_socket.recvfds(description, space_for_fds));
|
||||
Vector<int> fdnums;
|
||||
for (auto& description : descriptions) {
|
||||
Vector<int, 128> fdnums;
|
||||
TRY(local_socket.recvfds(description, space_for_fds, [&](auto const& description) -> ErrorOr<void> {
|
||||
auto fd_allocation = TRY(m_fds.with_exclusive([](auto& fds) { return fds.allocate(); }));
|
||||
m_fds.with_exclusive([&](auto& fds) { fds[fd_allocation.fd].set(*description, 0); });
|
||||
fdnums.append(fd_allocation.fd);
|
||||
}
|
||||
m_fds.with_exclusive([&](auto& fds) { fds[fd_allocation.fd].set(description, 0); });
|
||||
return fdnums.try_append(fd_allocation.fd);
|
||||
}));
|
||||
if (!fdnums.is_empty())
|
||||
TRY(try_add_cmsg(SOL_SOCKET, SCM_RIGHTS, fdnums.data(), fdnums.size() * sizeof(int)));
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user