diff options
Diffstat (limited to 'net/unix')
| -rw-r--r-- | net/unix/af_unix.c | 52 | 
1 files changed, 24 insertions, 28 deletions
| diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 657835f227d..783317dacd3 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -487,8 +487,8 @@ static int unix_socketpair(struct socket *, struct socket *);  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 *, @@ -534,7 +534,7 @@ static const struct proto_ops unix_dgram_ops = {  	.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, @@ -555,7 +555,7 @@ static const struct proto_ops unix_seqpacket_ops = {  	.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, @@ -1994,29 +1994,13 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl  	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? */ @@ -2042,14 +2026,26 @@ static unsigned int unix_datagram_poll(struct file *file, struct socket *sock,  	}  	/* 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;  } | 
