mirror of
https://github.com/apache/nuttx.git
synced 2026-06-02 01:21:26 +08:00
fs/epoll_fd: support dup file descriptor
Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
+39
-2
@@ -32,6 +32,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
|
||||||
#include <nuttx/clock.h>
|
#include <nuttx/clock.h>
|
||||||
#include <nuttx/fs/fs.h>
|
#include <nuttx/fs/fs.h>
|
||||||
@@ -47,6 +48,8 @@ struct epoll_head
|
|||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
int occupied;
|
int occupied;
|
||||||
|
int crefs;
|
||||||
|
sem_t sem;
|
||||||
struct file fp;
|
struct file fp;
|
||||||
struct inode in;
|
struct inode in;
|
||||||
FAR epoll_data_t *data;
|
FAR epoll_data_t *data;
|
||||||
@@ -57,6 +60,7 @@ struct epoll_head
|
|||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int epoll_do_open(FAR struct file *filep);
|
||||||
static int epoll_do_close(FAR struct file *filep);
|
static int epoll_do_close(FAR struct file *filep);
|
||||||
static int epoll_do_poll(FAR struct file *filep,
|
static int epoll_do_poll(FAR struct file *filep,
|
||||||
FAR struct pollfd *fds, bool setup);
|
FAR struct pollfd *fds, bool setup);
|
||||||
@@ -67,7 +71,7 @@ static int epoll_do_poll(FAR struct file *filep,
|
|||||||
|
|
||||||
static const struct file_operations g_epoll_ops =
|
static const struct file_operations g_epoll_ops =
|
||||||
{
|
{
|
||||||
NULL, /* open */
|
epoll_do_open, /* open */
|
||||||
epoll_do_close, /* close */
|
epoll_do_close, /* close */
|
||||||
NULL, /* read */
|
NULL, /* read */
|
||||||
NULL, /* write */
|
NULL, /* write */
|
||||||
@@ -108,12 +112,41 @@ static FAR struct epoll_head *epoll_head_from_fd(int fd)
|
|||||||
return (FAR struct epoll_head *)filep->f_inode->i_private;
|
return (FAR struct epoll_head *)filep->f_inode->i_private;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int epoll_do_open(FAR struct file *filep)
|
||||||
|
{
|
||||||
|
FAR struct epoll_head *eph = filep->f_inode->i_private;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = nxsem_wait(&eph->sem);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
eph->crefs++;
|
||||||
|
nxsem_post(&eph->sem);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int epoll_do_close(FAR struct file *filep)
|
static int epoll_do_close(FAR struct file *filep)
|
||||||
{
|
{
|
||||||
FAR struct epoll_head *eph = filep->f_inode->i_private;
|
FAR struct epoll_head *eph = filep->f_inode->i_private;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = nxsem_wait(&eph->sem);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
eph->crefs--;
|
||||||
|
nxsem_post(&eph->sem);
|
||||||
|
if (eph->crefs <= 0)
|
||||||
|
{
|
||||||
kmm_free(eph);
|
kmm_free(eph);
|
||||||
return OK;
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int epoll_do_poll(FAR struct file *filep,
|
static int epoll_do_poll(FAR struct file *filep,
|
||||||
@@ -138,6 +171,8 @@ static int epoll_do_create(int size, int flags)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nxsem_init(&eph->sem, 0, 0);
|
||||||
|
nxsem_set_protocol(&eph->sem, SEM_PRIO_NONE);
|
||||||
eph->size = size;
|
eph->size = size;
|
||||||
eph->data = (FAR epoll_data_t *)(eph + 1);
|
eph->data = (FAR epoll_data_t *)(eph + 1);
|
||||||
eph->poll = (FAR struct pollfd *)(eph->data + reserve);
|
eph->poll = (FAR struct pollfd *)(eph->data + reserve);
|
||||||
@@ -155,11 +190,13 @@ static int epoll_do_create(int size, int flags)
|
|||||||
fd = files_allocate(&eph->in, flags, 0, eph, 0);
|
fd = files_allocate(&eph->in, flags, 0, eph, 0);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
|
nxsem_destroy(&eph->sem);
|
||||||
kmm_free(eph);
|
kmm_free(eph);
|
||||||
set_errno(-fd);
|
set_errno(-fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nxsem_post(&eph->sem);
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user