aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2008-12-22 17:30:05 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2008-12-22 17:30:05 +0000
commit9ff7b3fdc5333d6285ecd3dd8dcd43346c063158 (patch)
tree62edfebbd60dfca2ee34e0cbfe7ea6998c337cc4 /main
parent85f332e26795d8332807f092512f9a9d6596e526 (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')
-rw-r--r--main/utils.c37
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;