commsfwsupport/commselements/commsfw/src/cftransport.cpp
branchRCL_3
changeset 84 486e9e9c45a7
parent 76 576874e13a2c
equal deleted inserted replaced
76:576874e13a2c 84:486e9e9c45a7
   223 class CTransportSelfSender : public CActive, public MBindingAwareTransportSender
   223 class CTransportSelfSender : public CActive, public MBindingAwareTransportSender
   224 	{
   224 	{
   225 public:
   225 public:
   226 	enum
   226 	enum
   227 		{
   227 		{
   228 		KSelfSenderInitialQueueLength = 20, /** Initial size of self-sender queue */
   228 		KSelfSenderInitialQueueLength = 120,	/** H a c k alert. Initial size of self-sender queue. This is based on testing involving closing 40 sockets by just closing the session */
   229 		KSelfSenderQueuePreAllocationGrowthStep = 20, /** Additionl space to reserve each time we pre-allocate some queue space to avoind too much re-allocation */
   229 		KSelfSenderQueueGrowthStep = 40,		/** Increment of self-sender queue size when full. PostMessage() functions panic if growth
   230 		KSelfSenderQueueGrowthStep = 20 /** Increment of self-sender queue size when full. PostMessage() functions panic if growth required and fails */
   230 											    required and fails; to minimise this risk ensure initial size adequate for all likely cases */
   231 		};
   231 		};
   232 
   232 
   233 	static CTransportSelfSender* NewL(MMessageDispatcher& aDispatcher, TWorkerId aSelfId);
   233 	static CTransportSelfSender* NewL(MMessageDispatcher& aDispatcher, TWorkerId aSelfId);
   234 
   234 
   235 private:
   235 private:
   262 		}
   262 		}
   263 	virtual TBool IsDropTransportPending() const
   263 	virtual TBool IsDropTransportPending() const
   264 		{
   264 		{
   265 		return EFalse;
   265 		return EFalse;
   266 		}
   266 		}
   267 	
       
   268 	void PreallocateQueueSpaceL(TInt aMinUndeliveredMessages);
       
   269 
   267 
   270 	~CTransportSelfSender();
   268 	~CTransportSelfSender();
   271 protected:
   269 protected:
   272 	void RunL();
   270 	void RunL();
   273 	TInt RunError(TInt aError);
   271 	TInt RunError(TInt aError);
   277 	void ConstructL();
   275 	void ConstructL();
   278 	TInt DoPostMessage(const TCFMessage& aMessage);
   276 	TInt DoPostMessage(const TCFMessage& aMessage);
   279 	TInt DoPostMessage(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TDesC8& aMessage);
   277 	TInt DoPostMessage(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TDesC8& aMessage);
   280 	TInt ProcessMessage(TCFMessage2& aMessage, TInt aFirstDispatchLeaveReason);
   278 	TInt ProcessMessage(TCFMessage2& aMessage, TInt aFirstDispatchLeaveReason);
   281 	void MaybeTriggerReceipt();
   279 	void MaybeTriggerReceipt();
   282 	void ResizeQueueL(TInt aAdditionalChips);
   280 	TInt ResizeQueue(TInt aAdditionalChips);
   283 private:
   281 private:
   284 	TChipReceiver iReceiver;
   282 	TChipReceiver iReceiver;
   285 	CCirBuf<TCFMessage>* iBuf;
   283 	CCirBuf<TCFMessage>* iBuf;
   286 	};
   284 	};
   287 
   285 
   311 	self->ConstructL();
   309 	self->ConstructL();
   312 	CActiveScheduler::Add(self);
   310 	CActiveScheduler::Add(self);
   313 	CleanupStack::Pop(self);
   311 	CleanupStack::Pop(self);
   314 	return self;
   312 	return self;
   315 	}
   313 	}
   316 /*
   314 
   317  * Preemptively allocate self sender queue length, given by aMinUndeliveredMessages.
   315 TInt CTransportSelfSender::ResizeQueue(TInt aAdditionalChips)
   318  * Note the current logic for queue enlargement is rather coarse, preferring linear growth by a fixed amount.
   316 	{
   319  * A better approach would have been to implement a logarithmic increase for the queue length, which would have saved a bit more memory when the  
       
   320  */
       
   321 void CTransportSelfSender::PreallocateQueueSpaceL(TInt aMinUndeliveredMessages)
       
   322 	{	
       
   323 	TInt currentLength = iBuf->Length();
       
   324 	if (aMinUndeliveredMessages > currentLength)
       
   325 		{
       
   326 		TInt resizeBy = aMinUndeliveredMessages - currentLength;
       
   327 		__CFLOG_VAR(( KLogCommsFw, KLogFwTransport, _L8("CTransportSelfSender::PreallocateQueueSpaceL(%d) Trying to enlarge queue from %d to %d chips"), aMinUndeliveredMessages, currentLength, currentLength + resizeBy + KSelfSenderQueuePreAllocationGrowthStep ));
       
   328 		ResizeQueueL(resizeBy + KSelfSenderQueuePreAllocationGrowthStep);
       
   329 		__CFLOG_VAR(( KLogCommsFw, KLogFwTransport, _L8("CTransportSelfSender::PreallocateQueueSpaceL queue enlargement successful") ));
       
   330 		}
       
   331 	}
       
   332 
       
   333 void CTransportSelfSender::ResizeQueueL(TInt aAdditionalChips)
       
   334 	{
       
   335 	__CFLOG_VAR(( KLogCommsFw, KLogFwTransport, _L8("CTransportSelfSender::ResizeQueueL(%d)"), aAdditionalChips ));
       
   336 	
       
   337 	TInt newLen = iBuf->Length() + aAdditionalChips;
   317 	TInt newLen = iBuf->Length() + aAdditionalChips;
   338 	__ASSERT_ALWAYS(newLen > iBuf->Count(), Panic(ECFInvalidQueueSize));
   318 	__ASSERT_ALWAYS(newLen > iBuf->Count(), Panic(ECFInvalidQueueSize));
   339 				
       
   340 	if (iBuf->Count() == 0)
       
   341 		{
       
   342 		iBuf->SetLengthL(newLen);
       
   343 		return;
       
   344 		}
       
   345 
   319 
   346 	// Create a new queue of the requisite size, copy the elements, and swap for the original
   320 	// Create a new queue of the requisite size, copy the elements, and swap for the original
   347 	// (there's no safe way to resize in-place).
   321 	// (there's no safe way to resize in-place).
   348 	CCirBuf<TCFMessage>* newBuf = new (ELeave) CCirBuf<TCFMessage>;
   322 	CCirBuf<TCFMessage>* newBuf = new CCirBuf<TCFMessage>;
   349 	CleanupStack::PushL(newBuf);
   323 	if(newBuf == NULL)
   350 	newBuf->SetLengthL(newLen);
   324 		{
   351 	CleanupStack::Pop(newBuf);
   325 		__CFLOG_VAR(( KLogCommsFw, KLogFwTransport, _L8("ERROR: CTransportSelfSender::ResizeQueue() unable to enlarge queue from %d chips to %d chips because error -4 occured"), iBuf->Length(), newLen ));
   352 	
   326 
       
   327 		return KErrNoMemory;
       
   328 		}
       
   329 
       
   330 	TRAPD(ret, newBuf->SetLengthL(newLen));
       
   331 	if(ret != KErrNone)
       
   332 		{
       
   333 		__CFLOG_VAR(( KLogCommsFw, KLogFwTransport, _L8("ERROR: CTransportSelfSender::ResizeQueue() unable to enlarge queue from %d chips to %d chips because error %d occured"), iBuf->Length(), newLen, ret ));
       
   334 
       
   335 		return ret;
       
   336 		}
   353 	TCFMessage entry;
   337 	TCFMessage entry;
   354 	while(iBuf->Remove(&entry))
   338 	while(iBuf->Remove(&entry))
   355 		{
   339 		{
   356 		VERIFY( newBuf->Add(&entry) );
   340 		VERIFY( newBuf->Add(&entry) );
   357 		}
   341 		}
   358 	delete iBuf;
   342 	delete iBuf;
   359 	iBuf = newBuf;
   343 	iBuf = newBuf;
       
   344 	return KErrNone;
   360 	}
   345 	}
   361 
   346 
   362 void CTransportSelfSender::PostMessage(const TCFMessage& aMessage)
   347 void CTransportSelfSender::PostMessage(const TCFMessage& aMessage)
   363 	{
   348 	{
   364 	TInt ret = DoPostMessage(aMessage);
   349 	TInt ret = DoPostMessage(aMessage);
   365 	if(ret != KErrNone)
   350 	if(ret != KErrNone)
   366 		{
   351 		{
   367 		TRAP_IGNORE(ResizeQueueL(KSelfSenderQueueGrowthStep));
   352 		ResizeQueue(KSelfSenderQueueGrowthStep);
   368 		ret = DoPostMessage(aMessage);
   353 		ret = DoPostMessage(aMessage);
   369 		}
   354 		//For the benefit of OOM testing as we currently do it (only the sequential failure model)
   370 	__ASSERT_ALWAYS(ret == KErrNone, Panic(ECFTransPeerDrainFailure));	// true, even though peer is us...
   355 		//we attempt to resize the queue for the second time.
       
   356 		//In real scenarios this approach has very limited or no value as the OOM conditions do rarely
       
   357 		//resemble the ones of our sequential failure OOM testing.
       
   358 		//Therefore it would probably make sense to configure out the code for UREL and only keep
       
   359 		//it for _DEBUG.
       
   360 		if(ret != KErrNone)
       
   361 			{
       
   362 			ResizeQueue(KSelfSenderQueueGrowthStep);
       
   363 			ret = DoPostMessage(aMessage);
       
   364 			__ASSERT_ALWAYS(ret == KErrNone, Panic(ECFTransPeerDrainFailure));	// true, even though peer is us...
       
   365 			}
       
   366 		}
   371 	}
   367 	}
   372 
   368 
   373 void CTransportSelfSender::PostMessage(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TDesC8& aMessage)
   369 void CTransportSelfSender::PostMessage(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TDesC8& aMessage)
   374 	{
   370 	{
   375 	__ASSERT_ALWAYS(aPostFrom.Size() + aPostTo.Size() + aMessage.Length() <= CommsFW::KMaxInlineMessageSize, User::Panic(KCFChannelPanic, ECFChanMsgTooBig));
   371 	__ASSERT_ALWAYS(aPostFrom.Size() + aPostTo.Size() + aMessage.Length() <= CommsFW::KMaxInlineMessageSize, User::Panic(KCFChannelPanic, ECFChanMsgTooBig));
   376 	TInt ret = DoPostMessage(aPostFrom, aPostTo, aMessage);
   372 	TInt ret = DoPostMessage(aPostFrom, aPostTo, aMessage);
   377 	if(ret != KErrNone)
   373 	if(ret != KErrNone)
   378 		{
   374 		{
   379 		TRAP_IGNORE(ResizeQueueL(KSelfSenderQueueGrowthStep));
   375 		ResizeQueue(KSelfSenderQueueGrowthStep);
   380 		ret = DoPostMessage(aPostFrom, aPostTo, aMessage);
   376 		ret = DoPostMessage(aPostFrom, aPostTo, aMessage);
   381 		}
   377 		//For the benefit of OOM testing as we currently do it (only the sequential failure model)
   382 	__ASSERT_ALWAYS(ret == KErrNone, Panic(ECFTransPeerDrainFailure));	// true, even though peer is us...
   378 		//we attempt to resize the queue for the second time.
       
   379 		//In real scenarios this approach has very limited or no value as the OOM conditions do rarely
       
   380 		//resemble the ones of our sequential failure OOM testing.
       
   381 		//Therefore it would probably make sense to configure out the code for UREL and only keep
       
   382 		//it for _DEBUG.
       
   383 		if(ret != KErrNone)
       
   384 			{
       
   385 			ResizeQueue(KSelfSenderQueueGrowthStep);
       
   386 			ret = DoPostMessage(aPostFrom, aPostTo, aMessage);
       
   387 			__ASSERT_ALWAYS(ret == KErrNone, Panic(ECFTransPeerDrainFailure));	// true, even though peer is us...
       
   388 			}
       
   389 		}
   383 	}
   390 	}
   384 
   391 
   385 
   392 
   386 #ifdef SYMBIAN_CFTRANSPORT_SUPPORT_IMPATIENCE
   393 #ifdef SYMBIAN_CFTRANSPORT_SUPPORT_IMPATIENCE
   387 /** Needs more testing before deployment
   394 /** Needs more testing before deployment
   444 				// First chip, safe to error
   451 				// First chip, safe to error
   445 				return KErrOverflow;
   452 				return KErrOverflow;
   446 				}
   453 				}
   447 			else
   454 			else
   448 				{
   455 				{
   449 				TRAP_IGNORE(ResizeQueueL(KSelfSenderQueueGrowthStep));
   456 				ResizeQueue(KSelfSenderQueueGrowthStep);
   450 				err = DoPostMessage(*msgPtr);
   457 				err = DoPostMessage(*msgPtr);
   451 				if(err != KErrNone)
   458 				if(err != KErrNone)
   452 					{
   459 					{
   453 					Panic(ECFTransPeerDrainFailure);	// true, even though peer is us... should try growing ring buf
   460 					Panic(ECFTransPeerDrainFailure);	// true, even though peer is us... should try growing ring buf
   454 					}
   461 					}
   952 
   959 
   953 	TBool IsDropTransportPending(TWorkerId aPeerId) const
   960 	TBool IsDropTransportPending(TWorkerId aPeerId) const
   954 		{
   961 		{
   955 		return GetSenderMandatory(aPeerId)->IsDropTransportPending();
   962 		return GetSenderMandatory(aPeerId)->IsDropTransportPending();
   956 		}
   963 		}
   957 	
       
   958 	void PreallocateQueueSpaceL(TInt aMinUndeliveredMessages);
       
   959 
   964 
   960 	void RunL();	// for deleting chippers posted to death row
   965 	void RunL();	// for deleting chippers posted to death row
   961 private:
   966 private:
   962 	CCommsTransportImpl(MWorkerThreadRegister& aThreadRegister, const CMetaDataVirtualCtorInPlace* aVirtCtor)
   967 	CCommsTransportImpl(MWorkerThreadRegister& aThreadRegister, const CMetaDataVirtualCtorInPlace* aVirtCtor)
   963 		: CAsyncOneShot(EPriorityLow),
   968 		: CAsyncOneShot(EPriorityLow),
  1403 		iChipperDeathRow.Remove(*chipper);
  1408 		iChipperDeathRow.Remove(*chipper);
  1404 		delete chipper;
  1409 		delete chipper;
  1405 		}
  1410 		}
  1406 	}
  1411 	}
  1407 
  1412 
  1408 void CCommsTransportImpl::PreallocateQueueSpaceL(TInt aMinUndeliveredMessages)
       
  1409 	{
       
  1410 #ifndef SYMBIAN_NETWORKING_INTERTHREAD_TRANSPORT_ONLY
       
  1411 	iSelfSender->PreallocateQueueSpaceL(aMinUndeliveredMessages);
       
  1412 #else
       
  1413 	(void)aSize; // Do nothing
       
  1414 #endif
       
  1415 	}
       
  1416 
       
  1417 //
  1413 //
  1418 
  1414 
  1419 EXPORT_C CCommsTransport* CCommsTransport::NewL(MWorkerThreadRegister& aThreadRegister, const CMetaDataVirtualCtorInPlace* aVirtCtor, CCFTransportHooks* /*aHooksWalker*/)
  1415 EXPORT_C CCommsTransport* CCommsTransport::NewL(MWorkerThreadRegister& aThreadRegister, const CMetaDataVirtualCtorInPlace* aVirtCtor, CCFTransportHooks* /*aHooksWalker*/)
  1420 	{
  1416 	{
  1421 	CCommsTransport* self = new(ELeave) CCommsTransport;
  1417 	CCommsTransport* self = new(ELeave) CCommsTransport;
  1540 EXPORT_C TBool CCommsTransport::IsDropTransportPending(TWorkerId aPeerId) const
  1536 EXPORT_C TBool CCommsTransport::IsDropTransportPending(TWorkerId aPeerId) const
  1541 	{
  1537 	{
  1542 	return iImpl->IsDropTransportPending(aPeerId);
  1538 	return iImpl->IsDropTransportPending(aPeerId);
  1543 	}
  1539 	}
  1544 
  1540 
  1545 EXPORT_C void CCommsTransport::PreallocateQueueSpaceL(TInt aMinUndeliveredMessages)
       
  1546 	{
       
  1547 	iImpl->PreallocateQueueSpaceL(aMinUndeliveredMessages);
       
  1548 	}
       
  1549 
  1541 
  1550 //
  1542 //
  1551 
  1543 
  1552 TCFMessage2::TCFMessage2(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TDesC8& aData)
  1544 TCFMessage2::TCFMessage2(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TDesC8& aData)
  1553 	{
  1545 	{