blob: 0452bc81f2a0f26f93abc36993d6e40b94754f86 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
#include <fs/vfs.h>
#include <halts.h>
#include <interrupts.h>
#include <lib/list.h>
#include <poll.h>
#include <sched/scheduler.h>
int poll(struct pollfd *fds, size_t nfds, int timeout) {
(void)timeout;
int rc = 0;
disable_interrupts();
struct list *read_list = &get_current_task()->read_list;
struct list *write_list = &get_current_task()->write_list;
struct list *disconnect_list = &get_current_task()->disconnect_list;
for (size_t i = 0; i < nfds; i++) {
if (fds[i].fd < 0)
continue;
vfs_fd_t *f = get_vfs_fd(fds[i].fd);
if (NULL == f) {
continue;
}
if (fds[i].events & POLLIN) {
list_add(read_list, f->inode);
}
if (fds[i].events & POLLOUT) {
list_add(write_list, f->inode);
}
if (fds[i].events & POLLHUP) {
list_add(disconnect_list, f->inode);
}
}
switch_task();
disable_interrupts();
list_reset(read_list);
list_reset(write_list);
list_reset(disconnect_list);
for (size_t i = 0; i < nfds; i++) {
if (0 > fds[i].fd) {
fds[i].revents = 0;
continue;
}
vfs_fd_t *f = get_vfs_fd(fds[i].fd);
if (!f) {
if (fds[i].events & POLLHUP)
fds[i].revents |= POLLHUP;
} else {
if (f->inode->has_data && fds[i].events & POLLIN)
fds[i].revents |= POLLIN;
if (f->inode->can_write && fds[i].events & POLLOUT)
fds[i].revents |= POLLOUT;
if (!(f->inode->is_open) && fds[i].events & POLLHUP)
fds[i].revents |= POLLHUP;
if (fds[i].revents)
rc++;
}
}
enable_interrupts();
return rc;
}
|