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 |