patch-2.2.15 linux/fs/select.c
Next file: linux/fs/smbfs/file.c
Previous file: linux/fs/romfs/inode.c
Back to the patch index
Back to the overall index
- Lines: 114
- Date:
Fri Apr 21 12:46:45 2000
- Orig file:
v2.2.14/fs/select.c
- Orig date:
Sat Aug 28 20:00:58 1999
diff -u --new-file --recursive --exclude-from ../../exclude v2.2.14/fs/select.c linux/fs/select.c
@@ -39,6 +39,39 @@
* Linus noticed. -- jrs
*/
+static poll_table* alloc_wait(int nfds)
+{
+ poll_table* out;
+ poll_table* walk;
+
+ out = (poll_table *) __get_free_page(GFP_KERNEL);
+ if(out==NULL)
+ return NULL;
+ out->nr = 0;
+ out->entry = (struct poll_table_entry *)(out + 1);
+ out->next = NULL;
+ nfds -=__MAX_POLL_TABLE_ENTRIES;
+ walk = out;
+ while(nfds > 0) {
+ poll_table *tmp = (poll_table *) __get_free_page(GFP_KERNEL);
+ if (!tmp) {
+ while(out != NULL) {
+ tmp = out->next;
+ free_page((unsigned long)out);
+ out = tmp;
+ }
+ return NULL;
+ }
+ tmp->nr = 0;
+ tmp->entry = (struct poll_table_entry *)(tmp + 1);
+ tmp->next = NULL;
+ walk->next = tmp;
+ walk = tmp;
+ nfds -=__MAX_POLL_TABLE_ENTRIES;
+ }
+ return out;
+}
+
static void free_wait(poll_table * p)
{
struct poll_table_entry * entry;
@@ -63,7 +96,6 @@
for (;;) {
if (p->nr < __MAX_POLL_TABLE_ENTRIES) {
struct poll_table_entry * entry;
-ok_table:
entry = p->entry + p->nr;
entry->filp = filp;
filp->f_count++;
@@ -74,17 +106,6 @@
p->nr++;
return;
}
- if (p->next == NULL) {
- poll_table *tmp = (poll_table *) __get_free_page(GFP_KERNEL);
- if (!tmp)
- return;
- tmp->nr = 0;
- tmp->entry = (struct poll_table_entry *)(tmp + 1);
- tmp->next = NULL;
- p->next = tmp;
- p = tmp;
- goto ok_table;
- }
p = p->next;
}
}
@@ -154,23 +175,21 @@
long __timeout = *timeout;
wait = wait_table = NULL;
- if (__timeout) {
- wait_table = (poll_table *) __get_free_page(GFP_KERNEL);
- if (!wait_table)
- return -ENOMEM;
-
- wait_table->nr = 0;
- wait_table->entry = (struct poll_table_entry *)(wait_table + 1);
- wait_table->next = NULL;
- wait = wait_table;
- }
-
lock_kernel();
retval = max_select_fd(n, fds);
if (retval < 0)
goto out;
n = retval;
+ if (__timeout) {
+ retval = -ENOMEM;
+ wait_table = alloc_wait(n);
+ if (!wait_table)
+ goto out;
+
+ wait = wait_table;
+ }
+
retval = 0;
for (;;) {
current->state = TASK_INTERRUPTIBLE;
@@ -406,12 +425,10 @@
err = -ENOMEM;
if (timeout) {
- wait_table = (poll_table *) __get_free_page(GFP_KERNEL);
+ wait_table = alloc_wait(nfds);
if (!wait_table)
goto out;
- wait_table->nr = 0;
- wait_table->entry = (struct poll_table_entry *)(wait_table + 1);
- wait_table->next = NULL;
+
wait = wait_table;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)