|
1 // Copyright (c) 2004-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 @internalComponent |
|
19 */ |
|
20 |
|
21 #if !defined(__SS_ROLES_H__) |
|
22 #define __SS_ROLES_H__ |
|
23 |
|
24 #include <elements/sd_roles.h> |
|
25 #include <ss_std.h> |
|
26 #include <comms-infras/ss_thread.h> |
|
27 #include <ss_pman.h> |
|
28 #include <comms-infras/ss_nodeinterfaces.h> |
|
29 #include <elements/cftransport.h> |
|
30 |
|
31 class CPlayer; |
|
32 class CWorkerThread; |
|
33 class MShimControlClient; |
|
34 class CommsFW::COwnEntryList; |
|
35 class TWorkerTierMappingsLoaded; |
|
36 |
|
37 namespace CommsDat |
|
38 { |
|
39 class CMDBSession; |
|
40 } |
|
41 |
|
42 /** Socket type values equal to or greater than this constant are reserved for internal use |
|
43 */ |
|
44 const TUint KReservedSockTypesBase=0x80000000; |
|
45 |
|
46 /** Used internally to identify tier entries in the protocol pairing lists |
|
47 */ |
|
48 const TUint KTierEntryProxyAddrFam=0xFFFFFFFD; |
|
49 const TUint KTierEntryProxySockType=0xFFFFFFFD; |
|
50 const TUint KTierEntryLoadCompleteProtocolType=0x0; |
|
51 |
|
52 /** Used internally to identify specific Player roles in the protocol pairing lists |
|
53 */ |
|
54 const TUint KPlayerRoleProxyAddrFam=0xFFFFFFFC; |
|
55 const TUint KPlayerRoleProxySockType=0xFFFFFFFC; |
|
56 const TUint KPlayerRoleTierResolver=0; |
|
57 |
|
58 namespace ESock |
|
59 { |
|
60 class CCommsFactoryContainer; |
|
61 class RTierThreadMap; |
|
62 } |
|
63 |
|
64 /** |
|
65 @class CPitBoss |
|
66 The PitBoss has responsibility for global resources and gross error handling (panics, etc). |
|
67 The Pit Boss thread must be started by the Configurator before any worker threads. The ESock |
|
68 instance loading it must be the only one having the WorkerId 0 (TWorkerThreadInfo::EMainThread). |
|
69 The PitBoss has two main responsibilities: |
|
70 -# 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. |
|
71 -# Manage Worker thread start and death: Registering Workers and installing protocols when they start and do a best effort cleanup if they die due to some error condition. |
|
72 |
|
73 Apart from these, the PitBoss also provides some minor but important services. For example as |
|
74 all ESock instances can have their own heap sometimes it happens that one Worker needs to do |
|
75 something that might cause allocation or freeing on another workers heap, such as inserting a |
|
76 sub-session into a Dealers session. So the PitBoss offer a function that can determine whether |
|
77 a different heap is needed (maybe the two workers have different heaps, maybe they share one heap) |
|
78 and does the switch. |
|
79 It also has AddSubSession() and RemoveSubSession() methods used by the Player, assuring this |
|
80 happens on the right heap for operations like Socket Transfers. |
|
81 */ |
|
82 NONSHARABLE_CLASS(CPitBoss) : public Den::CCommonPitBoss |
|
83 { |
|
84 public: |
|
85 static CPitBoss* NewL(CWorkerThread* aOwnerThread); |
|
86 ~CPitBoss(); |
|
87 |
|
88 TBool GetWorkerForProtocol(TUint aAddrFamily, TUint aSockType, TUint aProtocol, CommsFW::TWorkerId& aWorker) const; |
|
89 TBool GetWorkerForTier(TInt aTierId, CommsFW::TWorkerId& aWorker) const; |
|
90 inline TBool TierMappingsLoaded() const; |
|
91 void RequestLoadTierMapping(); |
|
92 void OnTierMappingLoadedL(const TWorkerTierMappingsLoaded* aMappingMsg, CommsFW::TWorkerId aSenderId); |
|
93 |
|
94 inline TBool GetWorkerForPlayerRole(TUint aRoleId, CommsFW::TWorkerId& aWorker) const; |
|
95 TBool GetWorkerForProtocol(TUint aIndex, CommsFW::TWorkerId& aWorker) const; |
|
96 TBool GetWorkerForProtocolByName(const TProtocolName& aName, CommsFW::TWorkerId& aWorker) const; |
|
97 TBool GetWorkerForNullSocket(CommsFW::TWorkerId& aWorker) const; |
|
98 TUint GetNumProtocols(); |
|
99 TInt GetLocalProtocolIndex(TInt aPitBossIndex) const; |
|
100 |
|
101 TBool FindOptimalDealer(const TSessionPref& aPref, Den::CCommonWorkerDealer*& aDealer); |
|
102 const CommsFW::COwnEntryList* GetCompleteList(); |
|
103 |
|
104 private: |
|
105 /** |
|
106 @class CPitBoss::TProtocolPairing |
|
107 Protocol pairings couple a protocol description (address family, socket type, protocol number & name) |
|
108 to the Worker thread(s) that host it (indexed by TSubSessInfo::TSubSessionPlane). |
|
109 It implements a single linked list in that is also contains a pointer |
|
110 to the next pairing. So all worker threads can access this list of pairings, but still avoid |
|
111 locking, workers are allowed to read from the list. The only thread allowed to insert/modify |
|
112 the list is the one containing the PitBoss (ESock_Main). |
|
113 Non-protocol objects such as tier managers and the tier resolver are also indexed by this scheme, |
|
114 using reserved negative values for the address family & socket type. |
|
115 */ |
|
116 NONSHARABLE_CLASS(TProtocolPairing) |
|
117 { |
|
118 public: |
|
119 TUint iAddrFamily; //< Address Family |
|
120 TUint iSockType; //< Socket Type |
|
121 TUint iProtocol; //< Protocol Number |
|
122 TProtocolName iName; //< Name of protocol |
|
123 CommsFW::TWorkerId iWorkerId; //< Worker ID for each plane-thread supporting this protocol/addr/sock_type |
|
124 TProtocolPairing* iNextPair; //< Next pairing in the list |
|
125 TProtocolPairing* iNextDead; //< Removed protocols (eg owning Player died) are queued in a separate dead list |
|
126 }; |
|
127 |
|
128 NONSHARABLE_CLASS(TProtocolPairingOwner) |
|
129 { |
|
130 public: |
|
131 TProtocolPairingOwner(); |
|
132 void Append(TProtocolPairing* aNode); |
|
133 void Release(); |
|
134 public: |
|
135 TProtocolPairing* iHead; |
|
136 }; |
|
137 |
|
138 private: |
|
139 CPitBoss(CWorkerThread* aOwnerThread); |
|
140 void ConstructL(); |
|
141 virtual void DoOnCPMsConfigured(); |
|
142 virtual void DoOnPeerDeath(CommsFW::TWorkerId aWorkerId); |
|
143 virtual TInt DoCreateRedShirt(RThread& aRedShirt, CommsFW::TWorkerId aWorkerId, Den::CCommonWorkerThread& aDeadWorker); |
|
144 virtual void DoProcessWorkerIntroductionL(const Den::TWorkerIntroductionMsg& aMsg); |
|
145 virtual void DoFreeWorkerReferences(CommsFW::TWorkerId aWorkerId); |
|
146 |
|
147 TProtocolPairing* FindProtocolPairing(TUint aAddrFamily, TUint aSockType, TUint aProtocol) const; |
|
148 void AddProtocolToListL(TUint aAddrFamily, TUint aSockType, TUint aProtocol, const TProtocolName& aName, CommsFW::TWorkerId aWorker, TProtocolPairingOwner& aList); |
|
149 void PopulateAndAddProtocolPairListL(TProtocolName& tierDesc, ESock::RTierThreadMap* map); |
|
150 void IncorporateProtocolListL(TProtocolPairingOwner& aList); |
|
151 void AddTierPairingToListL(TInt aTierUid, const TDesC& aTierName, CommsFW::TWorkerId aWorker, TProtocolPairingOwner& aList); |
|
152 inline void AddPlayerRolePairingL(TUint aRoleId, const TDesC& aRoleDesc, CommsFW::TWorkerId aWorker, TProtocolPairingOwner& aList); |
|
153 void RemoveProtocolPairingsForWorker(CommsFW::TWorkerId aWorkerId); |
|
154 void SendLoadTierMappingRequest(); |
|
155 |
|
156 void AddFactoryProxyProtocols(const ESock::CCommsFactoryContainer& aFC, const TDesC& aFCName, CommsFW::TWorkerId aWorkerId); |
|
157 void AddPendingIntroductionResponse(); |
|
158 void RemovePendingIntroductionResponse(); |
|
159 void FreeWorkerReferences(CommsFW::TWorkerId aWorkerId); |
|
160 |
|
161 |
|
162 private: |
|
163 /** |
|
164 When the main thread starts it will search the drives for a complete list of .ESK files and stores them here. |
|
165 A pointer to the list will later be sent to workers upon binding, with TWorkerMsg::EMainIntroduction. This way |
|
166 there will only ever be one scan for .ESK files on the filesystem. */ |
|
167 CommsFW::COwnEntryList* iCompleteEskList; |
|
168 |
|
169 /** |
|
170 List of "protocol pairings" is a lookup list for Workers, mainly Dealers, who need to search for |
|
171 specific protocols by name or number and possibly look up the Player that supports the protocols. |
|
172 @see ::AddProtocolPairingL |
|
173 @see ::FindProtocolPairing |
|
174 @see ::RemoveProtocolPairingsForWorker |
|
175 */ |
|
176 TProtocolPairing* iProtocolPairHead; |
|
177 |
|
178 /** |
|
179 List of pairings no longer supported by any active Player. |
|
180 @see ::RemoveProtocolPairingsForWorker |
|
181 */ |
|
182 TProtocolPairing* iDeadPairHead; |
|
183 |
|
184 /** The mapping of tiers to the worker threads to host their managers is loaded by the tier resolver upon demand, |
|
185 with a little complexity from the interplay of roles |
|
186 */ |
|
187 enum TLoadTierMappingPhase |
|
188 { |
|
189 EStart = 0, // not yet requested |
|
190 EDealerRequest, // one or more Dealers asked, request not yet issued to tier resolver (during boot) |
|
191 EResolverRequested, // request sent to tier resolver |
|
192 EComplete // response from tier resolver digested |
|
193 }; |
|
194 TLoadTierMappingPhase iLoadTierMappingPhase; |
|
195 CommsFW::TWorkerId iDefaultOptimalDealer; |
|
196 }; |
|
197 |
|
198 /** |
|
199 Represents the session for Player-side actions, such as tracking protocol |
|
200 references and session observers. Has responsibility for handling session |
|
201 close, including signalling close complete back to the Dealer |
|
202 */ |
|
203 NONSHARABLE_CLASS(CSockSessionProxy) : public Den::CCommonSessionProxy |
|
204 { |
|
205 public: |
|
206 static CSockSessionProxy* NewL(Den::CWorkerSession* aSockSession, CPlayer& aPlayer); |
|
207 ~CSockSessionProxy(); |
|
208 |
|
209 void AddProtocolL(CProtocolBase* aProtocol); |
|
210 void RemoveProtocolL(CProtocolBase* aProtocol); |
|
211 |
|
212 private: |
|
213 CSockSessionProxy(Den::CWorkerSession* aSockSession, CPlayer& aPlayer); |
|
214 void ConstructL(); |
|
215 |
|
216 private: |
|
217 CArrayFixFlat<CProtocolBase*>* iProtocols; |
|
218 }; |
|
219 |
|
220 /** |
|
221 @class CPlayer |
|
222 The main responsibility of the Player is receiving the provider operations/queries |
|
223 from the Dealer and serving them using the protocol plug-ins. |
|
224 It is also responsible for adding/removing sub-sessions from the provider container |
|
225 in the related session object as well as keeping a list of all sub-sessions handled |
|
226 by the Player instance (iSubSessions). |
|
227 */ |
|
228 NONSHARABLE_CLASS(CPlayer) : public Den::CCommonPlayer |
|
229 { |
|
230 friend class CWorkerThread; |
|
231 |
|
232 public: |
|
233 static CPlayer* NewL(CWorkerThread* aOwnerThread, Den::TPlayerRole aPlayerRole); |
|
234 ~CPlayer(); |
|
235 |
|
236 CSockSubSession* SubSession(const Den::TSubSessionUniqueId& aSubSessionUniqueId) const; |
|
237 CSockSession* CurrentSession() const; |
|
238 CWorkerThread& WorkerThread() const; |
|
239 |
|
240 TInt ProtocolInfo(TUint aIndex, TProtocolDesc& aProtocol); |
|
241 |
|
242 // A Player may not support all kinds of behaviour, eg control + data may be provided by separate threads |
|
243 // In future real-time data threads |
|
244 inline TBool HasDataPlane() const; |
|
245 inline TBool HasSubConnPlane() const; |
|
246 inline TBool HasConnPlane() const; |
|
247 inline TBool HasMetaConnPlane() const; |
|
248 inline TBool HasTierMgrPlane() const; |
|
249 inline TBool HasTierResolver() const; |
|
250 |
|
251 ESock::CSocket* NewSocketL(TBool aCompleteClientRequest, TInt& aHandle); |
|
252 void DeleteSocket(ESock::CSocket& aSocket); |
|
253 |
|
254 virtual TBool IsPlayerShutdownComplete(); |
|
255 virtual void DoProcessMessageL(const Den::RSafeMessage& aMsg, Den::CWorkerSubSession* aSubSession); |
|
256 Den::CCommonSessionProxy* DoCreateSessionProxyL(Den::CWorkerSession* aSession); |
|
257 |
|
258 inline CSockSessionProxy* CurrentSessionProxyL(); |
|
259 inline CSockManData* SockManGlobals() const; |
|
260 |
|
261 TDes8* BorrowTemporaryBuffer(TInt aSize); |
|
262 #ifdef _DEBUG |
|
263 TBool RunPostBootChecks(); |
|
264 #endif |
|
265 protected: |
|
266 TInt WriteSubSessionHandle(TInt aHandle); |
|
267 |
|
268 private: |
|
269 CPlayer(CWorkerThread* aOwnerThread, Den::TPlayerRole aPlayerRole); |
|
270 void ProtocolInfo(); |
|
271 void ProtocolInfoByName(); |
|
272 TInt ProtocolInfo(const TDesC &aName,TServerProtocolDesc &aProtocol); |
|
273 |
|
274 private: |
|
275 void CommsApiExtBindIfaceL(const RMessage2& aMessage, CSockSubSession& aSubSession); |
|
276 void CommsApiExtIfaceSendReceiveL(const RMessage2& aMessage, CSockSubSession& aSubSession); |
|
277 void CloseExtensionInterface(const RMessage2& aMessage, CSockSubSession& aSubSession); |
|
278 ESock::CSocket* NewSocketL(TUint anAddrFamily, TUint aSocketType, TUint aProtocol); |
|
279 void NewSocketDefaultL(); |
|
280 void NewSocketWithConnectionL(); |
|
281 void TransferSocketL(ESock::CSocket* aSocket); |
|
282 void LoadProtocolL(TUint anAddrFamily,TUint aSocketType,TUint aProtocol); |
|
283 void UnLoadProtocolL(TUint anAddrFamily,TUint aSocketType,TUint aProtocol); |
|
284 ESock::CHostResolver* NewHostResolverL(TUint anAddrFamily,TUint aSocketType); |
|
285 void NewHostResolverDefaultL(TUint anAddrFamily,TUint aSocketType); |
|
286 void NewHostResolverWithConnectionL(TUint anAddrFamily,TUint aSocketType, TInt aHandle); |
|
287 void NewServiceResolverL(TUint anAddrFamily,TUint aSocketType,TUint aProtocol); |
|
288 void NewNetDatabaseL(TUint anAddrFamily,TUint aSocketType); |
|
289 void NewSocketWithSubConnectionL(); |
|
290 ESock::CSubConnection* NewSubConnectionWithConnectionL(); |
|
291 ESock::CSubConnection* NewSubConnectionL(ESock::CConnection& aConnection); |
|
292 MShimControlClient* CSubConnectionProviderFromHandleL(ESock::CConnection& aConnection, TSubConnectionUniqueId aSubConnectionUniqueId); |
|
293 |
|
294 void NewConnectionL(); |
|
295 void NewConnectionWithNameL(CSockSubSession* aSubSession); |
|
296 void SetupNewConnectionL(ESock::CConnection* aConn); |
|
297 |
|
298 void FreeSocketMemory(); |
|
299 void InstallExtensionL(); |
|
300 |
|
301 void SendToSocketL(TInt aHandle); |
|
302 |
|
303 private: |
|
304 RBuf8 iTransferBuffer; |
|
305 }; |
|
306 |
|
307 #include <comms-infras/ss_roles.inl> |
|
308 |
|
309 #endif //__SS_ROLES_H__ |
|
310 |
|
311 |