patch-2.1.127 linux/fs/select.c
Next file: linux/fs/smbfs/proc.c
Previous file: linux/fs/proc/array.c
Back to the patch index
Back to the overall index
- Lines: 163
- Date:
Sat Oct 31 10:17:22 1998
- Orig file:
v2.1.126/linux/fs/select.c
- Orig date:
Wed Jul 1 19:38:56 1998
diff -u --recursive --new-file v2.1.126/linux/fs/select.c linux/fs/select.c
@@ -124,28 +124,25 @@
#define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
#define POLLEX_SET (POLLPRI)
-int do_select(int n, fd_set_buffer *fds, unsigned long timeout)
+int do_select(int n, fd_set_buffer *fds, long *timeout)
{
poll_table wait_table, *wait;
- int retval;
- int i;
-
- lock_kernel();
+ int retval, i;
+ long __timeout = *timeout;
wait = NULL;
- current->timeout = timeout;
- if (timeout) {
- struct poll_table_entry *entry = (struct poll_table_entry *)
- __get_free_page(GFP_KERNEL);
- if (!entry) {
- retval = -ENOMEM;
- goto out_nowait;
- }
+ if (__timeout) {
+ struct poll_table_entry *entry = (struct poll_table_entry *) __get_free_page(GFP_KERNEL);
+ if (!entry)
+ return -ENOMEM;
+
wait_table.nr = 0;
wait_table.entry = entry;
wait = &wait_table;
}
+ lock_kernel();
+
retval = max_select_fd(n, fds);
if (retval < 0)
goto out;
@@ -190,18 +187,22 @@
}
}
wait = NULL;
- if (retval || !current->timeout || signal_pending(current))
+ if (retval || !__timeout || signal_pending(current))
break;
- schedule();
+ __timeout = schedule_timeout(__timeout);
}
current->state = TASK_RUNNING;
out:
- if (timeout) {
+ if (*timeout) {
free_wait(&wait_table);
free_page((unsigned long) wait_table.entry);
}
-out_nowait:
+
+ /*
+ * Up-to-date the caller timeout.
+ */
+ *timeout = __timeout;
unlock_kernel();
return retval;
}
@@ -218,10 +219,10 @@
sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp)
{
fd_set_buffer *fds;
- unsigned long timeout;
+ long timeout;
int ret;
- timeout = ~0UL;
+ timeout = MAX_SCHEDULE_TIMEOUT;
if (tvp) {
time_t sec, usec;
@@ -232,8 +233,6 @@
timeout = ROUND_UP(usec, 1000000/HZ);
timeout += sec * (unsigned long) HZ;
- if (timeout)
- timeout += jiffies + 1;
}
ret = -ENOMEM;
@@ -253,12 +252,11 @@
zero_fd_set(n, fds->res_out);
zero_fd_set(n, fds->res_ex);
- ret = do_select(n, fds, timeout);
+ ret = do_select(n, fds, &timeout);
if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
- unsigned long timeout = current->timeout - jiffies - 1;
time_t sec = 0, usec = 0;
- if ((long) timeout > 0) {
+ if (timeout) {
sec = timeout / HZ;
usec = timeout % HZ;
usec *= (1000000/HZ);
@@ -266,7 +264,6 @@
put_user(sec, &tvp->tv_sec);
put_user(usec, &tvp->tv_usec);
}
- current->timeout = 0;
if (ret < 0)
goto out;
@@ -287,7 +284,8 @@
return ret;
}
-static int do_poll(unsigned int nfds, struct pollfd *fds, poll_table *wait)
+static int do_poll(unsigned int nfds, struct pollfd *fds, poll_table *wait,
+ long timeout)
{
int count = 0;
@@ -321,15 +319,15 @@
}
wait = NULL;
- if (count || !current->timeout || signal_pending(current))
+ if (count || !timeout || signal_pending(current))
break;
- schedule();
+ timeout = schedule_timeout(timeout);
}
current->state = TASK_RUNNING;
return count;
}
-asmlinkage int sys_poll(struct pollfd * ufds, unsigned int nfds, int timeout)
+asmlinkage int sys_poll(struct pollfd * ufds, unsigned int nfds, long timeout)
{
int i, fdcount, err, size;
struct pollfd * fds, *fds1;
@@ -342,9 +340,9 @@
goto out;
if (timeout < 0)
- timeout = 0x7fffffff;
+ timeout = MAX_SCHEDULE_TIMEOUT;
else if (timeout)
- timeout = ((unsigned long)timeout*HZ+999)/1000+jiffies+1;
+ timeout = (timeout*HZ+999)/1000+1;
err = -ENOMEM;
if (timeout) {
@@ -366,9 +364,7 @@
if (copy_from_user(fds, ufds, size))
goto out_fds;
- current->timeout = timeout;
- fdcount = do_poll(nfds, fds, wait);
- current->timeout = 0;
+ fdcount = do_poll(nfds, fds, wait, timeout);
/* OK, now copy the revents fields back to user space. */
fds1 = fds;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov