Re: [reSIProcate] dum shutdown issues (IMPORTANT)
Someof the changes I've made to dum as part of my shutdown-related changes:
added a pure virtual BaseUsage::end() so the HandleManager can end any
usages that are still kicking around. Note that end() is now void and
does not return the SipMessage&. This necessitated a number of changes
to the derived Usage code. It will also require some minor changes to
application code.
Jason
Jason Fischl wrote:
Hi all,
After fighting with shutdown for an entire day, I'd like to propose
some changes. Here are the current issues:
Shutting down a useragent requires us to:
- async end all active usages
- async shutdown call to DialogUsageManager
- async shutdown call to SipStack
- async end the StackThread (if we are using one)
The application is required to somehow coordinate all of these
requests to shutdown and wait for appropriate callbacks before moving
on to the next one.
There is no way to request dum to shutdown all usages. The order of
usage termination may be important for some applications. For
instance, some applications may require the registrations to be ended
last since they may have GRUUs bound to them. In other cases, the
order of unPUBLISH vs unSUBSCRIBE may also be important.
In the current implementation, if the application calls shutdown and
there are active usages, dum will wait for those usages to all end and
will then call the handler onDumCanBeDeleted. However, if there are
active ClientSubscriptions and dum never receives NOTIFY messages
with SubscriptionState == Terminated, dum will never exit. This can
happen if the presence server crashes.
Proposed changes:
- SipStack should be owned by DialogUsageManager. Is there really any
case where the application would want to reuse a SipStack object after
shutting down the dum?
- Application should be able to shutdown without having to explicitly
end all active Usages. Either dum should end the usages or it should
be able to shutdown without ending them. Either way, it should not
leak memory.
Current Interface:
void
DialogUsageManager::shutdown(DumShutdownHandler* handler);
virtual void
DumShutdownHandler::onDumCanBeDeleted()=0;
Proposed Interface:
// In all cases, no leaks (obviously :)
// End usages in the following order: ServerInviteSession,
ServerSubscription, ClientInviteSession, ClientSubscription,
// ClientPagerMessage, ClientPublication, ClientRegistration
// call DumShutdownHandler::onDumCanBeDeleted when all usages are
ended, SipStack is ended and StackThread is shutdown
// After giveUpSeconds, exit regardless. If giveUpSeconds == 0, wait
indefinitely
void DialogUsageManager::shutdown(DumShutdownHandler* handler,
unsigned long giveUpSeconds=0);
// call DumShutdownHandler::onDumCanBeDeleted when all usages are
ended, SipStack is ended and StackThread is shutdown
// After giveUpSeconds, exit regardless. If giveUpSeconds == 0, wait
indefinitely
void DialogUsageManager::shutdownIfNoUsages(DumShutdownHandler*
handler, unsigned long giveUpSeconds=0);
// Shutdown immediately - ignore existing usages.
// call DumShutdownHandler::onDumCanBeDeleted when all usages are
ended, SipStack is ended and StackThread is shutdown
void DialogUsageManager::forceShutdown(DumShutdownHandler* handler);