--------------------- PatchSet 11456 Date: 2007/05/27 14:17:50 Author: adrian Branch: HEAD Tag: (none) Log: Add in initial 'bunched updates' support.\nMake the code work when event bits are cleared - /dev/poll\nOR's updates; you have to POLLREMOVE the FD first.. Members: src/comm_devpoll.c:1.2->1.3 Index: squid/src/comm_devpoll.c =================================================================== RCS file: /cvsroot/squid/squid/src/comm_devpoll.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- squid/src/comm_devpoll.c 21 May 2007 05:21:36 -0000 1.2 +++ squid/src/comm_devpoll.c 27 May 2007 14:17:50 -0000 1.3 @@ -1,6 +1,6 @@ /* - * $Id: comm_devpoll.c,v 1.2 2007/05/21 05:21:36 adrian Exp $ + * $Id: comm_devpoll.c,v 1.3 2007/05/27 14:17:50 adrian Exp $ * * DEBUG: section 5 Socket Functions * @@ -37,6 +37,8 @@ #include +#define DEVPOLL_UPDATESIZE 1024 +#define DEVPOLL_QUERYSIZE 1024 static int devpoll_fd; static struct timespec zero_timespec; @@ -49,18 +51,20 @@ * can zero out an entry in the poll list if its active. */ +/* Current state */ struct _devpoll_state { char state; + int update_offset; }; -struct _devpoll_events { - int ds_used; - int ds_size; - struct pollfd *events; -}; +/* The update list */ +struct { + struct pollfd *pfds; + int cur; + int size; +} devpoll_update; static struct _devpoll_state *devpoll_state; -static struct _devpoll_events ds_events; static struct dvpoll do_poll; static int dpoll_nfds; @@ -77,32 +81,52 @@ /* This tracks the FD devpoll offset+state */ devpoll_state = xcalloc(Squid_MaxFD, sizeof(struct _devpoll_state)); - /* And this stuff is list used to submit events */ - ds_events.events = xcalloc(1024, sizeof(struct pollfd)); - ds_events.ds_used = 0; - ds_events.ds_size = 1024; - /* And this is the stuff we use to read events */ - do_poll.dp_fds = xcalloc(1024, sizeof(struct pollfd)); - dpoll_nfds = 1024; + do_poll.dp_fds = xcalloc(DEVPOLL_QUERYSIZE, sizeof(struct pollfd)); + dpoll_nfds = DEVPOLL_QUERYSIZE; + + devpoll_update.pfds = xcalloc(DEVPOLL_UPDATESIZE, sizeof(struct pollfd)); + devpoll_update.cur = -1; + devpoll_update.size = DEVPOLL_UPDATESIZE; fd_open(devpoll_fd, FD_UNKNOWN, "devpoll ctl"); commSetCloseOnExec(devpoll_fd); } static void -comm_update_fd(int fd, int events) +comm_flush_updates(void) { - struct pollfd pfd[1]; int i; + if (devpoll_update.cur == -1) + return; - pfd[0].fd = fd; - pfd[0].events = events; - pfd[0].revents = 0; + debug(5, 5) ("comm_flush_updates: %d fds queued\n", devpoll_update.cur + 1); - i = write(devpoll_fd, &pfd, sizeof(struct pollfd)); - assert(i == sizeof(struct pollfd)); + i = write(devpoll_fd, devpoll_update.pfds, (devpoll_update.cur + 1) * sizeof(struct pollfd)); + assert(i > 0); + assert(i == sizeof(struct pollfd) * (devpoll_update.cur + 1)); + devpoll_update.cur = -1; +} +/* + * We could be "optimal" and -change- an existing entry if they + * just add a bit - since the devpoll interface OR's multiple fd + * updates. We'll need to POLLREMOVE entries which has a bit cleared + * but for now I'll do whats "easier" and add the smart logic + * later. + */ +static void +comm_update_fd(int fd, int events) +{ + debug(5, 5) ("comm_update_fd: fd %d: events %d\n", fd, events); + if (devpoll_update.cur != -1 && (devpoll_update.cur == devpoll_update.size)) + comm_flush_updates(); + devpoll_update.cur++; + debug(5, 5) (" -> new slot (%d)\n", devpoll_update.cur); + devpoll_state[fd].update_offset = devpoll_update.cur; + devpoll_update.pfds[devpoll_update.cur].fd = fd; + devpoll_update.pfds[devpoll_update.cur].events = events; + devpoll_update.pfds[devpoll_update.cur].revents = 0; } void @@ -129,12 +153,15 @@ void commOpen(int fd) { + debug(5, 5) ("commOpen: %d\n", fd); devpoll_state[fd].state = 0; + devpoll_state[fd].update_offset = -1; } void commClose(int fd) { + debug(5, 5) ("commClose: %d\n", fd); comm_update_fd(fd, POLLREMOVE); } @@ -144,16 +171,18 @@ int st_new = (need_read ? POLLIN : 0) | (need_write ? POLLOUT : 0); int st_change; + if (fd_table[fd].flags.closing) + return; + debug(5, 5) ("commSetEvents(fd=%d, read=%d, write=%d)\n", fd, need_read, need_write); st_change = devpoll_state[fd].state ^ st_new; if (!st_change) return; + comm_update_fd(fd, POLLREMOVE); if (st_new) comm_update_fd(fd, st_new); - else - comm_update_fd(fd, POLLREMOVE); devpoll_state[fd].state = st_new; } @@ -169,6 +198,9 @@ do_poll.dp_nfds = dpoll_nfds; /* dp_fds is already allocated */ + debug(5, 5) ("do_comm_select: begin\n"); + comm_flush_updates(); + num = ioctl(devpoll_fd, DP_POLL, &do_poll); debug(5, 5) ("do_comm_select: ioctl() returned %d fds\n", num); @@ -186,8 +218,8 @@ for (i = 0; i < num; i++) { int fd = (int) do_poll.dp_fds[i].fd; - if (do_poll.dp_fds[i].revents & POLLERR) { - debug(5, 3) ("comm_select: devpoll event error: fd %d\n", fd); + if (do_poll.dp_fds[i].revents & (POLLERR | POLLHUP | POLLNVAL)) { + debug(5, 1) ("comm_select: devpoll event error: fd %d\n", fd); continue; /* XXX! */ } if (do_poll.dp_fds[i].revents & POLLIN) {