|
1 // Copyright (c) 1997-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 #include "ss_glob.h" |
|
16 |
|
17 #include <comms-infras/ss_roles.h> |
|
18 #include <ss_std.h> |
|
19 #include <comms-infras/ss_log.h> |
|
20 #include <ss_protprov.h> |
|
21 #include <comms-infras/ss_subconnprov.h> |
|
22 #include <comms-infras/ss_connprov.h> |
|
23 #include <comms-infras/ss_metaconnprov_internal.h> |
|
24 #include <elements/nm_common.h> //for Messages::TlsGlobals |
|
25 #include <comms-infras/ss_subconnflow.h> |
|
26 #include <comms-infras/ss_protflow.h> |
|
27 #include <comms-infras/ss_nodemessages.h> |
|
28 #include <comms-infras/ss_tiermanager.h> |
|
29 #include <comms-infras/ss_tiermanager_internal.h> |
|
30 #include "ss_apiext_messages.h" |
|
31 #include <comms-infras/ss_mcprnodemessages.h> |
|
32 #ifdef SYMBIAN_ZERO_COPY_NETWORKING |
|
33 #include <comms-infras/commsbufpondop.h> |
|
34 #else |
|
35 #include <es_mbman.h> |
|
36 #endif // SYMBIAN_ZERO_COPY_NETWORKING |
|
37 |
|
38 |
|
39 #ifdef _DEBUG |
|
40 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module |
|
41 // (if it could happen through user error then you should give it an explicit, documented, category + code) |
|
42 _LIT(KSpecAssert_ESockSSockS_GLOB, "ESockSSockS_GLOB"); |
|
43 #endif |
|
44 |
|
45 using namespace ESock; |
|
46 using namespace Messages; |
|
47 using namespace Den; |
|
48 |
|
49 CSockManData::CSockManData(CGlobals& aGlobals, CWorkerThread* aWorker) |
|
50 : iWorkerThread(aWorker), |
|
51 iTransportGlobals(aGlobals), |
|
52 iCommsApiExtRegister(aGlobals) |
|
53 { |
|
54 __ASSERT_DEBUG(!SockManGlobals::Get(), User::Panic(KSpecAssert_ESockSSockS_GLOB, 1)); |
|
55 SockManGlobals::Set(this); |
|
56 } |
|
57 |
|
58 CSockManData::~CSockManData() |
|
59 { |
|
60 SockManGlobals::Set(NULL); |
|
61 iFCMap.Close(); |
|
62 delete iTimer; |
|
63 delete iEskData; |
|
64 delete iWorkerThread; |
|
65 } |
|
66 |
|
67 CSockManData* CSockManData::NewL(CGlobals& aGlobals, CWorkerThread* aWorker) |
|
68 { |
|
69 CSockManData* globs = new(ELeave) CSockManData(aGlobals, aWorker); |
|
70 CleanupStack::PushL(globs); |
|
71 globs->ConstructL(); |
|
72 CleanupStack::Pop(globs); |
|
73 return globs; |
|
74 } |
|
75 |
|
76 void CSockManData::ConstructL() |
|
77 { |
|
78 iExtensions.SetOffset(_FOFF(CSocketServExtRef, iExtLink)); |
|
79 |
|
80 //at the moment the CProtocolFamilyFactoryBase subclasses' instances are created along with |
|
81 //the protocol family being loaded (applies to the new protocols only) |
|
82 iTimer=CDeltaTimer::NewL(ESocketTimerPriority, KTimerGranularity); |
|
83 iTimer->Deque(); //PERF: re-add upon first use |
|
84 |
|
85 // globals->iNumSessions=0; |
|
86 // globals->iNumFamilies=0; |
|
87 #ifdef SYMBIAN_ZERO_COPY_NETWORKING |
|
88 iCommsBufPond=TCommsBufPondTLSOp::Get(); |
|
89 #else |
|
90 iMBufManager=CMBufManager::Context(); |
|
91 #endif // SYMBIAN_ZERO_COPY_NETWORKING |
|
92 } |
|
93 |
|
94 TBool CSockManData::ShutdownGracefully() |
|
95 /** |
|
96 @return Whether the socket server intends to shutdown (ETrue) at first opportunity |
|
97 when there is no connections to it. If ETrue it doesnt accept new connections. |
|
98 */ |
|
99 { |
|
100 return SelfWorker()->ShuttingDown(); |
|
101 } |
|
102 |
|
103 EXPORT_C Messages::TNodeId CSockManData::GetPlaneFC(const TPlayerRole& aPlane) |
|
104 { |
|
105 return iFCMap.GetPlaneFC(aPlane); |
|
106 } |
|
107 |
|
108 |
|
109 void CSockManData::InstallFactoryContainersL() |
|
110 { |
|
111 __ASSERT_DEBUG( iWorkerThread->Player() , User::Panic(KSpecAssert_ESockSSockS_GLOB, 2)); // Only Players have factories |
|
112 CPlayer& player(*iWorkerThread->Player()); |
|
113 |
|
114 if (!iTierManagerFactories && player.HasTierMgrPlane()) |
|
115 { |
|
116 iTierManagerFactories = CTierManagerFactoryContainer::NewL(); |
|
117 TNodeId fc(iTierManagerFactories->Id()); |
|
118 iFCMap.AddPlaneFC(TCFPlayerRole(TCFPlayerRole::ETierMgrPlane), fc); |
|
119 iTransportGlobals.AddPersistentItf(fc); |
|
120 } |
|
121 |
|
122 if (!iMetaConnectionFactories && player.HasMetaConnPlane()) |
|
123 { |
|
124 iMetaConnectionFactories = CMetaConnectionFactoryContainer::NewL(); |
|
125 TNodeId fc(iMetaConnectionFactories->Id()); |
|
126 iFCMap.AddPlaneFC(TCFPlayerRole(TCFPlayerRole::EMetaConnPlane), fc); |
|
127 iTransportGlobals.AddPersistentItf(fc); |
|
128 } |
|
129 |
|
130 if (!iConnectionFactories && player.HasConnPlane()) |
|
131 { |
|
132 iConnectionFactories = CConnectionFactoryContainer::NewL(); |
|
133 TNodeId fc(iConnectionFactories->Id()); |
|
134 iFCMap.AddPlaneFC(TCFPlayerRole(TCFPlayerRole::EConnPlane), fc); |
|
135 iTransportGlobals.AddPersistentItf(fc); |
|
136 |
|
137 // Install a new object broker for all of the factory containers in affiliated worker threads |
|
138 __ASSERT_DEBUG(!iCommsFactoryContainerBrokerSingleton, User::Panic(KSpecAssert_ESockSSockS_GLOB, 3)); |
|
139 iCommsFactoryContainerBrokerSingleton = CCFFactoryContainerBroker::NewL(); |
|
140 iTransportGlobals.AddPersistentItf(iCommsFactoryContainerBrokerSingleton->Id()); |
|
141 |
|
142 // Keep this locally for factory requests in our own thread |
|
143 // Other workers learn about it through an advertisement message |
|
144 iCommsFactoryContainerBroker = iCommsFactoryContainerBrokerSingleton->Id(); |
|
145 } |
|
146 |
|
147 if (!iSubConnectionFactories && player.HasSubConnPlane()) |
|
148 { |
|
149 iSubConnectionFactories = CSubConnectionFactoryContainer::NewL(); |
|
150 TNodeId fc(iSubConnectionFactories->Id()); |
|
151 iFCMap.AddPlaneFC(TCFPlayerRole(TCFPlayerRole::ESubConnPlane), fc); |
|
152 iTransportGlobals.AddPersistentItf(fc); |
|
153 } |
|
154 |
|
155 LOG(ESockLog::Printf(_L("ProtocolFamilyFactories Initialisation"))); |
|
156 |
|
157 if (!iProtocolFamilyFactories && player.HasDataPlane()) |
|
158 { |
|
159 iProtocolFamilyFactories = CProtocolFamilyFactoryContainer::NewL(); |
|
160 iTransportGlobals.AddPersistentItf(iProtocolFamilyFactories->Id()); |
|
161 } |
|
162 |
|
163 if (!iSubConnectionFlowFactories&& player.HasDataPlane()) |
|
164 { |
|
165 iSubConnectionFlowFactories = CSubConnectionFlowFactoryContainer::NewL(); |
|
166 TNodeId fc(iSubConnectionFlowFactories->Id()); |
|
167 iFCMap.AddPlaneFC(TCFPlayerRole(TCFPlayerRole::EDataPlane), fc); |
|
168 iTransportGlobals.AddPersistentItf(fc); |
|
169 // SubConnection Factory Container receives the cookie of the Flow Factory Container, |
|
170 // as the former hosts requests to initiate Flow creation. |
|
171 // iSubConnectionFactories->SetFlowFactoryCookieL(0, (*iSubConnectionFlowFactories)()); |
|
172 } |
|
173 |
|
174 if (!iProtocolIntfFactories && player.HasDataPlane()) |
|
175 { |
|
176 iProtocolIntfFactories = CProtocolIntfFactoryContainer::NewL(); |
|
177 iTransportGlobals.AddPersistentItf(iProtocolIntfFactories->Id()); |
|
178 } |
|
179 |
|
180 // Now add our own factory containers to the object broker if we are hosting it, as we won't |
|
181 // be told about the broker if we are hosting it and won't then get a chance to send our FCs to it |
|
182 if (player.HasConnPlane()) |
|
183 { |
|
184 if (iTierManagerFactories) |
|
185 { |
|
186 AddFactoryContainerObjectBrokerClient( |
|
187 iTierManagerFactories->Id(), |
|
188 TCFPlayerRole(TCFPlayerRole::ETierMgrPlane) |
|
189 ); |
|
190 } |
|
191 |
|
192 if (iMetaConnectionFactories) |
|
193 { |
|
194 AddFactoryContainerObjectBrokerClient( |
|
195 iMetaConnectionFactories->Id(), |
|
196 TCFPlayerRole(TCFPlayerRole::EMetaConnPlane) |
|
197 ); |
|
198 } |
|
199 |
|
200 if (iConnectionFactories) |
|
201 { |
|
202 AddFactoryContainerObjectBrokerClient( |
|
203 iConnectionFactories->Id(), |
|
204 TCFPlayerRole(TCFPlayerRole::EConnPlane) |
|
205 ); |
|
206 } |
|
207 |
|
208 if (iSubConnectionFactories) |
|
209 { |
|
210 AddFactoryContainerObjectBrokerClient( |
|
211 iSubConnectionFactories->Id(), |
|
212 TCFPlayerRole(TCFPlayerRole::ESubConnPlane) |
|
213 ); |
|
214 } |
|
215 |
|
216 if (iSubConnectionFlowFactories) |
|
217 { |
|
218 AddFactoryContainerObjectBrokerClient( |
|
219 iSubConnectionFlowFactories->Id(), |
|
220 TCFPlayerRole(TCFPlayerRole::EDataPlane) |
|
221 ); |
|
222 } |
|
223 } |
|
224 |
|
225 // Register internal messages |
|
226 TCFMessage::RegisterL(); |
|
227 TCFSafeMessage::RegisterL(); |
|
228 TExtItfMsgTables::RegisterL(); |
|
229 } |
|
230 |
|
231 void CSockManData::AddFactoryContainerObjectBrokerClient( |
|
232 const Messages::TNodeId& aNodeId, |
|
233 const TCFPlayerRole& aType) |
|
234 { |
|
235 // Should only be adding them once |
|
236 __ASSERT_DEBUG(0 == iCommsFactoryContainerBrokerSingleton->CountClients<TDefaultClientMatchPolicy>(aType), User::Panic(KSpecAssert_ESockSSockS_GLOB, 4)); |
|
237 |
|
238 iCommsFactoryContainerBrokerSingleton->AddClientL( |
|
239 aNodeId, |
|
240 aType |
|
241 ); |
|
242 } |
|
243 |
|
244 void CSockManData::UninstallFactoryContainers() |
|
245 { |
|
246 // De-Register internal messages |
|
247 TCFMessage::DeRegister(); |
|
248 TCFSafeMessage::DeRegister(); |
|
249 TExtItfMsgTables::DeRegister(); |
|
250 |
|
251 delete iCommsFactoryContainerBrokerSingleton; |
|
252 delete iSubConnectionFactories; |
|
253 delete iConnectionFactories; |
|
254 delete iProtocolIntfFactories; |
|
255 delete iProtocolFamilyFactories; |
|
256 delete iSubConnectionFlowFactories; |
|
257 delete iMetaConnectionFactories; |
|
258 delete iTierManagerFactories; |
|
259 } |
|
260 |
|
261 // Support self-awareness when logging |
|
262 EXPORT_C CWorkerThread* CSockManData::SelfWorker() const |
|
263 { |
|
264 return iWorkerThread; |
|
265 } |
|
266 |
|
267 // Support self-awareness when logging |
|
268 EXPORT_C CPlayer* CSockManData::SelfPlayer() |
|
269 { |
|
270 return iWorkerThread->Player(); |
|
271 } |
|
272 |
|
273 void SockManGlobals::Set(CSockManData * aGlobals) |
|
274 { |
|
275 Dll::SetTls(aGlobals); |
|
276 } |
|
277 |
|
278 EXPORT_C CSockManData* SockManGlobals::Get() |
|
279 { |
|
280 CSockManData * d=(CSockManData *)Dll::Tls(); |
|
281 return d; |
|
282 } |
|
283 |
|
284 #ifdef SYMBIAN_NETWORKING_PERFMETRICS |
|
285 void CSockManData::IncludePerformanceData(TInt aDeltaClientRxBytes, TInt aDeltaClientRxBuffBytes, TInt aDeltaClientTxBytes) |
|
286 { |
|
287 if(aDeltaClientRxBytes >= 0) |
|
288 { |
|
289 iRxStats.AccumulateXfer(aDeltaClientRxBytes); |
|
290 } |
|
291 if(aDeltaClientRxBuffBytes >= 0) |
|
292 { |
|
293 iRxBuffStats.AccumulateXfer(aDeltaClientRxBuffBytes); |
|
294 } |
|
295 if(aDeltaClientTxBytes >= 0) |
|
296 { |
|
297 iTxStats.AccumulateXfer(aDeltaClientTxBytes); |
|
298 } |
|
299 } |
|
300 |
|
301 |
|
302 TBool CSockManData::AddToPerfLog(TAny* aSelf, TDes8& aBuffer, TDes8Overflow* aOverflowHandler) |
|
303 { |
|
304 CSockManData* self = static_cast<CSockManData*>(aSelf); |
|
305 _LIT8(KFormat, "ESock Rx: tot %u; cnt %u; %u, %u, %u, %u, %u, %u; RxBuff: tot %u; %u, %u, %u, %u, %u, %u, Tx: tot %u; cnt %u; %u; %u, %u, %u, %u, %u"); |
|
306 TXferStats& rx = self->iRxStats; |
|
307 TXferStats& rxB = self->iRxBuffStats; |
|
308 TXferStats& tx = self->iTxStats; |
|
309 aBuffer.AppendFormat(KFormat, aOverflowHandler, |
|
310 rx.iTotal, rx.iCount, rx.iBuckets[0], rx.iBuckets[1], rx.iBuckets[2], rx.iBuckets[3], rx.iBuckets[4], rx.iBuckets[5], |
|
311 rxB.iTotal, rxB.iBuckets[0], rxB.iBuckets[1], rxB.iBuckets[2], rxB.iBuckets[3], rxB.iBuckets[4], rxB.iBuckets[5], |
|
312 tx.iTotal, tx.iCount, tx.iBuckets[0], tx.iBuckets[1], tx.iBuckets[2], tx.iBuckets[3], tx.iBuckets[4], tx.iBuckets[5] |
|
313 ); |
|
314 return EFalse; |
|
315 } |
|
316 |
|
317 void CSockManData::TXferStats::AccumulateXfer(TUint aValue) |
|
318 { |
|
319 ++iCount; |
|
320 if(aValue > 0) |
|
321 { |
|
322 iTotal += aValue; |
|
323 TInt bucketCap = 128; |
|
324 TInt bucket = 0; |
|
325 while(bucket < KNumBuckets) |
|
326 { |
|
327 if(bucketCap > aValue) |
|
328 { |
|
329 ++iBuckets[bucket]; |
|
330 break; |
|
331 } |
|
332 bucketCap <<= 2; |
|
333 ++bucket; |
|
334 } |
|
335 } |
|
336 } |
|
337 |
|
338 |
|
339 CSockManData::~CSockManData() |
|
340 { |
|
341 CommsFW::CPerfMetricStore::RemoveClient(this); |
|
342 } |
|
343 |
|
344 #endif |
|
345 |
|
346 const ::CESockIniData* CSockManData::IniData() |
|
347 { |
|
348 return iEskData; |
|
349 } |
|
350 |
|
351 #ifdef ESOCK_HOME_THREAD_CHECK_ENABLED |
|
352 |
|
353 void CSockManData::AssertOwnThread() const |
|
354 { |
|
355 TThreadId home = iWorkerThread->OwnThread(); |
|
356 TThreadId curr = RThread().Id(); |
|
357 if(home != curr) |
|
358 { |
|
359 Fault(EWrongThread); |
|
360 } |
|
361 } |
|
362 |
|
363 #endif |
|
364 |
|
365 #ifdef _DEBUG |
|
366 |
|
367 void CSockManData::LogActiveProtocols() |
|
368 { |
|
369 TSglQueIter<CProtocolRef> i(*iProtocols); |
|
370 CProtocolRef* ref = NULL; |
|
371 while((ref = i++) != NULL) |
|
372 { |
|
373 CProtocolBase* prot = ref->Protocol(); |
|
374 if(prot) |
|
375 { |
|
376 CProtocolFamilyBase* fam = prot->ProtocolFamily(); |
|
377 LOG(ESockLog::Printf(KESockSessDetailTag, _L("* Prot %S refCnt = %d, family refCnt = %d"), &ref->Info().iName, prot->RefCount(), fam->RefCount() )); |
|
378 } |
|
379 } |
|
380 } |
|
381 |
|
382 #endif |
|
383 |
|
384 EXPORT_C CCommsFactoryBase* CSockManData::InstallFactoryL( ESock::EFactoryType aFactoryType, const TDesC8& aName, TUid aFactoryUid ) |
|
385 { |
|
386 CSockManData *globals=SockManGlobals::Get(); |
|
387 CCommsFactoryBase* pBase = NULL; |
|
388 switch (aFactoryType) |
|
389 { |
|
390 case EProtocolFamilyFactory: |
|
391 pBase = globals->iProtocolFamilyFactories->FindOrCreateL( aName, aFactoryUid ); |
|
392 break; |
|
393 default: |
|
394 User::Leave(KErrNotSupported); |
|
395 break; |
|
396 }; |
|
397 return pBase; |
|
398 } |