userlibandfileserver/fileserver/sfile/sf_plugin_man.cpp
changeset 243 c7a0ce20c48c
parent 148 31ea0f8e3c99
child 273 6a75fa55495f
--- a/userlibandfileserver/fileserver/sfile/sf_plugin_man.cpp	Mon Jul 26 10:52:56 2010 +0100
+++ b/userlibandfileserver/fileserver/sfile/sf_plugin_man.cpp	Fri Aug 06 16:34:38 2010 +0100
@@ -21,7 +21,7 @@
 
 CFsObjectCon* FsPluginManager::iPluginFactories = NULL;
 CFsObjectCon* FsPluginManager::iPluginConns     = NULL;
-RFastLock FsPluginManager::iChainLock;
+RReadWriteLock FsPluginManager::iChainLock;
 RPointerArray<CFsPlugin> FsPluginManager::iPluginChain;
 CFsSyncMessageScheduler* FsPluginManager::iScheduler = NULL;
 
@@ -153,7 +153,7 @@
 		return err;
 		}
 
-	LockChain();
+	WriteLockChain();
 	err = InsertInPluginStack(pP,aPos);
 	UnlockChain();
 	if(err != KErrNone)
@@ -235,7 +235,7 @@
 Transfer any outstanding requests to next/previous plugin depending on
 if it is post filter or not
 
-Must be called with the plugin chain locked.
+Must be called with the plugin chain write-locked.
 Attains plugin-thread's listlock.
 */
 void FsPluginManager::TransferRequests(CPluginThread* aPluginThread)
@@ -315,12 +315,12 @@
 	        if(pR->IsPostOperation())
 	            {
 	            //[set the plugin to] pass the request backwards in the chain
-	            PrevPlugin(pR->iCurrentPlugin, &mR, EFalse);
+	            PrevPlugin(pR->iCurrentPlugin, &mR);
 	            }
 	        else //IsPreOperations
 	            {
 	            //[set the plugin to] pass the request forwards in the chain
-	            NextPlugin(pR->iCurrentPlugin, &mR, EFalse);
+	            NextPlugin(pR->iCurrentPlugin, &mR);
 	            }
 
 	        if(pR->iCurrentPlugin)
@@ -386,19 +386,18 @@
 /**
 Find the next plugin that supports the operation
 
+Must be called with the plugin chain (at least read-) locked.
+
 @param aPlugin - On calling the function this may contain either NULL or the current plugin.
                  If it is called with NULL, then we start to look for plugins from the beginning of the chain.
                  If is is called with a plugin then we start to look after that plugin for the next one.
                  On return, aPlugin shall contain either a plugin or NULL.
                  
-@param aLock - If this is set to ETRUE, then the function shall lock the plugin chain.
-               If this is set to EFALSE, then the caller of the function MUST already hold the lock.
-
 @param aCheckCurrentOperation - Optional, if false, will return the next plugin,
  								whether the plugin is currently registered
 								for the current function or not. (so long as mounted on the current drive)
 */
-TInt FsPluginManager::NextPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest,TBool aLock, TBool aCheckCurrentOperation)
+TInt FsPluginManager::NextPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest, TBool aCheckCurrentOperation)
 	{
 	if(aMsgRequest->DirectToDrive())
 		{
@@ -410,9 +409,6 @@
 	TInt function = aMsgRequest->Operation()->Function();
 	TInt drive = aMsgRequest->DriveNumber();
 
-	if(aLock)
-	    LockChain();
-	
 	//the plugin chain lock must be held by this point.
 	TInt count = iPluginChain.Count();
 
@@ -431,25 +427,22 @@
 					{
 
 					aPlugin = iPluginChain[i];
-					if(aLock)
-					    UnlockChain();
 					return KErrNone;
 					}
 				}
 			}
 		}
 	aPlugin = NULL;
-	if(aLock)
-	    UnlockChain();
 	return KErrNotFound;
 	}
 
 /**
 Find the next plugin that supports the operation
+Must be called with the plugin chain (at least read-) locked.
 
 @see FsPluginManager::NextPlugin
 */
-TInt FsPluginManager::PrevPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest, TBool aLock)
+TInt FsPluginManager::PrevPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest)
 	{
 	if(aMsgRequest->DirectToDrive() && (aMsgRequest->CurrentOperationPtr() != NULL))
 		{
@@ -460,9 +453,6 @@
 	TInt start;
 	TInt function = aMsgRequest->Operation()->Function();
 	TInt drive = aMsgRequest->DriveNumber();
-
-	if(aLock)
-	    LockChain();
 	
 	//the plugin chain lock must be held by this point.
 	TInt count= iPluginChain.Count();
@@ -486,16 +476,12 @@
 					{
 
 					aPlugin = iPluginChain[i];
-					if(aLock)
-					    UnlockChain();
 					return KErrNone;
 					}
 				}
 			}
 		}
 	aPlugin = NULL;
-	if(aLock)
-	    UnlockChain();
 	return KErrNotFound;
 	}
 /**
@@ -584,7 +570,7 @@
 */
 CFsPlugin* FsPluginManager::FindByUniquePosition(TInt aUniquePosition)
 	{
-	LockChain();
+	ReadLockChain();
 	CFsPlugin* plugin = NULL;
 	TInt count= iPluginChain.Count();
 	for(TInt i=0;i<count;i++)
@@ -671,19 +657,27 @@
 	}
 
 /**
-Locks the chain
+Locks the chain for reading
 */
-void FsPluginManager::LockChain()
+void FsPluginManager::ReadLockChain()
 	{
-	iChainLock.Wait();
+    iChainLock.ReadLock();
 	}
 
 /**
+Locks the chain for writing
+*/
+void FsPluginManager::WriteLockChain()
+    {
+    iChainLock.WriteLock();
+    }
+
+/**
 Unlocks the chain
 */
 void FsPluginManager::UnlockChain()
 	{
-	iChainLock.Signal();
+    iChainLock.Unlock();
 	}
 
 /**
@@ -743,7 +737,7 @@
 	// Iterate through all plugins, cancelling outstanding session requests
 	aRequest->Set(CancelPluginOp, aSession);
 
-	FsPluginManager::LockChain();
+	FsPluginManager::ReadLockChain();
 	TInt count = FsPluginManager::ChainCount();
 	TInt oldCount = count;
 	TInt i;
@@ -759,7 +753,7 @@
 	    //so hopefully this wont take too long.
 	    FsPluginManager::UnlockChain();
 	    User::WaitForRequest(aRequest->Status());
-	    FsPluginManager::LockChain();
+	    FsPluginManager::ReadLockChain();
 	    __ASSERT_ALWAYS(aRequest->Status().Int()==KErrNone||aRequest->Status().Int()==KErrCancel,Fault(ESessionDisconnectThread2));
 	    count = FsPluginManager::ChainCount();
 	    //If a plugin was removed whilst the chain was unlocked we need to make sure we don't skip any plugins