return res;
 }
 
+static int tipc_wait_for_accept(struct socket *sock, long timeo)
+{
+       struct sock *sk = sock->sk;
+       DEFINE_WAIT(wait);
+       int err;
+
+       /* True wake-one mechanism for incoming connections: only
+        * one process gets woken up, not the 'whole herd'.
+        * Since we do not 'race & poll' for established sockets
+        * anymore, the common case will execute the loop only once.
+       */
+       for (;;) {
+               prepare_to_wait_exclusive(sk_sleep(sk), &wait,
+                                         TASK_INTERRUPTIBLE);
+               if (skb_queue_empty(&sk->sk_receive_queue)) {
+                       release_sock(sk);
+                       timeo = schedule_timeout(timeo);
+                       lock_sock(sk);
+               }
+               err = 0;
+               if (!skb_queue_empty(&sk->sk_receive_queue))
+                       break;
+               err = -EINVAL;
+               if (sock->state != SS_LISTENING)
+                       break;
+               err = sock_intr_errno(timeo);
+               if (signal_pending(current))
+                       break;
+               err = -EAGAIN;
+               if (!timeo)
+                       break;
+       }
+       finish_wait(sk_sleep(sk), &wait);
+       return err;
+}
+
 /**
  * accept - wait for connection request
  * @sock: listening socket
        struct tipc_port *new_tport;
        struct tipc_msg *msg;
        u32 new_ref;
-
+       long timeo;
        int res;
 
        lock_sock(sk);
                goto exit;
        }
 
-       while (skb_queue_empty(&sk->sk_receive_queue)) {
-               if (flags & O_NONBLOCK) {
-                       res = -EWOULDBLOCK;
-                       goto exit;
-               }
-               release_sock(sk);
-               res = wait_event_interruptible(*sk_sleep(sk),
-                               (!skb_queue_empty(&sk->sk_receive_queue)));
-               lock_sock(sk);
-               if (res)
-                       goto exit;
-       }
+       timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
+       res = tipc_wait_for_accept(sock, timeo);
+       if (res)
+               goto exit;
 
        buf = skb_peek(&sk->sk_receive_queue);