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 i;
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
int ret;
|
int ret = OK;
|
||||||
|
|
||||||
/* Process each descriptor in the list */
|
/* 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.
|
* 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 */
|
case POLLFD:
|
||||||
|
if (fds[i].fd >= 0)
|
||||||
ret = poll_fdsetup(fds[i].fd, &fds[i], true);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
{
|
||||||
/* Setup failed for fds[i]. We now need to teardown previously
|
ret = poll_fdsetup(fds[i].fd, &fds[i], true);
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
|
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)
|
int ret)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int status;
|
int status = OK;
|
||||||
|
|
||||||
/* Process each descriptor in the list */
|
/* Process each descriptor in the list */
|
||||||
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
for (i = 0; i < nfds; i++)
|
for (i = 0; i < nfds; i++)
|
||||||
{
|
{
|
||||||
/* Ignore negative descriptors */
|
switch (fds[i].events & POLLMASK)
|
||||||
|
|
||||||
if (fds[i].fd >= 0)
|
|
||||||
{
|
{
|
||||||
/* Teardown the poll */
|
case POLLFD:
|
||||||
|
if (fds[i].fd >= 0)
|
||||||
status = poll_fdsetup(fds[i].fd, &fds[i], false);
|
|
||||||
if (status < 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 */
|
/* 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
|
* Name: file_poll
|
||||||
*
|
*
|
||||||
* Description:
|
* 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
|
* support detached file, and also (2) by fdesc_poll() to perform all
|
||||||
* normal operations on file descriptors descriptors.
|
* normal operations on file descriptors descriptors.
|
||||||
*
|
*
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* include/poll.h
|
* 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>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -88,6 +88,11 @@
|
|||||||
#define POLLHUP (0x08)
|
#define POLLHUP (0x08)
|
||||||
#define POLLNVAL (0x10)
|
#define POLLNVAL (0x10)
|
||||||
|
|
||||||
|
#define POLLFD (0x00)
|
||||||
|
#define POLLFILE (0x40)
|
||||||
|
#define POLLSOCK (0x80)
|
||||||
|
#define POLLMASK (0xC0)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Type Definitions
|
* Public Type Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -107,11 +112,20 @@ typedef uint8_t pollevent_t;
|
|||||||
|
|
||||||
struct pollfd
|
struct pollfd
|
||||||
{
|
{
|
||||||
int fd; /* The descriptor being polled */
|
/* REVISIT: Un-named unions are forbidden by the coding standard because
|
||||||
sem_t *sem; /* Pointer to semaphore used to post output event */
|
* they are not available in C89.
|
||||||
pollevent_t events; /* The input event flags */
|
*/
|
||||||
pollevent_t revents; /* The output event flags */
|
|
||||||
FAR void *priv; /* For use by drivers */
|
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