diff -r 9d7ce34704c8 -r b564fb5fd78b commsfwsupport/commselements/serverden/src/sd_player.cpp --- a/commsfwsupport/commselements/serverden/src/sd_player.cpp Tue Aug 31 16:25:36 2010 +0300 +++ b/commsfwsupport/commselements/serverden/src/sd_player.cpp Wed Sep 01 12:35:48 2010 +0100 @@ -17,7 +17,7 @@ @file @internalComponent */ - + #include #include #include "sd_log.h" @@ -39,12 +39,10 @@ // // CSockSessionProxy // - EXPORT_C CCommonSessionProxy::CCommonSessionProxy(CWorkerSession* aSession, CCommonPlayer& aPlayer) : iSession(aSession), iPlayer(aPlayer), - iNumSubSessClosing(ELivingSession), - iSubSessionCloseThrottle(*this) + iNumSubSessClosing(ELivingSession) { //COMMONLOG((WorkerId(),KECommonBootingTag, _L8("CSockSessionProxy %08x:\tCSockSessionProxy(), iSockSession %08x"), this, iSession) ); } @@ -68,77 +66,37 @@ __ASSERT_DEBUG(!IsClosing(), User::Panic(KSpecAssert_ElemSvrDenPlayrC, 1)); iNumSubSessClosing = 1; // dummy subsession to prevent premature suicide during this close loop - - DeleteSubSessionsWithThrottling(); - } - -void CCommonSessionProxy::DeleteSubSessionsWithThrottling() - { - // Why Throttle? The original scenario is a process which opens a large number of sockets (100 in the - // original case) and terminates without closing them, leaving BeginSessionClose() to clean them up. - // In addition, the worker in question (pdummy1) synchronously deletes subsessions (1) and uses a shared - // shared heap configuration (i.e. limited memory). As each deletion results in a message being sent - // (to an SCPR), and there is no opportunity to drain these due to the synchronous deletion, the transport - // queue overflows and cannot be grown resulting in a panic. So use a (*low* priority) active object to - // delete a limited number of subsessions per RunL(). - // - // (1) a call to DeleteMe() results in an immediate upcall to NotifySubSessionDestroyed(). - - TInt count = KSubSessionThrottleSize; - - // The object container is stored as a packed array, so working backwards through it avoids invalidating - // the iterator when removing entries (and as a bonus is more efficient) + // The object container is stored as a packed array, so working backwards through it avoids invalidating + // the iterator when removing entries (and as a bonus is more efficient) + CCommonPlayer::TSubSessionContainer& subSessions(iPlayer.SubSessions()); + for(TInt i = subSessions.Count() - 1; i >= 0; --i) + { + CWorkerSubSession* subSession = subSessions[i]; + if(subSession->Session() == iSession) + { + ++iNumSubSessClosing; + if(!subSession->IsClosing()) + { + subSession->DeleteMe(); + } + } + } - CCommonPlayer::TSubSessionContainer& subSessions(iPlayer.SubSessions()); - for(TInt i = subSessions.Count() - 1; i >= 0; --i) - { - CWorkerSubSession* subSession = subSessions[i]; - if(subSession->Session() == iSession) - { - ++iNumSubSessClosing; - if(!subSession->IsClosing()) - { - subSession->DeleteMe(); - // Throttle the deletions as appropriate - if (--count <= 0) - { - COMMONLOG((Player().WorkerId(),KECommonBootingTag, _L8("CCommonSessionProxy %08x:\tDeleteSubSessionBunch(): throttled subsession deletion"), this) ); - // Re-prime the one shot - iSubSessionCloseThrottle.Call(); - return; - } - } - } - } - NotifySubSessionDestroyed(); // all, done, remove the dummy subsession - } + NotifySubSessionDestroyed(); // remove the dummy subsession + } EXPORT_C void CCommonSessionProxy::NotifySubSessionDestroyed() { - //COMMONLOG((Player().WorkerId(),KECommonBootintgTag, _L8("CCommonSessionProxy %08x:\tNotifySubSessionDestroyed(), iSockSession %08x"), this, iSession) ); - if(IsClosing() &&--iNumSubSessClosing <= 0) - { - __ASSERT_DEBUG(iNumSubSessClosing == 0, User::Panic(KSpecAssert_ElemSvrDenPlayrC, 2)); - CCommonWorkerThread& worker = iPlayer.WorkerThread(); - worker.CompleteSessionClose(iSession); - delete this; - } + //COMMONLOG((Player().WorkerId(),KECommonBootingTag, _L8("CCommonSessionProxy %08x:\tNotifySubSessionDestroyed(), iSockSession %08x"), this, iSession) ); + if(IsClosing() && --iNumSubSessClosing <= 0) + { + __ASSERT_DEBUG(iNumSubSessClosing == 0, User::Panic(KSpecAssert_ElemSvrDenPlayrC, 2)); + CCommonWorkerThread& worker = iPlayer.WorkerThread(); + worker.CompleteSessionClose(iSession); + delete this; + } } -// -// CCommonSessionProxy::CSubSessionCloseThrottle -// - -CCommonSessionProxy::CSubSessionCloseThrottle::CSubSessionCloseThrottle(CCommonSessionProxy& aProxy) - : CAsyncOneShot(EPriorityLow), iProxy(aProxy) // This must be low priority! - { - } - -void CCommonSessionProxy::CSubSessionCloseThrottle::RunL() - { - // Delete some more subsessions - iProxy.DeleteSubSessionsWithThrottling(); - } // // CCommonPlayer