serialserver/c32serialserver/INC/cs_thread.h
changeset 0 dfb7c4ff071f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/serialserver/c32serialserver/INC/cs_thread.h	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,220 @@
+// Copyright (c) 2005-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:
+// defines the workerThread class and assoicates. These operate at a level below the roles.h
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+*/
+
+#ifndef CS_THREAD_H
+#define CS_THREAD_H
+
+#include <cfutil.h>
+#include <cfextras.h>
+#include <elements/cftransport.h>
+#include <cs_panic.h>
+#include "cs_common.h"
+
+
+class CCommChannelHandler;
+
+typedef CommsFW::CWorkerThreadRegister<TC32WorkerThreadRegister, KMaxWorkerThreadId> CC32WorkerRegister;
+
+
+/**
+@class
+CC32WorkerThread
+The Worker Thread is the holder of the relevant C32 objects in the CPM instance,
+e.g. the Dealer and the Player (depending on configuration). It is also
+in charge of inter-thread communication as it holds the object enabling communication
+with the RootServer (CCommChannelHandler) and a list of objects for
+communication with other Worker threads (CCommsTransport).
+
+@see CCommChannelHandler
+@see CCommsTransport
+*/
+NONSHARABLE_CLASS(CC32WorkerThread) : public CBase, public CommsFW::MLegacyMessageReceiver
+	{
+public:
+	static CC32WorkerThread* NewL(CommsFW::TCFModuleInfo* aModuleInfo);
+	~CC32WorkerThread();
+
+	inline CC32Dealer* Dealer() const;
+	inline CC32Player* Player() const;
+	inline CommsFW::TWorkerId WorkerId() const;
+	inline CC32Dealer& DealerByRef() const;
+
+	/**
+	Use this to discover whether this Worker Thread is EMainThread ("C32_Main") which is
+	the main Dealer.
+	@see TWorkerThreadInfo
+	*/
+	TBool IsMainThread() const
+	    {
+	    return WorkerId()==TC32WorkerThreadRegister::EMainThread;
+	    }
+
+	/**
+	This is the main thread function used by the RootServer when creating a new C32 thread.
+	The RootServer will know the DLL ordinal for it, as specified in the .CMI file, and this is where
+	an C32 instance starts and ends operation (unless it PANICs).
+	@param aArg Will be the module info structure from the RootServer.
+	@see CommsFW::TCFModuleInfo
+	*/
+	IMPORT_C static TInt ThreadEntryPoint(TAny* aArg);
+	IMPORT_C static TInt RunC32Thread(CommsFW::TCFModuleInfo* aModuleInfo);
+
+	void SetDealerShutdownComplete(TBool aComplete);
+	inline TBool DealerShutdownComplete() const;
+	void SetPlayerShutdownComplete(TBool aComplete);
+	inline TBool PlayerShutdownComplete() const;
+
+	TBool ShuttingDown() const;
+	void SetShuttingDown();
+	void SessionShutdownComplete();
+	void MaybeTriggerThreadShutdownCallback();
+	void TriggerThreadShutdownCallback();
+
+	// RS control binding processing & message forwarding
+	void CFBindMessageReceived(const CommsFW::TCFBindMsg& aMsg);
+	void CFUnbindMessageReceived(const CommsFW::TCFUnbindMsg& aMsg);
+	void CFShutdownMessageReceived(const CommsFW::TCFShutdownMsg& aMsg);
+
+
+	// Test whether a message
+	TBool PeerReachable(CommsFW::TWorkerId aPeerId) const
+		{
+		return iTransport->PeerReachable(aPeerId);
+		}
+	// Send a message to a peer
+    void PostMessage(CommsFW::TWorkerId aWorkerId, CommsFW::TCFMessage& aMessage);
+
+	// From MLegacyMessageReceiver
+	void DispatchL(const CommsFW::TCFMessage& aMessage, CommsFW::TWorkerId aSenderId);
+	void OnDispatchLeave(const CommsFW::TCFMessage& aMessage, CommsFW::TWorkerId aSenderId, TInt aFirstDispatchLeaveReason);
+
+#ifdef _DEBUG
+  	inline RAllocator::TAllocFail AllocFailType() const;
+  	inline TInt AllocFailRate() const;
+#endif
+
+protected:
+	void ConstructL(CommsFW::TCFModuleInfo* aModuleInfo);
+	CC32WorkerThread();
+private:
+	void DetermineRoleL(const TDesC8& aIniData, TBool& aIsDealer, TBool& aIsPlayer);
+	void ProcessIniDataL();
+	TInt DecodePeerId(const CommsFW::TCFSubModuleAddress* aSubModule1, const CommsFW::TCFSubModuleAddress* aSubModule2, CommsFW::TWorkerId& aPeerId);
+	void MaybeCompleteUnbindings();
+	void MaybeCompleteUnbinding(CommsFW::TWorkerId aWorker);
+	static void DeleteHBufC8(TAny* aHBufC);
+
+	/**
+	@see ::iProlongBindingLife
+	*/
+	void IncProlongBindingLife()
+		{
+		++iProlongBindingLife;
+		}
+
+	/**
+	@see ::iProlongBindingLife
+	*/
+	void DecProlongBindingLife()
+		{
+		--iProlongBindingLife;
+		}
+
+private:
+
+	/** This is the handler used for bi-directional communication with the Root Server. */
+	CCommChannelHandler* iChannelHandler;
+
+	CC32WorkerRegister* iWorkerRegister;    // allows transport to find other threads
+	CommsFW::CCommsTransport* iTransport;
+	/**
+	Indentification of this thread. No other instance must have the same id.
+	@see TWorkerThreadInfo
+	*/
+	CommsFW::TWorkerId iWorkerId;
+
+	CC32Dealer* iDealer;
+
+	CC32Player* iPlayer;
+
+	/** Set when a CommsFW::TCFShutdownMsg is received from the Root Server. */
+	TBool iWorkerShuttingDown;
+
+	/**
+	Set by the Dealer instance to signal to the Worker Thread that it has
+	finished with the shutdown bookkeeping and is ready to be deleted.
+	This essentially means no sessions remain.
+	*/
+	TBool iDealerShutdownComplete;
+
+	/**
+	Set by the Player instance to signal to the Worker Thread that it has
+	finished with the shutdown bookkeeping and is ready to be deleted.
+	*/
+	TBool iPlayerShutdownComplete;
+
+	/**
+	If the value of this TInt is larger than 0 any unbind requests will not be served,
+	but postponed until iProlongBindingLife is 0. This is to ensure that if e.g. a
+	TWorkerMsg::ECleanupDeadPeer or TPlayerMsg::ESessionClose is received they will be fully
+	served before completing any unbind and thus deleting channel handlers.
+	*/
+	TInt iProlongBindingLife;
+
+#ifdef _DEBUG
+  	RAllocator::TAllocFail iFailType;
+  	TInt iFailRate;
+#endif
+
+	};
+
+
+
+NONSHARABLE_CLASS (CCommChannelHandler) : public CommsFW::CCFModuleChannelHandler
+/** Main Comms Channel traffic handler for the serialserver.
+The adapter responsible for communicating with the Root Server over the channel given with the
+CommsFW::TCFModuleInfo structure delivered via the parameter to the main thread function.
+@internalComponent
+*/
+	{
+	typedef CommsFW::CCFModuleChannelHandler inherited;
+public:
+	static CCommChannelHandler* NewL(CommsFW::RCFChannel::TMsgQueues aRxQueues,
+									 CommsFW::RCFChannel::TMsgQueues aTxQueues, CC32WorkerThread* aWorkerThread);
+	TInt Send(const CommsFW::TCFMessage& aMessage);
+private:
+	CCommChannelHandler(CC32WorkerThread* aWorkerThread);
+	virtual void CFMessageShutdown(const CommsFW::TCFShutdownMsg& aMessage);
+	virtual void CFMessageDiscover(const CommsFW::TCFDiscoverMsg& aMessage);
+	virtual void CFMessageBind(const CommsFW::TCFBindMsg& aMessage);
+	virtual void CFMessageUnbind(const CommsFW::TCFUnbindMsg& aMessage);
+private:
+	/** Pointer back to the worker thread owning this instance. */
+	CC32WorkerThread* iWorkerThread;
+
+	};
+
+#include "cs_thread.inl"
+
+#endif // CS_THREAD_H
+
+