aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c54
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
1569static 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