--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/ssock/SS_GLOB.CPP Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,398 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+#include "ss_glob.h"
+
+#include <comms-infras/ss_roles.h>
+#include <ss_std.h>
+#include <comms-infras/ss_log.h>
+#include <ss_protprov.h>
+#include <comms-infras/ss_subconnprov.h>
+#include <comms-infras/ss_connprov.h>
+#include <comms-infras/ss_metaconnprov_internal.h>
+#include <elements/nm_common.h> //for Messages::TlsGlobals
+#include <comms-infras/ss_subconnflow.h>
+#include <comms-infras/ss_protflow.h>
+#include <comms-infras/ss_nodemessages.h>
+#include <comms-infras/ss_tiermanager.h>
+#include <comms-infras/ss_tiermanager_internal.h>
+#include "ss_apiext_messages.h"
+#include <comms-infras/ss_mcprnodemessages.h>
+#ifdef SYMBIAN_ZERO_COPY_NETWORKING
+#include <comms-infras/commsbufpondop.h>
+#else
+#include <es_mbman.h>
+#endif // SYMBIAN_ZERO_COPY_NETWORKING
+
+
+#ifdef _DEBUG
+// Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
+// (if it could happen through user error then you should give it an explicit, documented, category + code)
+_LIT(KSpecAssert_ESockSSockS_GLOB, "ESockSSockS_GLOB");
+#endif
+
+using namespace ESock;
+using namespace Messages;
+using namespace Den;
+
+CSockManData::CSockManData(CGlobals& aGlobals, CWorkerThread* aWorker)
+: iWorkerThread(aWorker),
+ iTransportGlobals(aGlobals),
+ iCommsApiExtRegister(aGlobals)
+ {
+ __ASSERT_DEBUG(!SockManGlobals::Get(), User::Panic(KSpecAssert_ESockSSockS_GLOB, 1));
+ SockManGlobals::Set(this);
+ }
+
+CSockManData::~CSockManData()
+ {
+ SockManGlobals::Set(NULL);
+ iFCMap.Close();
+ delete iTimer;
+ delete iEskData;
+ delete iWorkerThread;
+ }
+
+CSockManData* CSockManData::NewL(CGlobals& aGlobals, CWorkerThread* aWorker)
+ {
+ CSockManData* globs = new(ELeave) CSockManData(aGlobals, aWorker);
+ CleanupStack::PushL(globs);
+ globs->ConstructL();
+ CleanupStack::Pop(globs);
+ return globs;
+ }
+
+void CSockManData::ConstructL()
+ {
+ iExtensions.SetOffset(_FOFF(CSocketServExtRef, iExtLink));
+
+ //at the moment the CProtocolFamilyFactoryBase subclasses' instances are created along with
+ //the protocol family being loaded (applies to the new protocols only)
+ iTimer=CDeltaTimer::NewL(ESocketTimerPriority, KTimerGranularity);
+ iTimer->Deque(); //PERF: re-add upon first use
+
+// globals->iNumSessions=0;
+// globals->iNumFamilies=0;
+#ifdef SYMBIAN_ZERO_COPY_NETWORKING
+ iCommsBufPond=TCommsBufPondTLSOp::Get();
+#else
+ iMBufManager=CMBufManager::Context();
+#endif // SYMBIAN_ZERO_COPY_NETWORKING
+ }
+
+TBool CSockManData::ShutdownGracefully()
+/**
+@return Whether the socket server intends to shutdown (ETrue) at first opportunity
+when there is no connections to it. If ETrue it doesnt accept new connections.
+*/
+ {
+ return SelfWorker()->ShuttingDown();
+ }
+
+EXPORT_C Messages::TNodeId CSockManData::GetPlaneFC(const TPlayerRole& aPlane)
+ {
+ return iFCMap.GetPlaneFC(aPlane);
+ }
+
+
+void CSockManData::InstallFactoryContainersL()
+ {
+ __ASSERT_DEBUG( iWorkerThread->Player() , User::Panic(KSpecAssert_ESockSSockS_GLOB, 2)); // Only Players have factories
+ CPlayer& player(*iWorkerThread->Player());
+
+ if (!iTierManagerFactories && player.HasTierMgrPlane())
+ {
+ iTierManagerFactories = CTierManagerFactoryContainer::NewL();
+ TNodeId fc(iTierManagerFactories->Id());
+ iFCMap.AddPlaneFC(TCFPlayerRole(TCFPlayerRole::ETierMgrPlane), fc);
+ iTransportGlobals.AddPersistentItf(fc);
+ }
+
+ if (!iMetaConnectionFactories && player.HasMetaConnPlane())
+ {
+ iMetaConnectionFactories = CMetaConnectionFactoryContainer::NewL();
+ TNodeId fc(iMetaConnectionFactories->Id());
+ iFCMap.AddPlaneFC(TCFPlayerRole(TCFPlayerRole::EMetaConnPlane), fc);
+ iTransportGlobals.AddPersistentItf(fc);
+ }
+
+ if (!iConnectionFactories && player.HasConnPlane())
+ {
+ iConnectionFactories = CConnectionFactoryContainer::NewL();
+ TNodeId fc(iConnectionFactories->Id());
+ iFCMap.AddPlaneFC(TCFPlayerRole(TCFPlayerRole::EConnPlane), fc);
+ iTransportGlobals.AddPersistentItf(fc);
+
+ // Install a new object broker for all of the factory containers in affiliated worker threads
+ __ASSERT_DEBUG(!iCommsFactoryContainerBrokerSingleton, User::Panic(KSpecAssert_ESockSSockS_GLOB, 3));
+ iCommsFactoryContainerBrokerSingleton = CCFFactoryContainerBroker::NewL();
+ iTransportGlobals.AddPersistentItf(iCommsFactoryContainerBrokerSingleton->Id());
+
+ // Keep this locally for factory requests in our own thread
+ // Other workers learn about it through an advertisement message
+ iCommsFactoryContainerBroker = iCommsFactoryContainerBrokerSingleton->Id();
+ }
+
+ if (!iSubConnectionFactories && player.HasSubConnPlane())
+ {
+ iSubConnectionFactories = CSubConnectionFactoryContainer::NewL();
+ TNodeId fc(iSubConnectionFactories->Id());
+ iFCMap.AddPlaneFC(TCFPlayerRole(TCFPlayerRole::ESubConnPlane), fc);
+ iTransportGlobals.AddPersistentItf(fc);
+ }
+
+ LOG(ESockLog::Printf(_L("ProtocolFamilyFactories Initialisation")));
+
+ if (!iProtocolFamilyFactories && player.HasDataPlane())
+ {
+ iProtocolFamilyFactories = CProtocolFamilyFactoryContainer::NewL();
+ iTransportGlobals.AddPersistentItf(iProtocolFamilyFactories->Id());
+ }
+
+ if (!iSubConnectionFlowFactories&& player.HasDataPlane())
+ {
+ iSubConnectionFlowFactories = CSubConnectionFlowFactoryContainer::NewL();
+ TNodeId fc(iSubConnectionFlowFactories->Id());
+ iFCMap.AddPlaneFC(TCFPlayerRole(TCFPlayerRole::EDataPlane), fc);
+ iTransportGlobals.AddPersistentItf(fc);
+ // SubConnection Factory Container receives the cookie of the Flow Factory Container,
+ // as the former hosts requests to initiate Flow creation.
+ // iSubConnectionFactories->SetFlowFactoryCookieL(0, (*iSubConnectionFlowFactories)());
+ }
+
+ if (!iProtocolIntfFactories && player.HasDataPlane())
+ {
+ iProtocolIntfFactories = CProtocolIntfFactoryContainer::NewL();
+ iTransportGlobals.AddPersistentItf(iProtocolIntfFactories->Id());
+ }
+
+ // Now add our own factory containers to the object broker if we are hosting it, as we won't
+ // be told about the broker if we are hosting it and won't then get a chance to send our FCs to it
+ if (player.HasConnPlane())
+ {
+ if (iTierManagerFactories)
+ {
+ AddFactoryContainerObjectBrokerClient(
+ iTierManagerFactories->Id(),
+ TCFPlayerRole(TCFPlayerRole::ETierMgrPlane)
+ );
+ }
+
+ if (iMetaConnectionFactories)
+ {
+ AddFactoryContainerObjectBrokerClient(
+ iMetaConnectionFactories->Id(),
+ TCFPlayerRole(TCFPlayerRole::EMetaConnPlane)
+ );
+ }
+
+ if (iConnectionFactories)
+ {
+ AddFactoryContainerObjectBrokerClient(
+ iConnectionFactories->Id(),
+ TCFPlayerRole(TCFPlayerRole::EConnPlane)
+ );
+ }
+
+ if (iSubConnectionFactories)
+ {
+ AddFactoryContainerObjectBrokerClient(
+ iSubConnectionFactories->Id(),
+ TCFPlayerRole(TCFPlayerRole::ESubConnPlane)
+ );
+ }
+
+ if (iSubConnectionFlowFactories)
+ {
+ AddFactoryContainerObjectBrokerClient(
+ iSubConnectionFlowFactories->Id(),
+ TCFPlayerRole(TCFPlayerRole::EDataPlane)
+ );
+ }
+ }
+
+ // Register internal messages
+ TCFMessage::RegisterL();
+ TCFSafeMessage::RegisterL();
+ TExtItfMsgTables::RegisterL();
+ }
+
+void CSockManData::AddFactoryContainerObjectBrokerClient(
+ const Messages::TNodeId& aNodeId,
+ const TCFPlayerRole& aType)
+ {
+ // Should only be adding them once
+ __ASSERT_DEBUG(0 == iCommsFactoryContainerBrokerSingleton->CountClients<TDefaultClientMatchPolicy>(aType), User::Panic(KSpecAssert_ESockSSockS_GLOB, 4));
+
+ iCommsFactoryContainerBrokerSingleton->AddClientL(
+ aNodeId,
+ aType
+ );
+ }
+
+void CSockManData::UninstallFactoryContainers()
+ {
+ // De-Register internal messages
+ TCFMessage::DeRegister();
+ TCFSafeMessage::DeRegister();
+ TExtItfMsgTables::DeRegister();
+
+ delete iCommsFactoryContainerBrokerSingleton;
+ delete iSubConnectionFactories;
+ delete iConnectionFactories;
+ delete iProtocolIntfFactories;
+ delete iProtocolFamilyFactories;
+ delete iSubConnectionFlowFactories;
+ delete iMetaConnectionFactories;
+ delete iTierManagerFactories;
+ }
+
+// Support self-awareness when logging
+EXPORT_C CWorkerThread* CSockManData::SelfWorker() const
+ {
+ return iWorkerThread;
+ }
+
+// Support self-awareness when logging
+EXPORT_C CPlayer* CSockManData::SelfPlayer()
+ {
+ return iWorkerThread->Player();
+ }
+
+void SockManGlobals::Set(CSockManData * aGlobals)
+ {
+ Dll::SetTls(aGlobals);
+ }
+
+EXPORT_C CSockManData* SockManGlobals::Get()
+ {
+ CSockManData * d=(CSockManData *)Dll::Tls();
+ return d;
+ }
+
+#ifdef SYMBIAN_NETWORKING_PERFMETRICS
+void CSockManData::IncludePerformanceData(TInt aDeltaClientRxBytes, TInt aDeltaClientRxBuffBytes, TInt aDeltaClientTxBytes)
+ {
+ if(aDeltaClientRxBytes >= 0)
+ {
+ iRxStats.AccumulateXfer(aDeltaClientRxBytes);
+ }
+ if(aDeltaClientRxBuffBytes >= 0)
+ {
+ iRxBuffStats.AccumulateXfer(aDeltaClientRxBuffBytes);
+ }
+ if(aDeltaClientTxBytes >= 0)
+ {
+ iTxStats.AccumulateXfer(aDeltaClientTxBytes);
+ }
+ }
+
+
+TBool CSockManData::AddToPerfLog(TAny* aSelf, TDes8& aBuffer, TDes8Overflow* aOverflowHandler)
+ {
+ CSockManData* self = static_cast<CSockManData*>(aSelf);
+ _LIT8(KFormat, "ESock Rx: tot %u; cnt %u; %u, %u, %u, %u, %u, %u; RxBuff: tot %u; %u, %u, %u, %u, %u, %u, Tx: tot %u; cnt %u; %u; %u, %u, %u, %u, %u");
+ TXferStats& rx = self->iRxStats;
+ TXferStats& rxB = self->iRxBuffStats;
+ TXferStats& tx = self->iTxStats;
+ aBuffer.AppendFormat(KFormat, aOverflowHandler,
+ rx.iTotal, rx.iCount, rx.iBuckets[0], rx.iBuckets[1], rx.iBuckets[2], rx.iBuckets[3], rx.iBuckets[4], rx.iBuckets[5],
+ rxB.iTotal, rxB.iBuckets[0], rxB.iBuckets[1], rxB.iBuckets[2], rxB.iBuckets[3], rxB.iBuckets[4], rxB.iBuckets[5],
+ tx.iTotal, tx.iCount, tx.iBuckets[0], tx.iBuckets[1], tx.iBuckets[2], tx.iBuckets[3], tx.iBuckets[4], tx.iBuckets[5]
+ );
+ return EFalse;
+ }
+
+void CSockManData::TXferStats::AccumulateXfer(TUint aValue)
+ {
+ ++iCount;
+ if(aValue > 0)
+ {
+ iTotal += aValue;
+ TInt bucketCap = 128;
+ TInt bucket = 0;
+ while(bucket < KNumBuckets)
+ {
+ if(bucketCap > aValue)
+ {
+ ++iBuckets[bucket];
+ break;
+ }
+ bucketCap <<= 2;
+ ++bucket;
+ }
+ }
+ }
+
+
+CSockManData::~CSockManData()
+ {
+ CommsFW::CPerfMetricStore::RemoveClient(this);
+ }
+
+#endif
+
+const ::CESockIniData* CSockManData::IniData()
+ {
+ return iEskData;
+ }
+
+#ifdef ESOCK_HOME_THREAD_CHECK_ENABLED
+
+void CSockManData::AssertOwnThread() const
+ {
+ TThreadId home = iWorkerThread->OwnThread();
+ TThreadId curr = RThread().Id();
+ if(home != curr)
+ {
+ Fault(EWrongThread);
+ }
+ }
+
+#endif
+
+#ifdef _DEBUG
+
+void CSockManData::LogActiveProtocols()
+ {
+ TSglQueIter<CProtocolRef> i(*iProtocols);
+ CProtocolRef* ref = NULL;
+ while((ref = i++) != NULL)
+ {
+ CProtocolBase* prot = ref->Protocol();
+ if(prot)
+ {
+ CProtocolFamilyBase* fam = prot->ProtocolFamily();
+ LOG(ESockLog::Printf(KESockSessDetailTag, _L("* Prot %S refCnt = %d, family refCnt = %d"), &ref->Info().iName, prot->RefCount(), fam->RefCount() ));
+ }
+ }
+ }
+
+#endif
+
+EXPORT_C CCommsFactoryBase* CSockManData::InstallFactoryL( ESock::EFactoryType aFactoryType, const TDesC8& aName, TUid aFactoryUid )
+ {
+ CSockManData *globals=SockManGlobals::Get();
+ CCommsFactoryBase* pBase = NULL;
+ switch (aFactoryType)
+ {
+ case EProtocolFamilyFactory:
+ pBase = globals->iProtocolFamilyFactories->FindOrCreateL( aName, aFactoryUid );
+ break;
+ default:
+ User::Leave(KErrNotSupported);
+ break;
+ };
+ return pBase;
+ }