mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-19 08:11:21 +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;
|
int dial_res;
|
||||||
/*! \brief Set when dialing is completed */
|
/*! \brief Set when dialing is completed */
|
||||||
unsigned int dialed:1;
|
unsigned int dialed:1;
|
||||||
/*! \brief Set when execution is completed */
|
/*! \brief Set if we've spawned a thread to do our work */
|
||||||
unsigned int executed:1;
|
unsigned int in_separate_thread:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! \brief Destructor for outgoing structure */
|
/*! \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);
|
RAII_VAR(struct pbx_outgoing *, outgoing, data, ao2_cleanup);
|
||||||
enum ast_dial_result res;
|
enum ast_dial_result res;
|
||||||
|
|
||||||
/* Notify anyone interested that dialing is complete */
|
|
||||||
res = ast_dial_run(outgoing->dial, NULL, 0);
|
res = ast_dial_run(outgoing->dial, NULL, 0);
|
||||||
ao2_lock(outgoing);
|
|
||||||
outgoing->dial_res = res;
|
if (outgoing->in_separate_thread) {
|
||||||
outgoing->dialed = 1;
|
/* Notify anyone interested that dialing is complete */
|
||||||
ast_cond_signal(&outgoing->cond);
|
ao2_lock(outgoing);
|
||||||
ao2_unlock(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 the outgoing leg was not answered we can immediately return and go no further */
|
||||||
if (res != AST_DIAL_RESULT_ANSWERED) {
|
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;
|
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);
|
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);
|
if (synchronous == AST_OUTGOING_WAIT_COMPLETE) {
|
||||||
ao2_ref(outgoing, -1);
|
/*
|
||||||
if (locked_channel) {
|
* Because we are waiting until this is complete anyway, there is no
|
||||||
if (!synchronous) {
|
* sense in creating another thread that we will just need to wait
|
||||||
ast_channel_unlock(dialed);
|
* 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) {
|
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. */
|
/* Determine the outcome of the dialing attempt up to it being answered. */
|
||||||
if (reason) {
|
if (reason) {
|
||||||
*reason = pbx_dial_reason(outgoing->dial_res,
|
*reason = pbx_dial_reason(outgoing->dial_res,
|
||||||
|
|||||||
Reference in New Issue
Block a user