[reSIProcate] dum shutdown issues (IMPORTANT)
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);