patch-2.4.0-test5 linux/fs/select.c
Next file: linux/fs/smbfs/ChangeLog
Previous file: linux/fs/qnx4/inode.c
Back to the patch index
Back to the overall index
- Lines: 105
- Date:
Sun Jul 23 22:39:44 2000
- Orig file:
v2.4.0-test4/linux/fs/select.c
- Orig date:
Fri Jul 14 12:12:14 2000
diff -u --recursive --new-file v2.4.0-test4/linux/fs/select.c linux/fs/select.c
@@ -24,6 +24,21 @@
#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
#define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)
+struct poll_table_entry {
+ struct file * filp;
+ wait_queue_t wait;
+ wait_queue_head_t * wait_address;
+};
+
+struct poll_table_page {
+ struct poll_table_page * next;
+ struct poll_table_entry * entry;
+ struct poll_table_entry entries[0];
+};
+
+#define POLL_TABLE_FULL(table) \
+ ((unsigned long)((table)->entry+1) > PAGE_SIZE + (unsigned long)(table))
+
/*
* Ok, Peter made a complicated, but straightforward multiple_wait() function.
* I have rewritten this, taking some shortcuts: This code may not be easy to
@@ -44,13 +59,12 @@
struct poll_table_entry * entry;
struct poll_table_page *old;
- entry = p->entry + p->nr;
- while (p->nr > 0) {
- p->nr--;
+ entry = p->entry;
+ do {
entry--;
remove_wait_queue(entry->wait_address,&entry->wait);
fput(entry->filp);
- }
+ } while (entry > p->entries);
old = p;
p = p->next;
free_page((unsigned long) old);
@@ -61,7 +75,7 @@
{
struct poll_table_page *table = p->table;
- if (!table || table->nr >= __MAX_POLL_TABLE_ENTRIES) {
+ if (!table || POLL_TABLE_FULL(table)) {
struct poll_table_page *new_table;
new_table = (struct poll_table_page *) __get_free_page(GFP_KERNEL);
@@ -70,8 +84,7 @@
__set_current_state(TASK_RUNNING);
return;
}
- new_table->nr = 0;
- new_table->entry = (struct poll_table_entry *)(new_table + 1);
+ new_table->entry = new_table->entries;
new_table->next = table;
p->table = new_table;
table = new_table;
@@ -79,9 +92,8 @@
/* Add a new entry */
{
- struct poll_table_entry * entry;
- entry = table->entry + table->nr;
- table->nr++;
+ struct poll_table_entry * entry = table->entry;
+ table->entry = entry+1;
get_file(filp);
entry->filp = filp;
entry->wait_address = wait_address;
@@ -221,6 +233,16 @@
return retval;
}
+static void *select_bits_alloc(int size)
+{
+ return kmalloc(6 * size, GFP_KERNEL);
+}
+
+static void select_bits_free(void *bits, int size)
+{
+ kfree(bits);
+}
+
/*
* We can actually return ERESTARTSYS instead of EINTR, but I'd
* like to be certain this leads to no problems. So I return
@@ -273,7 +295,7 @@
*/
ret = -ENOMEM;
size = FDS_BYTES(n);
- bits = kmalloc(6 * size, GFP_KERNEL);
+ bits = select_bits_alloc(size);
if (!bits)
goto out_nofds;
fds.in = (unsigned long *) bits;
@@ -318,7 +340,7 @@
set_fd_set(n, exp, fds.res_ex);
out:
- kfree(bits);
+ select_bits_free(bits, size);
out_nofds:
return ret;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)