瀏覽代碼

[lwp_ipc] support file descriptor transmit (#7318)

张世争 2 年之前
父節點
當前提交
3f442bbe4a
共有 2 個文件被更改,包括 66 次插入1 次删除
  1. 59 0
      components/lwp/lwp_ipc.c
  2. 7 1
      components/lwp/lwp_ipc.h

+ 59 - 0
components/lwp/lwp_ipc.c

@@ -356,6 +356,51 @@ static void sender_timeout(void *parameter)
     rt_schedule();
 }
 
+/**
+ * Get file vnode from fd.
+ */
+static void *_ipc_msg_get_file(int fd)
+{
+    struct dfs_file *d;
+
+    d = fd_get(fd);
+    if (d == RT_NULL)
+        return RT_NULL;
+
+    if (!d->vnode)
+        return RT_NULL;
+
+    d->vnode->ref_count++;
+    return (void *)d->vnode;
+}
+
+/**
+ * Get fd from file vnode.
+ */
+static int _ipc_msg_fd_new(void *file)
+{
+    int fd;
+    struct dfs_file *d;
+
+    fd = fd_new();
+    if (fd < 0)
+    {
+        return -1;
+    }
+
+    d = fd_get(fd);
+    if (!d)
+    {
+        fd_release(fd);
+        return -1;
+    }
+
+    d->vnode = (struct dfs_vnode *)file;
+    d->flags = O_RDWR; /* set flags as read and write */
+
+    return fd;
+}
+
 /**
  * Send data through an IPC channel, wait for the reply or not.
  */
@@ -398,6 +443,12 @@ static rt_err_t _rt_raw_channel_send_recv_timeout(rt_channel_t ch, rt_channel_ms
         return -RT_ENOMEM;
     }
 
+    /* IPC message : file descriptor */
+    if (data->type == RT_CHANNEL_FD)
+    {
+        data->u.fd.file = _ipc_msg_get_file(data->u.fd.fd);
+    }
+
     rt_ipc_msg_init(msg, data, need_reply);
 
     if (need_reply)
@@ -686,6 +737,10 @@ static rt_err_t _rt_raw_channel_recv_timeout(rt_channel_t ch, rt_channel_msg_t d
             ch->stat = RT_IPC_STAT_ACTIVE;  /* no valid suspened receivers */
         }
         *data = msg_ret->msg;      /* extract the transferred data */
+        if (data->type == RT_CHANNEL_FD)
+        {
+            data->u.fd.fd = _ipc_msg_fd_new(data->u.fd.file);
+        }
         _ipc_msg_free(msg_ret);     /* put back the message to kernel */
     }
     else
@@ -740,6 +795,10 @@ static rt_err_t _rt_raw_channel_recv_timeout(rt_channel_t ch, rt_channel_msg_t d
         }
         /* If waked up, the received message has been store into the thread. */
         *data = ((rt_ipc_msg_t)(thread->msg_ret))->msg;    /* extract data */
+        if (data->type == RT_CHANNEL_FD)
+        {
+            data->u.fd.fd = _ipc_msg_fd_new(data->u.fd.file);
+        }
         _ipc_msg_free(thread->msg_ret);     /* put back the message to kernel */
         thread->msg_ret = RT_NULL;
     }

+ 7 - 1
components/lwp/lwp_ipc.h

@@ -18,7 +18,8 @@ extern "C" {
 enum
 {
     RT_CHANNEL_RAW,
-    RT_CHANNEL_BUFFER
+    RT_CHANNEL_BUFFER,
+    RT_CHANNEL_FD
 };
 
 struct rt_channel_msg
@@ -32,6 +33,11 @@ struct rt_channel_msg
             void *buf;
             size_t length;
         } b;
+        struct chfd
+        {
+            void *file;
+            int fd;
+        } fd;
         void* d;
     } u;
 };