mirror of
https://github.com/0intro/libtask
synced 2024-11-24 22:59:43 +03:00
implement epoll (Jamie Turner)
This commit is contained in:
parent
f5ea2e72ba
commit
ef218ac4d8
121
fd.c
121
fd.c
@ -1,7 +1,14 @@
|
||||
#include "taskimpl.h"
|
||||
#if USE_EPOLL
|
||||
#include <sys/epoll.h>
|
||||
#else
|
||||
#include <sys/poll.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
#if USE_EPOLL
|
||||
static int epfd;
|
||||
#else
|
||||
enum
|
||||
{
|
||||
MAXFD = 1024
|
||||
@ -10,11 +17,69 @@ enum
|
||||
static struct pollfd pollfd[MAXFD];
|
||||
static Task *polltask[MAXFD];
|
||||
static int npollfd;
|
||||
#endif
|
||||
|
||||
static int startedfdtask;
|
||||
static Tasklist sleeping;
|
||||
static int sleepingcounted;
|
||||
static uvlong nsec(void);
|
||||
|
||||
#if USE_EPOLL
|
||||
|
||||
void
|
||||
fdtask(void *v)
|
||||
{
|
||||
struct epoll_event events[1000];
|
||||
int i, ms, nevents;
|
||||
Task *t;
|
||||
uvlong now;
|
||||
|
||||
USED(v);
|
||||
tasksystem();
|
||||
taskname("fdtask");
|
||||
for(;;){
|
||||
/* let everyone else run */
|
||||
while(taskyield() > 0)
|
||||
;
|
||||
/* we're the only one runnable - poll for i/o */
|
||||
errno = 0;
|
||||
taskstate("epoll");
|
||||
if((t=sleeping.head) == nil)
|
||||
ms = -1;
|
||||
else{
|
||||
/* sleep at most 5s */
|
||||
now = nsec();
|
||||
if(now >= t->alarmtime)
|
||||
ms = 0;
|
||||
else if(now+5*1000*1000*1000LL >= t->alarmtime)
|
||||
ms = (t->alarmtime - now)/1000000;
|
||||
else
|
||||
ms = 5000;
|
||||
}
|
||||
if((nevents = epoll_wait(epfd, events, 1000, ms)) < 0){
|
||||
if(errno == EINTR)
|
||||
continue;
|
||||
fprint(2, "epoll: %s\n", strerror(errno));
|
||||
taskexitall(0);
|
||||
}
|
||||
|
||||
/* wake up the guys who deserve it */
|
||||
for(i=0; i<nevents; i++){
|
||||
taskready((Task *)events[i].data.ptr);
|
||||
}
|
||||
|
||||
now = nsec();
|
||||
while((t=sleeping.head) && now >= t->alarmtime){
|
||||
deltask(&sleeping, t);
|
||||
if(!t->system && --sleepingcounted == 0)
|
||||
taskcount--;
|
||||
taskready(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
fdtask(void *v)
|
||||
{
|
||||
@ -71,6 +136,8 @@ fdtask(void *v)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
uint
|
||||
taskdelay(uint ms)
|
||||
{
|
||||
@ -79,6 +146,11 @@ taskdelay(uint ms)
|
||||
|
||||
if(!startedfdtask){
|
||||
startedfdtask = 1;
|
||||
#if USE_EPOLL
|
||||
epfd = epoll_create(1);
|
||||
if(epfd < 0)
|
||||
abort();
|
||||
#endif
|
||||
taskcreate(fdtask, 0, 32768);
|
||||
}
|
||||
|
||||
@ -113,6 +185,53 @@ taskdelay(uint ms)
|
||||
return (nsec() - now)/1000000;
|
||||
}
|
||||
|
||||
#if USE_EPOLL
|
||||
|
||||
void
|
||||
fdwait(int fd, int rw)
|
||||
{
|
||||
struct epoll_event ev;
|
||||
int bits, duped, r;
|
||||
|
||||
if(!startedfdtask){
|
||||
startedfdtask = 1;
|
||||
epfd = epoll_create(1);
|
||||
if(epfd < 0)
|
||||
abort();
|
||||
taskcreate(fdtask, 0, 32768);
|
||||
}
|
||||
|
||||
taskstate("fdwait for %s", rw=='r' ? "read" : rw=='w' ? "write" : "error");
|
||||
bits = 0;
|
||||
switch(rw){
|
||||
case 'r':
|
||||
bits |= EPOLLIN | EPOLLPRI;
|
||||
break;
|
||||
case 'w':
|
||||
bits |= EPOLLOUT;
|
||||
break;
|
||||
}
|
||||
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
ev.events = bits;
|
||||
ev.data.ptr = taskrunning;
|
||||
r = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
|
||||
duped = 0;
|
||||
if(r < 0 || errno == EEXIST){
|
||||
duped = 1;
|
||||
fd = dup(fd);
|
||||
r = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
|
||||
if(r != 0)
|
||||
abort();
|
||||
}
|
||||
taskswitch();
|
||||
epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &ev);
|
||||
if(duped)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
fdwait(int fd, int rw)
|
||||
{
|
||||
@ -147,6 +266,8 @@ fdwait(int fd, int rw)
|
||||
taskswitch();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Like fdread but always calls fdwait before reading. */
|
||||
int
|
||||
fdread1(int fd, void *buf, int n)
|
||||
|
@ -26,6 +26,13 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define USE_EPOLL 1
|
||||
|
||||
#if !defined(__linux)
|
||||
#undef USE_EPOLL
|
||||
#define USE_EPOLL 0
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
Loading…
Reference in New Issue
Block a user