datacommsserver/esockserver/test/providers/dummy/src/dummypr_subconnprov.cpp
branchRCL_3
changeset 18 9644881fedd0
parent 17 9ddb1d67ebaf
child 23 cbb19216b74d
--- a/datacommsserver/esockserver/test/providers/dummy/src/dummypr_subconnprov.cpp	Tue May 11 17:20:19 2010 +0300
+++ b/datacommsserver/esockserver/test/providers/dummy/src/dummypr_subconnprov.cpp	Tue May 25 14:00:39 2010 +0300
@@ -93,8 +93,46 @@
 	return (iContext.iMessage.IsMessage<TCFDataClient::TStart>() && 
 			TCprConfigModifier::Is(selectionInfo->CprConfig(), TCprConfigModifier::ESCPRHangOnStart));
 	}
+
+DEFINE_SMELEMENT(TCancelPreviousSelfRequest, NetStateMachine::MStateTransition, DummySCPRStates::TContext)
+void TCancelPreviousSelfRequest::DoL()
+    {
+    iContext.iNodeActivity->PostRequestTo(iContext.Node().Id(), Messages::TEBase::TCancel().CRef());
+    }
+
+DEFINE_SMELEMENT(TRebindSelf, NetStateMachine::MStateTransition, DummySCPRStates::TContext)
+void TRebindSelf::DoL()
+    {
+    iContext.iNodeActivity->PostRequestTo(iContext.Node().Id(), TCFDataClient::TBindTo(Messages::TNodeId::NullId()).CRef());
+    }
+
+
+
+
+CrazyIdle::~CrazyIdle()
+    {
+    ASSERT(PostedToNodeId()==Messages::TNodeId::NullId());
+    }
+
+MeshMachine::CNodeActivityBase* CrazyIdle::NewL(const MeshMachine::TNodeActivity& aActivitySig, MeshMachine::AMMNodeBase& aNode)
+    {
+    return new(ELeave)CrazyIdle(aActivitySig, aNode);
+    }
+
+DEFINE_SMELEMENT(CrazyIdle::TAwaitingCancelled, NetStateMachine::MState, DummySCPRStates::TContext)
+TBool CrazyIdle::TAwaitingCancelled::Accept()
+    {
+    if (iContext.iMessage.IsMessage<Messages::TEBase::TError>())
+        {
+        ASSERT(iContext.iNodeActivity);
+        iContext.iNodeActivity->SetPostedTo(iContext.iNodeActivity->SoleOriginator().Peer().RecipientId());
+        }
+    return EFalse;
+    }
 }
 
+
+
 namespace DummySCprParamsRequest
 {
 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
@@ -134,6 +172,41 @@
 NODEACTIVITY_END()
 }
 
+namespace CrazyIdleActivity
+{
+//CrazyIdleActivity is used to test yet another angle of the meshmachine cancelling behaviour.
+//What it does is:
+//(1) responds to TIdle with an attempt to bind the sender, then, without waiting for the bind to complete
+//(2) responds to TIdle normally (by deleting the sender)
+//(3) cancells the bind request
+//What it tests is:
+//For two related nodes and upon the teardown of their relation there is an obligation to synchronise the activities
+//running on the nodes and awaiting responses from each other. This obligation is put on the requestee, i.e.: a node that perfomes
+//an activity on behalf of a leaving node should gracefully terminate that activity (by having the activity respond to the requestor. 
+//That obligation therefore doesn't rest on the requestor (someone, but not everyone, needs to do something).
+//There's trivial race condition arising from this distribution of responsibility, i.e.: the requestor activity may decide to 
+//cancel when the relation is being terminated and TCancel may hit void. Activities must be resilient to this and not send
+//TCancels to disappearing nodes. CrazyIdleActivity tests precislely this: it initaites an activity (TBindTo), then tears down the
+//relation and cancels the previously initiated activity (TBindTo). CrazyIdleActivity must wrap up gracefully. 
+DECLARE_DEFINE_CUSTOM_NODEACTIVITY(ECFActivityDataClientIdle, crazyIdle, TCFControlProvider::TIdle, DummySCPRStates::CrazyIdle::NewL)
+    FIRST_NODEACTIVITY_ENTRY(CoreNetStates::TAwaitingDataClientIdle, MeshMachine::TNoTag)
+    //Issue TBindTo to self (this will then bind the data client reporting TIdle). Wait for BindTo activity to start before 
+    //telling the dataclient to go away (TDestroy) as otherwise TBindTo won't make it in sending TBindTo to the dataclient.
+    THROUGH_NODEACTIVITY_ENTRY(KNoTag, DummySCPRStates::TRebindSelf, DummySCPRStates::TNoTagWaitForBindTo)
+    THROUGH_NODEACTIVITY_ENTRY(KNoTag, CoreNetStates::THandleDataClientIdle, MeshMachine::TNoTag)
+    //There's an additional test peformed by DummySCPRStates::CrazyIdle::TAwaitingCancelled. The state sets the postedto of CrazyIdle
+    //to point at the dataclient and CrazyIdle::~CrazyIdle asserts that that postedto is cleared. Currently PostedTo isn't cleared automatically - some people
+    //argued that it shouldn't and that activities should clear postedto whenever it's good for them. Unfortunatelly some activities are
+    //a bit lousy doing this and in result they can store a postedto pointing a node that has responded to the request a long time ago
+    //and above all a node that may have a long time ago left. A facility has been added to meshmachine to clear postedto when the node pointed
+    //at it actually leaves. This facility is tested collectivelly by DummySCPRStates::CrazyIdle::TAwaitingCancelled and CrazyIdle::~CrazyIdle
+    NODEACTIVITY_ENTRY(KNoTag, DummySCPRStates::TCancelPreviousSelfRequest, DummySCPRStates::CrazyIdle::TAwaitingCancelled, DummySCPRStates::TNoTagWaitNoDataClients)
+    LAST_NODEACTIVITY_ENTRY(KNoTag, MeshMachine::TDoNothing)
+NODEACTIVITY_END()
+}
+
+
+
 // Activity Map For test-code ridden scpr
 namespace DummySCPRStates
 {
@@ -141,7 +214,8 @@
    ACTIVITY_MAP_ENTRY(DummySCprParamsRequest, dummySCprParamRequest)
    ACTIVITY_MAP_ENTRY(DummyBindToActivity, dummyBindTo)
    ACTIVITY_MAP_ENTRY(DummyBreakStartActivity, dummyBreakSCPrStart)   
-   ACTIVITY_MAP_ENTRY(DummyStartActivity, dummySCPrStart)   
+   ACTIVITY_MAP_ENTRY(DummyStartActivity, dummySCPrStart)
+   ACTIVITY_MAP_ENTRY(CrazyIdleActivity, crazyIdle)     
 ACTIVITY_MAP_END_BASE(SCprActivities, coreSCprActivities)
 }
 
@@ -228,3 +302,5 @@
 
 
 
+
+