mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-30 02:26:23 +00:00
Correctly handle call flow with outgoing queue, avoiding retries while call acti
ve (bug #1018) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2505 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -65,7 +65,7 @@ int fully_booted = 0;
|
|||||||
|
|
||||||
static int ast_socket = -1; /* UNIX Socket for allowing remote control */
|
static int ast_socket = -1; /* UNIX Socket for allowing remote control */
|
||||||
static int ast_consock = -1; /* UNIX Socket for controlling another asterisk */
|
static int ast_consock = -1; /* UNIX Socket for controlling another asterisk */
|
||||||
static int mainpid;
|
int ast_mainpid;
|
||||||
struct console {
|
struct console {
|
||||||
int fd; /* File descriptor */
|
int fd; /* File descriptor */
|
||||||
int p[2]; /* Pipe */
|
int p[2]; /* Pipe */
|
||||||
@@ -196,7 +196,7 @@ static void *netconsole(void *vconsole)
|
|||||||
|
|
||||||
if (gethostname(hostname, sizeof(hostname)))
|
if (gethostname(hostname, sizeof(hostname)))
|
||||||
strncpy(hostname, "<Unknown>", sizeof(hostname)-1);
|
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);
|
fdprint(con->fd, tmp);
|
||||||
for(;;) {
|
for(;;) {
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
@@ -1271,7 +1271,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
if (gethostname(hostname, sizeof(hostname)))
|
if (gethostname(hostname, sizeof(hostname)))
|
||||||
strncpy(hostname, "<Unknown>", sizeof(hostname)-1);
|
strncpy(hostname, "<Unknown>", sizeof(hostname)-1);
|
||||||
mainpid = getpid();
|
ast_mainpid = getpid();
|
||||||
ast_ulaw_init();
|
ast_ulaw_init();
|
||||||
ast_alaw_init();
|
ast_alaw_init();
|
||||||
callerid_init();
|
callerid_init();
|
||||||
@@ -1500,7 +1500,7 @@ int main(int argc, char *argv[])
|
|||||||
/* Register our quit function */
|
/* Register our quit function */
|
||||||
char title[256];
|
char title[256];
|
||||||
set_icon("Asterisk");
|
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);
|
set_title(title);
|
||||||
ast_cli_register(&quit);
|
ast_cli_register(&quit);
|
||||||
ast_cli_register(&astexit);
|
ast_cli_register(&astexit);
|
||||||
|
@@ -29,6 +29,7 @@ extern int fully_booted;
|
|||||||
extern char defaultlanguage[];
|
extern char defaultlanguage[];
|
||||||
extern time_t ast_startuptime;
|
extern time_t ast_startuptime;
|
||||||
extern time_t ast_lastreloadtime;
|
extern time_t ast_lastreloadtime;
|
||||||
|
extern int ast_mainpid;
|
||||||
|
|
||||||
#define VERBOSE_PREFIX_1 " "
|
#define VERBOSE_PREFIX_1 " "
|
||||||
#define VERBOSE_PREFIX_2 " == "
|
#define VERBOSE_PREFIX_2 " == "
|
||||||
|
@@ -50,6 +50,8 @@ struct outgoing {
|
|||||||
int retrytime;
|
int retrytime;
|
||||||
/* How long to wait for an answer */
|
/* How long to wait for an answer */
|
||||||
int waittime;
|
int waittime;
|
||||||
|
/* PID which is currently calling */
|
||||||
|
int callingpid;
|
||||||
|
|
||||||
/* What to connect to outgoing */
|
/* What to connect to outgoing */
|
||||||
char tech[256];
|
char tech[256];
|
||||||
@@ -157,6 +159,14 @@ static int apply_outgoing(struct outgoing *o, char *fn, FILE *f)
|
|||||||
}
|
}
|
||||||
} else if (!strcasecmp(buf, "retry")) {
|
} else if (!strcasecmp(buf, "retry")) {
|
||||||
o->retries++;
|
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 */
|
} else if (!strcasecmp(buf, "setvar")) { /* JDG variable support */
|
||||||
strncat(o->variable, c, sizeof(o->variable) - strlen(o->variable) - 1);
|
strncat(o->variable, c, sizeof(o->variable) - strlen(o->variable) - 1);
|
||||||
strncat(o->variable, "|", 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;
|
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)
|
static void *attempt_thread(void *data)
|
||||||
{
|
{
|
||||||
struct outgoing *o = data;
|
struct outgoing *o = data;
|
||||||
@@ -201,6 +226,9 @@ static void *attempt_thread(void *data)
|
|||||||
/* Max retries exceeded */
|
/* 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);
|
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);
|
unlink(o->fn);
|
||||||
|
} else {
|
||||||
|
/* Notate that the call is still active */
|
||||||
|
safe_append(o, time(NULL), "EndRetry");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ast_log(LOG_NOTICE, "Call completed to %s/%s\n", o->tech, o->dest);
|
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+");
|
f = fopen(fn, "r+");
|
||||||
if (f) {
|
if (f) {
|
||||||
if (!apply_outgoing(o, fn, f)) {
|
if (!apply_outgoing(o, fn, f)) {
|
||||||
/* Increment retries */
|
|
||||||
o->retries++;
|
|
||||||
#if 0
|
#if 0
|
||||||
printf("Retries: %d, max: %d\n", o->retries, o->maxretries);
|
printf("Retries: %d, max: %d\n", o->retries, o->maxretries);
|
||||||
#endif
|
#endif
|
||||||
if (o->retries <= o->maxretries + 1) {
|
if (o->retries <= o->maxretries) {
|
||||||
/* Add a retry line at the end */
|
if (o->callingpid && (o->callingpid == ast_mainpid)) {
|
||||||
fseek(f, 0L, SEEK_END);
|
ast_log(LOG_DEBUG, "Delaying retry since we're currently running '%s'\n", o->fn);
|
||||||
fprintf(f, "Retry: %d (%ld)\n", o->retries, (long) now);
|
} else {
|
||||||
fclose(f);
|
/* 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 */
|
/* Update the file time */
|
||||||
tbuf.actime = atime;
|
tbuf.actime = atime;
|
||||||
tbuf.modtime = now + o->retrytime;
|
tbuf.modtime = now + o->retrytime;
|
||||||
if (utime(o->fn, &tbuf))
|
if (utime(o->fn, &tbuf))
|
||||||
ast_log(LOG_WARNING, "Unable to set utime on %s: %s\n", fn, strerror(errno));
|
ast_log(LOG_WARNING, "Unable to set utime on %s: %s\n", fn, strerror(errno));
|
||||||
now += o->retrytime;
|
now += o->retrytime;
|
||||||
launch_service(o);
|
|
||||||
return now;
|
return now;
|
||||||
} else {
|
} 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);
|
ast_log(LOG_EVENT, "Queued call to %s/%s expired without completion after %d attempt(s)\n", o->tech, o->dest, o->retries - 1);
|
||||||
|
Reference in New Issue
Block a user