commsfwsupport/commselements/serverden/src/sd_player.cpp
branchRCL_3
changeset 26 b564fb5fd78b
parent 25 9d7ce34704c8
equal deleted inserted replaced
25:9d7ce34704c8 26:b564fb5fd78b
    15 
    15 
    16 /**
    16 /**
    17  @file
    17  @file
    18  @internalComponent
    18  @internalComponent
    19 */
    19 */
    20     
    20 
    21 #include <e32base.h>
    21 #include <e32base.h>
    22 #include <cfshared.h>
    22 #include <cfshared.h>
    23 #include "sd_log.h"
    23 #include "sd_log.h"
    24 #include "sd_roles.h"
    24 #include "sd_roles.h"
    25 #include "sd_msgs.h"
    25 #include "sd_msgs.h"
    37 using namespace CommsFW;
    37 using namespace CommsFW;
    38 
    38 
    39 //
    39 //
    40 // CSockSessionProxy
    40 // CSockSessionProxy
    41 //
    41 //
    42 
       
    43 EXPORT_C CCommonSessionProxy::CCommonSessionProxy(CWorkerSession* aSession, CCommonPlayer& aPlayer)
    42 EXPORT_C CCommonSessionProxy::CCommonSessionProxy(CWorkerSession* aSession, CCommonPlayer& aPlayer)
    44 :	iSession(aSession),
    43 :	iSession(aSession),
    45 	iPlayer(aPlayer),
    44 	iPlayer(aPlayer),
    46 	iNumSubSessClosing(ELivingSession),
    45 	iNumSubSessClosing(ELivingSession)
    47 	iSubSessionCloseThrottle(*this)
       
    48 	{
    46 	{
    49 	//COMMONLOG((WorkerId(),KECommonBootingTag, _L8("CSockSessionProxy %08x:\tCSockSessionProxy(), iSockSession %08x"), this, iSession) );
    47 	//COMMONLOG((WorkerId(),KECommonBootingTag, _L8("CSockSessionProxy %08x:\tCSockSessionProxy(), iSockSession %08x"), this, iSession) );
    50 	}
    48 	}
    51 
    49 
    52 EXPORT_C CCommonSessionProxy::~CCommonSessionProxy()
    50 EXPORT_C CCommonSessionProxy::~CCommonSessionProxy()
    66 	CCommonWorkerThread& worker = iPlayer.WorkerThread();
    64 	CCommonWorkerThread& worker = iPlayer.WorkerThread();
    67 	worker.IncProlongBindingLife();
    65 	worker.IncProlongBindingLife();
    68 	__ASSERT_DEBUG(!IsClosing(), User::Panic(KSpecAssert_ElemSvrDenPlayrC, 1));
    66 	__ASSERT_DEBUG(!IsClosing(), User::Panic(KSpecAssert_ElemSvrDenPlayrC, 1));
    69 	iNumSubSessClosing = 1;	// dummy subsession to prevent premature suicide during this close loop
    67 	iNumSubSessClosing = 1;	// dummy subsession to prevent premature suicide during this close loop
    70 
    68 
    71 	
    69 	// The object container is stored as a packed array, so working backwards through it avoids invalidating
    72 	DeleteSubSessionsWithThrottling();
    70 	// the iterator when removing entries (and as a bonus is more efficient)
    73 	}
    71 	CCommonPlayer::TSubSessionContainer& subSessions(iPlayer.SubSessions());
    74 
    72 	for(TInt i = subSessions.Count() - 1; i >= 0; --i)
    75 void CCommonSessionProxy::DeleteSubSessionsWithThrottling()
    73 		{
    76     {
    74 		CWorkerSubSession* subSession = subSessions[i];
    77     // Why Throttle?  The original scenario is a process which opens a large number of sockets (100 in the
    75 		if(subSession->Session() == iSession)
    78     // original case) and terminates without closing them, leaving BeginSessionClose() to clean them up.
    76 			{
    79     // In addition, the worker in question (pdummy1) synchronously deletes subsessions (1) and uses a shared
    77 			++iNumSubSessClosing;
    80     // shared heap configuration (i.e. limited memory).  As each deletion results in a message being sent
    78 			if(!subSession->IsClosing())
    81     // (to an SCPR), and there is no opportunity to drain these due to the synchronous deletion, the transport
    79 				{
    82     // queue overflows and cannot be grown resulting in a panic.  So use a (*low* priority) active object to
    80 				subSession->DeleteMe();
    83     // delete a limited number of subsessions per RunL().
    81 				}
    84     //
    82 			}
    85     // (1) a call to DeleteMe() results in an immediate upcall to NotifySubSessionDestroyed(). 
    83 		}
    86     
    84 
    87     TInt count = KSubSessionThrottleSize;
    85 	NotifySubSessionDestroyed();	// remove the dummy subsession
    88     
    86 	}
    89     // The object container is stored as a packed array, so working backwards through it avoids invalidating
       
    90     // the iterator when removing entries (and as a bonus is more efficient)
       
    91 
       
    92     CCommonPlayer::TSubSessionContainer& subSessions(iPlayer.SubSessions());
       
    93     for(TInt i = subSessions.Count() - 1; i >= 0; --i)
       
    94         {
       
    95         CWorkerSubSession* subSession = subSessions[i];
       
    96         if(subSession->Session() == iSession)
       
    97             {
       
    98             ++iNumSubSessClosing;
       
    99             if(!subSession->IsClosing())
       
   100                 {
       
   101                 subSession->DeleteMe();
       
   102                 // Throttle the deletions as appropriate
       
   103                 if (--count <= 0)
       
   104                     {
       
   105                     COMMONLOG((Player().WorkerId(),KECommonBootingTag, _L8("CCommonSessionProxy %08x:\tDeleteSubSessionBunch(): throttled subsession deletion"), this) );
       
   106                     // Re-prime the one shot
       
   107                     iSubSessionCloseThrottle.Call();
       
   108                     return;
       
   109                     }
       
   110                 }
       
   111             }
       
   112         }
       
   113     NotifySubSessionDestroyed();    // all, done, remove the dummy subsession
       
   114     }
       
   115 
    87 
   116 EXPORT_C void CCommonSessionProxy::NotifySubSessionDestroyed()
    88 EXPORT_C void CCommonSessionProxy::NotifySubSessionDestroyed()
   117 	{
    89 	{
   118 	//COMMONLOG((Player().WorkerId(),KECommonBootintgTag, _L8("CCommonSessionProxy %08x:\tNotifySubSessionDestroyed(), iSockSession %08x"), this, iSession) );
    90 	//COMMONLOG((Player().WorkerId(),KECommonBootingTag, _L8("CCommonSessionProxy %08x:\tNotifySubSessionDestroyed(), iSockSession %08x"), this, iSession) );
   119 	if(IsClosing() &&--iNumSubSessClosing <= 0)
    91 	if(IsClosing() && --iNumSubSessClosing <= 0)
   120 	    {
    92 		{
   121         __ASSERT_DEBUG(iNumSubSessClosing == 0, User::Panic(KSpecAssert_ElemSvrDenPlayrC, 2));
    93 		__ASSERT_DEBUG(iNumSubSessClosing == 0, User::Panic(KSpecAssert_ElemSvrDenPlayrC, 2));
   122         CCommonWorkerThread& worker = iPlayer.WorkerThread();
    94 		CCommonWorkerThread& worker = iPlayer.WorkerThread();
   123         worker.CompleteSessionClose(iSession);
    95 		worker.CompleteSessionClose(iSession);
   124         delete this;
    96 		delete this;
   125 	    }
    97 		}
   126 	}
    98 	}
   127 
    99 
   128 //
       
   129 // CCommonSessionProxy::CSubSessionCloseThrottle
       
   130 //
       
   131 
       
   132 CCommonSessionProxy::CSubSessionCloseThrottle::CSubSessionCloseThrottle(CCommonSessionProxy& aProxy)
       
   133   : CAsyncOneShot(EPriorityLow), iProxy(aProxy)     // This must be low priority!
       
   134     {
       
   135     }
       
   136 
       
   137 void CCommonSessionProxy::CSubSessionCloseThrottle::RunL()
       
   138     {
       
   139     // Delete some more subsessions
       
   140     iProxy.DeleteSubSessionsWithThrottling();
       
   141     }
       
   142 
   100 
   143 //
   101 //
   144 // CCommonPlayer
   102 // CCommonPlayer
   145 //
   103 //
   146 
   104