mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-04 20:04:50 +00:00
Merge "pbx: Use same thread if AST_OUTGOING_WAIT_COMPLETE specified"
This commit is contained in:
80
main/pbx.c
80
main/pbx.c
@@ -7529,8 +7529,8 @@ struct pbx_outgoing {
|
||||
int dial_res;
|
||||
/*! \brief Set when dialing is completed */
|
||||
unsigned int dialed:1;
|
||||
/*! \brief Set when execution is completed */
|
||||
unsigned int executed:1;
|
||||
/*! \brief Set if we've spawned a thread to do our work */
|
||||
unsigned int in_separate_thread:1;
|
||||
};
|
||||
|
||||
/*! \brief Destructor for outgoing structure */
|
||||
@@ -7553,13 +7553,19 @@ static void *pbx_outgoing_exec(void *data)
|
||||
RAII_VAR(struct pbx_outgoing *, outgoing, data, ao2_cleanup);
|
||||
enum ast_dial_result res;
|
||||
|
||||
/* Notify anyone interested that dialing is complete */
|
||||
res = ast_dial_run(outgoing->dial, NULL, 0);
|
||||
ao2_lock(outgoing);
|
||||
outgoing->dial_res = res;
|
||||
outgoing->dialed = 1;
|
||||
ast_cond_signal(&outgoing->cond);
|
||||
ao2_unlock(outgoing);
|
||||
|
||||
if (outgoing->in_separate_thread) {
|
||||
/* Notify anyone interested that dialing is complete */
|
||||
ao2_lock(outgoing);
|
||||
outgoing->dial_res = res;
|
||||
outgoing->dialed = 1;
|
||||
ast_cond_signal(&outgoing->cond);
|
||||
ao2_unlock(outgoing);
|
||||
} else {
|
||||
/* We still need the dial result, but we don't need to lock */
|
||||
outgoing->dial_res = res;
|
||||
}
|
||||
|
||||
/* If the outgoing leg was not answered we can immediately return and go no further */
|
||||
if (res != AST_DIAL_RESULT_ANSWERED) {
|
||||
@@ -7599,12 +7605,6 @@ static void *pbx_outgoing_exec(void *data)
|
||||
}
|
||||
}
|
||||
|
||||
/* Notify anyone else again that may be interested that execution is complete */
|
||||
ao2_lock(outgoing);
|
||||
outgoing->executed = 1;
|
||||
ast_cond_signal(&outgoing->cond);
|
||||
ao2_unlock(outgoing);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -7810,34 +7810,42 @@ static int pbx_outgoing_attempt(const char *type, struct ast_format_cap *cap,
|
||||
}
|
||||
}
|
||||
|
||||
/* This extra reference is dereferenced by pbx_outgoing_exec */
|
||||
ao2_ref(outgoing, +1);
|
||||
if (ast_pthread_create_detached(&thread, NULL, pbx_outgoing_exec, outgoing)) {
|
||||
ast_log(LOG_WARNING, "Unable to spawn dialing thread for '%s/%s'\n", type, addr);
|
||||
ao2_ref(outgoing, -1);
|
||||
if (locked_channel) {
|
||||
if (!synchronous) {
|
||||
ast_channel_unlock(dialed);
|
||||
|
||||
if (synchronous == AST_OUTGOING_WAIT_COMPLETE) {
|
||||
/*
|
||||
* Because we are waiting until this is complete anyway, there is no
|
||||
* sense in creating another thread that we will just need to wait
|
||||
* for, so instead we commandeer the current thread.
|
||||
*/
|
||||
pbx_outgoing_exec(outgoing);
|
||||
} else {
|
||||
outgoing->in_separate_thread = 1;
|
||||
|
||||
if (ast_pthread_create_detached(&thread, NULL, pbx_outgoing_exec, outgoing)) {
|
||||
ast_log(LOG_WARNING, "Unable to spawn dialing thread for '%s/%s'\n", type, addr);
|
||||
ao2_ref(outgoing, -1);
|
||||
if (locked_channel) {
|
||||
if (!synchronous) {
|
||||
ast_channel_unlock(dialed);
|
||||
}
|
||||
ast_channel_unref(dialed);
|
||||
}
|
||||
ast_channel_unref(dialed);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (synchronous) {
|
||||
ao2_lock(outgoing);
|
||||
/* Wait for dialing to complete */
|
||||
while (!outgoing->dialed) {
|
||||
ast_cond_wait(&outgoing->cond, ao2_object_get_lockaddr(outgoing));
|
||||
}
|
||||
ao2_unlock(outgoing);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (synchronous) {
|
||||
ao2_lock(outgoing);
|
||||
/* Wait for dialing to complete */
|
||||
while (!outgoing->dialed) {
|
||||
ast_cond_wait(&outgoing->cond, ao2_object_get_lockaddr(outgoing));
|
||||
}
|
||||
if (1 < synchronous
|
||||
&& outgoing->dial_res == AST_DIAL_RESULT_ANSWERED) {
|
||||
/* Wait for execution to complete */
|
||||
while (!outgoing->executed) {
|
||||
ast_cond_wait(&outgoing->cond, ao2_object_get_lockaddr(outgoing));
|
||||
}
|
||||
}
|
||||
ao2_unlock(outgoing);
|
||||
|
||||
/* Determine the outcome of the dialing attempt up to it being answered. */
|
||||
if (reason) {
|
||||
*reason = pbx_dial_reason(outgoing->dial_res,
|
||||
|
Reference in New Issue
Block a user