Update pollwait explusive
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 11 Jun 2011 17:39:30 +0000 (13:39 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 11 Jun 2011 17:39:30 +0000 (13:39 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
wrapper/poll.c

index f3f76fea7a8f119123defc705618edac07955252..94142ff34f0f3db7739baa917c25d4e4b8ec4dda 100644 (file)
@@ -1,31 +1,32 @@
 /*
  * Copyright (C) 2011 Mathieu Desnoyers (mathieu.desnoyers@efficios.com)
  *
- * wrapper around poll __pollwait and poll_get_entry. Using KALLSYMS to get its
- * address when available, else we need to have a kernel that exports this
- * function to GPL modules.
+ * wrapper around poll_get_entry, implementing __pollwait with exclusive
+ * wakeups. Using KALLSYMS to get poll_get_entry address when available,
+ * else we need to have a kernel that exports this function to GPL
+ * modules.
  *
- * Dual LGPL v2.1/GPL v2 license.
+ * GPL v2 license.
  */
 
 #ifdef CONFIG_KALLSYMS
 
 #include <linux/kallsyms.h>
 #include <linux/poll.h>
+#include <linux/wait.h>
 
 struct poll_table_entry;
 struct splice_pipe_desc;
 
 static
-void (*__pollwait_sym)(struct file *filp, wait_queue_head_t *wait_address,
-               poll_table *p);
+int (*pollwake_sym)(wait_queue_t *wait, unsigned mode, int sync, void *key);
 static
 struct poll_table_entry *(*poll_get_entry_sym)(struct poll_wqueues *p);
 
-void wrapper_pollwait_exclusive(struct file *filp,
-                        wait_queue_head_t *wait_address,
-                        poll_table *p)
-
+/* Add a new entry */
+static void __pollwait_exclusive(struct file *filp,
+                                wait_queue_head_t *wait_address,
+                                poll_table *p)
 {
        struct poll_wqueues *pwq = container_of(p, struct poll_wqueues, pt);
        struct poll_table_entry *entry;
@@ -36,15 +37,33 @@ void wrapper_pollwait_exclusive(struct file *filp,
                printk(KERN_WARNING "LTTng: poll_get_entry_sym symbol lookup failed.\n");
                return;
        }
-       entry = poll_get_entry_sym(pwq);
 
-       if (!__pollwait_sym)
-               __pollwait_sym = (void *) kallsyms_lookup_name("__pollwait");
-       if (!__pollwait_sym) {
-               printk(KERN_WARNING "LTTng: __pollwait symbol lookup failed.\n");
+       if (!pollwake_sym)
+               pollwake_sym = (void *) kallsyms_lookup_name("pollwake");
+       if (!pollwake_sym) {
+               printk(KERN_WARNING "LTTng: pollwake_sym symbol lookup failed.\n");
                return;
        }
-       return __pollwait_sym(filp, wait_address, p);
+
+       entry = poll_get_entry_sym(pwq);
+
+       if (!entry)
+               return;
+       get_file(filp);
+       entry->filp = filp;
+       entry->wait_address = wait_address;
+       entry->key = p->key;
+       init_waitqueue_func_entry(&entry->wait, pollwake_sym);
+       entry->wait.private = pwq;
+       add_wait_queue_exclusive(wait_address, &entry->wait);
+}
+
+void wrapper_pollwait_exclusive(struct file *filp,
+                        wait_queue_head_t *wait_address,
+                        poll_table *p)
+
+{
+       __pollwait_exclusive(filp, wait_address, p);
 }
 
 #else
This page took 0.027607 seconds and 4 git commands to generate.