Skip to content

Commit

Permalink
Input: reduce raciness when input handlers disconnect
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Dmitry Torokhov committed Jun 4, 2007
1 parent 26be5a5 commit 1dfa281
Show file tree
Hide file tree
Showing 4 changed files with 4 additions and 4 deletions.
2 changes: 1 addition & 1 deletion drivers/input/evdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -700,9 +700,9 @@ static void evdev_disconnect(struct input_handle *handle)
if (evdev->open) {
input_flush_device(handle, NULL);
input_close_device(handle);
wake_up_interruptible(&evdev->wait);
list_for_each_entry(client, &evdev->client_list, node)
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
wake_up_interruptible(&evdev->wait);
} else
evdev_free(evdev);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/input/joydev.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,9 +595,9 @@ static void joydev_disconnect(struct input_handle *handle)

if (joydev->open) {
input_close_device(handle);
wake_up_interruptible(&joydev->wait);
list_for_each_entry(client, &joydev->client_list, node)
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
wake_up_interruptible(&joydev->wait);
} else
joydev_free(joydev);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/input/mousedev.c
Original file line number Diff line number Diff line change
Expand Up @@ -767,9 +767,9 @@ static void mousedev_disconnect(struct input_handle *handle)

if (mousedev->open) {
input_close_device(handle);
wake_up_interruptible(&mousedev->wait);
list_for_each_entry(client, &mousedev->client_list, node)
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
wake_up_interruptible(&mousedev->wait);
} else
mousedev_free(mousedev);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/input/tsdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,9 +477,9 @@ static void tsdev_disconnect(struct input_handle *handle)

if (tsdev->open) {
input_close_device(handle);
wake_up_interruptible(&tsdev->wait);
list_for_each_entry(client, &tsdev->client_list, node)
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
wake_up_interruptible(&tsdev->wait);
} else
tsdev_free(tsdev);
}
Expand Down

0 comments on commit 1dfa281

Please sign in to comment.