Kernel: Don't block in send until full message is sent
Only block until some data was sent. This allows select + send to be actually non blocking if used correctly. Also fixes a bug with non blocking sockets that could not send the full message is one try.
This commit is contained in:
parent
850b3284ac
commit
5b0e5512a8
|
@ -544,33 +544,14 @@ namespace Kernel
|
|||
}
|
||||
|
||||
LockGuard _(inode->m_mutex);
|
||||
|
||||
const auto check_errors =
|
||||
[&inode, is_nonblock]() -> BAN::ErrorOr<void>
|
||||
{
|
||||
if (inode->has_hungup())
|
||||
{
|
||||
Thread::current().add_signal(SIGPIPE);
|
||||
return BAN::Error::from_errno(EPIPE);
|
||||
}
|
||||
if (is_nonblock && !inode->can_write())
|
||||
return BAN::Error::from_errno(EWOULDBLOCK);
|
||||
return {};
|
||||
};
|
||||
|
||||
TRY(check_errors());
|
||||
|
||||
size_t total_sent = 0;
|
||||
while (total_sent < buffer.size())
|
||||
if (inode->has_hungup())
|
||||
{
|
||||
TRY(check_errors());
|
||||
const size_t nsend = TRY(inode->sendto(buffer.slice(total_sent), address, address_len));
|
||||
if (nsend == 0)
|
||||
return 0;
|
||||
total_sent += nsend;
|
||||
Thread::current().add_signal(SIGPIPE);
|
||||
return BAN::Error::from_errno(EPIPE);
|
||||
}
|
||||
|
||||
return total_sent;
|
||||
if (is_nonblock && !inode->can_write())
|
||||
return BAN::Error::from_errno(EWOULDBLOCK);
|
||||
return inode->sendto(buffer, address, address_len);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<VirtualFileSystem::File> OpenFileDescriptorSet::file_of(int fd) const
|
||||
|
|
Loading…
Reference in New Issue