diff options
author | russell <russell@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-12-22 17:30:05 +0000 |
---|---|---|
committer | russell <russell@f38db490-d61c-443f-a65b-d21fe96a405b> | 2008-12-22 17:30:05 +0000 |
commit | 9ff7b3fdc5333d6285ecd3dd8dcd43346c063158 (patch) | |
tree | 62edfebbd60dfca2ee34e0cbfe7ea6998c337cc4 /main/utils.c | |
parent | 85f332e26795d8332807f092512f9a9d6596e526 (diff) |
Merged revisions 166317 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk
................
r166317 | russell | 2008-12-22 11:29:10 -0600 (Mon, 22 Dec 2008) | 10 lines
Merged revisions 166297 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r166297 | russell | 2008-12-22 11:22:56 -0600 (Mon, 22 Dec 2008) | 2 lines
Fix up timeout handling in ast_carefulwrite().
........
................
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.0@166319 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/utils.c')
-rw-r--r-- | main/utils.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/main/utils.c b/main/utils.c index 35efa6342..54175eae2 100644 --- a/main/utils.c +++ b/main/utils.c @@ -957,9 +957,11 @@ static int ast_wait_for_output(int fd, int timeoutms) .events = POLLOUT, }; int res; + struct timeval start = ast_tvnow(); + int elapsed = 0; /* poll() until the fd is writable without blocking */ - while ((res = poll(&pfd, 1, timeoutms)) <= 0) { + while ((res = poll(&pfd, 1, timeoutms - elapsed)) <= 0) { if (res == 0) { /* timed out. */ ast_log(LOG_NOTICE, "Timed out trying to write\n"); @@ -968,6 +970,10 @@ static int ast_wait_for_output(int fd, int timeoutms) /* poll() returned an error, check to see if it was fatal */ if (errno == EINTR || errno == EAGAIN) { + elapsed = ast_tvdiff_ms(ast_tvnow(), start); + if (elapsed >= timeoutms) { + return -1; + } /* This was an acceptable error, go back into poll() */ continue; } @@ -977,6 +983,10 @@ static int ast_wait_for_output(int fd, int timeoutms) return -1; } + elapsed = ast_tvdiff_ms(ast_tvnow(), start); + if (elapsed >= timeoutms) { + return -1; + } } return 0; @@ -990,19 +1000,15 @@ static int ast_wait_for_output(int fd, int timeoutms) * have a need to wait. This way, we get better performance. * If the descriptor is blocking, all assumptions on the guaranteed * detail do not apply anymore. - * Also note that in the current implementation, the delay is per-write, - * so you still have no guarantees, anyways. - * Fortunately the routine is only used in a few places (cli.c, manager.c, - * res_agi.c) so it is reasonably easy to check how it behaves there. - * - * XXX We either need to fix the code, or fix the documentation. */ int ast_carefulwrite(int fd, char *s, int len, int timeoutms) { + struct timeval start = ast_tvnow(); int res = 0; + int elapsed = 0; while (len) { - if (ast_wait_for_output(fd, timeoutms)) { + if (ast_wait_for_output(fd, timeoutms - elapsed)) { return -1; } @@ -1023,6 +1029,14 @@ int ast_carefulwrite(int fd, char *s, int len, int timeoutms) len -= res; s += res; res = 0; + + elapsed = ast_tvdiff_ms(ast_tvnow(), start); + if (elapsed >= timeoutms) { + /* We've taken too long to write + * This is only an error condition if we haven't finished writing. */ + res = len ? -1 : 0; + break; + } } return res; @@ -1032,11 +1046,10 @@ int ast_careful_fwrite(FILE *f, int fd, const char *src, size_t len, int timeout { struct timeval start = ast_tvnow(); int n = 0; + int elapsed = 0; while (len) { - int elapsed; - - if (ast_wait_for_output(fd, timeoutms)) { + if (ast_wait_for_output(fd, timeoutms - elapsed)) { /* poll returned a fatal error, so bail out immediately. */ return -1; } @@ -1061,7 +1074,7 @@ int ast_careful_fwrite(FILE *f, int fd, const char *src, size_t len, int timeout src += n; elapsed = ast_tvdiff_ms(ast_tvnow(), start); - if (elapsed > timeoutms) { + if (elapsed >= timeoutms) { /* We've taken too long to write * This is only an error condition if we haven't finished writing. */ n = len ? -1 : 0; |