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"); |
230 |
229 |
231 CNodeActivityBase* a = NULL; |
230 CNodeActivityBase* a = NULL; |
232 for (TInt i = iActivities.Count() - 1; i>=0 && a==NULL; i--) |
231 for (TInt i = iActivities.Count() - 1; i>=0 && a==NULL; i--) |
233 { |
232 { |
234 CNodeActivityBase* act = iActivities[i]; |
233 CNodeActivityBase* act = iActivities[i]; |
235 const TNodeId& postedTo = act->iPostedToId; |
234 const TNodeId& postedTo = act->PostedToNodeId(); |
236 if (!act->IsIdle() |
235 if (!act->IsIdle() |
237 && (postedTo.IsNull() || aContext.iSender == postedTo) |
236 && (postedTo.IsNull() || aContext.iSender == postedTo) |
238 && (recipient->NodeCtx() == act->ActivityId())) |
237 && (recipient->NodeCtx() == act->ActivityId())) |
239 { |
238 { |
240 a = act; |
239 a = act; |
428 context.iNodeActivity = NULL; |
427 context.iNodeActivity = NULL; |
429 } |
428 } |
430 } |
429 } |
431 } |
430 } |
432 |
431 |
|
432 |
433 EXPORT_C void AMMNodeBase::AbortActivitiesOriginatedBy(TNodeContextBase& aContext, const TNodeId& aCommsId, TBool aIsNodeBeingDestroyed) |
433 EXPORT_C void AMMNodeBase::AbortActivitiesOriginatedBy(TNodeContextBase& aContext, const TNodeId& aCommsId, TBool aIsNodeBeingDestroyed) |
434 { |
434 { |
435 CNodeActivityBase* caller = aContext.iNodeActivity; |
435 CNodeActivityBase* caller = aContext.iNodeActivity; |
436 TBool abortAll = aCommsId.IsNull(); |
436 TBool abortAll = aCommsId.IsNull(); |
437 |
437 |
438 for (TInt i = iActivities.Count() - 1; i>=0; i--) |
438 for (TInt i = iActivities.Count() - 1; i>=0; i--) |
439 { |
439 { |
440 aContext.iNodeActivity = iActivities[i]; |
440 aContext.iNodeActivity = iActivities[i]; |
|
441 |
|
442 if (!abortAll && aContext.iNodeActivity->PostedToNodeId() == aCommsId) |
|
443 {//clear postedto if a leaver has been set as a postedto at any of the running activities. |
|
444 //No other messages will ever come from the leaver and it is not gonna be safe to forward TCancels |
|
445 //to the leaver, so at least postedto must be cleared to avoid the crash. It could be speculated that |
|
446 //if the postedto is still set, then either the postedto node failed to respond or the local activity failed to |
|
447 //clear postedto when it had responded. Worth putting a speculative ASSERT here to catch misdeeds. |
|
448 |
|
449 //clearing postedto shouldn't be done in here (AbortActivitiesOriginatedBy), but I (RZ) have expressed my disrespect to the |
|
450 //this method before and the suggestion that it should go (replaced by a CancelActivitiesOriginatedBy). |
|
451 //So instead of introducing another method that loops through activities i decided to piggyback the function in an |
|
452 //existing method. Note that the final logic should be based on RNodeInterfaces and not TNodeIds. |
|
453 aContext.iNodeActivity->ClearPostedTo(); |
|
454 } |
441 |
455 |
442 // We dont want to abort already idle activities or they may error. |
456 // We dont want to abort already idle activities or they may error. |
443 if(aContext.iNodeActivity->IsIdle()) |
457 if(aContext.iNodeActivity->IsIdle()) |
444 { |
458 { |
445 continue; |
459 continue; |
620 } |
634 } |
621 } |
635 } |
622 |
636 |
623 void AMMNodeBase::StartActivityL(TNodeContextBase& aContext, const TNodeActivity& aActivitySig, const NetStateMachine::TStateTriple& aFirst) |
637 void AMMNodeBase::StartActivityL(TNodeContextBase& aContext, const TNodeActivity& aActivitySig, const NetStateMachine::TStateTriple& aFirst) |
624 { |
638 { |
625 CNodeActivityBase* a = aActivitySig.iCtor(aActivitySig,*this); |
639 CNodeActivityBase* nodeActivity; |
626 if (iActivities.Find(a)==KErrNotFound) |
640 // Activity is based on one of 2 declarations. One of which has an extra member. In the case of the instance |
|
641 // with a second member the activities Ctor will point to this second member. Since the first member is a TNodeActivity |
|
642 // We can compare the activities Ctor pointer to the address of the second member to assess which type of declarations |
|
643 // this is. |
|
644 |
|
645 if (aActivitySig.iFlags & TNodeActivity::EContextCtor) |
|
646 { // TNodeActivity's iCtor is a pointer to Activity Ctor |
|
647 nodeActivity = ((TNodeActivity::TStaticActivityContextCtor)aActivitySig.iCtor)(aActivitySig,aContext); |
|
648 } |
|
649 else |
|
650 { // TNodeActivity's iCtor is a pointer to activity constructor |
|
651 nodeActivity = ((TNodeActivity::TStaticActivityCtor)aActivitySig.iCtor)(aActivitySig,*this); |
|
652 } |
|
653 |
|
654 if (iActivities.Find(nodeActivity)==KErrNotFound) |
627 { |
655 { |
628 //The activity did not add itself to the list in any special way, append it here |
656 //The activity did not add itself to the list in any special way, append it here |
629 CleanupStack::PushL(a); |
657 CleanupStack::PushL(nodeActivity); |
630 a->AppendActivityL(); |
658 nodeActivity->AppendActivityL(); |
631 CleanupStack::Pop(a); |
659 CleanupStack::Pop(nodeActivity); |
632 } |
660 } |
|
661 |
633 //assign only after the activity is successfully appended |
662 //assign only after the activity is successfully appended |
634 aContext.iNodeActivity = a; |
663 aContext.iNodeActivity = nodeActivity; |
635 |
664 |
636 //if StartL leaves the "a" will be removed from the array and deleted in ::PostReceived |
665 //if StartL leaves the "a" will be removed from the array and deleted in ::PostReceived |
637 //since it will be idle |
666 //since it will be idle |
638 XNodePeerId originator(aContext.iSender, aContext.iPeer); |
667 XNodePeerId originator(aContext.iSender, aContext.iPeer); |
639 a->StartL(aContext, originator, aFirst); |
668 nodeActivity->StartL(aContext, originator, aFirst); |
640 } |
669 } |
641 |
670 |
642 void AMMNodeBase::PreallocateSpaceL(TUint aSize) |
671 void AMMNodeBase::PreallocateSpaceL(TUint aSize) |
643 { |
672 { |
644 __ASSERT_DEBUG(aSize>0, User::Panic(KSpecAssert_ElemMeshMachNodC, 4)); |
673 __ASSERT_DEBUG(aSize>0, User::Panic(KSpecAssert_ElemMeshMachNodC, 4)); |