Commit 9c5896be authored by Ralf Bächle's avatar Ralf Bächle

Redo race avoidance with cli with wait_event-like construction.

parent 0dfe6e55
...@@ -732,29 +732,36 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr, ...@@ -732,29 +732,36 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
if (sk->state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) if (sk->state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
return -EINPROGRESS; return -EINPROGRESS;
cli(); /* To avoid races on the sleep */
/* /*
* A Connect Ack with Choke or timeout or failed routing will go to closed. * A Connect Ack with Choke or timeout or failed routing will go to
* closed.
*/ */
while (sk->state == TCP_SYN_SENT) { if (sk->state == TCP_SYN_SENT) {
interruptible_sleep_on(sk->sleep); struct task_struct *tsk = current;
if (signal_pending(current)) { DECLARE_WAITQUEUE(wait, tsk);
sti();
add_wait_queue(sk->sleep, &wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (sk->state != TCP_SYN_SENT)
break;
if (!signal_pending(tsk)) {
schedule();
continue;
}
return -ERESTARTSYS; return -ERESTARTSYS;
} }
current->state = TASK_RUNNING;
remove_wait_queue(sk->sleep, &wait);
} }
if (sk->state != TCP_ESTABLISHED) { if (sk->state != TCP_ESTABLISHED) {
sti();
sock->state = SS_UNCONNECTED; sock->state = SS_UNCONNECTED;
return sock_error(sk); /* Always set at this point */ return sock_error(sk); /* Always set at this point */
} }
sock->state = SS_CONNECTED; sock->state = SS_CONNECTED;
sti();
return 0; return 0;
} }
......
...@@ -842,29 +842,36 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le ...@@ -842,29 +842,36 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
if (sk->state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) if (sk->state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
return -EINPROGRESS; return -EINPROGRESS;
cli(); /* To avoid races on the sleep */
/* /*
* A Connect Ack with Choke or timeout or failed routing will go to closed. * A Connect Ack with Choke or timeout or failed routing will go to
* closed.
*/ */
while (sk->state == TCP_SYN_SENT) { if (sk->state == TCP_SYN_SENT) {
interruptible_sleep_on(sk->sleep); struct task_struct *tsk = current;
if (signal_pending(current)) { DECLARE_WAITQUEUE(wait, tsk);
sti();
add_wait_queue(sk->sleep, &wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (sk->state != TCP_SYN_SENT)
break;
if (!signal_pending(tsk)) {
schedule();
continue;
}
return -ERESTARTSYS; return -ERESTARTSYS;
} }
current->state = TASK_RUNNING;
remove_wait_queue(sk->sleep, &wait);
} }
if (sk->state != TCP_ESTABLISHED) { if (sk->state != TCP_ESTABLISHED) {
sti();
sock->state = SS_UNCONNECTED; sock->state = SS_UNCONNECTED;
return sock_error(sk); /* Always set at this point */ return sock_error(sk); /* Always set at this point */
} }
sock->state = SS_CONNECTED; sock->state = SS_CONNECTED;
sti();
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment