浏览代码

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.
Andreas Kling 6 年之前
父节点
当前提交
cba05ce75e
共有 2 个文件被更改,包括 9 次插入1 次删除
  1. 6 0
      Kernel/Process.cpp
  2. 3 1
      Kernel/Process.h

+ 6 - 0
Kernel/Process.cpp

@@ -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

+ 3 - 1
Kernel/Process.h

@@ -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();