summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-03-07 11:26:17 +0100
committerAndreas Kling <kling@serenityos.org>2020-03-07 11:27:55 +0100
commitf2f16e1c2484951f8d8b7b2f439f158184df8321 (patch)
tree53933dfc63eabae3ec90e89d61ccd0e3fd1577e2 /Kernel
parent7a9cb2dfca90f3e7930faa217fcb5d847b44fe54 (diff)
downloadserenity-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.cpp9
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;