mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-30 18:21:52 +00:00
pjsip: Move from threadpool to taskpool
This change moves the PJSIP module from the threadpool API to the taskpool API. PJSIP-specific implementations for task usage have been removed and replaced with calls to the optimized taskpool implementations instead. The need for a pool of serializers has also been removed as taskpool inherently provides this. The default settings have also been changed to be more realistic for common usage. UpgradeNote: The threadpool_* options in pjsip.conf have now been deprecated though they continue to be read and used. They have been replaced with taskpool options that give greater control over the underlying taskpool used for PJSIP. An alembic upgrade script has been added to add these options to realtime as well.
This commit is contained in:
committed by
github-actions[bot]
parent
ef5a7d1baf
commit
bb6b76c2d8
@@ -676,6 +676,8 @@ struct serializer {
|
||||
struct ast_taskpool *pool;
|
||||
/*! Which group will wait for this serializer to shutdown. */
|
||||
struct ast_serializer_shutdown_group *shutdown_group;
|
||||
/*! Whether the serializer is suspended or not. */
|
||||
unsigned int suspended:1;
|
||||
};
|
||||
|
||||
static void serializer_dtor(void *obj)
|
||||
@@ -727,6 +729,15 @@ static int execute_tasks(void *data)
|
||||
ast_threadstorage_set_ptr(¤t_taskpool_serializer, tps);
|
||||
for (remaining = ast_taskprocessor_size(tps); remaining > 0; remaining--) {
|
||||
requeue = ast_taskprocessor_execute(tps);
|
||||
|
||||
/* If the serializer is suspended we will not execute any more tasks and
|
||||
* we will not requeue the taskpool task. Instead it will be requeued when
|
||||
* the serializer is unsuspended.
|
||||
*/
|
||||
if (ser->suspended) {
|
||||
requeue = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ast_threadstorage_set_ptr(¤t_taskpool_serializer, NULL);
|
||||
|
||||
@@ -916,6 +927,72 @@ int ast_taskpool_serializer_push_wait(struct ast_taskprocessor *serializer, int
|
||||
return sync_task.fail;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal A task that suspends the serializer after queuing an empty task
|
||||
*/
|
||||
static int taskpool_serializer_suspend_task(void *data)
|
||||
{
|
||||
struct ast_taskprocessor *serializer = data;
|
||||
struct ast_taskprocessor_listener *listener = ast_taskprocessor_listener(serializer);
|
||||
struct serializer *ser = ast_taskprocessor_listener_get_user_data(listener);
|
||||
|
||||
/* If already suspended this is a no-op */
|
||||
if (ser->suspended) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* First we queue the empty task to ensure the serializer doesn't reach empty, this
|
||||
* prevents any threads from queueing up a taskpool task that executes the serializer
|
||||
* while it is suspended, allowing us to queue it ourselves when the serializer is
|
||||
* unsuspended.
|
||||
*/
|
||||
if (ast_taskprocessor_push(serializer, taskpool_serializer_empty_task, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Next we suspend the serializer so that the execute_tasks currently executing stops
|
||||
* and doesn't requeue.
|
||||
*/
|
||||
ser->suspended = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ast_taskpool_serializer_suspend(struct ast_taskprocessor *serializer)
|
||||
{
|
||||
if (ast_taskprocessor_is_task(serializer)) {
|
||||
/* I am the session's serializer thread so I cannot suspend. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Once this returns there is no thread executing the tasks on the serializer, so they
|
||||
* will accumulate until the serializer is unsuspended.
|
||||
*/
|
||||
ast_taskpool_serializer_push_wait(serializer, taskpool_serializer_suspend_task, serializer);
|
||||
}
|
||||
|
||||
void ast_taskpool_serializer_unsuspend(struct ast_taskprocessor *serializer)
|
||||
{
|
||||
struct ast_taskprocessor_listener *listener = ast_taskprocessor_listener(serializer);
|
||||
struct serializer *ser = ast_taskprocessor_listener_get_user_data(listener);
|
||||
|
||||
ao2_lock(ser);
|
||||
|
||||
if (!ser->suspended) {
|
||||
ao2_unlock(ser);
|
||||
return;
|
||||
}
|
||||
|
||||
ser->suspended = 0;
|
||||
|
||||
ao2_unlock(ser);
|
||||
|
||||
/* And now we kick off handling of the queued tasks once again */
|
||||
if (ast_taskpool_push(ser->pool, execute_tasks, ao2_bump(serializer))) {
|
||||
ast_taskprocessor_unreference(serializer);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Clean up resources on Asterisk shutdown
|
||||
|
||||
Reference in New Issue
Block a user