commsfwsupport/commselements/serverden/inc/sd_thread.h
changeset 0 dfb7c4ff071f
child 21 07656293a99c
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @internalTechnology
       
    19 */
       
    20 
       
    21 #ifndef SYMBIAN_DEN_THREAD_H
       
    22 #define SYMBIAN_DEN_THREAD_H
       
    23 
       
    24 #include <cfextras.h>
       
    25 #include <cfshared.h>
       
    26 #include <elements/cftransport.h>
       
    27 
       
    28 
       
    29 #ifdef _DEBUG
       
    30 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
       
    31 // (if it could happen through user error then you should give it an explicit, documented, category + code)
       
    32 _LIT(KSpecAssert_ElemSvrDenThredH, "ElemSvrDenThredH");
       
    33 #endif
       
    34 
       
    35 namespace CommsFW
       
    36 {
       
    37 struct TCFModuleInfo;
       
    38 class TCFBindMsg;
       
    39 class TCFUnbindMsg;
       
    40 class TCFShutdownMsg;
       
    41 class TCFForwardMsg;
       
    42 }
       
    43 
       
    44 namespace Den
       
    45 {
       
    46 class CWorkerSession;
       
    47 class CWorkerRootServChannelHandler;
       
    48 class CCommonDealer;
       
    49 class CCommonWorkerDealer;
       
    50 class CCommonPlayer;
       
    51 class CCommonPitBoss;
       
    52 class CShutdownWatchDog;
       
    53 class CCommonWorkerThread;
       
    54 class CPeerDeathNotifier;
       
    55 class TPlayerRole;
       
    56 class TWorkerIntroductionMsg;
       
    57 
       
    58 class TWorkerThreadPublicInfo : public CommsFW::TWorkerThreadDataBase
       
    59 	{
       
    60 public:
       
    61     enum TType
       
    62         {
       
    63 	    ENullWorkerId      = 0xFFFF,     //< Non-existent worker
       
    64 		EMainThread        = 0,		//< the Pit Boss and Main Dealer run here
       
    65 		EFirstPlayerThread = 1,	//< Lowest possible player id
       
    66 		EMaxWorkerThreadId = CommsFW::KMaxWorkerId	//< Highest possible player id (NB: this is an inclusive bound. Be very careful in array-bound contexts!)
       
    67 		};
       
    68 
       
    69 	//RServer2 iSessionSustainer;	//< Used by the PitBoss to keep open a handle to a dealer so it can clean up its resources gracefully before closing the server, if the dealer thread dies.
       
    70 	CCommonWorkerThread* iWorker;
       
    71 	};
       
    72 
       
    73 /**
       
    74 @class TWorkerThreadRegister
       
    75 Structure containing information pertaining to a particular worker thread.
       
    76 */
       
    77 NONSHARABLE_CLASS(TWorkerThreadRegister) : public TWorkerThreadPublicInfo
       
    78 	{
       
    79 	friend class CCommonPitBoss;
       
    80 	//friend class CCommonWorkerThread;
       
    81 
       
    82 public:
       
    83 	TWorkerThreadRegister();
       
    84 
       
    85 private:
       
    86 	void Clear();
       
    87 	void PeerCleanupPending(CommsFW::TWorkerId aPeerId);
       
    88 	void PeerCleanupCompleted(CommsFW::TWorkerId aPeerId);
       
    89 	TBool AllPeerCleanupsCompleted() const;
       
    90 
       
    91 private:
       
    92 	CPeerDeathNotifier*	iPeerDeathNotifier; //< When the PitBoss binds to the worker thread this will be set up to monitor the thread, in case it dies.
       
    93 	TBool iShuttingDown;					//< Unused, should be removed.
       
    94 	CCommonDealer* iDealer;						//< Dealer instance of the worker thread (if exists).
       
    95 	CCommonPlayer* iPlayer;						//< Player instance of the worker thread (if exists).
       
    96 	CommsFW::TCFModuleName iModuleName;
       
    97 
       
    98 private:
       
    99 	/**
       
   100 	If a worker thread  dies the Pitboss will set a bit corresponding to the dead worker thread ID (/number)
       
   101 	in iPendingPeerCleanups in the TWorkerThreadRegister instance for each other worker and send them a TWorkerCleanupDeadPeerMsg.
       
   102 	The worker threads will respond by sending TWorkerMsg::ECleanupDeadPeerResp back when they have cleaned up anything
       
   103 	related to the dead worker and the PitBoss will reset the bit in their TWorkerThreadRegister instance.
       
   104 	@see HandleWorkerCleanupCompletionByPeer()
       
   105 	*/
       
   106 	TUint32 iPendingPeerCleanups;
       
   107 
       
   108 #ifdef _DEBUG
       
   109 	TBool iHasGlobalAllocFails;
       
   110 #endif
       
   111 	};
       
   112 
       
   113 typedef CommsFW::CWorkerThreadRegister<TWorkerThreadRegister, CommsFW::KMaxWorkerId> CWorkerRegister;
       
   114 
       
   115 
       
   116 /**
       
   117 @class CCommonWorkerThread
       
   118 The Worker Thread is the holder of the relevant ESock objects in the CPM instance,
       
   119 e.g. the PitBoss, the Dealer and the Player (depending on configuration). It is also
       
   120 in charge of inter-thread communication as it holds the object enabling communication
       
   121 with the RootServer (CWorkerRootServChannelHandler) and a list of objects for
       
   122 communication with other Worker threads (CWorkerTransport).
       
   123 
       
   124 @see CWorkerRootServChannelHandler
       
   125 @see CWorkerTransport
       
   126 */
       
   127 class CCommonWorkerThread : public CBase, public CommsFW::MLegacyMessageReceiver
       
   128 /**
       
   129 @internalComponent
       
   130 */
       
   131 	{
       
   132 	friend class CWorkerRootServChannelHandler;
       
   133 
       
   134 public:
       
   135 	IMPORT_C ~CCommonWorkerThread();
       
   136 
       
   137 	/**
       
   138 	@return the pointer to the Dealer in this thread. This method might return NULL if the worker thread doesnt have a Dealer.
       
   139 	*/
       
   140 	CCommonDealer* Dealer() const
       
   141 		{
       
   142 		return iDealer;
       
   143 		}
       
   144 	IMPORT_C CCommonWorkerDealer* WorkerDealer() const;
       
   145 
       
   146 	/**
       
   147 	@return the pointer to the Player in this thread. This method might return NULL	if the worker thread doesnt have a Player.
       
   148 	*/
       
   149 	CCommonPlayer* Player() const
       
   150 		{
       
   151 		return iPlayer;
       
   152 		}
       
   153 
       
   154 	CommsFW::TWorkerId WorkerId() const
       
   155 		{
       
   156 		return iWorkerId;
       
   157 		}
       
   158 
       
   159 	Messages::CGlobals&	TransportGlobals()
       
   160 		{
       
   161 		__ASSERT_DEBUG(iGlobals, User::Panic(KSpecAssert_ElemSvrDenThredH, 1));
       
   162 		return *iGlobals;
       
   163 		}
       
   164 
       
   165 	/**
       
   166 	Return the pointer to the domain PitBoss. This will be initialised when:
       
   167 	    -# If this is Main thread: In CCommonWorkerThread::ConstructL(TCFModuleInfo* aModuleInfo).
       
   168 		-# In other common worker threads: When receiving TWorkerMsg::EMainIntroduction.
       
   169 	*/
       
   170 	CCommonPitBoss& PitBoss() const
       
   171 		{
       
   172 		__ASSERT_DEBUG(iPitBoss, User::Panic(KSpecAssert_ElemSvrDenThredH, 2));
       
   173 		return *iPitBoss;
       
   174 		}
       
   175 
       
   176 	/**
       
   177 	Use this to discover whether this Worker Thread is EMainThread ("Esock_Main") which is
       
   178 	the main Dealer also containing the PitBoss.
       
   179 	@see TWorkerThreadInfo
       
   180 	*/
       
   181 	TBool IsMainThread()
       
   182 	    {
       
   183 	    return WorkerId()==TWorkerThreadRegister::EMainThread;
       
   184 	    }
       
   185 
       
   186 	TWorkerThreadRegister* WorkerProperties(CommsFW::TWorkerId aWorker)
       
   187 		{
       
   188 		return iWorkerRegister->GetWorkerGlobals(aWorker);
       
   189 		}
       
   190 
       
   191 	IMPORT_C void SetDealerShutdownComplete(TBool aComplete);
       
   192 	TBool DealerShutdownComplete() const
       
   193 		{
       
   194 		return iDealerShutdownComplete;
       
   195 		}
       
   196 
       
   197 	IMPORT_C void SetPlayerShutdownComplete(TBool aComplete);
       
   198 	TBool PlayerShutdownComplete() const
       
   199 		{
       
   200 		return iPlayerShutdownComplete;
       
   201 		}
       
   202 
       
   203 	IMPORT_C TBool ShuttingDown() const;
       
   204 	IMPORT_C void SetShuttingDown();
       
   205 	IMPORT_C void SessionShutdownComplete();
       
   206 	IMPORT_C void MaybeTriggerThreadShutdownCallback();
       
   207 	void TriggerThreadShutdownCallback();
       
   208 	IMPORT_C void DestroyDealer();
       
   209 	IMPORT_C  void DestroyPlayer();
       
   210 	void DropTransportToPeer(TInt aPeer);
       
   211 	IMPORT_C TBool MaybeCompleteUnbindings();
       
   212 
       
   213 	// RS control binding processing & message forwarding
       
   214 	void CFUnbindMessageReceived(const CommsFW::TCFUnbindMsg& aMsg);
       
   215 	void CFShutdownMessageReceived(const CommsFW::TCFShutdownMsg& aMsg);
       
   216 
       
   217 	// Test whether a message
       
   218 	TBool PeerReachable(CommsFW::TWorkerId aPeerId) const
       
   219 		{
       
   220 		return iTransport->PeerReachable(aPeerId);
       
   221 		}
       
   222 
       
   223 	// Send a message to a peer
       
   224     IMPORT_C void PostMessage(CommsFW::TWorkerId aWorkerId, CommsFW::TCFMessage& aMessage);
       
   225 	CommsFW::CCommsTransport* Transport() const
       
   226 		{
       
   227 		return iTransport;
       
   228 		}
       
   229 
       
   230 	//< Thread nominates self as the default optimal dealer
       
   231 	TBool DefaultOptimalDealer() const
       
   232 		{
       
   233 		return iDefaultOptimalDealer;
       
   234 		}
       
   235 
       
   236 	//
       
   237 	IMPORT_C void DispatchL(const CommsFW::TCFMessage& aMessage, CommsFW::TWorkerId aSenderId);
       
   238 	virtual TBool DoDispatchL(const CommsFW::TCFMessage& aMessage, CommsFW::TWorkerId aSenderId)=0;
       
   239 	IMPORT_C void OnDispatchLeave(const CommsFW::TCFMessage& aMessage, CommsFW::TWorkerId aSenderId, TInt aFirstDispatchLeaveReason);
       
   240 
       
   241 	// Process a non-internal message from a peer worker. Returns error code
       
   242 	IMPORT_C void IncProlongBindingLife();
       
   243 	IMPORT_C void DecProlongBindingLife();
       
   244 	IMPORT_C void CompleteSessionClose(CWorkerSession* aSession);
       
   245 	IMPORT_C void ConstructL(CommsFW::TCFModuleInfo& aModuleInfo, CShutdownWatchDog& aShutdownWatchDog);
       
   246 	//Default post mortem cleanup handler
       
   247 	IMPORT_C static TInt PostMortemCleanupThreadEntry(TAny* aArg);
       
   248 
       
   249 protected:
       
   250 	virtual CCommonPitBoss* DoCreatePitBossL(CCommonWorkerThread* aWorkerThread)=0;
       
   251 	virtual CCommonPlayer* DoCreatePlayerL(CCommonWorkerThread* aWorkerThread, TPlayerRole aPlayerRole)=0;
       
   252 	virtual CCommonDealer* DoCreateDealerL(CCommonWorkerThread* aWorkerThread, TPlayerRole aPlayerRole)=0;
       
   253 	virtual void DoCompleteUnbinding(CommsFW::TWorkerId aWorker) = 0;
       
   254 	virtual void DoSetShuttingDown() = 0;
       
   255 	virtual void DoPostMortemCleanup() = 0;
       
   256 	virtual void CFBindMessageReceived(const CommsFW::TCFBindMsg& aMsg) = 0;
       
   257 	virtual void CFMessageForward(const CommsFW::TCFForwardMsg& aMessage) = 0;
       
   258 
       
   259 	virtual void DoProcessWorkerIntroductionL(const TWorkerIntroductionMsg& aMessage) = 0;
       
   260 
       
   261 	IMPORT_C void SendIntroMessage(const CommsFW::TCFModuleName& aPeerName, CommsFW::TWorkerId aPeerId);
       
   262 	virtual void DoFillIntroMessage(CommsFW::TWorkerId aPeerId, TWorkerIntroductionMsg& aIntroMsg) = 0;
       
   263 
       
   264 	IMPORT_C CCommonWorkerThread();
       
   265 	IMPORT_C static void DeleteHBufC8(TAny* aHBufC);
       
   266 
       
   267 	IMPORT_C void DetermineRoleL(HBufC8* aIniData, TBool& aIsDealer, TBool& aIsPlayer, TPlayerRole &aPlayerRole);
       
   268 	virtual void DoDeterminePlayerRoleL(HBufC8* aIniData, TPlayerRole &aPlayerRole)=0;
       
   269 
       
   270 	void ProcessIniDataL();
       
   271 	IMPORT_C TInt DecodePeerId(const CommsFW::TCFSubModuleAddress* aSubModule1, const CommsFW::TCFSubModuleAddress* aSubModule2, CommsFW::TWorkerId& aPeerId);
       
   272 	IMPORT_C void MaybeCompleteUnbinding(CommsFW::TWorkerId aWorker);
       
   273 
       
   274 protected:
       
   275 	/** This is the handler used for bi-directional communication with the Root Server. */
       
   276 	CWorkerRootServChannelHandler* iChannelHandler;
       
   277 
       
   278 	CWorkerRegister* iWorkerRegister;
       
   279 	CommsFW::CCommsTransport* iTransport;
       
   280 
       
   281 	/**
       
   282 	Indentification of this thread. No other instance must have the same id.
       
   283 	@see TWorkerThreadInfo
       
   284 	*/
       
   285 	CommsFW::TWorkerId iWorkerId;
       
   286 
       
   287 	CCommonDealer* iDealer;
       
   288 	CCommonPlayer* iPlayer;
       
   289 	CCommonPitBoss* iPitBoss;
       
   290 
       
   291 	TBool iDefaultOptimalDealer;
       
   292 
       
   293 
       
   294 	/** Set when a CommsFW::TCFShutdownMsg is received from the Root Server. */
       
   295 	TBool iWorkerShuttingDown;
       
   296 
       
   297 	/**
       
   298 	Set by the Dealer instance to signal to the Worker Thread that it has
       
   299 	finished with the shutdown bookkeeping and is ready to be deleted.
       
   300 	*/
       
   301 	TBool iDealerShutdownComplete;
       
   302 
       
   303 	/**
       
   304 	Set by the Player instance to signal to the Worker Thread that it has
       
   305 	finished with the shutdown bookkeeping and is ready to be deleted.
       
   306 	*/
       
   307 	TBool iPlayerShutdownComplete;
       
   308 
       
   309 	/**
       
   310 	If the value of this TInt is larger than 0 any unbind requests will not be served,
       
   311 	but postponed until iProlongBindingLife is 0. This is to ensure that if e.g. a
       
   312 	TWorkerMsg::ECleanupDeadPeer or TPlayerMsg::ESessionClose is received they will be fully
       
   313 	served before completing any unbind and thus deleting channel handlers.
       
   314 	*/
       
   315 	TInt iProlongBindingLife;
       
   316 
       
   317 	CShutdownWatchDog* iShutdownWatchDog;
       
   318 	Messages::CGlobals* iGlobals;
       
   319 
       
   320 public:
       
   321 #ifdef _DEBUG
       
   322 	RAllocator::TAllocFail AllocFailType() const
       
   323 		{
       
   324 		return iFailType;
       
   325 		}
       
   326 	TInt AllocFailRate() const
       
   327 		{
       
   328 		return iFailRate;
       
   329 		}
       
   330 #endif
       
   331 
       
   332 //These must not be conditional (BC)
       
   333 private:
       
   334 	RAllocator::TAllocFail iFailType;
       
   335 	TInt iFailRate;
       
   336 	};
       
   337 
       
   338 NONSHARABLE_CLASS(CShutdownWatchDog) : public CPeriodic
       
   339 /**
       
   340 @internalComponent
       
   341 */
       
   342 	{
       
   343 public:
       
   344 	IMPORT_C void Shutdown(TBool aImmediate);
       
   345 	IMPORT_C static CShutdownWatchDog* NewL(CCommonWorkerThread* aWorker, const TCallBack& aShutDownCb);
       
   346 
       
   347 private:
       
   348 	CShutdownWatchDog(CCommonWorkerThread* aWorker, const TCallBack& aShutDownCb);
       
   349 	static TInt TryShutdown(TAny* aSelf);
       
   350 
       
   351 private:
       
   352 	TBool iImmediate;
       
   353 	CCommonWorkerThread* iWorker;
       
   354 	TCallBack iShutDownCb;
       
   355 	};
       
   356 
       
   357 } //namespace Den
       
   358 
       
   359 #endif
       
   360 //SYMBIAN_DEN_THREAD_H
       
   361 
       
   362