#define NOPLAN9DEFINES #include #include #include #include #include #include #include /* * Poll file descriptors in an idle loop. */ typedef struct Poll Poll; struct Poll { Channel *c; /* for sending back */ }; static Channel *sleepchan[64]; static int sleeptime[64]; static int nsleep; static struct pollfd pfd[64]; static struct Poll polls[64]; static int npoll; static void pollidle(void *v) { int i, n, t; uint now; for(;; yield()){ //fprint(2, "poll %d:", npoll); for(i=0; i= nelem(polls)){ fprint(2, "Too many polled fds.\n"); abort(); } npoll++; } pfd[i].fd = fd; pfd[i].events = rw=='r' ? POLLIN : POLLOUT; polls[i].c = &s.c; //threadstate("fdwait %d %d", f->fd, e); recvul(&s.c); } void threadsleep(int ms) { struct { Channel c; ulong x; } s; threadfdwaitsetup(); chaninit(&s.c, sizeof(ulong), 1); sleepchan[nsleep] = &s.c; sleeptime[nsleep++] = p9nsec()/1000000+ms; recvul(&s.c); } void threadfdnoblock(int fd) { fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0)|O_NONBLOCK); } long threadread(int fd, void *a, long n) { int nn; threadfdnoblock(fd); again: nn = read(fd, a, n); if(nn < 0){ if(errno == EINTR) goto again; if(errno == EAGAIN || errno == EWOULDBLOCK){ threadfdwait(fd, 'r'); goto again; } } return nn; } int threadrecvfd(int fd) { int nn; threadfdnoblock(fd); again: nn = recvfd(fd); if(nn < 0){ if(errno == EINTR) goto again; if(errno == EAGAIN || errno == EWOULDBLOCK){ threadfdwait(fd, 'r'); goto again; } } return nn; } int threadsendfd(int fd, int sfd) { int nn; threadfdnoblock(fd); again: nn = sendfd(fd, sfd); if(nn < 0){ if(errno == EINTR) goto again; if(errno == EAGAIN || errno == EWOULDBLOCK){ threadfdwait(fd, 'w'); goto again; } } return nn; } long threadreadn(int fd, void *a, long n) { int tot, nn; for(tot = 0; tot