--- a/datacommsserver/esockserver/core_states/ss_corepractivities.cpp Thu May 27 14:07:49 2010 +0300
+++ b/datacommsserver/esockserver/core_states/ss_corepractivities.cpp Fri Jun 11 14:52:21 2010 +0300
@@ -1604,12 +1604,20 @@
// CommsBinderActivity and CCommsBinderCombiningActivity.
//
//-=========================================================
-
+// When I node need to create the data client, this mutex block if the dataclient is leaving.
+// A scenario can arise when a connection is being started, stopped and started again in succession.
+// the stop might interfere with the second start and ccause the second start to fail.
+// this mutex will ensure that the leaving DC is completely destroyed, and then the second start is continued
+// - when any of the data clients is being destroyed
+// - when a non-leaving data client is present or the activity is already running
+//
EXPORT_C TBool CCommsBinderActivity::TDataClientMutex::IsBlocked(MeshMachine::TNodeContextBase& aContext)
{
TInt c = aContext.Node().CountActivities(aContext.iNodeActivity->ActivitySigId());
__ASSERT_DEBUG(c>0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 17)); //Diagnostic
- if (c == 1 || CCommsBinderActivity::IsDataClientPresent(aContext))
+ TInt numOfLeavingDataClients = aContext.Node().CountClients<TDefaultClientMatchPolicy>(
+ /*include*/TClientType(TCFClientType::EData, TCFClientType::ELeaving));
+ if (numOfLeavingDataClients == 0 && (c == 1 || CCommsBinderActivity::IsDataClientPresent(aContext)))
{
return EFalse;
}
@@ -1620,7 +1628,9 @@
{
TInt c = aContext.Node().CountActivities(aContext.iNodeActivity->ActivitySigId());
__ASSERT_DEBUG(c>0, User::Panic(KSpecAssert_ESockCrStaCPRAC, 18)); //Diagnostic
- if (c == 1 || CCommsBinderActivity::IsDataClientPresent(aContext, TCFClientType::EDefault))
+ TInt numOfLeavingDataClients = aContext.Node().CountClients<TDefaultClientMatchPolicy>(
+ /*include*/TClientType(TCFClientType::EData, TCFClientType::ELeaving));
+ if (numOfLeavingDataClients == 0 && (c == 1 || CCommsBinderActivity::IsDataClientPresent(aContext, TCFClientType::EDefault)))
{
return EFalse;
}
@@ -1701,6 +1711,28 @@
iPendingBinder->SetFlags(TCFClientType::EActivating);
}
+
+EXPORT_C void CCommsBinderActivity::Cancel(TNodeContextBase& aContext)
+ {
+ if (iPendingBinder)
+ {
+ //iPendingBinder is set when CCommsBinderActivity decides which of its dataclients it
+ //wishes to send along with its TCommsBinderResponse and promptly (on the same stack) as
+ //this response is sent. After TCommsBinderResponse, the error handling of CCommsBinderActivity
+ //changes in that it should not flag any errors back to the recpient of TCommsBinderResponse.
+ //Such response may be when:
+ //(1) the recipient responds to TCommsBinderResponse with TError - the activity is finished, the recipients doesn't wait for anything (certainly not for an error)
+ //(2) the recipients explicitly cancels (or implicitly cancells by leaving the local node) - the activity is finished, the recipient doesn't wait for anything (certainly not for an error)
+ SetError(KErrNone);
+ BindToComplete();
+ SetIdle();
+ }
+ else
+ {
+ CNodeRetryParallelActivity::Cancel(aContext);
+ }
+ }
+
void CCommsBinderActivity::BindToComplete()
{
__ASSERT_DEBUG(iPendingBinder, User::Panic(KSpecAssert_ESockCrStaCPRAC, 23));