From 44e921546471416e57574f9c00a8014864b60276 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Sun, 21 Oct 2007 11:20:33 +0000 Subject: * src/engine.c: Fix timeout calculations (struct timeout_ctl): New data type (UPDATE_TTW,smtp_stream_wait,smtp_wait): Operate on struct timeout_ctl. All callers updated. (init_timeout_ctl): New function. git-svn-id: file:///svnroot/mailfromd/trunk@1517 7a8a7f39-df28-0410-adc6-e0d955640f24 --- ChangeLog | 8 ++++++ src/engine.c | 79 +++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 54 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index ee51e4c7..c50cbd64 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2007-10-21 Sergey Poznyakoff + + * src/engine.c: Fix timeout calculations + (struct timeout_ctl): New data type + (UPDATE_TTW,smtp_stream_wait,smtp_wait): Operate on struct timeout_ctl. + All callers updated. + (init_timeout_ctl): New function. + 2007-10-12 Sergey Poznyakoff * src/mtasim.c (_def_read): Return 0 if zero bytes were read diff --git a/src/engine.c b/src/engine.c index 1801fdec..bb3fa18c 100644 --- a/src/engine.c +++ b/src/engine.c @@ -305,29 +305,42 @@ smtp_io_data_destroy(struct smtp_io_data *dat) } } -#define UPDATE_TTW(t,start) do { \ - time_t delta = time(NULL) - start; \ - if (t > delta) \ - t -= delta; \ +struct timeout_ctl { + time_t start; + time_t timeout; +}; + +static void +init_timeout_ctl(struct timeout_ctl *tctl, time_t timeout) +{ + tctl->start = time(NULL); + tctl->timeout = timeout; +} + +#define UPDATE_TTW(t) do { \ + time_t now = time(NULL); \ + time_t delta = now - (t).start; \ + if ((t).timeout > delta) \ + (t).timeout -= delta; \ else \ - t = 0; \ + (t).timeout = 0; \ + (t).start = now; \ } while (0) int -smtp_stream_wait(mu_stream_t stream, int flags, time_t *timeout) +smtp_stream_wait(mu_stream_t stream, int flags, struct timeout_ctl *tctl) { int rc; int oflags = flags; struct timeval tv; - time_t start = time(NULL); - while (*timeout) { - tv.tv_sec = *timeout; + while (tctl->timeout) { + tv.tv_sec = tctl->timeout; tv.tv_usec = 0; rc = mu_stream_wait(stream, &oflags, &tv); /* Correct the timeout */ - UPDATE_TTW(*timeout, start); + UPDATE_TTW(*tctl); switch (rc) { case 0: @@ -347,17 +360,18 @@ smtp_stream_wait(mu_stream_t stream, int flags, time_t *timeout) } int -smtp_wait(struct smtp_io_data *dat, int flags, time_t *timeout) +smtp_wait(struct smtp_io_data *dat, int flags, struct timeout_ctl *tctl) { - return smtp_stream_wait(dat->stream, flags, timeout); + return smtp_stream_wait(dat->stream, flags, tctl); } int smtp_send(struct smtp_io_data *dat, char *command) { size_t len = strlen(command); - time_t timeout = io_timeout; - time_t start = time(NULL); + struct timeout_ctl tctl; + + init_timeout_ctl (&tctl, io_timeout); dat->reply = NULL; /* Clear reply for logging purposes */ transcript(dat, "SEND:", command); @@ -365,7 +379,7 @@ smtp_send(struct smtp_io_data *dat, char *command) size_t nb; int rc; - UPDATE_TTW(timeout, start); + UPDATE_TTW(tctl); rc = mu_stream_write(dat->stream, command, len, dat->send_off, &nb); @@ -378,8 +392,7 @@ smtp_send(struct smtp_io_data *dat, char *command) len -= nb; command += nb; } else if (rc == EAGAIN) { - rc = smtp_wait(dat, MU_STREAM_READY_WR, - &timeout); + rc = smtp_wait(dat, MU_STREAM_READY_WR, &tctl); if (rc) { mu_error(_("smtp_wait failed: %s"), mu_strerror(rc)); @@ -424,13 +437,13 @@ smtp_send3(struct smtp_io_data *dat, char *command, char *arg1, char *arg2) int smtp_recvline(struct smtp_io_data *dat, time_t timeout) { - time_t start = time(NULL); - + struct timeout_ctl tctl; + init_timeout_ctl(&tctl, timeout); for (;;) { char *p; - UPDATE_TTW(timeout, start); - + UPDATE_TTW(tctl); + if (dat->level == 0) { int rc = mu_stream_read(dat->stream, dat->buf, sizeof dat->buf, @@ -443,8 +456,7 @@ smtp_recvline(struct smtp_io_data *dat, time_t timeout) dat->recv_off += dat->level; } else if (rc == EAGAIN) { rc = smtp_wait(dat, - MU_STREAM_READY_RD, - &timeout); + MU_STREAM_READY_RD, &tctl); if (rc) { mu_error(_("smtp_wait failed: %s"), mu_strerror(rc)); @@ -563,7 +575,7 @@ check_on_host(eval_environ_t env, char *email, char *client_addr, mf_status status = mf_success; int count = 0; SMFICTX *ctx = env_get_context(env); - time_t timeout, start = time(NULL); + struct timeout_ctl tctl; debug2(10, "email = %s, client_addr = %s", email, client_addr); @@ -578,15 +590,15 @@ check_on_host(eval_environ_t env, char *email, char *client_addr, mu_strerror (rc)); return mf_temp_failure; } - - timeout = connect_timeout; + + init_timeout_ctl(&tctl, connect_timeout); while ((rc = mu_stream_open(stream))) { if ((rc == EAGAIN || rc == EINPROGRESS) - && timeout) { + && tctl.timeout) { rc = smtp_stream_wait(stream, MU_STREAM_READY_WR, - &timeout); + &tctl); if (rc == 0) { - UPDATE_TTW(timeout, start); + UPDATE_TTW(tctl); continue; } } @@ -827,7 +839,7 @@ listens_on (const char *client_addr, int port) unsigned count = 0; mu_stream_t stream; int rc; - time_t timeout = connect_timeout, start = time(NULL); + struct timeout_ctl tctl; if (port == 0) port = 25; @@ -842,12 +854,13 @@ listens_on (const char *client_addr, int port) return mf_failure; } + init_timeout_ctl(&tctl, connect_timeout); while ((rc = mu_stream_open(stream))) { - if ((rc == EAGAIN || rc == EINPROGRESS) && timeout) { + if ((rc == EAGAIN || rc == EINPROGRESS) && tctl.timeout) { rc = smtp_stream_wait(stream, MU_STREAM_READY_WR, - &timeout); + &tctl); if (rc == 0) { - UPDATE_TTW(timeout, start); + UPDATE_TTW(tctl); continue; } } -- cgit v1.2.1