diff options
author | Andreas Kling <kling@serenityos.org> | 2020-03-07 11:26:17 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-03-07 11:27:55 +0100 |
commit | f2f16e1c2484951f8d8b7b2f439f158184df8321 (patch) | |
tree | 53933dfc63eabae3ec90e89d61ccd0e3fd1577e2 /Kernel | |
parent | 7a9cb2dfca90f3e7930faa217fcb5d847b44fe54 (diff) | |
download | serenity-f2f16e1c2484951f8d8b7b2f439f158184df8321.zip |
IPv4: Keep IPv4 socket locked during receive operations
We unlock/relock around blocking, but outside of that we now keep the
socket locked.
This fixes an intermittent ASSERT(m_can_read) failure.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Net/IPv4Socket.cpp | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index 2ab9c553ff..17f814fc2e 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -238,15 +238,17 @@ ssize_t IPv4Socket::sendto(FileDescription&, const void* data, size_t data_lengt ssize_t IPv4Socket::receive_byte_buffered(FileDescription& description, void* buffer, size_t buffer_length, int, sockaddr*, socklen_t*) { + Locker locker(lock()); if (m_receive_buffer.is_empty()) { if (protocol_is_disconnected()) return 0; if (!description.is_blocking()) return -EAGAIN; + locker.unlock(); auto res = Thread::current->block<Thread::ReadBlocker>(description); + locker.lock(); - LOCKER(lock()); if (!m_can_read) { if (res != Thread::BlockResult::WokeNormally) return -EINTR; @@ -267,9 +269,9 @@ ssize_t IPv4Socket::receive_byte_buffered(FileDescription& description, void* bu ssize_t IPv4Socket::receive_packet_buffered(FileDescription& description, void* buffer, size_t buffer_length, int flags, sockaddr* addr, socklen_t* addr_length) { + Locker locker(lock()); ReceivedPacket packet; { - LOCKER(lock()); if (m_receive_queue.is_empty()) { // FIXME: Shouldn't this return -ENOTCONN instead of EOF? // But if so, we still need to deliver at least one EOF read to userspace.. right? @@ -293,9 +295,10 @@ ssize_t IPv4Socket::receive_packet_buffered(FileDescription& description, void* return 0; } + locker.unlock(); auto res = Thread::current->block<Thread::ReadBlocker>(description); + locker.lock(); - LOCKER(lock()); if (!m_can_read) { if (res != Thread::BlockResult::WokeNormally) return -EINTR; |