summary refs log tree commit diff
path: root/net/llc/af_llc.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@mandriva.com>2005-09-22 04:22:39 -0300
committerArnaldo Carvalho de Melo <acme@mandriva.com>2005-09-22 04:22:39 -0300
commitb35bd11019ed1084a36632f1c1d936244d9cfb5b (patch)
tree731acb821880f84586c4d414ddb4c08a0eee7e35 /net/llc/af_llc.c
parent72b1ad4a7e239a2224e87194654acba56fc477d4 (diff)
downloadlinux-b35bd11019ed1084a36632f1c1d936244d9cfb5b.tar.gz
[LLC]: Convert llc_ui_wait_for_ functions to use prepare_to_wait/finish_wait
And make it look more like the similar routines in the TCP/IP source code.

Signed-off-by: Jochen Friedrich <jochen@scram.de>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Diffstat (limited to 'net/llc/af_llc.c')
-rw-r--r--net/llc/af_llc.c147
1 files changed, 67 insertions, 80 deletions
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index aed61e6376ed..436c8db67f55 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -426,12 +426,30 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr,
 		sk->sk_state = TCP_CLOSE;
 		goto out;
 	}
-	rc = llc_ui_wait_for_conn(sk, sk->sk_rcvtimeo);
-	if (rc)
-		dprintk("%s: llc_ui_wait_for_conn failed=%d\n", __FUNCTION__, rc);
+
+	if (sk->sk_state == TCP_SYN_SENT) {
+		const int timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
+
+		if (!timeo || !llc_ui_wait_for_conn(sk, timeo))
+			goto out;
+
+		rc = sock_intr_errno(timeo);
+		if (signal_pending(current))
+			goto out;
+	}
+
+	if (sk->sk_state == TCP_CLOSE)
+		goto sock_error;
+
+	sock->state = SS_CONNECTED;
+	rc = 0;
 out:
 	release_sock(sk);
 	return rc;
+sock_error:
+	rc = sock_error(sk) ? : -ECONNABORTED;
+	sock->state = SS_UNCONNECTED;
+	goto out;
 }
 
 /**
@@ -472,117 +490,88 @@ out:
 
 static int llc_ui_wait_for_disc(struct sock *sk, int timeout)
 {
-	DECLARE_WAITQUEUE(wait, current);
-	int rc;
+	DEFINE_WAIT(wait);
+	int rc = 0;
 
-	add_wait_queue_exclusive(sk->sk_sleep, &wait);
-	for (;;) {
-		__set_current_state(TASK_INTERRUPTIBLE);
-		rc = 0;
-		if (sk->sk_state != TCP_CLOSE) {
-			release_sock(sk);
-			timeout = schedule_timeout(timeout);
-			lock_sock(sk);
-		} else
-			break;
+	prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
+	while (sk->sk_state != TCP_CLOSE) {
+		release_sock(sk);
+		timeout = schedule_timeout(timeout);
+		lock_sock(sk);
 		rc = -ERESTARTSYS;
 		if (signal_pending(current))
 			break;
 		rc = -EAGAIN;
 		if (!timeout)
 			break;
+		rc = 0;
+		prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
 	}
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(sk->sk_sleep, &wait);
+	finish_wait(sk->sk_sleep, &wait);
 	return rc;
 }
 
 static int llc_ui_wait_for_conn(struct sock *sk, int timeout)
 {
-	DECLARE_WAITQUEUE(wait, current);
-	int rc;
+	DEFINE_WAIT(wait);
 
-	add_wait_queue_exclusive(sk->sk_sleep, &wait);
-	for (;;) {
-		__set_current_state(TASK_INTERRUPTIBLE);
-		rc = -EAGAIN;
-		if (sk->sk_state == TCP_CLOSE)
-			break;
-		rc = 0;
-		if (sk->sk_state != TCP_ESTABLISHED) {
-			release_sock(sk);
-			timeout = schedule_timeout(timeout);
-			lock_sock(sk);
-		} else
-			break;
-		rc = -ERESTARTSYS;
-		if (signal_pending(current))
-			break;
-		rc = -EAGAIN;
-		if (!timeout)
+	prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
+
+	while (sk->sk_state == TCP_SYN_SENT) {
+		release_sock(sk);
+		timeout = schedule_timeout(timeout);
+		lock_sock(sk);
+		if (signal_pending(current) || !timeout)
 			break;
+		prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
 	}
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(sk->sk_sleep, &wait);
-	return rc;
+	finish_wait(sk->sk_sleep, &wait);
+	return timeout;
 }
 
 static int llc_ui_wait_for_data(struct sock *sk, int timeout)
 {
-	DECLARE_WAITQUEUE(wait, current);
+	DEFINE_WAIT(wait);
 	int rc = 0;
 
-	add_wait_queue_exclusive(sk->sk_sleep, &wait);
 	for (;;) {
-		__set_current_state(TASK_INTERRUPTIBLE);
+		prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
 		if (sk->sk_shutdown & RCV_SHUTDOWN)
 			break;
-		/*
-		 * Well, if we have backlog, try to process it now.
-		 */
-                if (sk->sk_backlog.tail) {
-			release_sock(sk);
-			lock_sock(sk);
-		}
-		rc = 0;
-		if (skb_queue_empty(&sk->sk_receive_queue)) {
-			release_sock(sk);
-			timeout = schedule_timeout(timeout);
-			lock_sock(sk);
-		} else
+		if (!skb_queue_empty(&sk->sk_receive_queue))
 			break;
+		release_sock(sk);
+		timeout = schedule_timeout(timeout);
+		lock_sock(sk);
 		rc = -ERESTARTSYS;
 		if (signal_pending(current))
 			break;
 		rc = -EAGAIN;
 		if (!timeout)
 			break;
+		rc = 0;
 	}
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(sk->sk_sleep, &wait);
+	finish_wait(sk->sk_sleep, &wait);
 	return rc;
 }
 
 static int llc_ui_wait_for_busy_core(struct sock *sk, int timeout)
 {
-	DECLARE_WAITQUEUE(wait, current);
+	DEFINE_WAIT(wait);
 	struct llc_sock *llc = llc_sk(sk);
 	int rc;
 
-	add_wait_queue_exclusive(sk->sk_sleep, &wait);
 	for (;;) {
-		dprintk("%s: looping...\n", __FUNCTION__);
-		__set_current_state(TASK_INTERRUPTIBLE);
+		prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
 		rc = -ENOTCONN;
 		if (sk->sk_shutdown & RCV_SHUTDOWN)
 			break;
 		rc = 0;
-		if (llc_data_accept_state(llc->state) || llc->p_flag) {
-			release_sock(sk);
-			timeout = schedule_timeout(timeout);
-			lock_sock(sk);
-		} else
+		if (!llc_data_accept_state(llc->state) && !llc->p_flag)
 			break;
+		release_sock(sk);
+		timeout = schedule_timeout(timeout);
+		lock_sock(sk);
 		rc = -ERESTARTSYS;
 		if (signal_pending(current))
 			break;
@@ -590,8 +579,7 @@ static int llc_ui_wait_for_busy_core(struct sock *sk, int timeout)
 		if (!timeout)
 			break;
 	}
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(sk->sk_sleep, &wait);
+	finish_wait(sk->sk_sleep, &wait);
 	return rc;
 }
 
@@ -621,9 +609,11 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
 		     sk->sk_state != TCP_LISTEN))
 		goto out;
 	/* wait for a connection to arrive. */
-	rc = llc_ui_wait_for_data(sk, sk->sk_rcvtimeo);
-	if (rc)
-		goto out;
+	if (skb_queue_empty(&sk->sk_receive_queue)) {
+		rc = llc_ui_wait_for_data(sk, sk->sk_rcvtimeo);
+		if (rc)
+			goto out;
+	}
 	dprintk("%s: got a new connection on %02X\n", __FUNCTION__,
 	        llc_sk(sk)->laddr.lsap);
 	skb = skb_dequeue(&sk->sk_receive_queue);
@@ -672,19 +662,16 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
 	struct sockaddr_llc *uaddr = (struct sockaddr_llc *)msg->msg_name;
 	struct sk_buff *skb;
 	size_t copied = 0;
-	int rc = -ENOMEM, timeout;
+	int rc = -ENOMEM;
 	int noblock = flags & MSG_DONTWAIT;
 
 	dprintk("%s: receiving in %02X from %02X\n", __FUNCTION__,
 		llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);
 	lock_sock(sk);
-	timeout = sock_rcvtimeo(sk, noblock);
-	rc = llc_ui_wait_for_data(sk, timeout);
-	if (rc) {
-		dprintk("%s: llc_ui_wait_for_data failed recv "
-			"in %02X from %02X\n", __FUNCTION__,
-			llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);
-		goto out;
+	if (skb_queue_empty(&sk->sk_receive_queue)) {
+		rc = llc_ui_wait_for_data(sk, sock_rcvtimeo(sk, noblock));
+		if (rc)
+			goto out;
 	}
 	skb = skb_dequeue(&sk->sk_receive_queue);
 	if (!skb) /* shutdown */