mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-19 11:42:27 +00:00
Merged revisions 89610 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r89610 | file | 2007-11-26 17:10:29 -0400 (Mon, 26 Nov 2007) | 2 lines Fix issues with async dialing with an application executing. The application has to be terminated and control returned to the thread before hanging things up. (issue #BE-252) ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@89612 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
29
main/dial.c
29
main/dial.c
@@ -58,6 +58,7 @@ struct ast_dial_channel {
|
|||||||
char *device; /*!< Device being dialed */
|
char *device; /*!< Device being dialed */
|
||||||
void *options[AST_DIAL_OPTION_MAX]; /*!< Channel specific options */
|
void *options[AST_DIAL_OPTION_MAX]; /*!< Channel specific options */
|
||||||
int cause; /*!< Cause code in case of failure */
|
int cause; /*!< Cause code in case of failure */
|
||||||
|
int is_running_app:1; /*!< Is this running an application? */
|
||||||
struct ast_channel *owner; /*!< Asterisk channel */
|
struct ast_channel *owner; /*!< Asterisk channel */
|
||||||
AST_LIST_ENTRY(ast_dial_channel) list; /*!< Linked list information */
|
AST_LIST_ENTRY(ast_dial_channel) list; /*!< Linked list information */
|
||||||
};
|
};
|
||||||
@@ -135,8 +136,9 @@ static int music_disable(void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Application execution function for 'ANSWER_EXEC' option */
|
/*! \brief Application execution function for 'ANSWER_EXEC' option */
|
||||||
static void answer_exec_run(struct ast_channel *chan, char *app, char *args)
|
static void answer_exec_run(struct ast_dial *dial, struct ast_dial_channel *dial_channel, char *app, char *args)
|
||||||
{
|
{
|
||||||
|
struct ast_channel *chan = dial_channel->owner;
|
||||||
struct ast_app *ast_app = pbx_findapp(app);
|
struct ast_app *ast_app = pbx_findapp(app);
|
||||||
|
|
||||||
/* If the application was not found, return immediately */
|
/* If the application was not found, return immediately */
|
||||||
@@ -146,6 +148,12 @@ static void answer_exec_run(struct ast_channel *chan, char *app, char *args)
|
|||||||
/* All is well... execute the application */
|
/* All is well... execute the application */
|
||||||
pbx_exec(chan, ast_app, args);
|
pbx_exec(chan, ast_app, args);
|
||||||
|
|
||||||
|
/* If another thread is not taking over hang up the channel */
|
||||||
|
if (dial->thread != AST_PTHREADT_STOP) {
|
||||||
|
ast_hangup(chan);
|
||||||
|
dial_channel->owner = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -619,8 +627,11 @@ static enum ast_dial_result monitor_dial(struct ast_dial *dial, struct ast_chann
|
|||||||
channel->owner = NULL;
|
channel->owner = NULL;
|
||||||
}
|
}
|
||||||
/* If ANSWER_EXEC is enabled as an option, execute application on answered channel */
|
/* If ANSWER_EXEC is enabled as an option, execute application on answered channel */
|
||||||
if ((channel = find_relative_dial_channel(dial, who)) && (answer_exec = FIND_RELATIVE_OPTION(dial, channel, AST_DIAL_OPTION_ANSWER_EXEC)))
|
if ((channel = find_relative_dial_channel(dial, who)) && (answer_exec = FIND_RELATIVE_OPTION(dial, channel, AST_DIAL_OPTION_ANSWER_EXEC))) {
|
||||||
answer_exec_run(who, answer_exec->app, answer_exec->args);
|
channel->is_running_app = 1;
|
||||||
|
answer_exec_run(dial, channel, answer_exec->app, answer_exec->args);
|
||||||
|
channel->is_running_app = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (chan && dial->options[AST_DIAL_OPTION_MUSIC] &&
|
if (chan && dial->options[AST_DIAL_OPTION_MUSIC] &&
|
||||||
!ast_strlen_zero(dial->options[AST_DIAL_OPTION_MUSIC])) {
|
!ast_strlen_zero(dial->options[AST_DIAL_OPTION_MUSIC])) {
|
||||||
@@ -731,8 +742,16 @@ enum ast_dial_result ast_dial_join(struct ast_dial *dial)
|
|||||||
/* Stop the thread */
|
/* Stop the thread */
|
||||||
dial->thread = AST_PTHREADT_STOP;
|
dial->thread = AST_PTHREADT_STOP;
|
||||||
|
|
||||||
/* Now we signal it with SIGURG so it will break out of it's waitfor */
|
/* If the answered channel is running an application we have to soft hangup it, can't just poke the thread */
|
||||||
pthread_kill(thread, SIGURG);
|
if (AST_LIST_FIRST(&dial->channels)->is_running_app) {
|
||||||
|
struct ast_channel *chan = AST_LIST_FIRST(&dial->channels)->owner;
|
||||||
|
ast_channel_lock(chan);
|
||||||
|
ast_softhangup(chan, AST_SOFTHANGUP_EXPLICIT);
|
||||||
|
ast_channel_unlock(chan);
|
||||||
|
} else {
|
||||||
|
/* Now we signal it with SIGURG so it will break out of it's waitfor */
|
||||||
|
pthread_kill(thread, SIGURG);
|
||||||
|
}
|
||||||
|
|
||||||
/* Finally wait for the thread to exit */
|
/* Finally wait for the thread to exit */
|
||||||
pthread_join(thread, NULL);
|
pthread_join(thread, NULL);
|
||||||
|
Reference in New Issue
Block a user