commsfwsupport/commselements/commsfw/src/cftransport.cpp
changeset 79 cf589eb1e31e
parent 25 e53adc4c49de
child 84 486e9e9c45a7
equal deleted inserted replaced
75:a365cb779476 79:cf589eb1e31e
   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 = 40,	/** Initial size of self-sender queue (double what testing has observed) */
   228 		KSelfSenderInitialQueueLength = 20, /** Initial size of self-sender queue */
   229 		KSelfSenderQueueGrowthStep = 40,	/** Increment of self-sender queue size when full. PostMessage() functions panic if growth
   229 		KSelfSenderQueuePreAllocationGrowthStep = 20, /** Additionl space to reserve each time we pre-allocate some queue space to avoind too much re-allocation */
   230 											    required and fails; to minimise this risk ensure initial size adequate for all likely cases */
   230 		KSelfSenderQueueGrowthStep = 20 /** Increment of self-sender queue size when full. PostMessage() functions panic if growth required and fails */
   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);
   267 
   269 
   268 	~CTransportSelfSender();
   270 	~CTransportSelfSender();
   269 protected:
   271 protected:
   270 	void RunL();
   272 	void RunL();
   271 	TInt RunError(TInt aError);
   273 	TInt RunError(TInt aError);
   275 	void ConstructL();
   277 	void ConstructL();
   276 	TInt DoPostMessage(const TCFMessage& aMessage);
   278 	TInt DoPostMessage(const TCFMessage& aMessage);
   277 	TInt DoPostMessage(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TDesC8& aMessage);
   279 	TInt DoPostMessage(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TDesC8& aMessage);
   278 	TInt ProcessMessage(TCFMessage2& aMessage, TInt aFirstDispatchLeaveReason);
   280 	TInt ProcessMessage(TCFMessage2& aMessage, TInt aFirstDispatchLeaveReason);
   279 	void MaybeTriggerReceipt();
   281 	void MaybeTriggerReceipt();
   280 	TInt ResizeQueue(TInt aAdditionalChips);
   282 	void ResizeQueueL(TInt aAdditionalChips);
   281 private:
   283 private:
   282 	TChipReceiver iReceiver;
   284 	TChipReceiver iReceiver;
   283 	CCirBuf<TCFMessage>* iBuf;
   285 	CCirBuf<TCFMessage>* iBuf;
   284 	};
   286 	};
   285 
   287 
   309 	self->ConstructL();
   311 	self->ConstructL();
   310 	CActiveScheduler::Add(self);
   312 	CActiveScheduler::Add(self);
   311 	CleanupStack::Pop(self);
   313 	CleanupStack::Pop(self);
   312 	return self;
   314 	return self;
   313 	}
   315 	}
   314 
   316 /*
   315 TInt CTransportSelfSender::ResizeQueue(TInt aAdditionalChips)
   317  * Preemptively allocate self sender queue length, given by aMinUndeliveredMessages.
   316 	{
   318  * Note the current logic for queue enlargement is rather coarse, preferring linear growth by a fixed amount.
       
   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 	
   317 	TInt newLen = iBuf->Length() + aAdditionalChips;
   337 	TInt newLen = iBuf->Length() + aAdditionalChips;
   318 	__ASSERT_ALWAYS(newLen > iBuf->Count(), Panic(ECFInvalidQueueSize));
   338 	__ASSERT_ALWAYS(newLen > iBuf->Count(), Panic(ECFInvalidQueueSize));
       
   339 				
       
   340 	if (iBuf->Count() == 0)
       
   341 		{
       
   342 		iBuf->SetLengthL(newLen);
       
   343 		return;
       
   344 		}
   319 
   345 
   320 	// Create a new queue of the requisite size, copy the elements, and swap for the original
   346 	// Create a new queue of the requisite size, copy the elements, and swap for the original
   321 	// (there's no safe way to resize in-place).
   347 	// (there's no safe way to resize in-place).
   322 	CCirBuf<TCFMessage>* newBuf = new CCirBuf<TCFMessage>;
   348 	CCirBuf<TCFMessage>* newBuf = new (ELeave) CCirBuf<TCFMessage>;
   323 	if(newBuf == NULL)
   349 	CleanupStack::PushL(newBuf);
   324 		{
   350 	newBuf->SetLengthL(newLen);
   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 ));
   351 	CleanupStack::Pop(newBuf);
   326 
   352 	
   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 		}
       
   337 	TCFMessage entry;
   353 	TCFMessage entry;
   338 	while(iBuf->Remove(&entry))
   354 	while(iBuf->Remove(&entry))
   339 		{
   355 		{
   340 		VERIFY( newBuf->Add(&entry) );
   356 		VERIFY( newBuf->Add(&entry) );
   341 		}
   357 		}
   342 	delete iBuf;
   358 	delete iBuf;
   343 	iBuf = newBuf;
   359 	iBuf = newBuf;
   344 	return KErrNone;
       
   345 	}
   360 	}
   346 
   361 
   347 void CTransportSelfSender::PostMessage(const TCFMessage& aMessage)
   362 void CTransportSelfSender::PostMessage(const TCFMessage& aMessage)
   348 	{
   363 	{
   349 	TInt ret = DoPostMessage(aMessage);
   364 	TInt ret = DoPostMessage(aMessage);
   350 	if(ret != KErrNone)
   365 	if(ret != KErrNone)
   351 		{
   366 		{
   352 		ResizeQueue(KSelfSenderQueueGrowthStep);
   367 		TRAP_IGNORE(ResizeQueueL(KSelfSenderQueueGrowthStep));
   353 		ret = DoPostMessage(aMessage);
   368 		ret = DoPostMessage(aMessage);
   354 		//For the benefit of OOM testing as we currently do it (only the sequential failure model)
   369 		}
   355 		//we attempt to resize the queue for the second time.
   370 	__ASSERT_ALWAYS(ret == KErrNone, Panic(ECFTransPeerDrainFailure));	// true, even though peer is us...
   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 		}
       
   367 	}
   371 	}
   368 
   372 
   369 void CTransportSelfSender::PostMessage(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TDesC8& aMessage)
   373 void CTransportSelfSender::PostMessage(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TDesC8& aMessage)
   370 	{
   374 	{
   371 	__ASSERT_ALWAYS(aPostFrom.Size() + aPostTo.Size() + aMessage.Length() <= CommsFW::KMaxInlineMessageSize, User::Panic(KCFChannelPanic, ECFChanMsgTooBig));
   375 	__ASSERT_ALWAYS(aPostFrom.Size() + aPostTo.Size() + aMessage.Length() <= CommsFW::KMaxInlineMessageSize, User::Panic(KCFChannelPanic, ECFChanMsgTooBig));
   372 	TInt ret = DoPostMessage(aPostFrom, aPostTo, aMessage);
   376 	TInt ret = DoPostMessage(aPostFrom, aPostTo, aMessage);
   373 	if(ret != KErrNone)
   377 	if(ret != KErrNone)
   374 		{
   378 		{
   375 		ResizeQueue(KSelfSenderQueueGrowthStep);
   379 		TRAP_IGNORE(ResizeQueueL(KSelfSenderQueueGrowthStep));
   376 		ret = DoPostMessage(aPostFrom, aPostTo, aMessage);
   380 		ret = DoPostMessage(aPostFrom, aPostTo, aMessage);
   377 		//For the benefit of OOM testing as we currently do it (only the sequential failure model)
   381 		}
   378 		//we attempt to resize the queue for the second time.
   382 	__ASSERT_ALWAYS(ret == KErrNone, Panic(ECFTransPeerDrainFailure));	// true, even though peer is us...
   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 		}
       
   390 	}
   383 	}
   391 
   384 
   392 
   385 
   393 #ifdef SYMBIAN_CFTRANSPORT_SUPPORT_IMPATIENCE
   386 #ifdef SYMBIAN_CFTRANSPORT_SUPPORT_IMPATIENCE
   394 /** Needs more testing before deployment
   387 /** Needs more testing before deployment
   451 				// First chip, safe to error
   444 				// First chip, safe to error
   452 				return KErrOverflow;
   445 				return KErrOverflow;
   453 				}
   446 				}
   454 			else
   447 			else
   455 				{
   448 				{
   456 				ResizeQueue(KSelfSenderQueueGrowthStep);
   449 				TRAP_IGNORE(ResizeQueueL(KSelfSenderQueueGrowthStep));
   457 				err = DoPostMessage(*msgPtr);
   450 				err = DoPostMessage(*msgPtr);
   458 				if(err != KErrNone)
   451 				if(err != KErrNone)
   459 					{
   452 					{
   460 					Panic(ECFTransPeerDrainFailure);	// true, even though peer is us... should try growing ring buf
   453 					Panic(ECFTransPeerDrainFailure);	// true, even though peer is us... should try growing ring buf
   461 					}
   454 					}
   959 
   952 
   960 	TBool IsDropTransportPending(TWorkerId aPeerId) const
   953 	TBool IsDropTransportPending(TWorkerId aPeerId) const
   961 		{
   954 		{
   962 		return GetSenderMandatory(aPeerId)->IsDropTransportPending();
   955 		return GetSenderMandatory(aPeerId)->IsDropTransportPending();
   963 		}
   956 		}
       
   957 	
       
   958 	void PreallocateQueueSpaceL(TInt aMinUndeliveredMessages);
   964 
   959 
   965 	void RunL();	// for deleting chippers posted to death row
   960 	void RunL();	// for deleting chippers posted to death row
   966 private:
   961 private:
   967 	CCommsTransportImpl(MWorkerThreadRegister& aThreadRegister, const CMetaDataVirtualCtorInPlace* aVirtCtor)
   962 	CCommsTransportImpl(MWorkerThreadRegister& aThreadRegister, const CMetaDataVirtualCtorInPlace* aVirtCtor)
   968 		: CAsyncOneShot(EPriorityLow),
   963 		: CAsyncOneShot(EPriorityLow),
  1408 		iChipperDeathRow.Remove(*chipper);
  1403 		iChipperDeathRow.Remove(*chipper);
  1409 		delete chipper;
  1404 		delete chipper;
  1410 		}
  1405 		}
  1411 	}
  1406 	}
  1412 
  1407 
       
  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 
  1413 //
  1417 //
  1414 
  1418 
  1415 EXPORT_C CCommsTransport* CCommsTransport::NewL(MWorkerThreadRegister& aThreadRegister, const CMetaDataVirtualCtorInPlace* aVirtCtor, CCFTransportHooks* /*aHooksWalker*/)
  1419 EXPORT_C CCommsTransport* CCommsTransport::NewL(MWorkerThreadRegister& aThreadRegister, const CMetaDataVirtualCtorInPlace* aVirtCtor, CCFTransportHooks* /*aHooksWalker*/)
  1416 	{
  1420 	{
  1417 	CCommsTransport* self = new(ELeave) CCommsTransport;
  1421 	CCommsTransport* self = new(ELeave) CCommsTransport;
  1536 EXPORT_C TBool CCommsTransport::IsDropTransportPending(TWorkerId aPeerId) const
  1540 EXPORT_C TBool CCommsTransport::IsDropTransportPending(TWorkerId aPeerId) const
  1537 	{
  1541 	{
  1538 	return iImpl->IsDropTransportPending(aPeerId);
  1542 	return iImpl->IsDropTransportPending(aPeerId);
  1539 	}
  1543 	}
  1540 
  1544 
       
  1545 EXPORT_C void CCommsTransport::PreallocateQueueSpaceL(TInt aMinUndeliveredMessages)
       
  1546 	{
       
  1547 	iImpl->PreallocateQueueSpaceL(aMinUndeliveredMessages);
       
  1548 	}
  1541 
  1549 
  1542 //
  1550 //
  1543 
  1551 
  1544 TCFMessage2::TCFMessage2(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TDesC8& aData)
  1552 TCFMessage2::TCFMessage2(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TDesC8& aData)
  1545 	{
  1553 	{