diff options
-rw-r--r-- | Kernel/FileSystem/Plan9FileSystem.cpp | 7 | ||||
-rw-r--r-- | Kernel/Net/IPv4Socket.cpp | 4 | ||||
-rw-r--r-- | Kernel/Net/LocalSocket.cpp | 5 | ||||
-rw-r--r-- | Kernel/Net/TCPSocket.cpp | 2 | ||||
-rw-r--r-- | Kernel/Process.cpp | 12 | ||||
-rw-r--r-- | Kernel/Thread.cpp | 11 | ||||
-rw-r--r-- | Kernel/Thread.h | 42 |
7 files changed, 56 insertions, 27 deletions
diff --git a/Kernel/FileSystem/Plan9FileSystem.cpp b/Kernel/FileSystem/Plan9FileSystem.cpp index 94ac878f58..aa5bc2c4ba 100644 --- a/Kernel/FileSystem/Plan9FileSystem.cpp +++ b/Kernel/FileSystem/Plan9FileSystem.cpp @@ -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); diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index 6371808c0f..fb8d179601 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -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. diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp index b2d2fdd028..63008e2ab0 100644 --- a/Kernel/Net/LocalSocket.cpp +++ b/Kernel/Net/LocalSocket.cpp @@ -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()) diff --git a/Kernel/Net/TCPSocket.cpp b/Kernel/Net/TCPSocket.cpp index f223dfc8f8..78da2eb432 100644 --- a/Kernel/Net/TCPSocket.cpp +++ b/Kernel/Net/TCPSocket.cpp @@ -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()) { diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index f4e5995db3..3bb727452e 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -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; diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index c29543b8cf..01842b06b4 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -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); } diff --git a/Kernel/Thread.h b/Kernel/Thread.h index e9b39161bd..50ffe54a1a 100644 --- a/Kernel/Thread.h +++ b/Kernel/Thread.h @@ -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> |