Skip to content

Commit

Permalink
Bluetooth: rfcomm: Fix lost wakeups waiting to accept socket
Browse files Browse the repository at this point in the history
Fix race conditions which can cause lost wakeups (or missed
signals) while waiting to accept an rfcomm socket connection.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
  • Loading branch information
Peter Hurley authored and Gustavo F. Padovan committed Aug 11, 2011
1 parent e5842cd commit 950e2d5
Showing 1 changed file with 14 additions and 14 deletions.
28 changes: 14 additions & 14 deletions net/bluetooth/rfcomm/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,11 +485,6 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f

lock_sock(sk);

if (sk->sk_state != BT_LISTEN) {
err = -EBADFD;
goto done;
}

if (sk->sk_type != SOCK_STREAM) {
err = -EINVAL;
goto done;
Expand All @@ -501,28 +496,33 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f

/* Wait for an incoming connection. (wake-one). */
add_wait_queue_exclusive(sk_sleep(sk), &wait);
while (!(nsk = bt_accept_dequeue(sk, newsock))) {
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
if (!timeo) {
err = -EAGAIN;

if (sk->sk_state != BT_LISTEN) {
err = -EBADFD;
break;
}

release_sock(sk);
timeo = schedule_timeout(timeo);
lock_sock(sk);
nsk = bt_accept_dequeue(sk, newsock);
if (nsk)
break;

if (sk->sk_state != BT_LISTEN) {
err = -EBADFD;
if (!timeo) {
err = -EAGAIN;
break;
}

if (signal_pending(current)) {
err = sock_intr_errno(timeo);
break;
}

release_sock(sk);
timeo = schedule_timeout(timeo);
lock_sock(sk);
}
set_current_state(TASK_RUNNING);
__set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait);

if (err)
Expand Down

0 comments on commit 950e2d5

Please sign in to comment.