commsfwutils/commsbufs/mbufmgr/src/mb_chn.cpp
branchRCL_3
changeset 18 9644881fedd0
parent 0 dfb7c4ff071f
child 21 07656293a99c
equal deleted inserted replaced
17:9ddb1d67ebaf 18:9644881fedd0
   270 	else
   270 	else
   271 		{
   271 		{
   272 		len = Min(aLen, len);	
   272 		len = Min(aLen, len);	
   273 		}		
   273 		}		
   274 
   274 
   275 	TInt err = newChain.Alloc(len + aHdrReserve, *this);
   275 // Suppress the "follow-the-leader" behaviour of preserving the buffer sizing of the
       
   276 // existing chain. The goal of preserving buffer characteristics remains desirable but
       
   277 // not at the cost of having TCP use unnecessarily small buffers - this area needs 
       
   278 // rework once the Comms stack really adopts buffer pools and zero copy  	
       
   279 //	TInt err = newChain.Alloc(len + aHdrReserve, *this);
       
   280 	TInt err;
       
   281     if(First())
       
   282         {
       
   283         newChain.iNext = First()->Pool()->Pond().Alloc(len + aHdrReserve, 0, KMaxTInt);
       
   284         err = iNext ? KErrNone : KErrNoMBufs;      
       
   285         }
       
   286     else
       
   287         {
       
   288         RMBufAllocator allocator;
       
   289         err = newChain.Alloc(aLen + aHdrReserve, allocator);  
       
   290         }
       
   291 	
   276 	if(err != KErrNone)
   292 	if(err != KErrNone)
   277 		{
   293 		{
   278 		return err;
   294 		return err;
   279 		}
   295 		}
   280 
   296 
   530 newChain gets the other half.
   546 newChain gets the other half.
   531 @param anOffset The offset
   547 @param anOffset The offset
   532 @param newChain The result chain
   548 @param newChain The result chain
   533 */
   549 */
   534 	{
   550 	{
   535 	User::LeaveIfError(RCommsBufChain::Split(anOffset, newChain));
   551 	User::LeaveIfError(Split(anOffset, newChain));
   536 	}
   552 	}
   537 
   553 
   538 EXPORT_C TInt RMBufChain::Split(TInt anOffset, RMBufChain& newChain)
   554 EXPORT_C TInt RMBufChain::Split(TInt aOffset, RMBufChain& aNewChain)
   539 /** 	  	 
   555 /** 	  	 
   540 Split a chain into two new chains Original chain gets the 1st half 	  	 
   556 Split a chain into two new chains Original chain gets the 1st half 	  	 
   541 newChain gets the other half. 	  	 
   557 newChain gets the other half. 	  	 
   542 - refer RMBufChain::AllocL notes regarding the deliberate decision not to provide an overloaded min/max mbuf size variant 	  	 
   558 - refer RMBufChain::AllocL notes regarding the deliberate decision not to provide an overloaded min/max mbuf size variant 	  	 
   543 @param anOffset The offset 	  	 
   559 @param anOffset The offset 	  	 
   544 @param newChain The result chain 	  	 
   560 @param newChain The result chain 	  	 
   545 */
   561 */
   546 	{
   562 	{
   547 	return RCommsBufChain::Split(anOffset, newChain);		
   563     // RCommsBuf::Split() will not allocate a smaller buffer size than the current, as part of its approach of (trying to)
   548 	}
   564     // support zero-copy transfer by respecting the buffer pool in use. This work is incomplete (needs support throughout
       
   565     // the stack and probably a cleverer idea of what constitutes an acceptable buffer than simply size), so in the meantime
       
   566     // having MBufMgr reflect this behaviour by refusing to Split() a big buf into smaller bufs is unnecessarily purist.
       
   567     // Hence the functionality is implemented directly here
       
   568     
       
   569     __ASSERT_ALWAYS(iNext!=NULL, CommsBuf::Panic(EMBuf_EmptyChain));
       
   570     __ASSERT_ALWAYS(aOffset>=0, CommsBuf::Panic(EMBuf_NegativeOffset));
       
   571     
       
   572     // For testing post-conditions
       
   573 #ifdef _DEBUG
       
   574     TInt origLen = Length();
       
   575 #endif
       
   576     TInt splitBufOffset;
       
   577     TInt splitBufRemainder;
       
   578     RMBuf* splitBuf;
       
   579     RMBuf* splitBufPrev;
       
   580     
       
   581     if(!Goto(aOffset, splitBuf, splitBufOffset, splitBufRemainder, splitBufPrev))
       
   582         {
       
   583         aNewChain.Init();
       
   584         return KErrNone;
       
   585         }
       
   586     
       
   587     if(splitBufOffset != splitBuf->Offset()) // Not on an mbuf boundary
       
   588         {
       
   589         // Copy tail of splitBuf out to a new chain (hopefully a single buf, but needn't be)
       
   590         TInt splitDataOffset = splitBufOffset - splitBuf->Offset();
       
   591         TInt err = RMBufChain(splitBuf).Copy(aNewChain, splitDataOffset, splitBufRemainder);
       
   592         if(err != KErrNone)
       
   593             {
       
   594             return err;
       
   595             }
       
   596         splitBuf->AdjustDataEnd(-splitBufRemainder);
       
   597         RMBufChain splitTail(splitBuf->Next());
       
   598         aNewChain.Append(splitTail);
       
   599         splitBuf->SetNext(NULL);
       
   600         }
       
   601     else
       
   602         {
       
   603         // Split cleaves chain between bufs
       
   604         aNewChain = splitBuf;
       
   605         if(splitBufPrev)
       
   606             {
       
   607             splitBufPrev->Unlink();
       
   608             }
       
   609         }
       
   610     
       
   611     // Check post-conditions
       
   612 #ifdef _DEBUG
       
   613     TInt frag1Len = Length(); 
       
   614     TInt frag2Len = aNewChain.Length();
       
   615     ASSERT(origLen == frag1Len + frag2Len);
       
   616     ASSERT(frag1Len == aOffset);
       
   617 #endif
       
   618     return KErrNone;
       
   619 	}           
   549 
   620 
   550 // overloading for TLS
   621 // overloading for TLS
   551 EXPORT_C TInt RMBufChain::Split(TInt anOffset, RMBufChain& newChain, RMBufAllocator& /* aRMBufAllocator */)
   622 EXPORT_C TInt RMBufChain::Split(TInt anOffset, RMBufChain& newChain, RMBufAllocator& /* aRMBufAllocator */)
   552 	{
   623 	{
   553 	return RCommsBufChain::Split ( anOffset, newChain );
   624 	return RCommsBufChain::Split ( anOffset, newChain );