commsfwsupport/commselements/meshmachine/src/mm_node.cpp
branchRCL_3
changeset 18 9644881fedd0
parent 17 9ddb1d67ebaf
child 21 07656293a99c
equal deleted inserted replaced
17:9ddb1d67ebaf 18:9644881fedd0
    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));