commsfwsupport/commselements/commsfw/src/cftransport.cpp
branchRCL_3
changeset 76 576874e13a2c
parent 19 0b0e9fce0b58
child 84 486e9e9c45a7
--- a/commsfwsupport/commselements/commsfw/src/cftransport.cpp	Tue Sep 14 23:38:38 2010 +0300
+++ b/commsfwsupport/commselements/commsfw/src/cftransport.cpp	Wed Sep 15 13:33:11 2010 +0300
@@ -225,9 +225,9 @@
 public:
 	enum
 		{
-		KSelfSenderInitialQueueLength = 40,	/** Initial size of self-sender queue (double what testing has observed) */
-		KSelfSenderQueueGrowthStep = 40,	/** Increment of self-sender queue size when full. PostMessage() functions panic if growth
-											    required and fails; to minimise this risk ensure initial size adequate for all likely cases */
+		KSelfSenderInitialQueueLength = 20, /** Initial size of self-sender queue */
+		KSelfSenderQueuePreAllocationGrowthStep = 20, /** Additionl space to reserve each time we pre-allocate some queue space to avoind too much re-allocation */
+		KSelfSenderQueueGrowthStep = 20 /** Increment of self-sender queue size when full. PostMessage() functions panic if growth required and fails */
 		};
 
 	static CTransportSelfSender* NewL(MMessageDispatcher& aDispatcher, TWorkerId aSelfId);
@@ -264,6 +264,8 @@
 		{
 		return EFalse;
 		}
+	
+	void PreallocateQueueSpaceL(TInt aMinUndeliveredMessages);
 
 	~CTransportSelfSender();
 protected:
@@ -277,7 +279,7 @@
 	TInt DoPostMessage(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TDesC8& aMessage);
 	TInt ProcessMessage(TCFMessage2& aMessage, TInt aFirstDispatchLeaveReason);
 	void MaybeTriggerReceipt();
-	TInt ResizeQueue(TInt aAdditionalChips);
+	void ResizeQueueL(TInt aAdditionalChips);
 private:
 	TChipReceiver iReceiver;
 	CCirBuf<TCFMessage>* iBuf;
@@ -311,29 +313,43 @@
 	CleanupStack::Pop(self);
 	return self;
 	}
+/*
+ * Preemptively allocate self sender queue length, given by aMinUndeliveredMessages.
+ * Note the current logic for queue enlargement is rather coarse, preferring linear growth by a fixed amount.
+ * 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  
+ */
+void CTransportSelfSender::PreallocateQueueSpaceL(TInt aMinUndeliveredMessages)
+	{	
+	TInt currentLength = iBuf->Length();
+	if (aMinUndeliveredMessages > currentLength)
+		{
+		TInt resizeBy = aMinUndeliveredMessages - currentLength;
+		__CFLOG_VAR(( KLogCommsFw, KLogFwTransport, _L8("CTransportSelfSender::PreallocateQueueSpaceL(%d) Trying to enlarge queue from %d to %d chips"), aMinUndeliveredMessages, currentLength, currentLength + resizeBy + KSelfSenderQueuePreAllocationGrowthStep ));
+		ResizeQueueL(resizeBy + KSelfSenderQueuePreAllocationGrowthStep);
+		__CFLOG_VAR(( KLogCommsFw, KLogFwTransport, _L8("CTransportSelfSender::PreallocateQueueSpaceL queue enlargement successful") ));
+		}
+	}
 
-TInt CTransportSelfSender::ResizeQueue(TInt aAdditionalChips)
+void CTransportSelfSender::ResizeQueueL(TInt aAdditionalChips)
 	{
+	__CFLOG_VAR(( KLogCommsFw, KLogFwTransport, _L8("CTransportSelfSender::ResizeQueueL(%d)"), aAdditionalChips ));
+	
 	TInt newLen = iBuf->Length() + aAdditionalChips;
 	__ASSERT_ALWAYS(newLen > iBuf->Count(), Panic(ECFInvalidQueueSize));
+				
+	if (iBuf->Count() == 0)
+		{
+		iBuf->SetLengthL(newLen);
+		return;
+		}
 
 	// Create a new queue of the requisite size, copy the elements, and swap for the original
 	// (there's no safe way to resize in-place).
-	CCirBuf<TCFMessage>* newBuf = new CCirBuf<TCFMessage>;
-	if(newBuf == NULL)
-		{
-		__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 ));
-
-		return KErrNoMemory;
-		}
-
-	TRAPD(ret, newBuf->SetLengthL(newLen));
-	if(ret != KErrNone)
-		{
-		__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 ));
-
-		return ret;
-		}
+	CCirBuf<TCFMessage>* newBuf = new (ELeave) CCirBuf<TCFMessage>;
+	CleanupStack::PushL(newBuf);
+	newBuf->SetLengthL(newLen);
+	CleanupStack::Pop(newBuf);
+	
 	TCFMessage entry;
 	while(iBuf->Remove(&entry))
 		{
@@ -341,7 +357,6 @@
 		}
 	delete iBuf;
 	iBuf = newBuf;
-	return KErrNone;
 	}
 
 void CTransportSelfSender::PostMessage(const TCFMessage& aMessage)
@@ -349,21 +364,10 @@
 	TInt ret = DoPostMessage(aMessage);
 	if(ret != KErrNone)
 		{
-		ResizeQueue(KSelfSenderQueueGrowthStep);
+		TRAP_IGNORE(ResizeQueueL(KSelfSenderQueueGrowthStep));
 		ret = DoPostMessage(aMessage);
-		//For the benefit of OOM testing as we currently do it (only the sequential failure model)
-		//we attempt to resize the queue for the second time.
-		//In real scenarios this approach has very limited or no value as the OOM conditions do rarely
-		//resemble the ones of our sequential failure OOM testing.
-		//Therefore it would probably make sense to configure out the code for UREL and only keep
-		//it for _DEBUG.
-		if(ret != KErrNone)
-			{
-			ResizeQueue(KSelfSenderQueueGrowthStep);
-			ret = DoPostMessage(aMessage);
-		__ASSERT_ALWAYS(ret == KErrNone, Panic(ECFTransPeerDrainFailure));	// true, even though peer is us...
-			}
 		}
+	__ASSERT_ALWAYS(ret == KErrNone, Panic(ECFTransPeerDrainFailure));	// true, even though peer is us...
 	}
 
 void CTransportSelfSender::PostMessage(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TDesC8& aMessage)
@@ -372,21 +376,10 @@
 	TInt ret = DoPostMessage(aPostFrom, aPostTo, aMessage);
 	if(ret != KErrNone)
 		{
-		ResizeQueue(KSelfSenderQueueGrowthStep);
+		TRAP_IGNORE(ResizeQueueL(KSelfSenderQueueGrowthStep));
 		ret = DoPostMessage(aPostFrom, aPostTo, aMessage);
-		//For the benefit of OOM testing as we currently do it (only the sequential failure model)
-		//we attempt to resize the queue for the second time.
-		//In real scenarios this approach has very limited or no value as the OOM conditions do rarely
-		//resemble the ones of our sequential failure OOM testing.
-		//Therefore it would probably make sense to configure out the code for UREL and only keep
-		//it for _DEBUG.
-		if(ret != KErrNone)
-			{
-			ResizeQueue(KSelfSenderQueueGrowthStep);
-			ret = DoPostMessage(aPostFrom, aPostTo, aMessage);
-		__ASSERT_ALWAYS(ret == KErrNone, Panic(ECFTransPeerDrainFailure));	// true, even though peer is us...
-			}
 		}
+	__ASSERT_ALWAYS(ret == KErrNone, Panic(ECFTransPeerDrainFailure));	// true, even though peer is us...
 	}
 
 
@@ -453,7 +446,7 @@
 				}
 			else
 				{
-				ResizeQueue(KSelfSenderQueueGrowthStep);
+				TRAP_IGNORE(ResizeQueueL(KSelfSenderQueueGrowthStep));
 				err = DoPostMessage(*msgPtr);
 				if(err != KErrNone)
 					{
@@ -961,6 +954,8 @@
 		{
 		return GetSenderMandatory(aPeerId)->IsDropTransportPending();
 		}
+	
+	void PreallocateQueueSpaceL(TInt aMinUndeliveredMessages);
 
 	void RunL();	// for deleting chippers posted to death row
 private:
@@ -1410,6 +1405,15 @@
 		}
 	}
 
+void CCommsTransportImpl::PreallocateQueueSpaceL(TInt aMinUndeliveredMessages)
+	{
+#ifndef SYMBIAN_NETWORKING_INTERTHREAD_TRANSPORT_ONLY
+	iSelfSender->PreallocateQueueSpaceL(aMinUndeliveredMessages);
+#else
+	(void)aSize; // Do nothing
+#endif
+	}
+
 //
 
 EXPORT_C CCommsTransport* CCommsTransport::NewL(MWorkerThreadRegister& aThreadRegister, const CMetaDataVirtualCtorInPlace* aVirtCtor, CCFTransportHooks* /*aHooksWalker*/)
@@ -1538,6 +1542,10 @@
 	return iImpl->IsDropTransportPending(aPeerId);
 	}
 
+EXPORT_C void CCommsTransport::PreallocateQueueSpaceL(TInt aMinUndeliveredMessages)
+	{
+	iImpl->PreallocateQueueSpaceL(aMinUndeliveredMessages);
+	}
 
 //