Last year I wrote about a new API I created, taskpool, and how stasis was moved over to it. If you haven’t read that post you can do so here:
I’m happy to say that PJSIP has now been moved over to the same API! This was a journey that involved multiple revisions and attempts, but as of the latest releases (20.18.0, 22.8.0, 23.2.0) it has shipped. Let’s talk about the two aspects that made it complex.
Taskpool Execution In Taskpool
Almost everything in PJSIP executes within a taskprocessor. This means that there are cases where the code will queue a task on a taskprocessor from within a taskprocessor – sometimes synchronously. With the prior threadpool implementation this was perfectly acceptable as a new thread could be created if none were available and things would go on. With taskpool this is not the case. It may not be configured to allow unbound growth of threads. As a result taskpool had to be made more intelligent about where tasks execute in this scenario, such as allowing them to be executed within the current thread. This was done for PJSIP but is available to all taskpool API users, and happens transparently without knowledge of the API user.
Pausing A Taskprocessor
In certain scenarios in Asterisk we have a process called masquerade that essentially replaces the contents of one channel with that of another. It’s commonly involved in certain transfer scenarios or AMI Redirect cases. To accomplish this PJSIP has to pause the taskprocessor handling the SIP dialog and SIP session so that no further actions occur on it, and it is free to manipulate the channel in a more substantial manner. With threadpool since new threads could be created if none were available the easiest way to do so was to just block the thread until told to unpause. With taskpool blocking a task like that is not allowed as another thread may not be available to handle things, blocking everything. Taskpool takes a different approach and instead doesn’t block the thread but stops handling any tasks queued to the taskprocessor handling the SIP dialog and SIP session. Essentially there is no longer a thread handling the taskprocessor. After the taskprocessor is unpaused it is given back to the taskpool and a thread resumes handling the tasks. This ensures no thread is blocked waiting for a taskprocessor to be unpaused.
The Impact
Just like stasis from a user perspective only the configuration options changed and defaults were updated to better reflect the actual requirements of most users so few people will need to touch it – just upgrading your Asterisk will gain you this improvement. On my system the impact to CPU usage is about a 5-10% reduction. It’s not as much as stasis, but every bit helps!