aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor@insightbb.com>2007-06-03 23:29:36 -0400
committerDmitry Torokhov <dtor@insightbb.com>2007-06-03 23:50:05 -0400
commit1dfa2812404c37d7571622195f907cea3331616c (patch)
tree2533af73ff0e1e4d24603967bd6cdc092973dce9
parent26be5a509af5f80c7012bd4f0478a94746c9c9d9 (diff)
Input: reduce raciness when input handlers disconnect
There is a race between input handler's release() and disconnect() methods: when input handler disconnects it wakes up all regular users and then process to walk user list to wake up async. users. While disconnect() walks the list release() removes elements of the same list causing oopses. While this is not a substibute for proper locking we can reduce odds of getting an oops if we wake up normal readers after walking the list. Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/input/evdev.c2
-rw-r--r--drivers/input/joydev.c2
-rw-r--r--drivers/input/mousedev.c2
-rw-r--r--drivers/input/tsdev.c2
4 files changed, 4 insertions, 4 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index a4c3729d396..93b407cd460 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -700,9 +700,9 @@ static void evdev_disconnect(struct input_handle *handle)
700 if (evdev->open) { 700 if (evdev->open) {
701 input_flush_device(handle, NULL); 701 input_flush_device(handle, NULL);
702 input_close_device(handle); 702 input_close_device(handle);
703 wake_up_interruptible(&evdev->wait);
704 list_for_each_entry(client, &evdev->client_list, node) 703 list_for_each_entry(client, &evdev->client_list, node)
705 kill_fasync(&client->fasync, SIGIO, POLL_HUP); 704 kill_fasync(&client->fasync, SIGIO, POLL_HUP);
705 wake_up_interruptible(&evdev->wait);
706 } else 706 } else
707 evdev_free(evdev); 707 evdev_free(evdev);
708} 708}
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 9bcc5425049..c83bfe8914a 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -595,9 +595,9 @@ static void joydev_disconnect(struct input_handle *handle)
595 595
596 if (joydev->open) { 596 if (joydev->open) {
597 input_close_device(handle); 597 input_close_device(handle);
598 wake_up_interruptible(&joydev->wait);
599 list_for_each_entry(client, &joydev->client_list, node) 598 list_for_each_entry(client, &joydev->client_list, node)
600 kill_fasync(&client->fasync, SIGIO, POLL_HUP); 599 kill_fasync(&client->fasync, SIGIO, POLL_HUP);
600 wake_up_interruptible(&joydev->wait);
601 } else 601 } else
602 joydev_free(joydev); 602 joydev_free(joydev);
603} 603}
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 7678e987655..dc78f62cbee 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -767,9 +767,9 @@ static void mousedev_disconnect(struct input_handle *handle)
767 767
768 if (mousedev->open) { 768 if (mousedev->open) {
769 input_close_device(handle); 769 input_close_device(handle);
770 wake_up_interruptible(&mousedev->wait);
771 list_for_each_entry(client, &mousedev->client_list, node) 770 list_for_each_entry(client, &mousedev->client_list, node)
772 kill_fasync(&client->fasync, SIGIO, POLL_HUP); 771 kill_fasync(&client->fasync, SIGIO, POLL_HUP);
772 wake_up_interruptible(&mousedev->wait);
773 } else 773 } else
774 mousedev_free(mousedev); 774 mousedev_free(mousedev);
775} 775}
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c
index 5e5b5c91d75..af4581d00d8 100644
--- a/drivers/input/tsdev.c
+++ b/drivers/input/tsdev.c
@@ -477,9 +477,9 @@ static void tsdev_disconnect(struct input_handle *handle)
477 477
478 if (tsdev->open) { 478 if (tsdev->open) {
479 input_close_device(handle); 479 input_close_device(handle);
480 wake_up_interruptible(&tsdev->wait);
481 list_for_each_entry(client, &tsdev->client_list, node) 480 list_for_each_entry(client, &tsdev->client_list, node)
482 kill_fasync(&client->fasync, SIGIO, POLL_HUP); 481 kill_fasync(&client->fasync, SIGIO, POLL_HUP);
482 wake_up_interruptible(&tsdev->wait);
483 } else 483 } else
484 tsdev_free(tsdev); 484 tsdev_free(tsdev);
485} 485}