Bluetooth: hidp: test "terminate" before sleeping
authorDavid Herrmann <dh.herrmann@gmail.com>
Sat, 6 Apr 2013 18:28:41 +0000 (20:28 +0200)
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>
Wed, 17 Apr 2013 05:47:55 +0000 (02:47 -0300)
The "terminate" flag is guaranteed to be set before the session terminates
and the handlers are woken up. Hence, we need to add it to the
sleep-condition.

Note that testing the flags is not enough as nothing prevents us from
setting the flags again after the session-handler terminated.

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
net/bluetooth/hidp/core.c

index 22e9ab1403a070b46fb0f4235239519fef6eb5a3..e01a9246c14dd94b61c4f691ba8d6f0ac7f20c57 100644 (file)
@@ -330,11 +330,13 @@ static int hidp_get_raw_report(struct hid_device *hid,
 
        /* Wait for the return of the report. The returned report
           gets put in session->report_return.  */
-       while (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags)) {
+       while (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags) &&
+              !atomic_read(&session->terminate)) {
                int res;
 
                res = wait_event_interruptible_timeout(session->report_queue,
-                       !test_bit(HIDP_WAITING_FOR_RETURN, &session->flags),
+                       !test_bit(HIDP_WAITING_FOR_RETURN, &session->flags)
+                               || atomic_read(&session->terminate),
                        5*HZ);
                if (res == 0) {
                        /* timeout */
@@ -399,11 +401,13 @@ static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, s
                goto err;
 
        /* Wait for the ACK from the device. */
-       while (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)) {
+       while (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags) &&
+              !atomic_read(&session->terminate)) {
                int res;
 
                res = wait_event_interruptible_timeout(session->report_queue,
-                       !test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags),
+                       !test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)
+                               || atomic_read(&session->terminate),
                        10*HZ);
                if (res == 0) {
                        /* timeout */