Re: [reSIProcate-users] InviteSession::reject Assertion '0' failed. How to handle multithread ?
I've been using the stack and DUM with asserts disabled in a few
commercial products for a number of years without any issues. However
it is possible that if an assert condition would have triggered, then
the stack will instead crash (ie. memory access violation) if asserts
are disabled. See the following older post on the topic of asserts:
http://list.resiprocate.org/archive/resiprocate-devel-old/msg06195.html
Scott
On Wed, Feb 11, 2009 at 1:55 PM, Aurelien Grimaud <gstelzz@xxxxxxxx> wrote:
> 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
>>>>
>>
>>
>
>
>