userlibandfileserver/fileserver/sfile/sf_plugin_man.cpp
branchRCL_3
changeset 43 c1f20ce4abcf
parent 36 bbf8bed59bcb
child 44 3e88ff8f41d5
--- a/userlibandfileserver/fileserver/sfile/sf_plugin_man.cpp	Thu Aug 19 11:14:22 2010 +0300
+++ b/userlibandfileserver/fileserver/sfile/sf_plugin_man.cpp	Tue Aug 31 16:34:26 2010 +0300
@@ -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)
@@ -162,7 +162,7 @@
 		return err;
 		}
 
-	err = InitPlugin(*pP);
+	err = InitPlugin(*pP, aPluginFactory.Library());
 	if(err != KErrNone)
 		{
 		return err;
@@ -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++)
@@ -624,13 +610,13 @@
 Create a plugin thread
 Should only by called from main file server thread with plugin thread unavailable
 */
-TInt FsPluginManager::InitPlugin(CFsPlugin& aPlugin)
+TInt FsPluginManager::InitPlugin(CFsPlugin& aPlugin, RLibrary aLibrary)
 	{
 	TInt err = KErrNone;
 
 	if(!aPlugin.iThreadP)
 		{
-		TRAP(err,aPlugin.iThreadP=CPluginThread::NewL(aPlugin));
+		TRAP(err,aPlugin.iThreadP=CPluginThread::NewL(aPlugin, aLibrary));
 		if(err!=KErrNone)
 			return err;
 		}
@@ -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