--- linux-2.3.42/fs/select.c Tue Feb 1 11:47:07 2000 +++ linux-2.3.42-new/fs/select.c Thu Feb 3 11:02:12 2000 @@ -172,11 +172,11 @@ retval = max_select_fd(n, fds); read_unlock(¤t->files->file_lock); - lock_kernel(); if (retval < 0) goto out; n = retval; retval = 0; + lock_kernel(); for (;;) { set_current_state(TASK_INTERRUPTIBLE); for (i = 0 ; i < n; i++) { @@ -217,6 +217,7 @@ __timeout = schedule_timeout(__timeout); } current->state = TASK_RUNNING; + unlock_kernel(); out: if (*timeout) @@ -226,7 +227,6 @@ * Up-to-date the caller timeout. */ *timeout = __timeout; - unlock_kernel(); return retval; } @@ -334,29 +334,36 @@ #define POLLFD_PER_PAGE ((PAGE_SIZE) / sizeof(struct pollfd)) -static void do_pollfd(struct pollfd * fdp, poll_table * wait, int *count) +static void do_pollfd(unsigned int num, struct pollfd * fdpage, + poll_table * wait, int *count) { - int fd; - unsigned int mask; + int i; - mask = 0; - fd = fdp->fd; - if (fd >= 0) { - struct file * file = fget(fd); - mask = POLLNVAL; - if (file != NULL) { - mask = DEFAULT_POLLMASK; - if (file->f_op && file->f_op->poll) - mask = file->f_op->poll(file, wait); - mask &= fdp->events | POLLERR | POLLHUP; - fput(file); - } - if (mask) { - wait = NULL; - (*count)++; + for (i = 0; i < num; i++) { + int fd; + unsigned int mask; + struct pollfd *fdp; + + mask = 0; + fdp = (struct pollfd *)(fdpage + i); + fd = fdp->fd; + if (fd >= 0) { + struct file * file = fget(fd); + mask = POLLNVAL; + if (file != NULL) { + mask = DEFAULT_POLLMASK; + if (file->f_op && file->f_op->poll) + mask = file->f_op->poll(file, wait); + mask &= fdp->events | POLLERR | POLLHUP; + fput(file); + } + if (mask) { + wait = NULL; + (*count)++; + } } + fdp->revents = mask; } - fdp->revents = mask; } static int do_poll(unsigned int nfds, unsigned int nchunks, unsigned int nleft, @@ -369,12 +376,9 @@ set_current_state(TASK_INTERRUPTIBLE); for (i=0; i < nchunks; i++) - for (j = 0; j < POLLFD_PER_PAGE; j++) - do_pollfd(fds[i] + j, wait, &count); + do_pollfd(POLLFD_PER_PAGE, fds[i], wait, &count); if (nleft) - for (j = 0; j < nleft; j++) - do_pollfd(fds[nchunks] + j, wait, &count); - + do_pollfd(nleft, fds[nchunks], wait, &count); wait = NULL; if (count || !timeout || signal_pending(current)) break; @@ -388,7 +392,7 @@ { int i, j, fdcount, err; struct pollfd **fds; - poll_table *wait_table = NULL, *wait = NULL; + poll_table *wait = NULL; int nchunks, nleft; /* Do a sanity check on nfds ... */ @@ -405,13 +409,12 @@ err = -ENOMEM; if (timeout) { - wait_table = (poll_table *) __get_free_page(GFP_KERNEL); - if (!wait_table) + wait = (poll_table *) __get_free_page(GFP_KERNEL); + if (!wait) goto out; - wait_table->nr = 0; - wait_table->entry = (struct poll_table_entry *)(wait_table + 1); - wait_table->next = NULL; - wait = wait_table; + wait->nr = 0; + wait->entry = (struct poll_table_entry *)(wait + 1); + wait->next = NULL; } fds = NULL; @@ -442,11 +445,9 @@ for (i=0; i < nchunks; i++) if (copy_from_user(fds[i], ufds + i*POLLFD_PER_PAGE, PAGE_SIZE)) goto out_fds1; - if (nleft) { - if (copy_from_user(fds[nchunks], ufds + nchunks*POLLFD_PER_PAGE, - nleft * sizeof(struct pollfd))) - goto out_fds1; - } + if (nleft && copy_from_user(fds[nchunks], ufds + nchunks*POLLFD_PER_PAGE, + nleft * sizeof(struct pollfd))) + goto out_fds1; lock_kernel(); fdcount = do_poll(nfds, nchunks, nleft, fds, wait, timeout); @@ -473,7 +474,6 @@ if (nfds != 0) kfree(fds); out: - if (wait) - free_wait(wait_table); + free_wait(wait); return err; }