Repository navigation
Register the SIP queue thread before pjsua_create() - #36
Closed
PetrShtuka wants to merge 1 commit into
Closed
PetrShtuka wants to merge 1 commit into
PetrShtuka wants to merge 1 commit into
Conversation
pjsua_create() opens with pj_init(), which registers its caller only when it is the call that brings PJLIB up. When something else in the process has already initialized PJLIB -- the host, or a second PJSIP-based stack -- pj_init() only bumps its reference count, and the thread running the start stays unknown to PJLIB. The first per-thread call inside pjsua_create() then aborts with "Calling pjlib from unknown/external thread". A push-driven start runs on a transient sipQueue worker, so this is reachable from -wakeRegistration. PJLIB is now initialized first, which makes the existing thread registration legal, and the teardown releases that reference after pjsua_destroy() has released its own. PJLIB stays up for whoever else initialized it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #35 — review that one first.
Problem
Starting the engine aborts the process when something else has already initialized PJLIB:
pjsua_create()opens withpj_init(), which registers its caller only when it is the call that brings PJLIB up. If the host — or a second PJSIP-based stack in the same process — already initialized PJLIB,pj_init()only bumps its reference count and the thread running the start stays unknown to PJLIB. The first per-thread call insidepjsua_create()then aborts. A push-driven start runs on a transientsipQueueworker (-wakeRegistration→-startWithError:), so this is reachable from an incoming call.ensurePJThreadRegistered()could not cover it: it returns early while the library's owngPJInitializedflag is still false, and it has to, becausepj_thread_is_registered()is not safe before PJLIB is up.Changes
-startEngineLockedinitializes PJLIB itself, registers the calling thread, and only then callspjsua_create(). Both failure paths release that reference.pjsua_destroy()has released the onepjsua_create()took (confirmed against the vendored binary:pjsua_destroy2ends withpj_log_pop_indentandpj_shutdown), so PJLIB stays up for whoever else initialized it.Testing
./Scripts/run-package-tests.sh— 84 registry tests and 65 package tests, 0 failures. Reverting only the library hunks makestestEngineStartsWhenSomethingElseAlreadyInitializedPJLIBabort, which is how the fix was verified.🤖 Generated with Claude Code