fs/vfs/fs_poll.c: Add poll use in kernel space.
This commit is contained in:
parent
3f50451046
commit
56883eef3b
126
fs/vfs/fs_poll.c
126
fs/vfs/fs_poll.c
@ -136,7 +136,7 @@ static inline int poll_setup(FAR struct pollfd *fds, nfds_t nfds, sem_t *sem)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
int ret;
|
||||
int ret = OK;
|
||||
|
||||
/* Process each descriptor in the list */
|
||||
|
||||
@ -157,29 +157,71 @@ static inline int poll_setup(FAR struct pollfd *fds, nfds_t nfds, sem_t *sem)
|
||||
* spec, that appears to be the correct behavior.
|
||||
*/
|
||||
|
||||
if (fds[i].fd >= 0)
|
||||
switch (fds[i].events & POLLMASK)
|
||||
{
|
||||
/* Set up the poll on this valid file descriptor */
|
||||
|
||||
ret = poll_fdsetup(fds[i].fd, &fds[i], true);
|
||||
if (ret < 0)
|
||||
case POLLFD:
|
||||
if (fds[i].fd >= 0)
|
||||
{
|
||||
/* Setup failed for fds[i]. We now need to teardown previously
|
||||
* setup fds[0 .. (i - 1)] to release allocated resources and
|
||||
* to prevent memory corruption by access to freed/released 'fds'
|
||||
* and 'sem'.
|
||||
*/
|
||||
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
(void)poll_fdsetup(fds[j].fd, &fds[j], false);
|
||||
}
|
||||
|
||||
/* Indicate an error on the file descriptor */
|
||||
|
||||
fds[i].revents |= POLLERR;
|
||||
return ret;
|
||||
ret = poll_fdsetup(fds[i].fd, &fds[i], true);
|
||||
}
|
||||
break;
|
||||
|
||||
case POLLFILE:
|
||||
if (fds[i].ptr != NULL)
|
||||
{
|
||||
ret = file_poll(fds[i].ptr, &fds[i], true);
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_NET
|
||||
case POLLSOCK:
|
||||
if (fds[i].ptr != NULL)
|
||||
{
|
||||
ret = psock_poll(fds[i].ptr, &fds[i], true);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
/* Setup failed for fds[i]. We now need to teardown previously
|
||||
* setup fds[0 .. (i - 1)] to release allocated resources and
|
||||
* to prevent memory corruption by access to freed/released 'fds'
|
||||
* and 'sem'.
|
||||
*/
|
||||
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
switch (fds[j].events & POLLMASK)
|
||||
{
|
||||
case POLLFD:
|
||||
(void)poll_fdsetup(fds[j].fd, &fds[j], false);
|
||||
break;
|
||||
|
||||
case POLLFILE:
|
||||
(void)file_poll(fds[j].ptr, &fds[j], false);
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_NET
|
||||
case POLLSOCK:
|
||||
(void)psock_poll(fds[j].ptr, &fds[j], false);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Indicate an error on the file descriptor */
|
||||
|
||||
fds[i].revents |= POLLERR;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,24 +243,46 @@ static inline int poll_teardown(FAR struct pollfd *fds, nfds_t nfds, int *count,
|
||||
int ret)
|
||||
{
|
||||
unsigned int i;
|
||||
int status;
|
||||
int status = OK;
|
||||
|
||||
/* Process each descriptor in the list */
|
||||
|
||||
*count = 0;
|
||||
for (i = 0; i < nfds; i++)
|
||||
{
|
||||
/* Ignore negative descriptors */
|
||||
|
||||
if (fds[i].fd >= 0)
|
||||
switch (fds[i].events & POLLMASK)
|
||||
{
|
||||
/* Teardown the poll */
|
||||
|
||||
status = poll_fdsetup(fds[i].fd, &fds[i], false);
|
||||
if (status < 0)
|
||||
case POLLFD:
|
||||
if (fds[i].fd >= 0)
|
||||
{
|
||||
ret = status;
|
||||
status = poll_fdsetup(fds[i].fd, &fds[i], false);
|
||||
}
|
||||
break;
|
||||
|
||||
case POLLFILE:
|
||||
if (fds[i].ptr != NULL)
|
||||
{
|
||||
status = file_poll(fds[i].ptr, &fds[i], false);
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_NET
|
||||
case POLLSOCK:
|
||||
if (fds[i].ptr != NULL)
|
||||
{
|
||||
status = psock_poll(fds[i].ptr, &fds[i], false);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
status = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
ret = status;
|
||||
}
|
||||
|
||||
/* Check if any events were posted */
|
||||
@ -245,7 +309,7 @@ static inline int poll_teardown(FAR struct pollfd *fds, nfds_t nfds, int *count,
|
||||
* Name: file_poll
|
||||
*
|
||||
* Description:
|
||||
* Low-level poll operation based on struc file. This is used both to (1)
|
||||
* Low-level poll operation based on struct file. This is used both to (1)
|
||||
* support detached file, and also (2) by fdesc_poll() to perform all
|
||||
* normal operations on file descriptors descriptors.
|
||||
*
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* include/poll.h
|
||||
*
|
||||
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2008-2009, 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -88,6 +88,11 @@
|
||||
#define POLLHUP (0x08)
|
||||
#define POLLNVAL (0x10)
|
||||
|
||||
#define POLLFD (0x00)
|
||||
#define POLLFILE (0x40)
|
||||
#define POLLSOCK (0x80)
|
||||
#define POLLMASK (0xC0)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
@ -107,11 +112,20 @@ typedef uint8_t pollevent_t;
|
||||
|
||||
struct pollfd
|
||||
{
|
||||
int fd; /* The descriptor being polled */
|
||||
sem_t *sem; /* Pointer to semaphore used to post output event */
|
||||
pollevent_t events; /* The input event flags */
|
||||
pollevent_t revents; /* The output event flags */
|
||||
FAR void *priv; /* For use by drivers */
|
||||
/* REVISIT: Un-named unions are forbidden by the coding standard because
|
||||
* they are not available in C89.
|
||||
*/
|
||||
|
||||
union
|
||||
{
|
||||
int fd; /* The descriptor being polled */
|
||||
FAR void *ptr; /* The psock or file being polled */
|
||||
};
|
||||
|
||||
FAR sem_t *sem; /* Pointer to semaphore used to post output event */
|
||||
pollevent_t events; /* The input event flags */
|
||||
pollevent_t revents; /* The output event flags */
|
||||
FAR void *priv; /* For use by drivers */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
Loading…
Reference in New Issue
Block a user