181 | 181 |
case FETCH_AGAIN:
|
182 | 182 |
/* delivering mail, queue for delivery */
|
183 | 183 |
log_debug3("%s: adding to deliver queue", a->name);
|
184 | |
TAILQ_REMOVE(&matchq, mctx, match_entry);
|
185 | |
TAILQ_INSERT_TAIL(&deliverq, mctx, deliver_entry);
|
|
184 |
TAILQ_REMOVE(&matchq, mctx, entry);
|
|
185 |
TAILQ_INSERT_TAIL(&deliverq, mctx, entry);
|
186 | 186 |
break;
|
187 | 187 |
case FETCH_COMPLETE:
|
188 | 188 |
/* finished with mail, queue on done queue */
|
189 | 189 |
log_debug3("%s: adding to done queue", a->name);
|
190 | |
TAILQ_REMOVE(&matchq, mctx, match_entry);
|
191 | |
TAILQ_INSERT_TAIL(&doneq, mctx, done_entry);
|
|
190 |
TAILQ_REMOVE(&matchq, mctx, entry);
|
|
191 |
TAILQ_INSERT_TAIL(&doneq, mctx, entry);
|
|
192 |
|
|
193 |
/*
|
|
194 |
* XXX Destroy mail data now it is finished, just keep the
|
|
195 |
* struct mail.
|
|
196 |
*/
|
|
197 |
shm_destroy(&mctx->mail->shm);
|
192 | 198 |
break;
|
193 | 199 |
}
|
194 | 200 |
|
|
212 | 218 |
if (TAILQ_EMPTY(&mctx->dqueue)) {
|
213 | 219 |
/* delivery done. return to match queue */
|
214 | 220 |
log_debug3("%s: returning to match queue", a->name);
|
215 | |
TAILQ_REMOVE(&deliverq, mctx, deliver_entry);
|
216 | |
TAILQ_INSERT_TAIL(&matchq, mctx, match_entry);
|
|
221 |
TAILQ_REMOVE(&deliverq, mctx, entry);
|
|
222 |
TAILQ_INSERT_TAIL(&matchq, mctx, entry);
|
217 | 223 |
return (0);
|
218 | 224 |
}
|
219 | 225 |
|
|
252 | 258 |
|
253 | 259 |
remove:
|
254 | 260 |
TAILQ_REMOVE(&mctx->dqueue, dctx, entry);
|
|
261 |
log_debug("%s: message %u delivered (rule %u) after %.3f seconds",
|
|
262 |
a->name, mctx->mail->idx, dctx->rule->idx, get_time() - dctx->tim);
|
255 | 263 |
xfree(dctx);
|
256 | 264 |
return (0);
|
257 | 265 |
}
|
|
271 | 279 |
m = mctx->mail;
|
272 | 280 |
log_debug3("%s: running done queue", a->name);
|
273 | 281 |
|
274 | |
TAILQ_REMOVE(&doneq, mctx, done_entry);
|
|
282 |
TAILQ_REMOVE(&doneq, mctx, entry);
|
275 | 283 |
ARRAY_FREE(&mctx->stack);
|
|
284 |
log_debug("%s: message %u done after %.3f seconds", a->name, m->idx,
|
|
285 |
get_time() - mctx->tim);
|
276 | 286 |
xfree(mctx);
|
277 | 287 |
|
278 | 288 |
if (mctx->account->fetch->done != NULL) {
|
|
312 | 322 |
mctx = TAILQ_FIRST(mq);
|
313 | 323 |
m = mctx->mail;
|
314 | 324 |
|
315 | |
TAILQ_REMOVE(mq, mctx, done_entry);
|
|
325 |
TAILQ_REMOVE(mq, mctx, entry);
|
316 | 326 |
ARRAY_FREE(&mctx->stack);
|
317 | 327 |
xfree(mctx);
|
318 | 328 |
|
|
406 | 416 |
fetch_account(struct io *pio, struct account *a, struct ios *ios, double tim)
|
407 | 417 |
{
|
408 | 418 |
struct mail *m;
|
409 | |
u_int n, dropped, kept;
|
410 | |
int error, blocked;
|
|
419 |
u_int n, dropped, kept, total;
|
|
420 |
int error, blocked, holding;
|
411 | 421 |
const char *cause = NULL;
|
412 | 422 |
struct match_ctx *mctx;
|
413 | 423 |
struct io *rio;
|
|
430 | 440 |
/* fetch a message */
|
431 | 441 |
error = FETCH_AGAIN;
|
432 | 442 |
rio = NULL;
|
|
443 |
holding = 0;
|
433 | 444 |
while (error == FETCH_AGAIN) {
|
434 | 445 |
log_debug3("%s: queue lengths: match %u, deliver %u, "
|
435 | |
"done %u; blocked=%d", a->name,
|
|
446 |
"done %u; blocked=%d; holding=%d", a->name,
|
436 | 447 |
queue_length(&matchq), queue_length(&deliverq),
|
437 | |
queue_length(&doneq), blocked);
|
438 | |
|
439 | |
if (rio != pio) {
|
440 | |
error = a->fetch->fetch(a, m);
|
441 | |
switch (error) {
|
442 | |
case FETCH_ERROR:
|
443 | |
if (rio == pio)
|
|
448 |
queue_length(&doneq), blocked, holding);
|
|
449 |
|
|
450 |
total = queue_length(&matchq) + queue_length(&deliverq);
|
|
451 |
if (total >= MAXMAILQUEUED)
|
|
452 |
holding = 1;
|
|
453 |
if (total < MINMAILQUEUED)
|
|
454 |
holding = 0;
|
|
455 |
|
|
456 |
if (!holding) {
|
|
457 |
if (rio != pio) {
|
|
458 |
error = a->fetch->fetch(a, m);
|
|
459 |
switch (error) {
|
|
460 |
case FETCH_ERROR:
|
|
461 |
if (rio != pio) {
|
|
462 |
cause = "fetching";
|
|
463 |
goto out;
|
|
464 |
}
|
444 | 465 |
fatalx("child: lost parent");
|
445 | |
cause = "fetching";
|
446 | |
goto out;
|
447 | |
case FETCH_COMPLETE:
|
448 | |
goto out;
|
|
466 |
case FETCH_COMPLETE:
|
|
467 |
goto out;
|
|
468 |
}
|
449 | 469 |
}
|
450 | 470 |
}
|
451 | 471 |
if (error == FETCH_AGAIN) {
|
452 | 472 |
if (fetch_poll(a, blocked, ios, &rio) != 0)
|
453 | 473 |
goto out;
|
454 | 474 |
}
|
455 | |
|
|
475 |
|
456 | 476 |
if (run_match(a, &cause) != 0)
|
457 | 477 |
goto out;
|
458 | 478 |
if (run_deliver(a, pio, &blocked, &cause) != 0)
|
|
485 | 505 |
|
486 | 506 |
/* construct mctx */
|
487 | 507 |
mctx = xcalloc(1, sizeof *mctx);
|
|
508 |
mctx->tim = get_time();
|
488 | 509 |
mctx->io = pio;
|
489 | 510 |
mctx->account = a;
|
490 | 511 |
mctx->mail = m;
|
|
496 | 517 |
|
497 | 518 |
/* and queue it */
|
498 | 519 |
log_debug3("%s: adding to match queue", a->name);
|
499 | |
TAILQ_INSERT_TAIL(&matchq, mctx, match_entry);
|
|
520 |
TAILQ_INSERT_TAIL(&matchq, mctx, entry);
|
500 | 521 |
|
501 | 522 |
/* finish up a done mail */
|
502 | 523 |
if (run_done(a, &dropped, &kept, &cause) != 0)
|
503 | 524 |
goto out;
|
|
525 |
if (queue_length(&doneq) > MAXMAILQUEUED) {
|
|
526 |
while (queue_length(&doneq) > MINMAILQUEUED) {
|
|
527 |
if (run_done(a, &dropped, &kept, &cause) != 0)
|
|
528 |
goto out;
|
|
529 |
}
|
|
530 |
}
|
504 | 531 |
|
505 | 532 |
if (conf.purge_after == 0 || a->fetch->purge == NULL)
|
506 | 533 |
continue;
|
|
872 | 899 |
struct mail *m = dctx->mail;
|
873 | 900 |
struct msg msg;
|
874 | 901 |
|
|
902 |
dctx->tim = get_time();
|
875 | 903 |
if (t->deliver->deliver == NULL)
|
876 | 904 |
return (0);
|
877 | 905 |
|