X-Git-Url: http://www.dolda2000.com/gitweb/?a=blobdiff_plain;f=lib%2Fmtio-epoll.c;h=a0b2f41e61348a1d5f9493fae2c88f1ea5b0a756;hb=bb0730048938c21b043d88918a9492929c4fa2a9;hp=2a2599218467813d38fa3d17a558b8d286015675;hpb=589987f8218c9aa61d65f582a3b3e1bbd32bda81;p=ashd.git diff --git a/lib/mtio-epoll.c b/lib/mtio-epoll.c index 2a25992..a0b2f41 100644 --- a/lib/mtio-epoll.c +++ b/lib/mtio-epoll.c @@ -37,21 +37,16 @@ static struct blocker *blockers; struct blocker { struct blocker *n, *p, *n2, *p2; int fd, reg; - int ev; + int ev, rev, id; int thpos; time_t to; struct muth *th; }; -struct timeentry { - time_t to; - struct blocker *bl; -}; - static int epfd = -1, fdln = 0; static int exitstatus; static struct blocker **fdlist; -static typedbuf(struct timeentry) timeheap; +static typedbuf(struct blocker *) timeheap; static int regfd(struct blocker *bl) { @@ -136,23 +131,23 @@ static void remfd(struct blocker *bl) bl->reg = 0; } -static void thraise(struct timeentry ent, int n) +static void thraise(struct blocker *bl, int n) { int p; while(n > 0) { p = (n - 1) >> 1; - if(timeheap.b[p].to <= ent.to) + if(timeheap.b[p]->to <= bl->to) break; timeheap.b[n] = timeheap.b[p]; - timeheap.b[n].bl->thpos = n; + timeheap.b[n]->thpos = n; n = p; } - timeheap.b[n] = ent; - ent.bl->thpos = n; + timeheap.b[n] = bl; + bl->thpos = n; } -static void thlower(struct timeentry ent, int n) +static void thlower(struct blocker *bl, int n) { int c; @@ -160,27 +155,26 @@ static void thlower(struct timeentry ent, int n) c = (n << 1) + 1; if(c >= timeheap.d) break; - if((c + 1 < timeheap.d) && (timeheap.b[c + 1].to < timeheap.b[c].to)) + if((c + 1 < timeheap.d) && (timeheap.b[c + 1]->to < timeheap.b[c]->to)) c = c + 1; - if(timeheap.b[c].to > ent.to) + if(timeheap.b[c]->to > bl->to) break; timeheap.b[n] = timeheap.b[c]; - timeheap.b[n].bl->thpos = n; + timeheap.b[n]->thpos = n; n = c; } - timeheap.b[n] = ent; - ent.bl->thpos = n; + timeheap.b[n] = bl; + bl->thpos = n; } static void addtimeout(struct blocker *bl, time_t to) { sizebuf(timeheap, ++timeheap.d); - thraise((struct timeentry){.to = to, .bl = bl}, timeheap.d - 1); + thraise(bl, timeheap.d - 1); } static void deltimeout(struct blocker *bl) { - struct timeentry ent; int n; if(bl->thpos == timeheap.d - 1) { @@ -188,43 +182,83 @@ static void deltimeout(struct blocker *bl) return; } n = bl->thpos; - ent = timeheap.b[--timeheap.d]; - if((n > 0) && (timeheap.b[(n - 1) >> 1].to > ent.to)) - thraise(ent, n); + bl = timeheap.b[--timeheap.d]; + if((n > 0) && (timeheap.b[(n - 1) >> 1]->to > bl->to)) + thraise(bl, n); else - thlower(ent, n); + thlower(bl, n); } -int block(int fd, int ev, time_t to) +static int addblock(struct blocker *bl) { - struct blocker *bl; - int rv; - - omalloc(bl); - bl->fd = fd; - bl->ev = ev; - bl->th = current; - if((epfd >= 0) && regfd(bl)) { - free(bl); + if((epfd >= 0) && regfd(bl)) return(-1); - } bl->n = blockers; if(blockers) blockers->p = bl; blockers = bl; - if(to > 0) - addtimeout(bl, bl->to = (time(NULL) + to)); - rv = yield(); + if(bl->to > 0) + addtimeout(bl, bl->to); + return(0); +} + +static void remblock(struct blocker *bl) +{ if(bl->to > 0) deltimeout(bl); if(bl->n) bl->n->p = bl->p; if(bl->p) bl->p->n = bl->n; - if(bl == blockers) + if(blockers == bl) blockers = bl->n; remfd(bl); - free(bl); +} + +struct selected mblock(time_t to, int n, struct selected *spec) +{ + int i, id; + struct blocker bls[n]; + + to = (to > 0)?(time(NULL) + to):0; + for(i = 0; i < n; i++) { + bls[i] = (struct blocker) { + .fd = spec[i].fd, + .ev = spec[i].ev, + .id = i, + .to = to, + .th = current, + }; + if(addblock(&bls[i])) { + for(i--; i >= 0; i--) + remblock(&bls[i]); + return((struct selected){.fd = -1, .ev = -1}); + } + } + id = yield(); + for(i = 0; i < n; i++) + remblock(&bls[i]); + if(id < 0) + return((struct selected){.fd = -1, .ev = -1}); + return((struct selected){.fd = bls[id].fd, .ev = bls[id].rev}); +} + +int block(int fd, int ev, time_t to) +{ + struct blocker bl; + int rv; + + bl = (struct blocker) { + .fd = fd, + .ev = ev, + .id = -1, + .to = (to > 0)?(time(NULL) + to):0, + .th = current, + }; + if(addblock(&bl)) + return(-1); + rv = yield(); + remblock(&bl); return(rv); } @@ -248,8 +282,8 @@ int ioloop(void) now = time(NULL); if(timeheap.d == 0) toval = -1; - else if(timeheap.b[0].to > now) - toval = (timeheap.b[0].to - now) * 1000; + else if(timeheap.b[0]->to > now) + toval = (timeheap.b[0]->to - now) * 1000; else toval = 1000; if(exitstatus) @@ -275,13 +309,25 @@ int ioloop(void) ev = -1; for(bl = fdlist[fd]; bl; bl = nbl) { nbl = bl->n2; - if((ev < 0) || (ev & bl->ev)) - resume(bl->th, ev); + if((ev < 0) || (ev & bl->ev)) { + if(bl->id < 0) { + resume(bl->th, ev); + } else { + bl->rev = ev; + resume(bl->th, bl->id); + } + } } } now = time(NULL); - while((timeheap.d > 0) && (timeheap.b[0].to <= now)) - resume(timeheap.b[0].bl->th, 0); + while((timeheap.d > 0) && ((bl = timeheap.b[0])->to <= now)) { + if(bl->id < 0) { + resume(bl->th, 0); + } else { + bl->rev = 0; + resume(bl->th, bl->id); + } + } } for(bl = blockers; bl; bl = bl->n) remfd(bl);