commsfwsupport/commselements/meshmachine/src/mm_node.cpp
changeset 30 df67dc5d759e
parent 22 592244873960
child 32 d2396c80c344
equal deleted inserted replaced
25:e53adc4c49de 30:df67dc5d759e
    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));