userlibandfileserver/fileserver/sfile/sf_request.cpp
changeset 247 d8d70de2bd36
parent 90 947f0dc9f7a8
--- a/userlibandfileserver/fileserver/sfile/sf_request.cpp	Tue Jul 06 15:50:07 2010 +0300
+++ b/userlibandfileserver/fileserver/sfile/sf_request.cpp	Wed Aug 18 11:08:29 2010 +0300
@@ -974,7 +974,7 @@
 //
 	{
 	TInt err = KErrNone;
-	if(!iCurrentPlugin->IsPluginThread(*this))
+	if(!iCurrentPlugin->OriginatedFromPlugin(*this))
 		{
 		// The request hasn't come from this plugin so it's safe to dispatch		
 		TFsPluginRequest request(this);
@@ -997,14 +997,17 @@
 	
 	// Find the previous plugin in the chain and dispatch
 	//  - If no more plugins are interested in this message, then complete
-	FsPluginManager::PrevPlugin(iCurrentPlugin, this, ETrue);
+	FsPluginManager::ReadLockChain();
+	FsPluginManager::PrevPlugin(iCurrentPlugin, this);
 	if(iCurrentPlugin == NULL)
 		{
+	    FsPluginManager::UnlockChain();
 		Complete(GetError());
 		return;
 		}
 
 	Dispatch();
+	FsPluginManager::UnlockChain();
 	return;
 	}
 	
@@ -1015,7 +1018,7 @@
 //
 	{
 	TInt err = KErrNone;
-	if(!iCurrentPlugin->IsPluginThread(*this))
+	if(!iCurrentPlugin->OriginatedFromPlugin(*this))
 		{
 		// The request hasn't come from this plugin so it's safe to dispatch		
 		TFsPluginRequest request(this);		
@@ -1024,7 +1027,7 @@
 
 		if((iOperation->Function() == EFsDismountPlugin) && (err !=  KErrPermissionDenied))
 			{
-			TRAP(leaveValue, err = iOperation->DoRequestL(this));
+		    err = KErrNone;
 			}
 
 		if(leaveValue != KErrNone)
@@ -1042,10 +1045,12 @@
 		// Find the next plugin in the chain and dispatch
 		//  - If no more plugins are interested in this message, 
 		//	  then Dispatch() will process the request in drive/main thread context.
-		FsPluginManager::NextPlugin(iCurrentPlugin, this,(TBool)ETrue);
+	    FsPluginManager::ReadLockChain();
+		FsPluginManager::NextPlugin(iCurrentPlugin, this);
 		if(iCurrentPlugin && IsPostOperation())
 			SetPostOperation(EFalse);
 		Dispatch();
+		FsPluginManager::UnlockChain();
 		return;
 		}
 	// KErrCompletion may be returned by the plugin to 
@@ -1054,18 +1059,21 @@
 		{
 		// Find the previous plugin in the chain and dispatch
 		//  - If no more plugins are interested in this message, then complete
-		FsPluginManager::PrevPlugin(iCurrentPlugin, this,(TBool)ETrue);
+	    FsPluginManager::ReadLockChain();
+		FsPluginManager::PrevPlugin(iCurrentPlugin, this);
 		if(iCurrentPlugin != NULL)
 			{
 			SetPostOperation(ETrue);
 			err = KErrNone;
 			Dispatch();
+			FsPluginManager::UnlockChain();
 			return;
 			}
 		else
 			{
 			err = KErrNone;	
 			}
+		FsPluginManager::UnlockChain();
 		}
 		
 	Complete(err);
@@ -1116,19 +1124,26 @@
 		}
 
 	SetError(err);
-
+	
+    if (IsExpectedResult(err) && !IsPluginSpecific() && !IsNotifierSpecific())
+        DoNotifyDiskSpace(KErrNone);
 
 	// Start issuing the post-operation requests starting from the bottom of the chain
 	iCurrentPlugin = NULL;
 	if (PostInterceptEnabled())
 		{
-		FsPluginManager::PrevPlugin(iCurrentPlugin, this,(TBool)ETrue);
-		if(iCurrentPlugin && !iCurrentPlugin->IsPluginThread(*this))
+	    FsPluginManager::ReadLockChain();
+		FsPluginManager::PrevPlugin(iCurrentPlugin, this);
+		if(iCurrentPlugin && !iCurrentPlugin->OriginatedFromPlugin(*this))
 			{
 			SetPostOperation(ETrue);
 			if (DispatchToPlugin())
+			    {
+		        FsPluginManager::UnlockChain();  
 				return;
+			    }
 			}
+		FsPluginManager::UnlockChain();		
 		}		
 
 	Complete(GetError());
@@ -1142,16 +1157,6 @@
 	{
 	__THRD_PRINT2(_L("----- CFsMessageRequest::Complete() req %08x with %d"), this, aError);
 
-	if (aError==KErrNoMemory)
-		{
-		if (iDrive)	// Not all message requests are associated with a drive!
-			{
-			TDriveInfo di;
-			iDrive->DriveInfo(di);
-			if (di.iType == EMediaRam)
-				aError = KErrNoMemory;
-			}
-		}
 	if(aError!=KErrNone)
 		{
 		if(iOperation->IsOpenSubSess())
@@ -1298,9 +1303,7 @@
 	if(aError==KErrNone)
 		{
 		if(!(FsNotify::IsChangeQueEmpty(driveNumber)))
-			FsNotify::HandleChange(this,driveNumber);	
-		if ((driveNumber != KDriveInvalid) && !(FsNotify::IsDiskSpaceQueEmpty(driveNumber)))
-			FsNotify::HandleDiskSpace(this, DriveNumber());
+			FsNotify::HandleChange(this,driveNumber);
 	
 #ifdef SYMBIAN_F32_ENHANCED_CHANGE_NOTIFICATION
 		if 	(iOperation->iFunction == EFsFileWrite)
@@ -1337,6 +1340,16 @@
 		}
 	}
 
+void CFsMessageRequest::DoNotifyDiskSpace(TInt aError)
+    {
+    __PRINT1(_L("----- CFsMessageRequest::DoNotifyDiskSpace() with %d"),aError);
+    if(aError != KErrNone)
+        return;
+
+    TInt driveNumber = DriveNumber();
+    if ((driveNumber != KDriveInvalid) && !(FsNotify::IsDiskSpaceQueEmpty(driveNumber)))
+        FsNotify::HandleDiskSpace(this, driveNumber);
+    }
 
 void CFsMessageRequest::Free()
 //
@@ -1409,13 +1422,16 @@
 		iCurrentPlugin = NULL;
 		if (PostInterceptEnabled())
 			{
-			FsPluginManager::PrevPlugin(iCurrentPlugin, this,(TBool)ETrue);
-			if(iCurrentPlugin && !iCurrentPlugin->IsPluginThread(*this))
+		    FsPluginManager::ReadLockChain();
+			FsPluginManager::PrevPlugin(iCurrentPlugin, this);
+			if(iCurrentPlugin && !iCurrentPlugin->OriginatedFromPlugin(*this))
 				{
 				SetPostOperation(ETrue);
 				Dispatch();
+				FsPluginManager::UnlockChain();
 				return r;	// EReqActionComplete
 				}
+			FsPluginManager::UnlockChain();
 			}		
 
 		Complete(KErrNone);
@@ -1443,6 +1459,7 @@
 	__THRD_PRINT1(_L("CFsMessageRequest::Dispatch() req %08x"), this);
 
 	TInt r = KErrNone;
+	TBool pluginChainLocked = EFalse;
 
 	if (iReqState == EReqStateInitialise && aInitialise)
 		{
@@ -1462,16 +1479,18 @@
 			}
 		if(!IsPluginSpecific() && (iOwnerPlugin == NULL))
 			{
+		    FsPluginManager::ReadLockChain(); // Unlocked in DispatchToPlugin
+		    pluginChainLocked = ETrue;
 			iCurrentPlugin = NULL;
 			iClientThreadId = 0;
-			FsPluginManager::NextPlugin(iCurrentPlugin, this, (TBool)ETrue);
+			FsPluginManager::NextPlugin(iCurrentPlugin, this);
 
 			// find out whether there is a plugin registered to post intercept this message
 			CFsPlugin* postInterceptPlugin = NULL;
 			if (iCurrentPlugin == NULL)
-				FsPluginManager::PrevPlugin(postInterceptPlugin, this, (TBool)ETrue);
+				FsPluginManager::PrevPlugin(postInterceptPlugin, this);
 
-			// Save the client's thread Id for subsequent testing by CFsPlugin::IsPluginThread() - doing so on the fly 
+			// Save the client's thread Id for subsequent testing by CFsPlugin::OriginatedFromPlugin() - doing so on the fly 
 			// is risky because some messages are completed early in which case Message().Client() will result in a panic
 			if ((iCurrentPlugin || postInterceptPlugin) && Message().Handle() != NULL && Message().Handle() != KLocalMessageHandle)
 				{
@@ -1490,16 +1509,23 @@
 		__PLUGIN_PRINT1(_L("PLUGIN: CFsMessageRequest %x dispatched to plugin (async)"), this);
 		// The request has been delivered to the plugin thread
 		//  - leave the main thread now and await asynchronous completion
+		if(pluginChainLocked)
+		    FsPluginManager::UnlockChain();
 		return;
 		}
 
+	//DispatchToPlugin didn't (deliver then unlock) so make sure we unlock here.
+    if(pluginChainLocked)
+        FsPluginManager::UnlockChain();
 
 	// Is there a PostInitialise function ?
 	if (iReqState ==  EReqStatePostInitialise && aInitialise && r == KErrNone)
 		{
 		TInt r = PostInitialise();
 		if (r == EReqActionComplete)
+		    {
 			return;
+		    }
 		else if (r == EReqActionBusy)				// request postponed ?
 			SetState(EReqStatePostInitialise);		// reinitialize when request is next processed
 		}
@@ -1559,6 +1585,7 @@
 //
 // Common route: Receive -> Process -> Dispatch -> DispatchToPlugin
 //
+// (Is called with FsPluginManager ReadLocked)
 	{
 	TInt drivenumber = DriveNumber();
 	if(iCurrentPlugin)
@@ -1572,16 +1599,16 @@
 				iCurrentPlugin = NULL;
 				}
 
-			while(iCurrentPlugin && iCurrentPlugin->IsPluginThread(*this))
+			while(iCurrentPlugin && iCurrentPlugin->OriginatedFromPlugin(*this))
 				{
 				// Skip the current plugin if the request originated from the plugin
 				if(IsPostOperation())
 					{
-					FsPluginManager::PrevPlugin(iCurrentPlugin, this,(TBool)ETrue);
+					FsPluginManager::PrevPlugin(iCurrentPlugin, this);
 					}
 				else
 					{
-					FsPluginManager::NextPlugin(iCurrentPlugin, this,(TBool)ETrue);
+					FsPluginManager::NextPlugin(iCurrentPlugin, this);
 					}
 				}
 				
@@ -1611,7 +1638,7 @@
 					//  - Pass the message on to the next plugin
 					if(FsFunction() != EFsPluginOpen)
 					    {
-	                    FsPluginManager::NextPlugin(iCurrentPlugin, this,(TBool)ETrue);
+	                    FsPluginManager::NextPlugin(iCurrentPlugin, this);
 	                    continue;
 					    }
 					else // FsFunction == EFsPluginOpen
@@ -1619,7 +1646,6 @@
 					    /* 
 					     * PluginOpen requests should not be passed down the plugin stack.
 					     * 
-
 					     */
 					    iCurrentPlugin = NULL;
 					    continue;
@@ -1630,7 +1656,7 @@
 					// The plugin has processed synchronously (case 2)
 					//  - Pass the message back up the stack
 					SetPostOperation(ETrue);
-					FsPluginManager::PrevPlugin(iCurrentPlugin, this,(TBool)ETrue);
+					FsPluginManager::PrevPlugin(iCurrentPlugin, this);
 					continue;
 					}
 				_LIT(KPanic,"Panic: F32-BAD-PLUGIN-ERROR");
@@ -1652,13 +1678,17 @@
 			}			
 		}
 
+	/*
+	 * Special case- DismountPlugin runs in the context of the plugin thread
+	 */
 	if(iOperation->Function() == EFsDismountPlugin)
 		{
 		// Don't pass plugin dismounts to the drive thread
+	    FsPluginManager::UnlockChain();
 		Process();
+		FsPluginManager::ReadLockChain(); //inverted unlock/lock to get around dismount plugin being a special case
 		return(ETrue);
 		}
-		
 	return EFalse;
 	}