23 #include <elements/mm_context_internal.h> |
23 #include <elements/mm_context_internal.h> |
24 #include <elements/mm_log.h> |
24 #include <elements/mm_log.h> |
25 |
25 |
26 #include <elements/nm_messages_base.h> |
26 #include <elements/nm_messages_base.h> |
27 #include <elements/nm_messages_child.h> |
27 #include <elements/nm_messages_child.h> |
28 |
|
29 |
28 |
30 #ifdef _DEBUG |
29 #ifdef _DEBUG |
31 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module |
30 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module |
32 // (if it could happen through user error then you should give it an explicit, documented, category + code) |
31 // (if it could happen through user error then you should give it an explicit, documented, category + code) |
33 _LIT(KSpecAssert_ElemMeshMachNodC, "ElemMeshMachNodC"); |
32 _LIT(KSpecAssert_ElemMeshMachNodC, "ElemMeshMachNodC"); |
456 { |
455 { |
457 //Abort for one originator only (Cancel the activity if last originator & error just this one originator) |
456 //Abort for one originator only (Cancel the activity if last originator & error just this one originator) |
458 TInt idx = aContext.iNodeActivity->FindOriginator(aCommsId); |
457 TInt idx = aContext.iNodeActivity->FindOriginator(aCommsId); |
459 if (KErrNotFound!=idx) |
458 if (KErrNotFound!=idx) |
460 { |
459 { |
|
460 TBool canSend = ETrue; |
461 if(aContext.iNodeActivity->iOriginators.Count() == 1) // only if this is the final originator |
461 if(aContext.iNodeActivity->iOriginators.Count() == 1) // only if this is the final originator |
462 { |
462 { |
463 aContext.iNodeActivity->SetError(KErrAbort); |
463 aContext.iNodeActivity->SetError(KErrAbort); |
464 aContext.iNodeActivity->Cancel(aContext); |
464 aContext.iNodeActivity->Cancel(aContext); |
|
465 //This is a workaround for CCommsBinderRequest. The proper fix is to abolish the concept of aborting activities. |
|
466 //Aborting activities is a bad idea as an aborted activity isn't given a chance to perform graceful cleanup. |
|
467 //Today activities get aborted because their orinators urgently leave. I.e.: they are trully leaving now! Last orders! |
|
468 //It is then incorrect to leave the activity d'tor to finish the wrap up - because the node will be gone by then. |
|
469 //So whether and when to send an error must be decided here, by this generic code that has no clue on the subtleties |
|
470 //of individual activities. If there is no abort - there is urgent leavers. They send TLeaveRequest and they politely |
|
471 //wait for the completion and all this code is unnecessary. |
|
472 canSend = (aContext.iNodeActivity->Error() != KErrNone); |
465 } |
473 } |
466 |
474 |
467 |
|
468 //In the "quiet mode", when the hosting node is being destroyed, we can not afford sending |
475 //In the "quiet mode", when the hosting node is being destroyed, we can not afford sending |
469 //an error to the node as it would hit void. |
476 //an error to the node as it would hit void. |
470 TNodePeerId& originator = aContext.iNodeActivity->iOriginators[idx]; |
477 TNodePeerId& originator = aContext.iNodeActivity->iOriginators[idx]; |
471 TBool canSend = !((aIsNodeBeingDestroyed && originator == aContext.NodeId()) |
478 canSend &= !((aIsNodeBeingDestroyed && originator == aContext.NodeId()) |
472 || aContext.iMessage.IsMessage<TEChild::TLeft>()); |
479 || aContext.iMessage.IsMessage<TEChild::TLeft>()); |
473 if (canSend) |
480 if (canSend) |
474 { |
481 { |
475 aContext.iNodeActivity->PostToOriginator(originator, TEBase::TError(aContext.iMessage.MessageId(), KErrAbort).CRef()); |
482 aContext.iNodeActivity->PostToOriginator(originator, TEBase::TError(aContext.iMessage.MessageId(), KErrAbort).CRef()); |
476 } |
483 } |
477 |
484 aContext.iNodeActivity->RemoveOriginator(idx); |
478 |
|
479 aContext.iNodeActivity->RemoveOriginator(idx); |
|
480 } |
485 } |
481 } |
486 } |
482 } |
487 } |
483 } |
488 } |
484 aContext.iReturn = KErrNone; |
489 aContext.iReturn = KErrNone; |
614 } |
619 } |
615 } |
620 } |
616 |
621 |
617 void AMMNodeBase::StartActivityL(TNodeContextBase& aContext, const TNodeActivity& aActivitySig, const NetStateMachine::TStateTriple& aFirst) |
622 void AMMNodeBase::StartActivityL(TNodeContextBase& aContext, const TNodeActivity& aActivitySig, const NetStateMachine::TStateTriple& aFirst) |
618 { |
623 { |
619 CNodeActivityBase* a = aActivitySig.iCtor(aActivitySig,*this); |
624 CNodeActivityBase* nodeActivity; |
620 if (iActivities.Find(a)==KErrNotFound) |
625 // Activity is based on one of 2 declarations. One of which has an extra member. In the case of the instance |
|
626 // with a second member the activities Ctor will point to this second member. Since the first member is a TNodeActivity |
|
627 // We can compare the activities Ctor pointer to the address of the second member to assess which type of declarations |
|
628 // this is. |
|
629 |
|
630 if (aActivitySig.iFlags & TNodeActivity::EContextCtor) |
|
631 { // TNodeActivity's iCtor is a pointer to Activity Ctor |
|
632 nodeActivity = ((TNodeActivity::TStaticActivityContextCtor)aActivitySig.iCtor)(aActivitySig,aContext); |
|
633 } |
|
634 else |
|
635 { // TNodeActivity's iCtor is a pointer to activity constructor |
|
636 nodeActivity = ((TNodeActivity::TStaticActivityCtor)aActivitySig.iCtor)(aActivitySig,*this); |
|
637 } |
|
638 |
|
639 if (iActivities.Find(nodeActivity)==KErrNotFound) |
621 { |
640 { |
622 //The activity did not add itself to the list in any special way, append it here |
641 //The activity did not add itself to the list in any special way, append it here |
623 CleanupStack::PushL(a); |
642 CleanupStack::PushL(nodeActivity); |
624 a->AppendActivityL(); |
643 nodeActivity->AppendActivityL(); |
625 CleanupStack::Pop(a); |
644 CleanupStack::Pop(nodeActivity); |
626 } |
645 } |
|
646 |
627 //assign only after the activity is successfully appended |
647 //assign only after the activity is successfully appended |
628 aContext.iNodeActivity = a; |
648 aContext.iNodeActivity = nodeActivity; |
629 |
649 |
630 //if StartL leaves the "a" will be removed from the array and deleted in ::PostReceived |
650 //if StartL leaves the "a" will be removed from the array and deleted in ::PostReceived |
631 //since it will be idle |
651 //since it will be idle |
632 XNodePeerId originator(aContext.iSender, aContext.iPeer); |
652 XNodePeerId originator(aContext.iSender, aContext.iPeer); |
633 a->StartL(aContext, originator, aFirst); |
653 nodeActivity->StartL(aContext, originator, aFirst); |
634 } |
654 } |
635 |
655 |
636 void AMMNodeBase::PreallocateSpaceL(TUint aSize) |
656 void AMMNodeBase::PreallocateSpaceL(TUint aSize) |
637 { |
657 { |
638 __ASSERT_DEBUG(aSize>0, User::Panic(KSpecAssert_ElemMeshMachNodC, 4)); |
658 __ASSERT_DEBUG(aSize>0, User::Panic(KSpecAssert_ElemMeshMachNodC, 4)); |