aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp')
-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)
177 177
178/** 178/**
179 * dccp_wait_for_ccid - Wait for ccid to tell us we can send a packet 179 * dccp_wait_for_ccid - Wait for ccid to tell us we can send a packet
180 * @sk: socket to wait for 180 * @sk: socket to wait for
181 * @skb: current skb to pass on for waiting
182 * @delay: sleep timeout in milliseconds (> 0)
183 * This function is called by default when the socket is closed, and
184 * when a non-zero linger time is set on the socket. For consistency
181 */ 185 */
182static int dccp_wait_for_ccid(struct sock *sk, struct sk_buff *skb) 186static int dccp_wait_for_ccid(struct sock *sk, struct sk_buff *skb, int delay)
183{ 187{
184 struct dccp_sock *dp = dccp_sk(sk); 188 struct dccp_sock *dp = dccp_sk(sk);
185 DEFINE_WAIT(wait); 189 DEFINE_WAIT(wait);
186 unsigned long delay; 190 unsigned long jiffdelay;
187 int rc; 191 int rc;
188 192
189 while (1) { 193 do {
194 dccp_pr_debug("delayed send by %d msec\n", delay);
195 jiffdelay = msecs_to_jiffies(delay);
196
190 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); 197 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
191 198
199 sk->sk_write_pending++;
200 release_sock(sk);
201 schedule_timeout(jiffdelay);
202 lock_sock(sk);
203 sk->sk_write_pending--;
204
192 if (sk->sk_err) 205 if (sk->sk_err)
193 goto do_error; 206 goto do_error;
194 if (signal_pending(current)) 207 if (signal_pending(current))
195 goto do_interrupted; 208 goto do_interrupted;
196 209
197 rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb); 210 rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);
198 if (rc <= 0) 211 } while ((delay = rc) > 0);
199 break;
200 dccp_pr_debug("delayed send by %d msec\n", rc);
201 delay = msecs_to_jiffies(rc);
202 sk->sk_write_pending++;
203 release_sock(sk);
204 schedule_timeout(delay);
205 lock_sock(sk);
206 sk->sk_write_pending--;
207 }
208out: 212out:
209 finish_wait(sk->sk_sleep, &wait); 213 finish_wait(sk->sk_sleep, &wait);
210 return rc; 214 return rc;
@@ -231,7 +235,7 @@ void dccp_write_xmit(struct sock *sk, int block)
231 msecs_to_jiffies(err)+jiffies); 235 msecs_to_jiffies(err)+jiffies);
232 break; 236 break;
233 } else 237 } else
234 err = dccp_wait_for_ccid(sk, skb); 238 err = dccp_wait_for_ccid(sk, skb, err);
235 if (err && err != -EINTR) 239 if (err && err != -EINTR)
236 DCCP_BUG("err=%d after dccp_wait_for_ccid", err); 240 DCCP_BUG("err=%d after dccp_wait_for_ccid", err);
237 } 241 }