diff options
Diffstat (limited to 'net/dccp')
-rw-r--r-- | net/dccp/output.c | 34 |
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 | */ |
182 | static int dccp_wait_for_ccid(struct sock *sk, struct sk_buff *skb) | 186 | static 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 | } | ||
208 | out: | 212 | out: |
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 | } |