On Wed, May 21, 2008 at 7:07 AM, Turnaev Eugeny <turnaev at t72.ru> wrote: > > Suppose situation: > > I have an active call and valid call_id, > now i want to connect or disconnect port from conference. > So i have to call for example: > > status = py_pjsua.conf_connect(player_port, call_port) > > How can i check in python that player_port, call_port and call port are valid? > > Well seems easy... > call_port = py_pjsua.call_get_conf_port(call_id) > player_port = py_pjsua.player_get_conf_port(player_id) > > if call_port >= 0 and player_port >= 0: > do stuff.. ports are valid > > Now imagine: > > > if call_port >= 0 and player_port >= 0: > > # here context switch ! .. callback is called > # and call becomes invalid .. and also > # call_port becomes invalid.. > # context switch back to this function > > status = py_pjsua.conf_connect(player_port, call_port) > > # a call to py_pjsua.conf_connect(player_port, call_port) > # will fail and application will suddenly exit! > > > > # py_pjsua.c > > static PyObject *py_pjsua_conf_connect > (PyObject *pSelf, PyObject *pArgs) > { > ... > > status = pjsua_conf_connect(source, sink); > > return Py_BuildValue("i", status); > } > > > > # pjsua_media.c > > PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source, > pjsua_conf_port_id sink) > { > return pjmedia_conf_connect_port(pjsua_var.mconf, source, sink, 0); > } > > > > # conference.c > > PJ_DEF(pj_status_t) pjmedia_conf_connect_port( pjmedia_conf *conf, > unsigned src_slot, > unsigned sink_slot, > int level ) > { > .... > /* Check arguments */ > PJ_ASSERT_RETURN(conf && src_slot<conf->max_ports && > sink_slot<conf->max_ports, PJ_EINVAL); > > /* Ports must be valid. */ > PJ_ASSERT_RETURN(conf->ports[src_slot] != NULL, PJ_EINVAL); > PJ_ASSERT_RETURN(conf->ports[sink_slot] != NULL, PJ_EINVAL); > > > > > as i understand.. this macro will return from function PJ_EINVAL > and PJ_EINVAL and then must be returned from python envelope > as return Py_BuildValue("i", status); > > but i see in console: > > 11:43:59.968 os_core_unix.c pjlib 0.8.0-trunk for POSIX initialized > 11:43:59.969 sip_endpoint.c Creating endpoint instance... > 11:43:59.969 pjlib select() I/O Queue created (0xb7799098) > 11:43:59.969 sip_endpoint.c Module "mod-msg-print" registered > 11:43:59.969 sip_transport. Transport manager created. > python: ../src/pjmedia/conference.c:914: pjmedia_conf_connect_port: Assertion `conf && src_slot<conf->max_ports && sink_slot<conf->max_ports' failed. > Aborted > > > and application exits.. > > How i can workaround this ? > > I think the correct way would be to return status > status = py_pjsua.conf_connect(player_port, call_port) > from conf_connect call as invalid status.. > or at least raise an exception in py_pjsua.c -> static PyObject *py_pjsua_conf_connect function. > > Also this problem mirrors in > conf_disconnect and i suspect many other python envelopes. > (For example call_id .. i can retrieve call_id with enum_calls in python.. then a context may be switched.. call become invalid > context switch back and i would call something that PJ_ASSERT_RETURN( call_id is valid ) -> that would crash my python app too > i guess ) > How about building the libraries with CFLAGS+=-DNDEBUG? ;-) We have a pretty strong convention about the use of assert vs the usual error handling throughout the libraries. Assertion is used to trap developer's mistake (developer can be you or me) and it must not be used as a replacement for error handling. And assertion must not be used for errors coming from external events, such as incoming message from remote party; in this case, only error handling must be used. PJ_ASSERT_RETURN does both. The idea is to trap programming error during development phase (with assert), and once the application is built in release mode, we can safely turn assertion off (with -DNDEBUG) and it will switch its behavior to use error handling instead. So because of this you can safely turn assertion off in your release build (Windows apps do that all the time, and that's what I always do too). Or you can turn if off during development too if this is too annoying for you. :) Cheers Benny