Before sys$write returns, check for pending unmasked signals.

If there is one, put the process into a new BlockedSignal state which makes
the next scheduler iteration dispatch the signal.
This commit is contained in:
Andreas Kling 2018-11-10 02:43:33 +01:00
parent 8605711f4b
commit cba05ce75e
Notes: sideshowbarker 2024-07-19 16:11:39 +09:00
2 changed files with 9 additions and 1 deletions

View File

@ -978,6 +978,12 @@ ssize_t Process::sys$write(int fd, const void* data, size_t size)
if (!descriptor)
return -EBADF;
auto nwritten = descriptor->write((const byte*)data, size);
if (has_unmasked_pending_signals()) {
block(BlockedSignal);
Scheduler::yield();
if (nwritten == 0)
return -EINTR;
}
#ifdef DEBUG_IO
kprintf("Process::sys$write: nwritten=%u\n", nwritten);
#endif

View File

@ -52,6 +52,7 @@ public:
BlockedSleep,
BlockedWait,
BlockedRead,
BlockedSignal,
};
enum RingLevel {
@ -64,7 +65,7 @@ public:
bool is_blocked() const
{
return m_state == BlockedSleep || m_state == BlockedWait || m_state == BlockedRead;
return m_state == BlockedSleep || m_state == BlockedWait || m_state == BlockedRead || m_state == BlockedSignal;
}
PageDirectory& page_directory() { return *m_page_directory; }
@ -317,6 +318,7 @@ static inline const char* toString(Process::State state)
case Process::BlockedSleep: return "Sleep";
case Process::BlockedWait: return "Wait";
case Process::BlockedRead: return "Read";
case Process::BlockedSignal: return "Signal";
case Process::BeingInspected: return "Inspect";
}
ASSERT_NOT_REACHED();