Re: [reSIProcate-users] InviteSession::reject Assertion '0' failed. How to handle multithread ?
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