summaryrefslogtreecommitdiffstats
path: root/net/dccp/output.c
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2007-10-04 14:38:49 -0700
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 16:54:31 -0700
commitbc8498721dfe3f7d537f4f75302be7dbe9c7b939 (patch)
tree6bf28dc1b1443e1ea47c3f45135ef1f11a5cd42a /net/dccp/output.c
parentaf289e803fdf2fcd19cf4a57c3c896dba146c756 (diff)
downloadlinux-stable-bc8498721dfe3f7d537f4f75302be7dbe9c7b939.tar.gz
linux-stable-bc8498721dfe3f7d537f4f75302be7dbe9c7b939.tar.bz2
linux-stable-bc8498721dfe3f7d537f4f75302be7dbe9c7b939.zip
[DCCP]: Wait for CCID
This performs a minor optimisation: when ccid_hc_tx_send_packet returns a value greater zero, then the same call previously was done again at the begin of the while loop in dccp_wait_for_ccid. This patch exploits the available information and schedule-timeouts directly instead. Documentation also added. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> Signed-off-by: Ian McDonald <ian.mcdonald@jandi.co.nz> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dccp/output.c')
-rw-r--r--net/dccp/output.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 6a334ed5e9d6..f49544618f20 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -177,34 +177,38 @@ void dccp_write_space(struct sock *sk)
/**
* dccp_wait_for_ccid - Wait for ccid to tell us we can send a packet
- * @sk: socket to wait for
+ * @sk: socket to wait for
+ * @skb: current skb to pass on for waiting
+ * @delay: sleep timeout in milliseconds (> 0)
+ * This function is called by default when the socket is closed, and
+ * when a non-zero linger time is set on the socket. For consistency
*/
-static int dccp_wait_for_ccid(struct sock *sk, struct sk_buff *skb)
+static int dccp_wait_for_ccid(struct sock *sk, struct sk_buff *skb, int delay)
{
struct dccp_sock *dp = dccp_sk(sk);
DEFINE_WAIT(wait);
- unsigned long delay;
+ unsigned long jiffdelay;
int rc;
- while (1) {
+ do {
+ dccp_pr_debug("delayed send by %d msec\n", delay);
+ jiffdelay = msecs_to_jiffies(delay);
+
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
+ sk->sk_write_pending++;
+ release_sock(sk);
+ schedule_timeout(jiffdelay);
+ lock_sock(sk);
+ sk->sk_write_pending--;
+
if (sk->sk_err)
goto do_error;
if (signal_pending(current))
goto do_interrupted;
rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);
- if (rc <= 0)
- break;
- dccp_pr_debug("delayed send by %d msec\n", rc);
- delay = msecs_to_jiffies(rc);
- sk->sk_write_pending++;
- release_sock(sk);
- schedule_timeout(delay);
- lock_sock(sk);
- sk->sk_write_pending--;
- }
+ } while ((delay = rc) > 0);
out:
finish_wait(sk->sk_sleep, &wait);
return rc;
@@ -231,7 +235,7 @@ void dccp_write_xmit(struct sock *sk, int block)
msecs_to_jiffies(err)+jiffies);
break;
} else
- err = dccp_wait_for_ccid(sk, skb);
+ err = dccp_wait_for_ccid(sk, skb, err);
if (err && err != -EINTR)
DCCP_BUG("err=%d after dccp_wait_for_ccid", err);
}