diff options
author | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-03-20 21:13:12 +0000 |
---|---|---|
committer | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-03-20 21:13:12 +0000 |
commit | c9b1bd8b5213b9309b16cb6f42a757b3e79acd3e (patch) | |
tree | c5e9ec5c15030b6db441050607a0947058c4a9ff | |
parent | 87e7c952733a6fc60f1f348be3465ec4b8489ab6 (diff) |
Correctly handle call flow with outgoing queue, avoiding retries while call acti
ve (bug #1018)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@2505 f38db490-d61c-443f-a65b-d21fe96a405b
-rwxr-xr-x | asterisk.c | 8 | ||||
-rwxr-xr-x | include/asterisk/options.h | 1 | ||||
-rwxr-xr-x | pbx/pbx_spool.c | 53 |
3 files changed, 50 insertions, 12 deletions
diff --git a/asterisk.c b/asterisk.c index 9cff2c73d..2811a7cad 100755 --- a/asterisk.c +++ b/asterisk.c @@ -65,7 +65,7 @@ int fully_booted = 0; static int ast_socket = -1; /* UNIX Socket for allowing remote control */ static int ast_consock = -1; /* UNIX Socket for controlling another asterisk */ -static int mainpid; +int ast_mainpid; struct console { int fd; /* File descriptor */ int p[2]; /* Pipe */ @@ -196,7 +196,7 @@ static void *netconsole(void *vconsole) if (gethostname(hostname, sizeof(hostname))) strncpy(hostname, "<Unknown>", sizeof(hostname)-1); - snprintf(tmp, sizeof(tmp), "%s/%d/%s\n", hostname, mainpid, ASTERISK_VERSION); + snprintf(tmp, sizeof(tmp), "%s/%d/%s\n", hostname, ast_mainpid, ASTERISK_VERSION); fdprint(con->fd, tmp); for(;;) { FD_ZERO(&rfds); @@ -1271,7 +1271,7 @@ int main(int argc, char *argv[]) } if (gethostname(hostname, sizeof(hostname))) strncpy(hostname, "<Unknown>", sizeof(hostname)-1); - mainpid = getpid(); + ast_mainpid = getpid(); ast_ulaw_init(); ast_alaw_init(); callerid_init(); @@ -1500,7 +1500,7 @@ int main(int argc, char *argv[]) /* Register our quit function */ char title[256]; set_icon("Asterisk"); - snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %d)", hostname, mainpid); + snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %d)", hostname, ast_mainpid); set_title(title); ast_cli_register(&quit); ast_cli_register(&astexit); diff --git a/include/asterisk/options.h b/include/asterisk/options.h index f9314bb1f..22a84138b 100755 --- a/include/asterisk/options.h +++ b/include/asterisk/options.h @@ -29,6 +29,7 @@ extern int fully_booted; extern char defaultlanguage[]; extern time_t ast_startuptime; extern time_t ast_lastreloadtime; +extern int ast_mainpid; #define VERBOSE_PREFIX_1 " " #define VERBOSE_PREFIX_2 " == " diff --git a/pbx/pbx_spool.c b/pbx/pbx_spool.c index ef367855a..d5e2b960f 100755 --- a/pbx/pbx_spool.c +++ b/pbx/pbx_spool.c @@ -50,6 +50,8 @@ struct outgoing { int retrytime; /* How long to wait for an answer */ int waittime; + /* PID which is currently calling */ + int callingpid; /* What to connect to outgoing */ char tech[256]; @@ -157,6 +159,14 @@ static int apply_outgoing(struct outgoing *o, char *fn, FILE *f) } } else if (!strcasecmp(buf, "retry")) { o->retries++; + } else if (!strcasecmp(buf, "startretry")) { + if (sscanf(c, "%d", &o->callingpid) != 1) { + ast_log(LOG_WARNING, "Unable to retrieve calling PID!\n"); + o->callingpid = 0; + } + } else if (!strcasecmp(buf, "endretry") || !strcasecmp(buf, "abortretry")) { + o->callingpid = 0; + o->retries++; } else if (!strcasecmp(buf, "setvar")) { /* JDG variable support */ strncat(o->variable, c, sizeof(o->variable) - strlen(o->variable) - 1); strncat(o->variable, "|", sizeof(o->variable) - strlen(o->variable) - 1); @@ -182,6 +192,21 @@ static int apply_outgoing(struct outgoing *o, char *fn, FILE *f) return 0; } +static void safe_append(struct outgoing *o, time_t now, char *s) +{ + int fd; + FILE *f; + fd = open(o->fn, O_WRONLY|O_APPEND); + if (fd > -1) { + f = fdopen(fd, "a"); + if (f) { + fprintf(f, "%s: %d (%ld) (%ld)\n", s, o->retries, (long)ast_mainpid, (long) now); + fclose(f); + } else + close(fd); + } +} + static void *attempt_thread(void *data) { struct outgoing *o = data; @@ -201,6 +226,9 @@ static void *attempt_thread(void *data) /* Max retries exceeded */ ast_log(LOG_EVENT, "Queued call to %s/%s expired without completion after %d attempt(s)\n", o->tech, o->dest, o->retries - 1); unlink(o->fn); + } else { + /* Notate that the call is still active */ + safe_append(o, time(NULL), "EndRetry"); } } else { ast_log(LOG_NOTICE, "Call completed to %s/%s\n", o->tech, o->dest); @@ -234,23 +262,32 @@ static int scan_service(char *fn, time_t now, time_t atime) f = fopen(fn, "r+"); if (f) { if (!apply_outgoing(o, fn, f)) { - /* Increment retries */ - o->retries++; #if 0 printf("Retries: %d, max: %d\n", o->retries, o->maxretries); #endif - if (o->retries <= o->maxretries + 1) { - /* Add a retry line at the end */ - fseek(f, 0L, SEEK_END); - fprintf(f, "Retry: %d (%ld)\n", o->retries, (long) now); - fclose(f); + if (o->retries <= o->maxretries) { + if (o->callingpid && (o->callingpid == ast_mainpid)) { + ast_log(LOG_DEBUG, "Delaying retry since we're currently running '%s'\n", o->fn); + } else { + /* Increment retries */ + o->retries++; + /* If someone else was calling, they're presumably gone now + so abort their retry and continue as we were... */ + if (o->callingpid) + safe_append(o, time(NULL), "AbortRetry"); + + /* Add a retry line at the end */ + fseek(f, 0L, SEEK_END); + fprintf(f, "StartRetry: %d %d (%ld)\n", ast_mainpid, o->retries, (long) now); + fclose(f); + launch_service(o); + } /* Update the file time */ tbuf.actime = atime; tbuf.modtime = now + o->retrytime; if (utime(o->fn, &tbuf)) ast_log(LOG_WARNING, "Unable to set utime on %s: %s\n", fn, strerror(errno)); now += o->retrytime; - launch_service(o); return now; } else { ast_log(LOG_EVENT, "Queued call to %s/%s expired without completion after %d attempt(s)\n", o->tech, o->dest, o->retries - 1); |