diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index b2ae25ae3038..008f6fdf95c3 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -1566,6 +1566,42 @@ static int listen(struct socket *sock, int len) | |||
1566 | return res; | 1566 | return res; |
1567 | } | 1567 | } |
1568 | 1568 | ||
1569 | static int tipc_wait_for_accept(struct socket *sock, long timeo) | ||
1570 | { | ||
1571 | struct sock *sk = sock->sk; | ||
1572 | DEFINE_WAIT(wait); | ||
1573 | int err; | ||
1574 | |||
1575 | /* True wake-one mechanism for incoming connections: only | ||
1576 | * one process gets woken up, not the 'whole herd'. | ||
1577 | * Since we do not 'race & poll' for established sockets | ||
1578 | * anymore, the common case will execute the loop only once. | ||
1579 | */ | ||
1580 | for (;;) { | ||
1581 | prepare_to_wait_exclusive(sk_sleep(sk), &wait, | ||
1582 | TASK_INTERRUPTIBLE); | ||
1583 | if (skb_queue_empty(&sk->sk_receive_queue)) { | ||
1584 | release_sock(sk); | ||
1585 | timeo = schedule_timeout(timeo); | ||
1586 | lock_sock(sk); | ||
1587 | } | ||
1588 | err = 0; | ||
1589 | if (!skb_queue_empty(&sk->sk_receive_queue)) | ||
1590 | break; | ||
1591 | err = -EINVAL; | ||
1592 | if (sock->state != SS_LISTENING) | ||
1593 | break; | ||
1594 | err = sock_intr_errno(timeo); | ||
1595 | if (signal_pending(current)) | ||
1596 | break; | ||
1597 | err = -EAGAIN; | ||
1598 | if (!timeo) | ||
1599 | break; | ||
1600 | } | ||
1601 | finish_wait(sk_sleep(sk), &wait); | ||
1602 | return err; | ||
1603 | } | ||
1604 | |||
1569 | /** | 1605 | /** |
1570 | * accept - wait for connection request | 1606 | * accept - wait for connection request |
1571 | * @sock: listening socket | 1607 | * @sock: listening socket |
@@ -1582,7 +1618,7 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
1582 | struct tipc_port *new_tport; | 1618 | struct tipc_port *new_tport; |
1583 | struct tipc_msg *msg; | 1619 | struct tipc_msg *msg; |
1584 | u32 new_ref; | 1620 | u32 new_ref; |
1585 | 1621 | long timeo; | |
1586 | int res; | 1622 | int res; |
1587 | 1623 | ||
1588 | lock_sock(sk); | 1624 | lock_sock(sk); |
@@ -1592,18 +1628,10 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
1592 | goto exit; | 1628 | goto exit; |
1593 | } | 1629 | } |
1594 | 1630 | ||
1595 | while (skb_queue_empty(&sk->sk_receive_queue)) { | 1631 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); |
1596 | if (flags & O_NONBLOCK) { | 1632 | res = tipc_wait_for_accept(sock, timeo); |
1597 | res = -EWOULDBLOCK; | 1633 | if (res) |
1598 | goto exit; | 1634 | goto exit; |
1599 | } | ||
1600 | release_sock(sk); | ||
1601 | res = wait_event_interruptible(*sk_sleep(sk), | ||
1602 | (!skb_queue_empty(&sk->sk_receive_queue))); | ||
1603 | lock_sock(sk); | ||
1604 | if (res) | ||
1605 | goto exit; | ||
1606 | } | ||
1607 | 1635 | ||
1608 | buf = skb_peek(&sk->sk_receive_queue); | 1636 | buf = skb_peek(&sk->sk_receive_queue); |
1609 | 1637 | ||