fix a few rare race conditions that could lead to a lockup
This commit is contained in:
parent
93bb5ca5c7
commit
77ee3fe10c
|
@ -1250,6 +1250,7 @@ struct switch_sql_queue_manager {
|
||||||
int thread_running;
|
int thread_running;
|
||||||
switch_thread_cond_t *cond;
|
switch_thread_cond_t *cond;
|
||||||
switch_mutex_t *cond_mutex;
|
switch_mutex_t *cond_mutex;
|
||||||
|
switch_mutex_t *cond2_mutex;
|
||||||
switch_mutex_t *mutex;
|
switch_mutex_t *mutex;
|
||||||
char *pre_trans_execute;
|
char *pre_trans_execute;
|
||||||
char *post_trans_execute;
|
char *post_trans_execute;
|
||||||
|
@ -1262,10 +1263,26 @@ struct switch_sql_queue_manager {
|
||||||
|
|
||||||
static int qm_wake(switch_sql_queue_manager_t *qm)
|
static int qm_wake(switch_sql_queue_manager_t *qm)
|
||||||
{
|
{
|
||||||
if (switch_mutex_trylock(qm->cond_mutex) == SWITCH_STATUS_SUCCESS) {
|
switch_status_t status;
|
||||||
|
int tries = 0;
|
||||||
|
|
||||||
|
top:
|
||||||
|
|
||||||
|
status = switch_mutex_trylock(qm->cond_mutex);
|
||||||
|
|
||||||
|
if (status == SWITCH_STATUS_SUCCESS) {
|
||||||
switch_thread_cond_signal(qm->cond);
|
switch_thread_cond_signal(qm->cond);
|
||||||
switch_mutex_unlock(qm->cond_mutex);
|
switch_mutex_unlock(qm->cond_mutex);
|
||||||
return 1;
|
return 1;
|
||||||
|
} else {
|
||||||
|
if (switch_mutex_trylock(qm->cond2_mutex) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_mutex_unlock(qm->cond2_mutex);
|
||||||
|
} else {
|
||||||
|
if (++tries < 10) {
|
||||||
|
switch_cond_next();
|
||||||
|
goto top;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1407,6 +1424,7 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_stop(switch_sql_queue_m
|
||||||
|
|
||||||
if (qm->thread) {
|
if (qm->thread) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s Stopping SQL thread.\n", qm->name);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s Stopping SQL thread.\n", qm->name);
|
||||||
|
qm_wake(qm);
|
||||||
switch_thread_join(&status, qm->thread);
|
switch_thread_join(&status, qm->thread);
|
||||||
qm->thread = NULL;
|
qm->thread = NULL;
|
||||||
status = SWITCH_STATUS_SUCCESS;
|
status = SWITCH_STATUS_SUCCESS;
|
||||||
|
@ -1596,6 +1614,7 @@ SWITCH_DECLARE(switch_status_t) switch_sql_queue_manager_init_name(const char *n
|
||||||
qm->max_trans = max_trans;
|
qm->max_trans = max_trans;
|
||||||
|
|
||||||
switch_mutex_init(&qm->cond_mutex, SWITCH_MUTEX_NESTED, qm->pool);
|
switch_mutex_init(&qm->cond_mutex, SWITCH_MUTEX_NESTED, qm->pool);
|
||||||
|
switch_mutex_init(&qm->cond2_mutex, SWITCH_MUTEX_NESTED, qm->pool);
|
||||||
switch_mutex_init(&qm->mutex, SWITCH_MUTEX_NESTED, qm->pool);
|
switch_mutex_init(&qm->mutex, SWITCH_MUTEX_NESTED, qm->pool);
|
||||||
switch_thread_cond_create(&qm->cond, qm->pool);
|
switch_thread_cond_create(&qm->cond, qm->pool);
|
||||||
|
|
||||||
|
@ -1850,7 +1869,9 @@ static void *SWITCH_THREAD_FUNC switch_user_sql_thread(switch_thread_t *thread,
|
||||||
check:
|
check:
|
||||||
|
|
||||||
if ((lc = qm_ttl(qm)) == 0) {
|
if ((lc = qm_ttl(qm)) == 0) {
|
||||||
|
switch_mutex_lock(qm->cond2_mutex);
|
||||||
switch_thread_cond_wait(qm->cond, qm->cond_mutex);
|
switch_thread_cond_wait(qm->cond, qm->cond_mutex);
|
||||||
|
switch_mutex_unlock(qm->cond2_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 40;
|
i = 40;
|
||||||
|
|
|
@ -37,6 +37,7 @@ struct switch_scheduler_task_container {
|
||||||
int64_t executed;
|
int64_t executed;
|
||||||
int in_thread;
|
int in_thread;
|
||||||
int destroyed;
|
int destroyed;
|
||||||
|
int running;
|
||||||
switch_scheduler_func_t func;
|
switch_scheduler_func_t func;
|
||||||
switch_memory_pool_t *pool;
|
switch_memory_pool_t *pool;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
@ -124,7 +125,11 @@ static int task_thread_loop(int done)
|
||||||
tp->in_thread = 1;
|
tp->in_thread = 1;
|
||||||
switch_thread_create(&thread, thd_attr, task_own_thread, tp, tp->pool);
|
switch_thread_create(&thread, thd_attr, task_own_thread, tp, tp->pool);
|
||||||
} else {
|
} else {
|
||||||
|
tp->running = 1;
|
||||||
|
switch_mutex_unlock(globals.task_mutex);
|
||||||
switch_scheduler_execute(tp);
|
switch_scheduler_execute(tp);
|
||||||
|
switch_mutex_lock(globals.task_mutex);
|
||||||
|
tp->running = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,6 +243,13 @@ SWITCH_DECLARE(uint32_t) switch_scheduler_del_task_id(uint32_t task_id)
|
||||||
tp->task.task_id, tp->task.group);
|
tp->task.task_id, tp->task.group);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tp->running) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Attempt made to delete running task #%u (group %s)\n",
|
||||||
|
tp->task.task_id, tp->task.group);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
tp->destroyed++;
|
tp->destroyed++;
|
||||||
if (switch_event_create(&event, SWITCH_EVENT_DEL_SCHEDULE) == SWITCH_STATUS_SUCCESS) {
|
if (switch_event_create(&event, SWITCH_EVENT_DEL_SCHEDULE) == SWITCH_STATUS_SUCCESS) {
|
||||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-ID", "%u", tp->task.task_id);
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Task-ID", "%u", tp->task.task_id);
|
||||||
|
|
Loading…
Reference in New Issue