static int unix_accept(struct socket *, struct socket *, int);
static int unix_getname(struct socket *, struct sockaddr *, int *, int);
static unsigned int unix_poll(struct file *, struct socket *, poll_table *);
-static unsigned int unix_datagram_poll(struct file *, struct socket *,
- poll_table *);
+static unsigned int unix_dgram_poll(struct file *, struct socket *,
+ poll_table *);
static int unix_ioctl(struct socket *, unsigned int, unsigned long);
static int unix_shutdown(struct socket *, int);
static int unix_stream_sendmsg(struct kiocb *, struct socket *,
.socketpair = unix_socketpair,
.accept = sock_no_accept,
.getname = unix_getname,
- .poll = unix_datagram_poll,
+ .poll = unix_dgram_poll,
.ioctl = unix_ioctl,
.listen = sock_no_listen,
.shutdown = unix_shutdown,
.socketpair = unix_socketpair,
.accept = unix_accept,
.getname = unix_getname,
- .poll = unix_datagram_poll,
+ .poll = unix_dgram_poll,
.ioctl = unix_ioctl,
.listen = unix_listen,
.shutdown = unix_shutdown,
return mask;
}
-static unsigned int unix_datagram_poll(struct file *file, struct socket *sock,
- poll_table *wait)
+static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
+ poll_table *wait)
{
- struct sock *sk = sock->sk, *peer;
- unsigned int mask;
+ struct sock *sk = sock->sk, *other;
+ unsigned int mask, writable;
poll_wait(file, sk->sk_sleep, wait);
-
- peer = unix_peer_get(sk);
- if (peer) {
- if (peer != sk) {
- /*
- * Writability of a connected socket additionally
- * depends on the state of the receive queue of the
- * peer.
- */
- poll_wait(file, &unix_sk(peer)->peer_wait, wait);
- } else {
- sock_put(peer);
- peer = NULL;
- }
- }
-
mask = 0;
/* exceptional events? */
}
/* writable? */
- if (unix_writable(sk) && !(peer && unix_recvq_full(peer)))
+ writable = unix_writable(sk);
+ if (writable) {
+ other = unix_peer_get(sk);
+ if (other) {
+ if (unix_peer(other) != sk) {
+ poll_wait(file, &unix_sk(other)->peer_wait,
+ wait);
+ if (unix_recvq_full(other))
+ writable = 0;
+ }
+
+ sock_put(other);
+ }
+ }
+
+ if (writable)
mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
else
set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
- if (peer)
- sock_put(peer);
-
return mask;
}