libc: Implement select() on top of epoll()
This commit is contained in:
parent
a4369e4b8b
commit
8049641c65
|
@ -1,6 +1,9 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/epoll.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <frigg/debug.hpp>
|
#include <frigg/debug.hpp>
|
||||||
#include <mlibc/ensure.h>
|
#include <mlibc/ensure.h>
|
||||||
|
|
||||||
|
@ -22,17 +25,77 @@ void FD_ZERO(fd_set *set) {
|
||||||
|
|
||||||
int select(int num_fds, fd_set *__restrict read_set, fd_set *__restrict write_set,
|
int select(int num_fds, fd_set *__restrict read_set, fd_set *__restrict write_set,
|
||||||
fd_set *__restrict except_set, struct timeval *__restrict timeout) {
|
fd_set *__restrict except_set, struct timeval *__restrict timeout) {
|
||||||
frigg::infoLogger() << "\e[35mmlibc: Broken select() called.\e[39m" << frigg::endLog;
|
__ensure(!timeout);
|
||||||
|
|
||||||
int num_returned = 0;
|
// TODO: Do not keep errors from epoll (?).
|
||||||
for(int i = 0; i < num_fds; i++) {
|
int fd = epoll_create1(0);
|
||||||
if(except_set && FD_ISSET(i, except_set))
|
if(fd == -1)
|
||||||
FD_CLR(i, except_set);
|
return -1;
|
||||||
if(read_set && FD_ISSET(i, read_set))
|
|
||||||
num_returned++;
|
for(int k = 0; k < FD_SETSIZE; k++) {
|
||||||
if(write_set && FD_ISSET(i, write_set))
|
struct epoll_event ev;
|
||||||
num_returned++;
|
memset(&ev, 0, sizeof(struct epoll_event));
|
||||||
|
|
||||||
|
if(read_set && FD_ISSET(k, read_set))
|
||||||
|
ev.events |= EPOLLIN; // TODO: Additional events.
|
||||||
|
if(write_set && FD_ISSET(k, write_set))
|
||||||
|
ev.events |= EPOLLOUT; // TODO: Additional events.
|
||||||
|
if(except_set && FD_ISSET(k, except_set))
|
||||||
|
ev.events |= EPOLLPRI;
|
||||||
|
|
||||||
|
if(!ev.events)
|
||||||
|
continue;
|
||||||
|
ev.data.u32 = k;
|
||||||
|
|
||||||
|
if(epoll_ctl(fd, EPOLL_CTL_ADD, k, &ev))
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return num_returned;
|
|
||||||
|
struct epoll_event evnts[16];
|
||||||
|
int n = epoll_wait(fd, evnts, 16, -1);
|
||||||
|
if(n == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
fd_set res_read_set;
|
||||||
|
fd_set res_write_set;
|
||||||
|
fd_set res_except_set;
|
||||||
|
FD_ZERO(&res_read_set);
|
||||||
|
FD_ZERO(&res_write_set);
|
||||||
|
FD_ZERO(&res_except_set);
|
||||||
|
int m = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < n; i++) {
|
||||||
|
int k = evnts[i].data.u32;
|
||||||
|
|
||||||
|
if(read_set && FD_ISSET(k, read_set)
|
||||||
|
&& evnts[i].events & EPOLLIN) {
|
||||||
|
FD_SET(k, &res_read_set);
|
||||||
|
m++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(write_set && FD_ISSET(k, write_set)
|
||||||
|
&& evnts[i].events & EPOLLOUT) {
|
||||||
|
FD_SET(k, &res_write_set);
|
||||||
|
m++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(except_set && FD_ISSET(k, except_set)
|
||||||
|
&& evnts[i].events & EPOLLPRI) {
|
||||||
|
FD_SET(k, &res_except_set);
|
||||||
|
m++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(close(fd))
|
||||||
|
__ensure("close() failed on epoll file");
|
||||||
|
|
||||||
|
if(read_set)
|
||||||
|
memcpy(read_set, &res_read_set, sizeof(fd_set));
|
||||||
|
if(write_set)
|
||||||
|
memcpy(write_set, &res_write_set, sizeof(fd_set));
|
||||||
|
if(except_set)
|
||||||
|
memcpy(except_set, &res_except_set, sizeof(fd_set));
|
||||||
|
|
||||||
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue