diff options
author | Dmitry Torokhov <dtor@insightbb.com> | 2007-06-03 23:29:36 -0400 |
---|---|---|
committer | Dmitry Torokhov <dtor@insightbb.com> | 2007-06-03 23:50:05 -0400 |
commit | 1dfa2812404c37d7571622195f907cea3331616c (patch) | |
tree | 2533af73ff0e1e4d24603967bd6cdc092973dce9 | |
parent | 26be5a509af5f80c7012bd4f0478a94746c9c9d9 (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.c | 2 | ||||
-rw-r--r-- | drivers/input/joydev.c | 2 | ||||
-rw-r--r-- | drivers/input/mousedev.c | 2 | ||||
-rw-r--r-- | drivers/input/tsdev.c | 2 |
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 | } |