aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--src/engine.c79
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 <gray@gnu.org.ua>
+
+ * 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 <gray@gnu.org.ua>
* 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;
}
}

Return to:

Send suggestions and report system problems to the System administrator.