mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-24 05:25:13 +00:00
Kernel: Fix checking BlockResult
We now have BlockResult::WokeNormally and BlockResult::NotBlocked, both of which indicate no error. We can no longer just check for BlockResult::WokeNormally and assume anything else must be an interruption.
This commit is contained in:
parent
1493dd9dc6
commit
419703a1f2
Notes:
sideshowbarker
2024-07-19 05:02:33 +09:00
Author: https://github.com/tomuta Commit: https://github.com/SerenityOS/serenity/commit/419703a1f23 Pull-request: https://github.com/SerenityOS/serenity/pull/2721 Reviewed-by: https://github.com/awesomekling
7 changed files with 56 additions and 27 deletions
|
@ -423,7 +423,7 @@ KResult Plan9FS::post_message(Message& message)
|
|||
|
||||
while (size > 0) {
|
||||
if (!description.can_write()) {
|
||||
if (Thread::current()->block<Thread::WriteBlocker>(description) != Thread::BlockResult::WokeNormally)
|
||||
if (Thread::current()->block<Thread::WriteBlocker>(description).was_interrupted())
|
||||
return KResult(-EINTR);
|
||||
}
|
||||
ssize_t nwritten = description.write(data, size);
|
||||
|
@ -441,7 +441,7 @@ KResult Plan9FS::do_read(u8* data, size_t size)
|
|||
auto& description = file_description();
|
||||
while (size > 0) {
|
||||
if (!description.can_read()) {
|
||||
if (Thread::current()->block<Thread::ReadBlocker>(description) != Thread::BlockResult::WokeNormally)
|
||||
if (Thread::current()->block<Thread::ReadBlocker>(description).was_interrupted())
|
||||
return KResult(-EINTR);
|
||||
}
|
||||
ssize_t nread = description.read(data, size);
|
||||
|
@ -524,8 +524,7 @@ KResult Plan9FS::wait_for_specific_message(u16 tag, Message& out_message)
|
|||
// Block until either:
|
||||
// * Someone else reads the message we're waiting for, and hands it to us;
|
||||
// * Or we become the one to read and dispatch messages.
|
||||
auto block_result = Thread::current()->block<Plan9FS::Blocker>(completion);
|
||||
if (block_result != Thread::BlockResult::WokeNormally) {
|
||||
if (Thread::current()->block<Plan9FS::Blocker>(completion).was_interrupted()) {
|
||||
LOCKER(m_lock);
|
||||
m_completions.remove(tag);
|
||||
return KResult(-EINTR);
|
||||
|
|
|
@ -250,7 +250,7 @@ ssize_t IPv4Socket::receive_byte_buffered(FileDescription& description, void* bu
|
|||
locker.lock();
|
||||
|
||||
if (!m_can_read) {
|
||||
if (res != Thread::BlockResult::WokeNormally)
|
||||
if (res.was_interrupted())
|
||||
return -EINTR;
|
||||
|
||||
// Unblocked due to timeout.
|
||||
|
@ -300,7 +300,7 @@ ssize_t IPv4Socket::receive_packet_buffered(FileDescription& description, void*
|
|||
locker.lock();
|
||||
|
||||
if (!m_can_read) {
|
||||
if (res != Thread::BlockResult::WokeNormally)
|
||||
if (res.was_interrupted())
|
||||
return -EINTR;
|
||||
|
||||
// Unblocked due to timeout.
|
||||
|
|
|
@ -176,7 +176,7 @@ KResult LocalSocket::connect(FileDescription& description, const sockaddr* addre
|
|||
return KSuccess;
|
||||
}
|
||||
|
||||
if (Thread::current()->block<Thread::ConnectBlocker>(description) != Thread::BlockResult::WokeNormally) {
|
||||
if (Thread::current()->block<Thread::ConnectBlocker>(description).was_interrupted()) {
|
||||
m_connect_side_role = Role::None;
|
||||
return KResult(-EINTR);
|
||||
}
|
||||
|
@ -300,8 +300,7 @@ ssize_t LocalSocket::recvfrom(FileDescription& description, void* buffer, size_t
|
|||
return -EAGAIN;
|
||||
}
|
||||
} else if (!can_read(description, 0)) {
|
||||
auto result = Thread::current()->block<Thread::ReadBlocker>(description);
|
||||
if (result != Thread::BlockResult::WokeNormally)
|
||||
if (Thread::current()->block<Thread::ReadBlocker>(description).was_interrupted())
|
||||
return -EINTR;
|
||||
}
|
||||
if (!has_attached_peer(description) && buffer_for_me.is_empty())
|
||||
|
|
|
@ -372,7 +372,7 @@ KResult TCPSocket::protocol_connect(FileDescription& description, ShouldBlock sh
|
|||
m_direction = Direction::Outgoing;
|
||||
|
||||
if (should_block == ShouldBlock::Yes) {
|
||||
if (Thread::current()->block<Thread::ConnectBlocker>(description) != Thread::BlockResult::WokeNormally)
|
||||
if (Thread::current()->block<Thread::ConnectBlocker>(description).was_interrupted())
|
||||
return KResult(-EINTR);
|
||||
ASSERT(setup_state() == SetupState::Completed);
|
||||
if (has_error()) {
|
||||
|
|
|
@ -1774,7 +1774,7 @@ ssize_t Process::do_write(FileDescription& description, const u8* data, int data
|
|||
#ifdef IO_DEBUG
|
||||
dbg() << "block write on " << description.absolute_path();
|
||||
#endif
|
||||
if (Thread::current()->block<Thread::WriteBlocker>(description) != Thread::BlockResult::WokeNormally) {
|
||||
if (Thread::current()->block<Thread::WriteBlocker>(description).was_interrupted()) {
|
||||
if (nwritten == 0)
|
||||
return -EINTR;
|
||||
}
|
||||
|
@ -1837,7 +1837,7 @@ ssize_t Process::sys$read(int fd, u8* buffer, ssize_t size)
|
|||
return -EISDIR;
|
||||
if (description->is_blocking()) {
|
||||
if (!description->can_read()) {
|
||||
if (Thread::current()->block<Thread::ReadBlocker>(*description) != Thread::BlockResult::WokeNormally)
|
||||
if (Thread::current()->block<Thread::ReadBlocker>(*description).was_interrupted())
|
||||
return -EINTR;
|
||||
if (!description->can_read())
|
||||
return -EAGAIN;
|
||||
|
@ -2610,7 +2610,7 @@ KResultOr<siginfo_t> Process::do_waitid(idtype_t idtype, int id, int options)
|
|||
return KResult(-EINVAL);
|
||||
}
|
||||
|
||||
if (Thread::current()->block<Thread::WaitBlocker>(options, waitee_pid) != Thread::BlockResult::WokeNormally)
|
||||
if (Thread::current()->block<Thread::WaitBlocker>(options, waitee_pid).was_interrupted())
|
||||
return KResult(-EINTR);
|
||||
|
||||
ScopedSpinLock lock(g_processes_lock);
|
||||
|
@ -3075,7 +3075,7 @@ int Process::sys$select(const Syscall::SC_select_params* params)
|
|||
#endif
|
||||
|
||||
if (!timeout || select_has_timeout) {
|
||||
if (current_thread->block<Thread::SelectBlocker>(computed_timeout, select_has_timeout, rfds, wfds, efds) != Thread::BlockResult::WokeNormally)
|
||||
if (current_thread->block<Thread::SelectBlocker>(computed_timeout, select_has_timeout, rfds, wfds, efds).was_interrupted())
|
||||
return -EINTR;
|
||||
// While we blocked, the process lock was dropped. This gave other threads
|
||||
// the opportunity to mess with the memory. For example, it could free the
|
||||
|
@ -3161,7 +3161,7 @@ int Process::sys$poll(const Syscall::SC_poll_params* params)
|
|||
#endif
|
||||
|
||||
if (!timeout || has_timeout) {
|
||||
if (current_thread->block<Thread::SelectBlocker>(actual_timeout, has_timeout, rfds, wfds, Thread::SelectBlocker::FDVector()) != Thread::BlockResult::WokeNormally)
|
||||
if (current_thread->block<Thread::SelectBlocker>(actual_timeout, has_timeout, rfds, wfds, Thread::SelectBlocker::FDVector()).was_interrupted())
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
|
@ -3513,7 +3513,7 @@ int Process::sys$accept(int accepting_socket_fd, sockaddr* user_address, socklen
|
|||
|
||||
if (!socket.can_accept()) {
|
||||
if (accepting_socket_description->is_blocking()) {
|
||||
if (Thread::current()->block<Thread::AcceptBlocker>(*accepting_socket_description) != Thread::BlockResult::WokeNormally)
|
||||
if (Thread::current()->block<Thread::AcceptBlocker>(*accepting_socket_description).was_interrupted())
|
||||
return -EINTR;
|
||||
} else {
|
||||
return -EAGAIN;
|
||||
|
|
|
@ -226,7 +226,7 @@ u64 Thread::sleep(u32 ticks)
|
|||
u64 wakeup_time = g_uptime + ticks;
|
||||
auto ret = Thread::current()->block<Thread::SleepBlocker>(wakeup_time);
|
||||
if (wakeup_time > g_uptime) {
|
||||
ASSERT(ret != Thread::BlockResult::WokeNormally);
|
||||
ASSERT(ret.was_interrupted());
|
||||
}
|
||||
return wakeup_time;
|
||||
}
|
||||
|
@ -236,7 +236,7 @@ u64 Thread::sleep_until(u64 wakeup_time)
|
|||
ASSERT(state() == Thread::Running);
|
||||
auto ret = Thread::current()->block<Thread::SleepBlocker>(wakeup_time);
|
||||
if (wakeup_time > g_uptime)
|
||||
ASSERT(ret != Thread::BlockResult::WokeNormally);
|
||||
ASSERT(ret.was_interrupted());
|
||||
return wakeup_time;
|
||||
}
|
||||
|
||||
|
@ -937,16 +937,17 @@ Thread::BlockResult Thread::wait_on(WaitQueue& queue, const char* reason, timeva
|
|||
// we were in one while being called.
|
||||
}
|
||||
|
||||
BlockResult result;
|
||||
BlockResult result(BlockResult::WokeNormally);
|
||||
{
|
||||
// To be able to look at m_wait_queue_node we once again need the
|
||||
// scheduler lock, which is held when we insert into the queue
|
||||
ScopedSpinLock sched_lock(g_scheduler_lock);
|
||||
|
||||
result = m_wait_queue_node.is_in_list() ? BlockResult::InterruptedByTimeout : BlockResult::WokeNormally;
|
||||
if (m_wait_queue_node.is_in_list())
|
||||
result = BlockResult::InterruptedByTimeout;
|
||||
|
||||
// Make sure we cancel the timer if woke normally.
|
||||
if (timeout && result == BlockResult::WokeNormally)
|
||||
if (timeout && !result.was_interrupted())
|
||||
TimerQueue::the().cancel_timer(timer_id);
|
||||
}
|
||||
|
||||
|
|
|
@ -300,12 +300,42 @@ public:
|
|||
u64 sleep(u32 ticks);
|
||||
u64 sleep_until(u64 wakeup_time);
|
||||
|
||||
enum class BlockResult {
|
||||
WokeNormally,
|
||||
NotBlocked,
|
||||
InterruptedBySignal,
|
||||
InterruptedByDeath,
|
||||
InterruptedByTimeout,
|
||||
class BlockResult {
|
||||
public:
|
||||
enum Type {
|
||||
WokeNormally,
|
||||
NotBlocked,
|
||||
InterruptedBySignal,
|
||||
InterruptedByDeath,
|
||||
InterruptedByTimeout,
|
||||
};
|
||||
|
||||
BlockResult() = delete;
|
||||
|
||||
BlockResult(Type type)
|
||||
: m_type(type)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==(Type type) const
|
||||
{
|
||||
return m_type == type;
|
||||
}
|
||||
|
||||
bool was_interrupted() const
|
||||
{
|
||||
switch (m_type) {
|
||||
case InterruptedBySignal:
|
||||
case InterruptedByDeath:
|
||||
case InterruptedByTimeout:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
};
|
||||
|
||||
template<typename T, class... Args>
|
||||
|
|
Loading…
Add table
Reference in a new issue