From b1a8110926eb995a2a2f28b8c78004e557fa13f9 Mon Sep 17 00:00:00 2001 From: leitner Date: Sat, 6 Sep 2003 01:36:50 +0000 Subject: [PATCH] epoll now works enough for test/io5 --- io/io_close.c | 2 +- io/io_dontwantread.c | 32 ++++++++++++++++++++++-- io/io_dontwantwrite.c | 32 ++++++++++++++++++++++-- io/io_waituntil2.c | 57 +++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 116 insertions(+), 7 deletions(-) diff --git a/io/io_close.c b/io/io_close.c index b155b24..af5698a 100644 --- a/io/io_close.c +++ b/io/io_close.c @@ -3,10 +3,10 @@ void io_close(int64 d) { io_entry* e; - close(d); if ((e=array_get(&io_fds,sizeof(io_entry),d))) { e->inuse=0; io_dontwantread(d); io_dontwantwrite(d); } + close(d); } diff --git a/io/io_dontwantread.c b/io/io_dontwantread.c index db8d91c..e0f1e45 100644 --- a/io/io_dontwantread.c +++ b/io/io_dontwantread.c @@ -2,10 +2,38 @@ #include #include #include "io_internal.h" +#ifdef HAVE_KQUEUE +#include +#include +#include +#endif +#ifdef HAVE_EPOLL +#include +#endif void io_dontwantread(int64 d) { + int newfd; io_entry* e=array_get(&io_fds,sizeof(io_entry),d); - if (!e) return; - if (e->wantread && !e->wantwrite) --io_wanted_fds; + if (!e || !e->wantread) return; + newfd=(e->wantread && !e->wantwrite); + io_wanted_fds-=newfd; +#ifdef HAVE_EPOLL + if (io_waitmode==EPOLL) { + struct epoll_event x; + x.events=EPOLLIN; + if (e->wantwrite) x.events|=EPOLLOUT; + x.data.fd=d; + epoll_ctl(io_master,newfd?EPOLL_CTL_DEL:EPOLL_CTL_MOD,d,&x); + } +#endif +#ifdef HAVE_KQUEUE + if (io_waitmode==KQUEUE) { + struct kevent kev; + struct timespec ts; + EV_SET(&kev, d, EVFILT_READ, EV_DELETE, 0, 0, 0); + ts.tv_sec=0; ts.tv_nsec=0; + kevent(io_master,&kev,1,0,0,&ts); + } +#endif e->wantread=0; } diff --git a/io/io_dontwantwrite.c b/io/io_dontwantwrite.c index a0e4716..f76bd98 100644 --- a/io/io_dontwantwrite.c +++ b/io/io_dontwantwrite.c @@ -2,10 +2,38 @@ #include #include #include "io_internal.h" +#ifdef HAVE_KQUEUE +#include +#include +#include +#endif +#ifdef HAVE_EPOLL +#include +#endif void io_dontwantwrite(int64 d) { + int newfd; io_entry* e=array_get(&io_fds,sizeof(io_entry),d); - if (!e) return; - if (!e->wantread && e->wantwrite) --io_wanted_fds; + if (!e || !e->wantwrite) return; + newfd=(!e->wantread && e->wantwrite); --io_wanted_fds; + io_wanted_fds-=newfd; +#ifdef HAVE_EPOLL + if (io_waitmode==EPOLL) { + struct epoll_event x; + x.events=EPOLLOUT; + if (e->wantread) x.events|=EPOLLIN; + x.data.fd=d; + epoll_ctl(io_master,newfd?EPOLL_CTL_DEL:EPOLL_CTL_MOD,d,&x); + } +#endif +#ifdef HAVE_KQUEUE + if (io_waitmode==KQUEUE) { + struct kevent kev; + struct timespec ts; + EV_SET(&kev, d, EVFILT_WRITE, EV_DELETE, 0, 0, 0); + ts.tv_sec=0; ts.tv_nsec=0; + kevent(io_master,&kev,1,0,0,&ts); + } +#endif e->wantwrite=0; } diff --git a/io/io_waituntil2.c b/io/io_waituntil2.c index 5b78a71..9a95db4 100644 --- a/io/io_waituntil2.c +++ b/io/io_waituntil2.c @@ -3,11 +3,64 @@ #include #include #include "io_internal.h" +#ifdef HAVE_KQUEUE +#include +#endif +#ifdef HAVE_EPOLL +#include +#endif int64 io_waituntil2(int64 milliseconds) { struct pollfd* p; - long i,r; + long i,j,r; if (!io_wanted_fds) return 0; +#ifdef HAVE_EPOLL + if (io_waitmode==EPOLL) { + int n; + struct epoll_event y[100]; + if ((n=epoll_wait(io_master,y,100,milliseconds))==-1) return -1; + for (i=n-1; i>=0; --i) { + io_entry* e=array_get(&io_fds,sizeof(io_entry),y[i].data.fd); + if (e) { + if (y[i].events&EPOLLIN) { + e->canread=1; + e->next_read=first_readable; + first_readable=y[i].data.fd; + } + if (y[i].events&EPOLLOUT) { + e->canwrite=1; + e->next_write=first_writeable; + first_writeable=y[i].data.fd; + } + } + } + return n; + } +#endif +#ifdef HAVE_KQUEUE + if (io_waitmode==KQUEUE) { + struct kevent y[100]; + int n; + struct timespec ts; + ts.tv_sec=milliseconds/1000; ts.tv_nsec=(milliseconds%1000)*1000000; + if ((n=kevent(io_master,0,0,y,100,&ts))==-1) return; + while (n>0) { + io_entry* e=array_get(&io_fds,sizeof io_entry,y[--n].ident); + if (e) { + if (y[n].filter==EVFILT_READ) { + e->canread=1; + e->next_read=first_readable; + first_readable=y[n].ident; + } + if (y[n].filter==EVFILT_WRITE) { + e->canwrite=1; + e->next_write=first_writeable; + first_writeable=y[i].ident; + } + } + } + } +#endif for (i=r=0; i=0; --i) { + for (j=r-1; j>=0; --j) { io_entry* e=array_get(&io_fds,sizeof(io_entry),p->fd); if (p->revents&POLLIN) { e->canread=1;