Просмотр исходного кода

waitqueue增加三状态suspend
lwp_console和serial驱动改为支持可被signal中止
修改serial读失败时的返回值为0

shaojinchun 5 лет назад
Родитель
Сommit
6433f1a49e

+ 2 - 0
components/drivers/include/ipc/waitqueue.h

@@ -43,6 +43,8 @@ rt_inline void rt_wqueue_init(rt_wqueue_t *queue)
 void rt_wqueue_add(rt_wqueue_t *queue, struct rt_wqueue_node *node);
 void rt_wqueue_remove(struct rt_wqueue_node *node);
 int  rt_wqueue_wait(rt_wqueue_t *queue, int condition, int timeout);
+int  rt_wqueue_wait_killable(rt_wqueue_t *queue, int condition, int timeout);
+int  rt_wqueue_wait_interruptible(rt_wqueue_t *queue, int condition, int timeout);
 void rt_wqueue_wakeup(rt_wqueue_t *queue, void *key);
 
 #define DEFINE_WAIT_FUNC(name, function)                \

+ 10 - 2
components/drivers/serial/serial.c

@@ -127,6 +127,7 @@ static int serial_fops_read(struct dfs_fd *fd, void *buf, size_t count)
 {
     int size = 0;
     rt_device_t device;
+    int wait_ret;
 
     device = (rt_device_t)fd->data;
 
@@ -137,14 +138,21 @@ static int serial_fops_read(struct dfs_fd *fd, void *buf, size_t count)
         {
             if (fd->flags & O_NONBLOCK)
             {
-                size = -EAGAIN;
                 break;
             }
 
-            rt_wqueue_wait(&(device->wait_queue), 0, RT_WAITING_FOREVER);
+            wait_ret = rt_wqueue_wait_interruptible(&(device->wait_queue), 0, RT_WAITING_FOREVER);
+            if (wait_ret != RT_EOK)
+            {
+                break;
+            }
         }
     }while (size <= 0);
 
+    if (size < 0)
+    {
+        size = 0;
+    }
     return size;
 }
 

+ 24 - 2
components/drivers/src/waitqueue.c

@@ -74,13 +74,14 @@ void rt_wqueue_wakeup(rt_wqueue_t *queue, void *key)
         rt_schedule();
 }
 
-int rt_wqueue_wait(rt_wqueue_t *queue, int condition, int msec)
+static int _rt_wqueue_wait(rt_wqueue_t *queue, int condition, int msec, int suspend_flag)
 {
     int tick;
     rt_thread_t tid = rt_thread_self();
     rt_timer_t  tmr = &(tid->thread_timer);
     struct rt_wqueue_node __wait;
     rt_base_t level;
+    rt_err_t ret;
 
     /* current context checking */
     RT_DEBUG_NOT_IN_INTERRUPT;
@@ -102,8 +103,14 @@ int rt_wqueue_wait(rt_wqueue_t *queue, int condition, int msec)
         goto __exit_wakeup;
     }
 
+    ret = rt_thread_suspend(tid, RT_INTERRUPTIBLE);
+    if (ret != RT_EOK)
+    {
+        rt_hw_interrupt_enable(level);
+        /* suspend failed */
+        return -RT_EINTR;
+    }
     rt_wqueue_add(queue, &__wait);
-    rt_thread_suspend(tid, RT_UNINTERRUPTIBLE);
 
     /* start timer */
     if (tick != RT_WAITING_FOREVER)
@@ -128,3 +135,18 @@ __exit_wakeup:
 
     return 0;
 }
+
+int rt_wqueue_wait(rt_wqueue_t *queue, int condition, int msec)
+{
+    return _rt_wqueue_wait(queue, condition, msec, RT_UNINTERRUPTIBLE);
+}
+
+int rt_wqueue_wait_killable(rt_wqueue_t *queue, int condition, int msec)
+{
+    return _rt_wqueue_wait(queue, condition, msec, RT_KILLABLE);
+}
+
+int rt_wqueue_wait_interruptible(rt_wqueue_t *queue, int condition, int msec)
+{
+    return _rt_wqueue_wait(queue, condition, msec, RT_INTERRUPTIBLE);
+}

+ 10 - 1
components/lwp/lwp_console.c

@@ -235,6 +235,7 @@ static int console_fops_read(struct dfs_fd *fd, void *buf, size_t count)
     struct rt_console_device *console;
     struct rt_lwp *lwp;
     struct rt_wqueue *wq;
+    int wait_ret;
 
     console = (struct rt_console_device *)fd->data;
     RT_ASSERT(console != RT_NULL);
@@ -256,9 +257,17 @@ static int console_fops_read(struct dfs_fd *fd, void *buf, size_t count)
         {
             break;
         }
-        rt_wqueue_wait(wq, 0, RT_WAITING_FOREVER);
+        wait_ret = rt_wqueue_wait_interruptible(wq, 0, RT_WAITING_FOREVER);
+        if (wait_ret != 0)
+        {
+            break;
+        }
     }
     rt_hw_interrupt_enable(level);
+    if (size < 0)
+    {
+        size = 0;
+    }
     return size;
 }