mirror of
https://github.com/Ai-Thinker-Open/Ai-Thinker-Open_RTL8710BX_ALIOS_SDK.git
synced 2026-08-27 17:01:31 +00:00
rel_1.6.0 init
This commit is contained in:
commit
27b3e2883d
19359 changed files with 8093121 additions and 0 deletions
365
Living_SDK/kernel/vfs/select.c
Executable file
365
Living_SDK/kernel/vfs/select.c
Executable file
|
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <aos/aos.h>
|
||||
#include <aos/network.h>
|
||||
#include <vfs_conf.h>
|
||||
#include <vfs_err.h>
|
||||
#include <vfs_inode.h>
|
||||
#include <vfs.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <vfs_file.h>
|
||||
|
||||
#ifdef __ICCARM__
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#ifdef IO_NEED_TRAP
|
||||
#include <vfs_trap.h>
|
||||
#endif
|
||||
|
||||
extern aos_mutex_t g_vfs_mutex;
|
||||
|
||||
#if (AOS_CONFIG_VFS_POLL_SUPPORT>0)
|
||||
|
||||
#if !defined(WITH_LWIP) && !defined(WITH_SAL)&& defined(VCALL_RHINO)
|
||||
#define NEED_WAIT_IO
|
||||
#endif
|
||||
|
||||
#include <aos/network.h>
|
||||
|
||||
#ifdef CONFIG_NO_TCPIP
|
||||
|
||||
struct poll_arg {
|
||||
aos_sem_t sem;
|
||||
};
|
||||
|
||||
static void setup_fd(int fd)
|
||||
{
|
||||
}
|
||||
|
||||
static void teardown_fd(int fd)
|
||||
{
|
||||
}
|
||||
|
||||
static void vfs_poll_notify(struct pollfd *fd, void *arg)
|
||||
{
|
||||
struct poll_arg *parg = arg;
|
||||
aos_sem_signal(&parg->sem);
|
||||
}
|
||||
|
||||
static int wait_io(int maxfd, fd_set *rfds, struct poll_arg *parg, int timeout)
|
||||
{
|
||||
timeout = timeout >= 0 ? timeout : AOS_WAIT_FOREVER;
|
||||
aos_sem_wait(&parg->sem, timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_parg(struct poll_arg *parg)
|
||||
{
|
||||
aos_sem_new(&parg->sem, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void deinit_parg(struct poll_arg *parg)
|
||||
{
|
||||
aos_sem_free(&parg->sem);
|
||||
}
|
||||
#elif defined(NEED_WAIT_IO)
|
||||
|
||||
#include <sys/syscall.h>
|
||||
#define gettid() syscall(SYS_gettid)
|
||||
|
||||
struct poll_arg {
|
||||
aos_sem_t sem;
|
||||
};
|
||||
|
||||
static void setup_fd(int fd)
|
||||
{
|
||||
int f = fcntl(fd, F_GETFL) | O_ASYNC;
|
||||
if (fcntl(fd, F_SETFL, f) < 0) {
|
||||
perror("fcntl setup");
|
||||
}
|
||||
if (fcntl(fd, F_SETOWN, gettid()) < 0) {
|
||||
perror("fcntl setown");
|
||||
}
|
||||
}
|
||||
|
||||
static void teardown_fd(int fd)
|
||||
{
|
||||
int f = fcntl(fd, F_GETFL) & ~O_ASYNC;
|
||||
if (fcntl(fd, F_SETFL, f) < 0) {
|
||||
perror("fcntl teardown");
|
||||
}
|
||||
}
|
||||
|
||||
static int wait_io(int maxfd, fd_set *rfds, struct poll_arg *parg, int timeout)
|
||||
{
|
||||
struct timeval tv = { 0 };
|
||||
int ret;
|
||||
fd_set saved_fds = *rfds;
|
||||
|
||||
/* check if already data available */
|
||||
ret = select(maxfd + 1, rfds, NULL, NULL, &tv);
|
||||
if (ret > 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
timeout = timeout >= 0 ? timeout : AOS_WAIT_FOREVER;
|
||||
ret = aos_sem_wait(&parg->sem, timeout);
|
||||
if (ret != VFS_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*rfds = saved_fds;
|
||||
ret = select(maxfd + 1, rfds, NULL, NULL, &tv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void vfs_poll_notify(struct pollfd *fd, void *arg)
|
||||
{
|
||||
struct poll_arg *parg = arg;
|
||||
aos_sem_signal(&parg->sem);
|
||||
}
|
||||
|
||||
static void vfs_io_cb(int fd, void *arg)
|
||||
{
|
||||
struct poll_arg *parg = arg;
|
||||
aos_sem_signal(&parg->sem);
|
||||
}
|
||||
|
||||
void cpu_io_register(void (*f)(int, void *), void *arg);
|
||||
void cpu_io_unregister(void (*f)(int, void *), void *arg);
|
||||
static int init_parg(struct poll_arg *parg)
|
||||
{
|
||||
cpu_io_register(vfs_io_cb, parg);
|
||||
aos_sem_new(&parg->sem, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void deinit_parg(struct poll_arg *parg)
|
||||
{
|
||||
aos_sem_free(&parg->sem);
|
||||
cpu_io_unregister(vfs_io_cb, parg);
|
||||
}
|
||||
|
||||
#else
|
||||
struct poll_arg {
|
||||
int efd;
|
||||
};
|
||||
|
||||
static void vfs_poll_notify(struct pollfd *fd, void *arg)
|
||||
{
|
||||
struct poll_arg *parg = arg;
|
||||
uint64_t val = 1;
|
||||
write(parg->efd, &val, sizeof val);
|
||||
}
|
||||
|
||||
static void setup_fd(int fd)
|
||||
{
|
||||
}
|
||||
|
||||
static void teardown_fd(int fd)
|
||||
{
|
||||
}
|
||||
|
||||
static int init_parg(struct poll_arg *parg)
|
||||
{
|
||||
int efd;
|
||||
efd = eventfd(0, 0);
|
||||
|
||||
if (efd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
parg->efd = efd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void deinit_parg(struct poll_arg *parg)
|
||||
{
|
||||
close(parg->efd);
|
||||
}
|
||||
|
||||
static int wait_io(int maxfd, fd_set *rfds, struct poll_arg *parg, int timeout)
|
||||
{
|
||||
struct timeval tv = {
|
||||
.tv_sec = timeout / 1024,
|
||||
.tv_usec = (timeout % 1024) * 1024,
|
||||
};
|
||||
|
||||
FD_SET(parg->efd, rfds);
|
||||
maxfd = parg->efd > maxfd ? parg->efd : maxfd;
|
||||
return select(maxfd + 1, rfds, NULL, NULL, timeout >= 0 ? &tv : NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int pre_poll(struct pollfd *fds, int nfds, fd_set *rfds, void *parg)
|
||||
{
|
||||
int i;
|
||||
int maxfd = 0;
|
||||
|
||||
for (i = 0; i < nfds; i++) {
|
||||
struct pollfd *pfd = &fds[i];
|
||||
|
||||
pfd->revents = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < nfds; i++) {
|
||||
file_t *f;
|
||||
struct pollfd *pfd = &fds[i];
|
||||
|
||||
if (pfd->fd < AOS_CONFIG_VFS_FD_OFFSET) {
|
||||
setup_fd(pfd->fd);
|
||||
FD_SET(pfd->fd, rfds);
|
||||
maxfd = pfd->fd > maxfd ? pfd->fd : maxfd;
|
||||
continue;
|
||||
}
|
||||
|
||||
f = get_file(pfd->fd);
|
||||
|
||||
if (f == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pfd = &fds[i];
|
||||
(f->node->ops.i_ops->poll)(f, true, vfs_poll_notify, pfd, parg);
|
||||
}
|
||||
|
||||
return maxfd;
|
||||
}
|
||||
|
||||
static int post_poll(struct pollfd *fds, int nfds)
|
||||
{
|
||||
int j;
|
||||
int ret = 0;
|
||||
|
||||
for (j = 0; j < nfds; j++) {
|
||||
file_t *f;
|
||||
struct pollfd *pfd = &fds[j];
|
||||
|
||||
if (pfd->fd < AOS_CONFIG_VFS_FD_OFFSET) {
|
||||
teardown_fd(pfd->fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
f = get_file(pfd->fd);
|
||||
|
||||
if (f == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(f->node->ops.i_ops->poll)(f, false, NULL, NULL, NULL);
|
||||
|
||||
if (pfd->revents) {
|
||||
ret ++;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int aos_poll(struct pollfd *fds, int nfds, int timeout)
|
||||
{
|
||||
fd_set rfds;
|
||||
|
||||
int ret = VFS_SUCCESS;
|
||||
int nset = 0;
|
||||
struct poll_arg parg;
|
||||
|
||||
if (init_parg(&parg) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
ret = pre_poll(fds, nfds, &rfds, &parg);
|
||||
|
||||
if (ret < 0) {
|
||||
goto check_poll;
|
||||
}
|
||||
|
||||
ret = wait_io(ret, &rfds, &parg, timeout);
|
||||
|
||||
if (ret >= 0) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nfds; i++) {
|
||||
struct pollfd *pfd = fds + i;
|
||||
|
||||
if (FD_ISSET(pfd->fd, &rfds)) {
|
||||
pfd->revents |= POLLIN;
|
||||
}
|
||||
}
|
||||
|
||||
nset += ret;
|
||||
}
|
||||
|
||||
check_poll:
|
||||
nset += post_poll(fds, nfds);
|
||||
|
||||
deinit_parg(&parg);
|
||||
|
||||
return ret < 0 ? 0 : nset;
|
||||
}
|
||||
#endif
|
||||
|
||||
int aos_fcntl(int fd, int cmd, int val)
|
||||
{
|
||||
if (fd < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (fd < AOS_CONFIG_VFS_FD_OFFSET) {
|
||||
#ifdef IO_NEED_TRAP
|
||||
return trap_fcntl(fd, cmd, val);
|
||||
#else
|
||||
return -ENOENT;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aos_ioctl_in_loop(int cmd, unsigned long arg)
|
||||
{
|
||||
int err;
|
||||
int fd;
|
||||
|
||||
for (fd = AOS_CONFIG_VFS_FD_OFFSET;
|
||||
fd < AOS_CONFIG_VFS_FD_OFFSET + AOS_CONFIG_VFS_DEV_NODES; fd++) {
|
||||
file_t *f;
|
||||
inode_t *node;
|
||||
|
||||
if ((err = aos_mutex_lock(&g_vfs_mutex, AOS_WAIT_FOREVER)) != 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
f = get_file(fd);
|
||||
|
||||
if (f == NULL) {
|
||||
aos_mutex_unlock(&g_vfs_mutex);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if ((err = aos_mutex_unlock(&g_vfs_mutex)) != 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
node = f->node;
|
||||
|
||||
if ((node->ops.i_ops->ioctl) != NULL) {
|
||||
err = (node->ops.i_ops->ioctl)(f, cmd, arg);
|
||||
|
||||
if (err != VFS_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return VFS_SUCCESS;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue