Closed Meonardo closed 3 years ago
I finally figured out this problem by call pjsua_destroy
in another thread(not the main thread), it worked but not recommend.
As I found the documents on pjsip official website:
PJLIB API should be called from a registered thread, otherwise it will raise assertion such as "Calling pjlib from unknown/external thread...". With GCD, we cannot really be sure of which thread executing the PJLIB function. Registering that thread to PJLIB seems to be a simple and easy solution, however it potentially introduces a random crash which is harder to debug. Here are few possible crash scenarios:
PJLIB's pj_thread_desc should remain valid until the registered thread stopped, otherwise crash of invalid pointer access may occur, e.g: in pj_thread_check_stack().
Some compatibility problems between GCD and PJLIB, see #1837 for more info.
If you want to avoid any possibility of blocking operation by PJLIB (or any higher API layer such as PJMEDIA, PJNATH, PJSUA that usually calls PJLIB), instead of dispatching the task using GCD, the safest way is to create and manage your own thread pool and register that thread pool to PJLIB. Or alternatively, simply use PJSUA timer mechanism (with zero delay), see pjsua_schedule_timer()/pjsua_schedule_timer2() docs for more info.
Version
Latest version(3.7.3).
File / Feature
File: VSLEndPoint.m Method:
destroyPJSUAInstance pjsua_destroy();
Expected behavior
Destroy pjsua successfully.
Actual behavior
Call
pjsua_destroy
block the main-threadOther info
The steps I was doing:
- (BOOL)hangup:(NSError **)error
- (BOOL)unregisterAccount:(NSError * _Nullable __autoreleasing *)error
- (void)removeAccount:(VSLAccount *)account
- (void)removeEndpoint
- (void)destroyPJSUAInstance
methodpj_status_t status = pjsua_destroy();
.