Changes between Version 1 and Version 2 of Python_SIP/Basic_Concept


Ignore:
Timestamp:
Jul 22, 2008 10:11:14 PM (16 years ago)
Author:
bennylp
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Python_SIP/Basic_Concept

    v1 v2  
    4040It's with the callback classes. 
    4141 
    42 Callback classes also provide the mean to ''connect'' pjsua objects with your application's objects. The idea is like this. All the pjsua main classes above (''Lib'', ''Account'', ''Call'', and ''Buddy'') are final classes, meaning they are not intended to be subclasses or derived. Each of these classes (except ''Lib'') have their corresponding callback class ([http://www.pjsip.org/python/pjsua.htm#AccountCallback AccountCallback], [[http://www.pjsip.org/python/pjsua.htm#CallCallback CallCallback], and [[http://www.pjsip.org/python/pjsua.htm#BuddyCallback BuddyCallback]), and events emitted by these classes will be sent to the callback class. These callback classes are subclass-able, and in fact you must derive a class from these callback class in order to customize the processing of the events. 
     42Callback classes also provide the mean to ''connect'' pjsua objects with your application's objects. The idea is like this. All the pjsua main classes above (''Lib'', ''Account'', ''Call'', and ''Buddy'') are final classes, meaning they are not intended to be subclasses or derived. Each of these classes (except ''Lib'') have their corresponding callback class ([http://www.pjsip.org/python/pjsua.htm#AccountCallback AccountCallback], [http://www.pjsip.org/python/pjsua.htm#CallCallback CallCallback], and [http://www.pjsip.org/python/pjsua.htm#BuddyCallback BuddyCallback]), and events emitted by these classes will be sent to the callback class. These callback classes are subclass-able, and in fact you must derive a class from these callback class in order to customize the processing of the events. 
    4343 
    4444It's probably much easier to explain with an example. 
     
    5959    def on_state(self): 
    6060        text_ctrl.set_text("Call state is " + self.call.info().state_text) 
     61  }}} 
    6162 
     63As you can see above, the primary objective of deriving a class from the callback class is to customize the processing of an event. And in your callback class, you can put your own object attributes there to connect the call object with your application objects. 
     64 
     65Then you ''install'' your callback to the Call object like this: 
     66 
     67  {{{ 
     68#!python 
    6269 
    6370def make_call(dst_uri): 
     
    7077    return call 
    7178  }}} 
     79 
     80or using {{{set_callback()}}} method like this: 
     81 
     82  {{{ 
     83#!python 
     84 
     85def make_call(dst_uri): 
     86    my_cb = MyCallCallback(none) 
     87    try: 
     88        call = acc.make_call(dst_uri) 
     89        call.set_callback(my_cb) 
     90    except pjsua.Error, err: 
     91        print 'Error making call', err 
     92        return None 
     93    return call 
     94  }}} 
     95 
     96This later method is not preferred since it is possible to loose events with this method, e.g. due to the use of multi-threading, events may be emitted by the call object while the callback is not installed. It is possible to avoid loosing events this way by using library lock though, as will be explained later. 
    7297 
    7398I hope the snippet above will give you a bit of info on the basic pattern used by the library. More will be explained in later sections. 
     
    93118 
    94119 
    95 ==== Threading ==== 
     120==== Threading and Concurrency ==== 
    96121 
    97122For platforms that require polling, the pjsua module provides it's own worker thread to poll pjsip, so it is not necessary to instantiate own your polling thread. Having said that the application should be prepared to have the callbacks called by different thread than the main thread. 
    98123 
    99124The pjsua module should be thread safe. 
     125 
     126Internally, the pjsua module actually is not re-entrant, since we found there is a deadlock somewhere when more than one threads are used. The library uses one single lock object to prevent the main thread and pjsua module worker thread from deadlocking.  
     127 
     128The {{{lib.auto_lock()}}} returns an object that automatically acquires the library lock and it will automatically release the lock when the object is destroyed. So to protect a function, the code will be like this: 
     129 
     130{{{ 
     131#!python 
     132 
     133def my_function(): 
     134    # this will acquire library lock: 
     135    lck = pjsua.Lib.instance().auto_lock() 
     136    # and when lck is destroyed, the lock will be released 
     137}}} 
     138 
     139