< Previous by Date Date Index Next by Date >
< Previous in Thread Thread Index Next in Thread >

Re: [reSIProcate-users] InviteSession::reject Assertion '0' failed. How to handle multithread ?


Thanks for your answers.
I was already aware of this thread issue, and all my dum commands are queued in dum.

I added a test handle->isTerminated() and it works just fine.

For production, I would like to disable assert at compilation time (to avoid core dump hanging up multiple calls).
Is it safe to disable assert ?

Aurelien

Scott Godin a écrit :
Hi Aurelien,

Since your application is multi-threaded and you plan to make DUM
calls from multi-threads, please make sure you have read the following
wiki page on threading:
http://www.resiprocate.org/DUM_Threading#Tips_on_Making_Thread_Safe_Calls_when_using_DUM

You may also want to take a look at the recon project, since this is
an example of how to build a thread safe application on-top of DUM.

Other comments inline...

Scott

On Tue, Feb 10, 2009 at 6:55 PM, Aurelien Grimaud <gstelzz@xxxxxxxx> wrote:
Aurelien Grimaud a écrit :
Hi,
I have a problem with InviteSession usage.

I have an application based on resiprocate which has different sources of
event.
SipStack is one of them, but also two other sources which interacts with
initial client or server dialog.
Each source runs in a different thread and can interact with a SIP dialog,
by rejecting the call for instance.

My problem is syncronization with the ServerInviteSession state.
The application thread receives a new ServerSession commands from
InviteSessionHandler.
The application thread pushes a 100 provisional to dum using dum.post()
(which is later  sent via ServerInviteSessionHandler)
The application thread receives an offer commands from
InviteSessionHandler.
then in parallel :
      The application thread wants to reject the call and schedule a
reject by pushing a reject command with dum::post()
      The UAC cancels the call, the application threads receives an
onTerminated()
dum treats the reject command -> assert(0) because ServerInviteSession is
in state Terminated.

How should it be handled if I do not want to run everything in one thread
?
I could test the mState but it is private ...
Well, I guess I could use InviteSession->isTerminated() to test state, and
not call reject() on a terminated session.

Correct.  There are some other fn's that should be usable to ensure
the state is valid for other operations: ie. isConnected, isAccepted,
and isEarly.

Note that if you cannot call reject() on a Terminated session, calling
provisional(), end() or accept() will lead to no-op, calling provideOffer(),
requestOffer() or provideAnswer() will throw a DialogUsageException.
Should not all command lead to throw, or assert, or no-op ?

I agree - all the calls should be cleaned up to throw exceptions for
consistency.

The other problem is that I am actually testing wether handler is valid or
not before calling reject, and it is valid.
But, when receiving CANCEL, the handler should have been invalidated in
dispatchCancel, right ?

Testing a stored handle via an isValid() call is definitely a good
thing to do before using it.  The handle becomes invalid when the
InviteSession dialog is destroyed.  For receiving a CANCEL this
happens just after ServerInviteSession::dispatchCancel.  The call at
then end of the fn to mDum.destroy(this) queues an DestroyUsage
event/message on the message queue to have the InviteSession
destroyed.  The next process loop iteration will actually destroy the
InviteSession and invalidate the handle.

I'll have a closer look to output and find out what is happening there.
Meanwhile, any comment is welcome.

Aurelien
Thanks.

Aurelien