--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/commsfwsupport/commselements/commsfw/inc/cftransport.h Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,312 @@
+// 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:
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#ifndef SYMBIAN_NETWORKING_CFTRANSPORT_H
+#define SYMBIAN_NETWORKING_CFTRANSPORT_H
+
+#include <elements/nm_address.h>
+#include <elements/nm_transport.h>
+#include <elements/metavirtctor.h>
+
+
+/** Synchronously dispatching within the same thread is strongly discouraged but relied upon by the legacy EINTSOCK interface.
+Between threads the function is supported but the dispatch is not synchronous (risk of deadlock)
+*/
+#define SYMBIAN_CFTRANSPORT_SUPPORT_SYNC_SEND
+
+namespace NetInterfaces
+ {
+ class TInterfaceControl;
+ }
+
+namespace CommsFW
+{
+
+/**
+ CFTransport panic category
+*/
+_LIT(KCFTransportPanic, "CFTransport");
+
+/** Panics generated by the Comms Channels
+*/
+enum TCFTransportPanics
+ {
+ /** Peer failing to drain input properly
+ */
+ ECFTransPeerDrainFailure = 0,
+ /** Invalid interface registration, eg unsupported or duplicate
+ */
+ ECFTransBadRegistration = 1,
+ /** Cookie invalid or corrupt. If null then common causes are forgetting to initialise at all or with TCFClientSignalBase-derived classes
+ failing to chain the metadata attribute table to the parent, eg END_ATTRIBUTE_TABLE_BASE(TCFSignalExtnBase, 0)
+ */
+ ECFTransInvalidCookie = 2,
+ /** No legacy message handler registered and a legacy message was received
+ */
+ ECFTransLegacyHandlerAbsent = 3,
+ /** Invalid worker thread id
+ */
+ ECFTransInvalidWorkerId = 4,
+ /** No transport to worker
+ */
+ ECFTransAbsentWorker = 5,
+ /** Attempt to register a handler for an interface already registered - must first deregister original
+ */
+ ECFTransDuplicateHandler = 6,
+ /** Use of a function requiring the global thread register when the pointer to it has not been set.
+ Without the global register many operations on peer threads are impossible.
+ */
+ ECFTransThreadRegisterUnspecified = 7,
+ /** RCFInterfaceBase not opened with recipient peer details
+ */
+ ECFTransNotOpened = 8,
+ /** Internal fault not directly generated by client activity
+ */
+ ECFTransItfClassFault = 8,
+ /** After Leave()ing from the original dispatch the recipient dispatch also left from the leave-handling
+ dispatch. This is a fatal error because a common requirement for handling the first leave is sending
+ an error signal; leaving again suggests that the code is not handling the possibility of a Leave()
+ properly, rather than explicitly opting to ignore it.
+ */
+ ECFTransLeaveFromLeaveHandler = 9,
+ /** Message recieved for an object whose interface cookie has already been deregistered (ie object probably deleted). This indicates a protocol
+ failure: the recipient interface's must remain registered until all messages for it have been received. A common approach is the sending of a
+ sign-off message guaranteeing no further communication from a node (analogous to a TCP FIN or a CommsChan PIG)
+ */
+ ECFTransStaleCookie = 10,
+ /** More interfaces have been deregistered than were ever registered. Because the particular cookies aren't tracked it isn't necessarily the
+ current deregistration that is at fault
+ */
+ ECFExcessInterfaceDeregistration = 11,
+ /** Interface registration with a non-null cookie is not allowed, as it's too likely that it represents a fault such as a double registration.
+ If it really is a safe and proper use (eg of an aliased cookie) then TCookieOp::SetNull() the cookie first
+ */
+ ECFInterfaceRegistrationOverwrite = 12,
+ /** Interface not registered for dispatch
+ */
+ ECFInterfaceNotRegistered = 13,
+ /** Queue sizing error. This is probably an internal fault.
+ */
+ ECFInvalidQueueSize = 14,
+ };
+
+IMPORT_C void Panic(TCFTransportPanics aReason);
+
+_LIT8(KLogFwTransport, "Trans");
+
+#ifdef SYMBIAN_TRACE_ENABLE
+// Markers to enable correlation between utrace and CDU logs.
+_LIT8(KLogFwMarker, "Mark");
+#endif
+
+typedef TUint16 TWorkerId;
+static const TUint16 KInvalidWorkerId = 0xFFFF;
+static const TUint16 KMaxWorkerId = 16;
+
+//
+// Cookies
+//
+
+class TCFMessage;
+class RCFChannelMsgQueues;
+typedef TInt TId;
+
+//
+// Thread knowledge
+//
+
+class MGlobalThreadRegister
+ {
+public:
+ virtual TWorkerId UpperBoundWorkerId() const = 0;
+ virtual RAllocator& WorkerHeap(TWorkerId aWorkerId) const = 0;
+ virtual void PanicWorker(TWorkerId aWorkerId, const TDesC& aCategory, TInt aReason) const = 0;
+ };
+
+class MWorkerThreadRegister : public MGlobalThreadRegister
+ {
+public:
+ virtual TWorkerId SelfWorkerId() const = 0;
+ };
+
+class TWorkerThreadDataBase
+ {
+public:
+ IMPORT_C void Init(TWorkerId aWorkerId, TBool aHoldingReference);
+ IMPORT_C void Clear();
+ inline TBool IsValid() const;
+public:
+ TWorkerId iWorkerId;
+ TThreadId iThreadId;
+ RThread iThread;
+ RAllocator* iHeap;
+ TBool iHoldingReference;
+ };
+
+
+class CWorkerThreadDataGlobalsBase : public CBase
+ {
+protected:
+ inline CWorkerThreadDataGlobalsBase();
+ inline ~CWorkerThreadDataGlobalsBase();
+ inline void ConstructL(TInt aWorkerDataSize, TWorkerId aUpperBoundId);
+protected:
+ TWorkerThreadDataBase* iWorkers;
+ };
+
+
+template<class TWTD, TInt TUpperThreadIdBound>
+class CWorkerThreadDataGlobals : public CWorkerThreadDataGlobalsBase, public MGlobalThreadRegister
+ {
+public:
+ static CWorkerThreadDataGlobals<TWTD, TUpperThreadIdBound>* NewL();
+
+ TWorkerId UpperBoundWorkerId() const;
+ TWTD* GetWorkerGlobals(TWorkerId aWorker) const;
+ TBool WorkerPresent(TWorkerId aId) const;
+ RAllocator& WorkerHeap(TWorkerId aWorkerId) const;
+ void PanicWorker(TWorkerId aWorkerId, const TDesC& aCategory, TInt aReason) const;
+protected:
+ CWorkerThreadDataGlobals();
+ inline void ConstructL(TInt aWorkerDataSize, TWorkerId aUpperBoundId);
+ };
+
+
+template<class TWTD, TInt TUpperThreadIdBound>
+class CWorkerThreadRegister : public CBase, public MWorkerThreadRegister
+ {
+public:
+ static CWorkerThreadRegister<TWTD, TUpperThreadIdBound>* NewL(TWorkerId aSelfId, CWorkerThreadDataGlobals<TWTD, TUpperThreadIdBound>* aGlobalThreadRegister);
+ void SetGlobalThreadRegister(CWorkerThreadDataGlobals<TWTD, TUpperThreadIdBound>* aGlobalThreadRegister);
+ TWTD* GetWorkerGlobals(TWorkerId aWorker) const;
+ TWorkerId UpperBoundWorkerId() const;
+ TBool WorkerPresent(TWorkerId aWorkerId) const;
+ RAllocator& WorkerHeap(TWorkerId aWorkerId) const;
+ void PanicWorker(TWorkerId aWorkerId, const TDesC& aCategory, TInt aReason) const;
+ TWorkerId SelfWorkerId() const;
+ TWTD* GetSelfWorkerGlobals() const;
+private:
+ CWorkerThreadRegister<TWTD, TUpperThreadIdBound>(TWorkerId aSelfId, CWorkerThreadDataGlobals<TWTD, TUpperThreadIdBound>* aGlobalThreadRegister);
+private:
+ TWorkerId iSelfId;
+ CWorkerThreadDataGlobals<TWTD, TUpperThreadIdBound>* iGlobals;
+ };
+
+//These APIs have been separated from the transport abstraction (MTransportSender)
+//and are here only to satisfy the comms transport implementation
+class MCommsTransportSender : public Messages::MTransportSender
+ {
+public:
+ virtual void PostMessage(const Messages::TRuntimeCtxId& aPostFrom, const Messages::TRuntimeCtxId& aPostTo, const Meta::SMetaData& aMessage);
+
+ //Legacy & helpers
+ virtual void PostMessage(const TCFMessage& aMessage) = 0;
+ virtual void PostMessage(const Messages::TRuntimeCtxId& aPostFrom, const Messages::TRuntimeCtxId& aPostTo, const TDesC8& aMessage) = 0;
+
+#ifdef SYMBIAN_CFTRANSPORT_SUPPORT_SYNC_SEND
+ /** The caller intends to block for some out-of-band synchronisation mechanism (eg a semaphore) and so dispatch
+ must be done immediately as part of this sending call if the peer object is running in the same worker thread, so
+ that the recipient can signal the caller if appropriate. Such synchronisation mechanisms are strongly discouraged
+ but exist in some legacy code.
+
+ @deprecated
+ */
+ virtual void SendMessageSync(const TCFMessage& aMessage) = 0;
+#endif
+ };
+
+
+class MLegacyMessageReceiver
+ {
+public:
+ virtual void DispatchL(const TCFMessage& aMessage, TWorkerId aSenderId) = 0;
+ /** If the dispatching function Leave()s then control transfers here. This allows a carefully-written object to avoid
+ adding its own TRAP and still provide handling for a Leave, ie an efficiency gain.
+ */
+ virtual void OnDispatchLeave(const TCFMessage& /*aMessage*/, TWorkerId /*aSenderId*/, TInt /*aFirstDispatchLeaveReason*/)
+ {
+ }
+ };
+
+
+class CCommsTransportImpl;
+class CCFTransportHooks;
+
+class CCommsTransport : public CBase //PS removed inheritance not to export virtuals and
+ //hide CCommsTransportImpl. Polymorphism is given
+ //by CCommsTransportImpl.
+ {
+public:
+ IMPORT_C static CCommsTransport* NewL(MWorkerThreadRegister& aThreadRegister, const Meta::CMetaDataVirtualCtorInPlace* aVirtCtor, CCFTransportHooks* aHooksWalker);
+ IMPORT_C ~CCommsTransport();
+
+ // From MTransportReceiver
+ IMPORT_C TInt RegisteredCount() const;
+ IMPORT_C void RegisterAddress(Messages::TRuntimeCtxId& aCookie);
+ IMPORT_C void DeregisterAddress(Messages::TRuntimeCtxId& aCookie);
+
+ // From MTransportSender
+ IMPORT_C void PostMessage(const Messages::TRuntimeCtxId& aPostFrom, const Messages::TRuntimeCtxId& aPostTo, const Meta::SMetaData& aMessage);
+
+ // TCFMessage + legacy
+ IMPORT_C void RegisterLegacyInterface(MLegacyMessageReceiver* aLegacyInterface);
+ IMPORT_C void PostMessage(const TCFMessage& aMessage);
+
+private:
+ // TCFMessage + legacy
+ IMPORT_C void PostMessage(const Messages::TRuntimeCtxId& aPostFrom, const Messages::TRuntimeCtxId& aPostTo, const TDesC8& aMessage);
+
+#ifdef SYMBIAN_CFTRANSPORT_SUPPORT_IMPATIENCE
+ IMPORT_C TInt ImpatientPostMessage(const TCFMessage& aMessage);
+ IMPORT_C TInt ImpatientPostMessage(const Messages::TRuntimeCtxId& aPostFrom, const Messages::TRuntimeCtxId& aPostTo, const TDesC8& aMessage);
+#endif
+#ifdef SYMBIAN_CFTRANSPORT_SUPPORT_SYNC_SEND
+ IMPORT_C void SendMessageSync(const TCFMessage& aMessage);
+#endif
+
+public:
+ // Transports peer threads via message queues, normally established by the RootServer via binding commands. The Request Id
+ // identifies the specific command being responded to; some callers need to store this for delayed reporting
+ IMPORT_C TInt EstablishTransportToPeer(TWorkerId aPeerId, const RCFChannelMsgQueues& aInboundQueues, const RCFChannelMsgQueues& aOutboundQueues);
+ IMPORT_C TInt DropTransportToPeer(TWorkerId aPeerId);
+ IMPORT_C TBool PeerReachable(TWorkerId aPeerId) const;
+ IMPORT_C void SetLastRequestIdConcerningPeer(TWorkerId aPeerId, CommsFW::TId aRequestId);
+ IMPORT_C CommsFW::TId LastRequestIdConcerningPeer(TWorkerId aPeerId) const;
+ IMPORT_C void SetDropTransportPending(TWorkerId aPeerId, TBool aDropPending);
+ IMPORT_C TBool IsDropTransportPending(TWorkerId aPeerId) const;
+
+ IMPORT_C TWorkerId WorkerId() const;
+ IMPORT_C Messages::MTransportSender& GetSender();
+ IMPORT_C Messages::MTransportReceiver& GetReceiver();
+
+private:
+ CCommsTransport()
+ {
+ }
+private:
+ CCommsTransportImpl* iImpl;
+ };
+
+#include <elements/cftransport.inl>
+
+} // namespace CommsFW
+
+#endif // SYMBIAN_NETWORKING_CFTRANSPORT_H
+