Search code examples
pythonpjsippjsua2

Calling pj_thread_register from python


I'm trying to use pjsip via pjsua2 in python. I have a problem with threading.

import pjsua2 as pj
import threading

# pjsua2 test function
def pjsua2_test():
  # Create and initialize the library
  ep = pj.Endpoint()
  ep.libCreate()

if __name__ == "__main__":
  pjsuadaemonthread = threading.Thread(name='PJSUA',
                      target=pjsua2_test)
  pjsuadaemonthread.start()
  ep = pj.Endpoint()
  ep.libHandleEvents(10)

I get this error:

python3: ../src/pj/os_core_unix.c:692: pj_thread_this: Assertion `!"Calling pjlib from unknown/external thread. You must " "register external threads with pj_thread_register() " "before calling any pjlib functions."' failed.

How do I call pj_thread_register(), from python?


Solution

  • This is the syntax to pj_thread_register():

    ep.libRegisterThread('PJSUA')
    

    Unfortunately even if you call libRegisterThread it does not seem compatible with python threading.

    I think this is because pjsip internally uses threads of type pj_thread_t and python threads are not of type pj_thread_t.

    For more info take a look at Endpoint::libRegisterThread in the pjsip source code.

    However, if you just want to run pjsip on a different thread, the code below may help. It runs pjsip on a background thread named 'PJSUA-THREAD'. The key is to call libCreate() on a different thread like I do below.

    '''Tests running PJSUA2 in a different thread'''
    import logging
    import threading
    import pjsua2
    
    date_fmt = '%Y-%m-%d,%H:%M:%S'
    log_format = "%(levelname)s %(asctime)s.%(msecs)03d %(threadName)s %(name)s.%(funcName)s %(message)s"
    logging.basicConfig(format=log_format, datefmt=date_fmt, level=logging.DEBUG)
    
    _logger = logging.getLogger(__name__)
    
    THREAD_NAME = "PJSUA-THREAD"
    
    def main():
        _logger.debug("entered main()")
        pjsuadaemonthread = threading.Thread(name=THREAD_NAME, target=pjsua2_test)
        pjsuadaemonthread.start()
        _logger.debug("thread started")
        pjsuadaemonthread.join()
    
    # pjsua2 test function
    def pjsua2_test():
        # NOTE: PjSip will initialize and run on PJSUA-THREAD, see logs
        ep = pjsua2.Endpoint()
        ep.libCreate()
        _logger.debug("after libCreate()")
        ep_cfg = pjsua2.EpConfig()
        ep_cfg.uaConfig.mainThreadOnly = False
        ep_cfg.uaConfig.threadCnt = 1
        ep.libInit(ep_cfg)
        _logger.debug("after libInit(ep_cfg)")
        ep.libStart()
        _logger.debug("after libStart()")
        iter_count = 0
        event_count = 0
        while iter_count < 10:
            event_count += ep.libHandleEvents(10)
            _logger.debug("iter_count %d (%d events processed)", iter_count, event_count)
            iter_count += 1
        ep.libDestroy()
        _logger.debug("after ep.libDestroy()")
    
    if __name__ == "__main__":
        main()
        _logger.debug("after main()")
    

    Here is the log output. You can see pjsip is running on thread PJSUA-THREAD.

    DEBUG 2020-05-31,14:49:43.259 MainThread __main__.main entered main()
    14:49:43.261         os_core_unix.c !pjlib 2.8 for POSIX initialized
    14:49:43.261         sip_endpoint.c  .Creating endpoint instance...
    14:49:43.262                  pjlib  .select() I/O Queue created (0x7fd530013550)
    14:49:43.262         sip_endpoint.c  .Module "mod-msg-print" registered
    14:49:43.262        sip_transport.c  .Transport manager created.
    14:49:43.262           pjsua_core.c  .PJSUA state changed: NULL --> CREATED
    DEBUG 2020-05-31,14:49:43.262 PJSUA-THREAD __main__.pjsua2_test after libCreate()
    14:49:43.262         sip_endpoint.c  .Module "mod-pjsua-log" registered
    14:49:43.263         sip_endpoint.c  .Module "mod-tsx-layer" registered
    14:49:43.263         sip_endpoint.c  .Module "mod-stateful-util" registered
    14:49:43.263         sip_endpoint.c  .Module "mod-ua" registered
    14:49:43.263         sip_endpoint.c  .Module "mod-100rel" registered
    14:49:43.263         sip_endpoint.c  .Module "mod-pjsua" registered
    14:49:43.263         sip_endpoint.c  .Module "mod-invite" registered
    14:49:43.496             alsa_dev.c  ..ALSA driver found 32 devices
    14:49:43.496             alsa_dev.c  ..ALSA initialized
    14:49:43.496                  pjlib  ..select() I/O Queue created (0x7fd53009cf08)
    14:49:43.499         sip_endpoint.c  .Module "mod-evsub" registered
    14:49:43.499         sip_endpoint.c  .Module "mod-presence" registered
    14:49:43.499         sip_endpoint.c  .Module "mod-mwi" registered
    14:49:43.499         sip_endpoint.c  .Module "mod-refer" registered
    14:49:43.499         sip_endpoint.c  .Module "mod-pjsua-pres" registered
    14:49:43.499         sip_endpoint.c  .Module "mod-pjsua-im" registered
    14:49:43.499         sip_endpoint.c  .Module "mod-pjsua-options" registered
    14:49:43.499           pjsua_core.c  .1 SIP worker threads created
    14:49:43.499           pjsua_core.c  .pjsua version 2.8 for Linux-5.3.0.53/x86_64/glibc-2.27 initialized
    14:49:43.499           pjsua_core.c  .PJSUA state changed: CREATED --> INIT
    DEBUG 2020-05-31,14:49:43.262 MainThread __main__.main thread started
    DEBUG 2020-05-31,14:49:43.499 PJSUA-THREAD __main__.pjsua2_test after libInit(ep_cfg)
    14:49:43.499           pjsua_core.c  PJSUA state changed: INIT --> STARTING
    DEBUG 2020-05-31,14:49:43.500 PJSUA-THREAD __main__.pjsua2_test after libStart()
    14:49:43.500         sip_endpoint.c  .Module "mod-unsolicited-mwi" registered
    14:49:43.500           pjsua_core.c  .PJSUA state changed: STARTING --> RUNNING
    DEBUG 2020-05-31,14:49:43.510 PJSUA-THREAD __main__.pjsua2_test iter_count 0 (0 events processed)
    DEBUG 2020-05-31,14:49:43.520 PJSUA-THREAD __main__.pjsua2_test iter_count 1 (0 events processed)
    DEBUG 2020-05-31,14:49:43.531 PJSUA-THREAD __main__.pjsua2_test iter_count 2 (0 events processed)
    DEBUG 2020-05-31,14:49:43.541 PJSUA-THREAD __main__.pjsua2_test iter_count 3 (0 events processed)
    DEBUG 2020-05-31,14:49:43.551 PJSUA-THREAD __main__.pjsua2_test iter_count 4 (0 events processed)
    DEBUG 2020-05-31,14:49:43.562 PJSUA-THREAD __main__.pjsua2_test iter_count 5 (0 events processed)
    DEBUG 2020-05-31,14:49:43.572 PJSUA-THREAD __main__.pjsua2_test iter_count 6 (0 events processed)
    DEBUG 2020-05-31,14:49:43.582 PJSUA-THREAD __main__.pjsua2_test iter_count 7 (0 events processed)
    DEBUG 2020-05-31,14:49:43.593 PJSUA-THREAD __main__.pjsua2_test iter_count 8 (0 events processed)
    DEBUG 2020-05-31,14:49:43.603 PJSUA-THREAD __main__.pjsua2_test iter_count 9 (0 events processed)
    14:49:43.604           pjsua_core.c  Shutting down, flags=0...
    14:49:43.604           pjsua_core.c  PJSUA state changed: RUNNING --> CLOSING
    14:49:43.610           pjsua_call.c  .Hangup all calls..
    14:49:43.610          pjsua_media.c  .Call 0: deinitializing media..
    14:49:43.610          pjsua_media.c  .Call 1: deinitializing media..
    14:49:43.610          pjsua_media.c  .Call 2: deinitializing media..
    14:49:43.610          pjsua_media.c  .Call 3: deinitializing media..
    14:49:43.610           pjsua_pres.c  .Shutting down presence..
    14:49:44.610           pjsua_core.c  .Destroying...
    14:49:44.610          pjsua_media.c  .Shutting down media..
    14:49:44.997      sip_transaction.c  .Stopping transaction layer module
    14:49:44.997      sip_transaction.c  .Stopped transaction layer module
    14:49:44.997         sip_endpoint.c  .Module "mod-unsolicited-mwi" unregistered
    14:49:44.997         sip_endpoint.c  .Module "mod-pjsua-options" unregistered
    14:49:44.997         sip_endpoint.c  .Module "mod-pjsua-im" unregistered
    14:49:44.997         sip_endpoint.c  .Module "mod-pjsua-pres" unregistered
    14:49:44.997         sip_endpoint.c  .Module "mod-pjsua" unregistered
    14:49:44.997         sip_endpoint.c  .Module "mod-stateful-util" unregistered
    14:49:44.997         sip_endpoint.c  .Module "mod-refer" unregistered
    14:49:44.997         sip_endpoint.c  .Module "mod-mwi" unregistered
    14:49:44.997         sip_endpoint.c  .Module "mod-presence" unregistered
    14:49:44.997         sip_endpoint.c  .Module "mod-evsub" unregistered
    14:49:44.997         sip_endpoint.c  .Module "mod-invite" unregistered
    14:49:44.997         sip_endpoint.c  .Module "mod-100rel" unregistered
    14:49:44.997         sip_endpoint.c  .Module "mod-ua" unregistered
    14:49:44.997      sip_transaction.c  .Transaction layer module destroyed
    14:49:44.997         sip_endpoint.c  .Module "mod-tsx-layer" unregistered
    14:49:44.997         sip_endpoint.c  .Module "mod-msg-print" unregistered
    14:49:44.997         sip_endpoint.c  .Module "mod-pjsua-log" unregistered
    14:49:44.997         sip_endpoint.c  .Endpoint 0x7fd5300087b8 destroyed
    14:49:44.997           pjsua_core.c  .PJSUA state changed: CLOSING --> NULL
    14:49:44.997           pjsua_core.c  .PJSUA destroyed...
    DEBUG 2020-05-31,14:49:44.997 PJSUA-THREAD __main__.pjsua2_test after ep.libDestroy()
    DEBUG 2020-05-31,14:49:45.000 MainThread __main__.<module> after main()