X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=fd%2Ffd.c;h=b969205456bdbfadf59c8e47c92dc7946e2f8e50;hp=966fe3576bda6b64de589711d982550322162986;hb=02b9e09173fbc1c481fb7f9aeff7d268f1af99e9;hpb=e10d80f4c2fbfd2f542e385a4da6a5515b5aad74 diff --git a/fd/fd.c b/fd/fd.c index 966fe357..b9692054 100644 --- a/fd/fd.c +++ b/fd/fd.c @@ -27,7 +27,7 @@ #include "fd/event.h" #include "fd/fd.h" -static fd_set fd_sets[FD_MODES]; +static fd_set readset, writeset, errorset; static int max_fd; static avl_tree_t *fds; @@ -40,8 +40,9 @@ int fd_compare(struct fd *a, struct fd *b) { bool fd_init(void) { int i; - for(i = 0; i < FD_MODES; i++) - FD_ZERO(&fd_sets[i]); + FD_ZERO(&readset); + FD_ZERO(&writeset); + FD_ZERO(&exceptset); fds = avl_tree_new((avl_compare_t)fd_compare, NULL); @@ -58,7 +59,14 @@ bool fd_add(struct fd *fd) { if(!avl_add(fds, fd)) return false; - FD_SET(fd->fd, &fd_sets[fd->mode]); + if(fd->read) + FD_SET(fd->fd, &readset); + + if(fd->write) + FD_SET(fd->fd, &writeset); + + if(fd->error) + FD_SET(fd->fd, &errorset); if(fd->fd > max_fd) max_fd = fd->fd; @@ -67,7 +75,9 @@ bool fd_add(struct fd *fd) { }; bool fd_del(struct fd *fd) { - FD_CLR(fd->fd, &fd_sets[fd->mode]); + FD_CLR(fd->fd, &readset); + FD_CLR(fd->fd, &writeset); + FD_CLR(fd->fd, &errorset); if(fd->fd >= max_fd) max_fd = ((struct fd *)fds->tail)->fd; @@ -75,20 +85,40 @@ bool fd_del(struct fd *fd) { return avl_del(fds, fd); }; +bool fd_mod(struct fd *fd) { + if(fd->read) + FD_SET(fd->fd, &readset); + else + FD_CLR(fd->fd, &readset); + + if(fd->write) + FD_SET(fd->fd, &writeset); + else + FD_CLR(fd->fd, &writeset); + + if(fd->error) + FD_SET(fd->fd, &errorset); + else + FD_CLR(fd->fd, &errorset); +} + bool fd_run(void) { struct timeval tv; int result; - fd_set fd_cur[FD_MODES]; + fd_set readtmp, writetmp, errortmp; fd_running = true; logger(LOG_INFO, "fd: running"); while(fd_running) { - memcpy(fd_cur, fd_sets, sizeof(fd_cur)); + readtmp = readset; + writetmp = writeset; + errortmp = errorset; + tv = event_timeout(); - result = select(max_fd + 1, &fd_cur[0], &fd_cur[1], &fd_cur[2], tv.tv_sec >= 0 ? &tv : NULL); + result = select(max_fd + 1, &readtmp, &writetmp, &errortmp, tv.tv_sec >= 0 ? &tv : NULL); if(result < 0) { if(errno != EINTR && errno != EAGAIN) { @@ -103,8 +133,12 @@ bool fd_run(void) { struct fd *fd; avl_foreach(fds, fd, { - if(FD_ISSET(fd->fd, &fd_cur[fd->mode])) - fd->handler(fd); + if(fd->read && FD_ISSET(fd->fd, &readtmp)) + fd->read(fd); + if(fd->write && FD_ISSET(fd->fd, &writetmp)) + fd->write(fd); + if(fd->error && FD_ISSET(fd->fd, &errortmp)) + fd->error(fd); }); } else { event_handle();