--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/commsfwsupport/commselements/serverden/inc/sd_roles.h Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,690 @@
+// Copyright (c) 2008-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:
+// THIS WHOLE FILE IS INTERNAL COMPONENT - DO NOT ADD NON-INTERNAL ITEMS
+//
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#ifndef SYMBIAN_DEN_ROLES_H
+#define SYMBIAN_DEN_ROLES_H
+
+#include <e32property.h>
+#include <elements/sd_std.h>
+#include <elements/sd_thread.h>
+#include <elements/interfacetable.h>
+
+namespace Den
+{
+
+class CCommonPlayer;
+class CCommonDealer;
+class CWorkerSubSession;
+class TWorkerIntroductionMsg;
+
+class CWorkerDataGlobals : public CommsFW::CWorkerThreadDataGlobals<TWorkerThreadRegister, CommsFW::KMaxWorkerId>
+ {
+public:
+ static CWorkerDataGlobals* NewL()
+ {
+ CWorkerDataGlobals* self = new(ELeave) CWorkerDataGlobals();
+ CleanupStack::PushL(self);
+ self->ConstructL(sizeof(TWorkerThreadRegister), CommsFW::KMaxWorkerId);
+ CleanupStack::Pop(self);
+ return self;
+
+ // Because the curr
+ }
+
+ CCommonWorkerThread* WorkerThread(CommsFW::TWorkerId aWorker) const
+ {
+ return GetWorkerGlobals(aWorker)->iWorker;
+ }
+ };
+
+/**
+Interface used by the CPeerDeathNotifier to notify a subscriber of thread death.
+@see CPitBoss
+*/
+NONSHARABLE_CLASS(MPeerDeathObserver)
+ {
+public:
+ virtual void OnPeerDeath(CommsFW::TWorkerId aWorkerId) = 0;
+ };
+
+/**
+Monitors a worker thread and notifies the observer if it dies.
+@see RThread::Logon()
+*/
+NONSHARABLE_CLASS(CPeerDeathNotifier) : public CActive
+ {
+public:
+ CPeerDeathNotifier(CommsFW::TWorkerId aWorkerId, RThread aThread, MPeerDeathObserver& aObserver);
+private:
+ RUndertaker iUndertaker; //< Unused, should be removed
+private:
+ void DoCancel();
+ void RunL();
+private:
+ CommsFW::TWorkerId iWorkerId; //< The worker id of the thread being monitored.
+ RThread iThread; //< The handle to the thread being monitored.
+ MPeerDeathObserver& iObserver; //< The observer to Notify.
+ };
+
+
+/**
+Interface used by the CConfigurationLevelMonitor to notify a subscriber when
+the Reference Configurator has configured the core components (configuration level == RootServer::ECoreComponentsStarted).
+@see CPitBoss
+*/
+NONSHARABLE_CLASS(MConfiguratorObserver)
+ {
+public:
+ virtual void OnCPMsConfigured() = 0;
+ virtual TUid PropertyKey()=0;
+ };
+
+/**
+Subscribes to the configuration level property published by the reference configurator.
+Calls the subscribed MConfiguratorObserver when the Reference Configurator has configured
+the core components (configuration level == RootServer::ECoreComponentsStarted).
+@see CPitBoss
+*/
+NONSHARABLE_CLASS(CConfigurationLevelMonitor) : public CActive
+ {
+public:
+ static CConfigurationLevelMonitor* NewL(MConfiguratorObserver* aObserver);
+ ~CConfigurationLevelMonitor();
+protected:
+ CConfigurationLevelMonitor(MConfiguratorObserver* aObserver);
+ void Subscribe();
+ void RunL();
+ void DoCancel();
+protected:
+ /** The configuration level property published by the reference configurator.
+ */
+ RProperty iConfLevelProperty;
+
+ /** The observer waiting for notification that core components have been configured. */
+ MConfiguratorObserver* iObserver;
+
+ /** Set ETrue when the level has reached RootServer::ECoreComponentsStarted.
+ Used to ensure the observer is only called once even though the level keeps
+ being published beyond RootServer::ECoreComponentsStarted.
+ */
+ TBool iCoreComponentsConfigured;
+ };
+
+/**
+The PitBoss has responsibility for global resources and gross error handling (panics, etc).
+The Pit Boss thread must be started by the Configurator before any worker threads. The
+instance loading it must be the only one having the WorkerId 0 (TWorkerThreadInfo::EMainThread).
+The PitBoss has two main responsibilities:
+ -# Maintain global data structures, accessible to all Workers to which the PitBoss
+ pointer is published (through the TWorkerMainIntroductionMsg).
+ Mostly the workers will access this data using PitBoss access functions which are thread-safe,
+ taking special measures to guarantee this where needed.
+ -# Manage Worker thread start and death: Registering Workers and
+ do a best effort cleanup if they die due to some error condition.
+
+Apart from these, the PitBoss also provides some minor but important services. For example as
+all instances can have their own heap sometimes it happens that one Worker needs to do
+something that might cause allocation or freeing on another workers heap, such as inserting a
+sub-session into a Dealers session. So the PitBoss offer a function that can determine whether
+a different heap is needed (maybe the two workers have different heaps, maybe they share one heap)
+and does the switch.
+It also has AddSubSession() and RemoveSubSession() methods used by the Player, assuring this
+happens on the right heap.
+*/
+class CCommonPitBoss : public CBase,
+ public MPeerDeathObserver,
+ public MConfiguratorObserver,
+ public NetInterfaces::TInterfaceControl
+ {
+ friend class TWorkerThreadRegister;
+public:
+ IMPORT_C ~CCommonPitBoss();
+
+protected:
+ IMPORT_C CCommonPitBoss(CCommonWorkerThread* aOwnerThread);
+
+public:
+ IMPORT_C void BindMessageReceived(const CommsFW::TCFModuleName& aPeerName, CommsFW::TWorkerId aPeerId);
+ IMPORT_C void ProcessWorkerIntroductionL(const TWorkerIntroductionMsg& aMsg);
+ IMPORT_C void BroadcastConfigurationComplete(TConfigurationCompletionType aType);
+
+ IMPORT_C TBool ModuleConfigurationComplete() const;
+ TInt NextSessionId();
+
+ IMPORT_C void ConstructL();
+
+ IMPORT_C TBool IsShuttingDown() const;
+ void StartShutdown();
+ IMPORT_C void SessionShutdownComplete();
+ IMPORT_C TBool FindOptimalDealer(CommsFW::TWorkerId aWorkerId, CCommonWorkerDealer*& aDealer);
+ void ShutdownIfReady();
+
+ IMPORT_C void PeerWorkerExiting(CommsFW::TWorkerId aWorker);
+
+ TBool TestAndLockImmediateShutdownPresent() const;
+ void ReleaseImmediateShutdownPresent() const;
+ void SetImmediateShutdownPresent();
+ IMPORT_C TBool TestImmediateShutdownPresent() const;
+
+ CWorkerDataGlobals& WorkerDataGlobals() const
+ {
+ return *iWorkerDataGlobals;
+ }
+
+ CCommonDealer* Dealer(const TWorkerThreadRegister& aRegister)
+ {
+ return aRegister.iDealer;
+ }
+
+ CCommonPlayer* Player(const TWorkerThreadRegister& aRegister)
+ {
+ return aRegister.iPlayer;
+ }
+
+ CCommonWorkerThread* OwnerThread()
+ {
+ return iOwnerThread;
+ }
+
+ IMPORT_C CCommonDealer* GetDealer(CommsFW::TWorkerId aId);
+ IMPORT_C CCommonPlayer* GetPlayer(const TWorkerIntroductionMsg& aMsg);
+
+ IMPORT_C void PostMessage(CommsFW::TWorkerId aWorkerId, CommsFW::TCFMessage& aMessage);
+ CCommonDealer* Dealer(CommsFW::TWorkerId aWorkerId) const;
+ CCommonPlayer* Player(CommsFW::TWorkerId aWorkerId) const;
+ inline CCommonWorkerThread& WorkerThread() const;
+ IMPORT_C const RThread& RThreadRef(CommsFW::TWorkerId aWorkerId) const;
+ /** Resolve a Worker thread's CFModule name to its thread id (module names are far less volatile than thread assignments
+ which in the future may become highly dynamic. So module names are used to couple tier ids to threads
+ */
+ IMPORT_C TBool ResolveWorkerNameToId(const TDesC8& aWorkerName, CommsFW::TWorkerId& aWorkerId) const;
+ /** Resolve a PlayerRole to its thread id (module names are far less volatile than thread assignments
+ which in the future may become highly dynamic. So module names are used to couple tier ids to threads
+ */
+ IMPORT_C TBool ResolvePlayerRoleToId(const TPlayerRole& aRoleId, CommsFW::TWorkerId& aWorkerId) const;
+
+ IMPORT_C TBool WorkerExists(CommsFW::TWorkerId aId) const;
+
+ // Session container manipulation - used by Player
+ IMPORT_C TInt AddSubSession(CWorkerSubSession* aSubSession, CWorkerSession* aSession, TInt& aHandle);
+ IMPORT_C void RemoveSubSession(TInt aHandle, CWorkerSession* aSession);
+
+ IMPORT_C void HandleWorkerCleanupCompletionByPeer(CommsFW::TWorkerId aWorkerId, CommsFW::TWorkerId aPeerId);
+ void CompleteWorkerThreadCleanup(CommsFW::TWorkerId aWorkerId);
+
+ // MPeerDeathNotification
+ IMPORT_C void OnPeerDeath(CommsFW::TWorkerId aWorkerId);
+ virtual void DoOnPeerDeath(CommsFW::TWorkerId aWorkerId) = 0;
+ //Defaut RedShirt, uses PostMortemCleanupThreadEntry
+ IMPORT_C virtual TInt DoCreateRedShirt(RThread& aRedShirt, CommsFW::TWorkerId aWorkerId, CCommonWorkerThread& aDeadWorker);
+
+ // MConfiguratorObserver
+ IMPORT_C void OnCPMsConfigured();
+ virtual void DoOnCPMsConfigured()=0;
+
+ TUid PropertyKey()
+ {
+ return iPropertyKey;
+ }
+
+ inline TSubSessionUniqueId NextSubSessionUniqueId();
+ inline TSessionUniqueId NextSessionUniqueId();
+
+ void FreeWorkerReferences(CommsFW::TWorkerId aWorkerId);
+
+ IMPORT_C RAllocator* MaybeSwitchHeap(CommsFW::TWorkerId aForeignWorkerId);
+ void AddPendingIntroductionResponse();
+ void RemovePendingIntroductionResponse();
+
+ IMPORT_C void SetFailNextForAllHeaps(TInt aFailNext);
+ IMPORT_C TBool TestFailNextForAllHeaps() const;
+
+protected:
+ virtual void DoProcessWorkerIntroductionL(const TWorkerIntroductionMsg& aMsg) = 0;
+ virtual void DoFreeWorkerReferences(CommsFW::TWorkerId aWorkerId) = 0;
+
+protected:
+ CCommonWorkerThread* iOwnerThread;
+ CWorkerDataGlobals* iWorkerDataGlobals;
+ /**
+ Incremented when a request to bind to another instance has been received and decremented when a
+ binding is complete.
+ When the reference configurator configuration level have reached the point signifying that all core
+ components have been configured and this TInt is 0, it is safe to delete data structures used only during
+ startup.
+ @see OnCoreComponentsConfigured()
+ */
+ TInt iPendingIntroResponses;
+
+
+ /**
+ ETrue if the PitBoss is in the process of shutting down. Set when optional or graceful shutdown
+ is received by ESock_Main from the RootServer.
+ */
+ TBool iShuttingDown;
+
+ /**
+ Set ETrue when immediate shutdown is received by ESock_Main from the RootServer or if
+ optional/graceful shutdown has been received at some point and the last session is closed.
+ */
+ TBool iSessionShutdownComplete;
+
+ /**
+ Set ETrue when all Worker threads have finished tidying up during a shut down procedure.
+ The ESock_Main instance will only shut down when this is ETrue.
+ */
+ TBool iPeerShutdownComplete;
+
+ /**
+ This is used by Worker threads (as well as ESock_Main) during immediate shutdown. As a Worker
+ could potentially delete a sub-session at the same time as the Dealer trying to mark it orphaned,
+ these two operations need to be protected during immediate shutdown (but not normally).
+ */
+ mutable RWorkerLock iImmediateShutdownLock;
+
+ /**
+ Set ETrue when immediate shutdown is received from the RootServer.
+ */
+ TBool iImmediateShutdownMark;
+
+ /**
+ Monitor configuration level to know when it is safe to delete data used solely during startup/binding.
+ Note that if we should support loading new Socket Server modules at run time, sometime after system start,
+ this will need to be changed so the list is always available to new modules.
+ */
+ CConfigurationLevelMonitor* iConfLevelMonitor;
+
+ /**
+ Session/subsession unique id counter. This value represents a next (free)
+ id that will be assigned to a newly created CWorkerSubSession object.
+ */
+ TUint iNextUniqueId;
+ TUid iPropertyKey;
+
+//TODO: consider if this list is worth having in Den (urel + udeb) or just in esock (urel)
+//#ifdef _DEBUG
+ // We want to check for leaks whenever a heap is about to be destroyed, however if a thread using
+ // the heap panicked or was killed then this will give false leak indications, so we maintain this
+ // list of heaps known to be "forsaken" in this way.
+ class RForsakenHeapList : private RPointerArray<RAllocator>
+ {
+ public:
+ TInt Add(RAllocator* aHeap)
+ {
+ if(!IsForsaken(aHeap))
+ {
+ return Append(aHeap);
+ }
+ return KErrNone;
+ }
+ TBool IsForsaken(const RAllocator* aHeap) const
+ {
+ return Find(aHeap) >= 0;
+ }
+ void Close()
+ {
+ RPointerArray<RAllocator>::Close();
+ }
+ };
+ RForsakenHeapList iForsakenHeapList;
+//#endif
+ };
+
+const TInt KResetAllocFails = -73738;
+
+/** Helper class for switching the current thread to share that of a peer worker thread. This is necessary for heap manipulating
+actions such as adding to a container owned by the peer, as well as the more obvious case of deleting an object created by them.
+Construct a THeapSwitcher instance passing the identity of the peer thread to switch to using their heap. Destroy the THeapSwitcher
+instance or explicitly call RevertToOwnHeap() to resume using the normal heap for the caller thread.
+*/
+class THeapSwitcher
+ {
+public:
+ IMPORT_C THeapSwitcher(CCommonPitBoss& aPitBoss, const Messages::TNodeId& aTarget);
+ IMPORT_C THeapSwitcher(CCommonPitBoss& aPitBoss, CommsFW::TWorkerId aForeignWorkerId);
+ IMPORT_C ~THeapSwitcher();
+ IMPORT_C void RevertToOwnHeap();
+
+private:
+ IMPORT_C void MaybeSwitch(CCommonPitBoss& aPitBoss, CommsFW::TWorkerId aForeignWorkerId);
+ RAllocator* iPrev;
+ };
+
+/**
+The Dealer is an interface to the Symbian OS server (CServer2) and as such one of its most
+important possessions is the list of CSession2's kept by the CServer2. On a conceptual level
+one can say that the Dealer owns the CWorkerSession's due to their inherited relationship.
+Sub-sessions are also supported in the form of the CPlayerSubSession and its derivatives. These are owned
+by the provider container (CSubSessionIx) in the CWorkerSession.
+*/
+class CCommonDealer : public CBase
+ {
+public:
+ IMPORT_C static CCommonDealer* NewL(CCommonServer* aServer);
+ IMPORT_C ~CCommonDealer();
+
+ IMPORT_C const TDesC& ServerName() const;
+ IMPORT_C void DeleteSession(CWorkerSession* aSession);
+ IMPORT_C void CleanupDeadWorker(CommsFW::TWorkerId aPeerId);
+
+ TInt SubsessionCountInPlayer(CommsFW::TWorkerId aPeerId);
+
+ TBool CanShutdown() const
+ {
+ return iServer->CanShutdown();
+ };
+
+ CCommonWorkerThread& WorkerThread()
+ {
+ return iServer->WorkerThread();
+ }
+
+ CommsFW::TWorkerId WorkerId() const
+ {
+ return iServer->WorkerId();
+ }
+
+ /**
+ Returns whether the dealer is the main dealer or not.
+ A main dealer is a dealer which can receive IPC messages directly from a client.
+ Non-main dealers can not, and must have IPC messages handed to them by a main dealer.
+ */
+ virtual TBool MainDealer() const
+ {
+ return ETrue;
+ }
+
+ TBool CanUnbindFromWorker(CommsFW::TWorkerId aWorker);
+ IMPORT_C void ProcessConfigurationComplete(TConfigurationCompletionType aType);
+ void ProcessShutdownRequest(CommsFW::TCFShutdownType aType);
+ void ProcessSubSessions(CommsFW::TWorkerId aPeerId, CWorkerSession::TSubSessionProcessor aSubSessionProcessor, TAny* aArg);
+
+ enum TParkReason
+ {
+ /** During initial configuration a client request may have an indeterminate outcome, in that it relates to a
+ protocol that isn't known but might be yet to load. This would expose clients to the need to cope with a startup race
+ so instead such requests are "parked" until start-up is complete and an authorative answer can be made.
+ */
+ EIndeterminateDuringBoot,
+ /** The hosting of tier managers by worker threads is only determined upon the first need. The actual work is done by
+ the tier resolver; until this completes all requests needing this are parked
+ */
+ EAwaitingTierToWorkerMapping,
+ /** Some test cases concern competing client requests, such as a connection start and stop. A test harness can specify that
+ a sequence of requests is parked and then released together. This is only supported when _DEBUG_SOCKET_FUNCTIONS is defined,
+ ie usually only in UDEB
+ */
+ EDebugParking,
+ };
+
+ IMPORT_C TInt ParkRequest(CWorkerSession* aSession, const RMessage2& aMessage, TParkReason aReason) const; // Requests are parked by sessions, which consider servers const
+
+#if defined (__ELEMENTS_MESSAGE_INTERCEPT_ACTIVE)
+ void ReleaseDebugParkedRequests(CWorkerSession* aSess, TInt aSubSessHandle);
+#endif // __ELEMENTS_MESSAGE_INTERCEPT_ACTIVE
+
+protected:
+ IMPORT_C CCommonDealer(CCommonServer* aServer);
+ IMPORT_C void ConstructL();
+ void ReleaseParkedRequests(TParkReason aReason);
+
+protected:
+ class TParkedRequest
+ {
+ public:
+ TParkedRequest(CWorkerSession* aSession, const RMessage2& aMessage, TParkReason aReason);
+ public:
+ CWorkerSession* iSession;
+ RMessage2 iMessage;
+ TParkReason iReason;
+ };
+
+ typedef RArray<TParkedRequest> RParkedRequestArray;
+ mutable RParkedRequestArray iParkedRequests;
+ CCommonServer* iServer;
+ };
+
+/**
+All Worker Threads, which are not the main Dealer can contain a Dealer, a Player, or both
+(often referred to as a DealerPlayer). If the Worker contains a DealerPlayer, the Dealer is
+also said to be a WorkerDealer or an Optimal Dealer, as clients can create connections directly
+to it and thus avoid a thread context shift between Dealer and Player when IPC messages are processed.
+*/
+NONSHARABLE_CLASS(CCommonWorkerDealer) : public CCommonDealer
+ {
+protected:
+ static const TInt KMaxEligibleList = 8; //< Maximum length for queue of clients eligible to connect to WorkerDealer
+
+public:
+ IMPORT_C static CCommonWorkerDealer* NewL(CCommonServer* aServer);
+ IMPORT_C ~CCommonWorkerDealer();
+ IMPORT_C void AddEligiblePidL(TProcessId aId);
+ IMPORT_C void RemoveEligiblePid(TProcessId aId);
+ IMPORT_C TBool IsEligible(TProcessId aId);
+ TBool ProcessShutdownRequest(CommsFW::TCFShutdownType aType);
+
+ /**
+ This dealer is not a main dealer, so return false. It can only receive messages from a main dealer and
+ not directly from a client.
+
+ @see CCommonDealer::MainDealer
+ */
+ virtual TBool MainDealer() const
+ {
+ return EFalse;
+ }
+
+protected:
+ IMPORT_C explicit CCommonWorkerDealer(CCommonServer* aServer);
+ IMPORT_C void ConstructL();
+
+private:
+ /**
+ CCommonWorkerDealer::XEligibleClients
+ Contains a list of clients eligible to connect to a WorkerDealer.
+ Uses locking in the accessor functions to prevent unpleasant situations.
+ This is an X-class because it has an unusual pattern of being embedded in
+ the containing C-class yet having a necessary ConstructL() and destructor.
+ */
+ NONSHARABLE_CLASS(XEligibleClients)
+ {
+ public:
+ XEligibleClients();
+ ~XEligibleClients();
+ void ConstructL();
+ void AddL(TProcessId aId);
+ void Remove(TProcessId aId);
+ TBool IsEligible(TProcessId aId);
+ private:
+ /**
+ The list of IDs authorized to create a session directly on this WorkerDealer.
+ @see ::AddL
+ @see ::Remove
+ @see ::IsEligible
+ */
+ TProcessId iEligibleClients[KMaxEligibleList];
+
+ /**
+ Provide atomic access to the list (iEligibleClients)
+ @see ::AddL
+ @see ::Remove
+ */
+ RWorkerLock iLock;
+ };
+
+private:
+ //RServer2 iSessionSustainer; // Unused, should be removed.
+ XEligibleClients iEligibleClients; //< List of clients eligible to connect to the WorkerDealer.
+ };
+
+/**
+Represents the session for Player-side actions, such as tracking protocol
+references and session observers. Has responsibility for handling session
+close, including signalling close complete back to the Dealer
+*/
+class CCommonSessionProxy : public CBase
+ {
+private:
+ enum { ELivingSession = 0x80000000 };
+
+public:
+ IMPORT_C ~CCommonSessionProxy();
+
+ static TInt GetLinkOffset()
+ {
+ return _FOFF(CCommonSessionProxy, iLink);
+ }
+
+ const CWorkerSession* Session() const
+ {
+ return iSession;
+ }
+
+ CCommonPlayer& Player() const
+ {
+ return iPlayer;
+ }
+
+ TBool IsClosing() const
+ {
+ return iNumSubSessClosing != ELivingSession;
+ }
+
+ void BeginSessionClose();
+ IMPORT_C void NotifySubSessionDestroyed();
+
+protected:
+ IMPORT_C CCommonSessionProxy(CWorkerSession* aSession, CCommonPlayer& aPlayer);
+
+private:
+ CWorkerSession* iSession; //< The session which is represented by proxy instance
+ CCommonPlayer& iPlayer;
+ TInt iNumSubSessClosing; //< Number of subsessions in current thread to complete
+ TDblQueLink iLink;
+ };
+
+/**
+class CCommonPlayer
+The main responsibility is adding/removing sub-sessions from the provider container
+in the related session object as well as keeping a list of all sub-sessions handled
+by the Player instance (iSubSessions).
+*/
+class CCommonPlayer : public CBase
+ {
+public:
+ typedef RPointerArray<CWorkerSubSession> TSubSessionContainer;
+
+public:
+ IMPORT_C ~CCommonPlayer();
+
+ IMPORT_C void ProcessMessageL(const RSafeMessage& aMsg, CWorkerSubSession* aSubSession);
+ virtual void DoProcessMessageL(const RSafeMessage& aMsg, CWorkerSubSession* aSubSession) = 0;
+
+ void PanicClient(CWorkerSubSession& aSubSession, TInt aPanic);
+ void PanicClient(CWorkerSubSession& aSubSession, const TDesC& aCategory, TInt aPanic);
+ IMPORT_C void PanicClient(TInt aPanic);
+ IMPORT_C void PanicClient(const TDesC& aCategory, TInt aPanic);
+
+ IMPORT_C void CleanupDeadWorker(CommsFW::TWorkerId aPeerId);
+
+ inline TPlayerRole PlayerRole() const;
+ void SetPlayerRole(const TPlayerRole& aType);
+
+ inline CCommonWorkerThread& WorkerThread() const;
+ inline CommsFW::CCommsTransport& Transport() const;
+ inline CommsFW::TWorkerId WorkerId() const;
+ inline CCommonPitBoss& PitBoss() const;
+
+ inline const RSafeMessage& SafeMessage() const;
+
+ inline CWorkerSession* Session() const;
+ void SetSession(CWorkerSession* aWorkerSession)
+ {
+ iSession=aWorkerSession;
+ }
+
+ CCommonWorkerThread* OwnerThread()
+ {
+ return iOwnerThread;
+ }
+
+ inline TSubSessionContainer& SubSessions();
+
+ TBool CanUnbindFromWorker(CommsFW::TWorkerId aWorker);
+
+ IMPORT_C void MaybeSetPlayerShutdownComplete(TBool aForceShutdownNow);
+ virtual TBool IsPlayerShutdownComplete() = 0;
+
+ void ProcessShutdownRequest(CommsFW::TCFShutdownType aType);
+
+ IMPORT_C void DontCompleteCurrentRequest();
+ IMPORT_C TBool ShouldCompleteCurrentRequest() const;
+
+ IMPORT_C void SetReturn(TInt aReturn);
+
+ TInt PostMortemCleanup();
+
+ IMPORT_C CWorkerSubSession* SubSession(const TSubSessionUniqueId& aSubSessionUniqueId) const;
+
+ IMPORT_C CCommonSessionProxy* CurrentSessionProxyL();
+ CCommonSessionProxy* FindOrCreateSessionProxyL(CWorkerSession* aSession);
+ CCommonSessionProxy* FindSessionProxy(CWorkerSession* aSession);
+
+protected:
+ IMPORT_C CCommonPlayer(CCommonWorkerThread* aOwnerThread, TPlayerRole aPlayerRole);
+ TInt Return()
+ {
+ return iReturn;
+ }
+
+ void Reset()
+ {
+ iComplete=ETrue;
+ iReturn=KErrNone;
+ }
+
+ virtual CCommonSessionProxy* DoCreateSessionProxyL(CWorkerSession* aSession) = 0;
+
+private:
+ CCommonWorkerThread* iOwnerThread; //< Thread owning this Player
+ CCommonSessionProxy* iCurrentSessionProxy; //< Current session proxy - only valid within current ProcessL().
+ TDblQue<CCommonSessionProxy> iSessionProxies; //< All session proxies belonging to this Player
+ CWorkerSession* iSession; //< Current session, which might possibly belong to Dealer in different thread - only valid within current ProcessL().
+ TSubSessionContainer iSubSessions; //< All sub-sessions belonging to this Player.
+ TPlayerRole iPlayerRole;
+ const RSafeMessage* iCurrentMessage; //< Current RMessage - only valid within current ProcessL().
+
+protected:
+ TBool iComplete; //< Whether to complete the current message at the end of ProcessL() - only valid within current ProcessL().
+ TInt iReturn; //< Return code to use for completing current RMessage - only valid within current ProcessL().
+ };
+
+
+#include <elements/sd_roles.inl>
+
+} //namespace Den
+
+#endif
+//SYMBIAN_DEN_ROLES_H
+
+
+