| 43 |
|
|
| 44 |
|
|
| 45 |
|
struct Callback *iosend_cb = NULL; |
| 46 |
– |
struct Callback *iosendctrl_cb = NULL; |
| 46 |
|
static unsigned int current_serial = 0; |
| 47 |
|
|
| 48 |
|
|
| 221 |
|
} |
| 222 |
|
|
| 223 |
|
/* |
| 225 |
– |
** slinkq_unblocked |
| 226 |
– |
** Called when a server control socket is ready for writing. |
| 227 |
– |
*/ |
| 228 |
– |
static void |
| 229 |
– |
slinkq_unblocked(fde_t *fd, struct Client *client_p) |
| 230 |
– |
{ |
| 231 |
– |
ClearSlinkqBlocked(client_p); |
| 232 |
– |
send_queued_slink_write(client_p); |
| 233 |
– |
} |
| 234 |
– |
|
| 235 |
– |
/* |
| 224 |
|
** send_queued_write |
| 225 |
|
** This is called when there is a chance that some output would |
| 226 |
|
** be possible. This attempts to empty the send queue as far as |
| 297 |
|
} |
| 298 |
|
} |
| 299 |
|
} |
| 312 |
– |
|
| 313 |
– |
/* |
| 314 |
– |
** send_queued_slink_write |
| 315 |
– |
** This is called when there is a chance the some output would |
| 316 |
– |
** be possible. This attempts to empty the send queue as far as |
| 317 |
– |
** possible, and then if any data is left, a write is rescheduled. |
| 318 |
– |
*/ |
| 319 |
– |
void |
| 320 |
– |
send_queued_slink_write(struct Client *to) |
| 321 |
– |
{ |
| 322 |
– |
int retlen; |
| 323 |
– |
|
| 324 |
– |
/* |
| 325 |
– |
** Once socket is marked dead, we cannot start writing to it, |
| 326 |
– |
** even if the error is removed... |
| 327 |
– |
*/ |
| 328 |
– |
if (IsDead(to) || IsSlinkqBlocked(to)) |
| 329 |
– |
return; /* no use calling send() now */ |
| 330 |
– |
|
| 331 |
– |
/* Next, lets try to write some data */ |
| 332 |
– |
if (to->localClient->slinkq != NULL) |
| 333 |
– |
{ |
| 334 |
– |
retlen = send(to->localClient->ctrlfd.fd, |
| 335 |
– |
to->localClient->slinkq + to->localClient->slinkq_ofs, |
| 336 |
– |
to->localClient->slinkq_len, 0); |
| 337 |
– |
if (retlen < 0) |
| 338 |
– |
{ |
| 339 |
– |
/* If we have a fatal error */ |
| 340 |
– |
if (!ignoreErrno(errno)) |
| 341 |
– |
{ |
| 342 |
– |
dead_link_on_write(to, errno); |
| 343 |
– |
return; |
| 344 |
– |
} |
| 345 |
– |
} |
| 346 |
– |
else if (retlen == 0) |
| 347 |
– |
{ |
| 348 |
– |
/* 0 bytes is an EOF .. */ |
| 349 |
– |
dead_link_on_write(to, 0); |
| 350 |
– |
return; |
| 351 |
– |
} |
| 352 |
– |
else |
| 353 |
– |
{ |
| 354 |
– |
execute_callback(iosendctrl_cb, to, retlen, |
| 355 |
– |
to->localClient->slinkq + to->localClient->slinkq_ofs); |
| 356 |
– |
to->localClient->slinkq_len -= retlen; |
| 357 |
– |
|
| 358 |
– |
assert(to->localClient->slinkq_len >= 0); |
| 359 |
– |
if (to->localClient->slinkq_len) |
| 360 |
– |
to->localClient->slinkq_ofs += retlen; |
| 361 |
– |
else |
| 362 |
– |
{ |
| 363 |
– |
to->localClient->slinkq_ofs = 0; |
| 364 |
– |
MyFree(to->localClient->slinkq); |
| 365 |
– |
to->localClient->slinkq = NULL; |
| 366 |
– |
} |
| 367 |
– |
} |
| 368 |
– |
|
| 369 |
– |
/* Finally, if we have any more data, reschedule a write */ |
| 370 |
– |
if (to->localClient->slinkq_len) |
| 371 |
– |
{ |
| 372 |
– |
SetSlinkqBlocked(to); |
| 373 |
– |
comm_setselect(&to->localClient->ctrlfd, COMM_SELECT_WRITE, |
| 374 |
– |
(PF *)slinkq_unblocked, (void *)to, 0); |
| 375 |
– |
} |
| 376 |
– |
} |
| 377 |
– |
} |
| 300 |
|
|
| 301 |
|
/* send_queued_all() |
| 302 |
|
* |