userlibandfileserver/fileserver/sfile/sf_plugin_man.cpp
changeset 247 d8d70de2bd36
parent 200 73ea206103e6
child 273 6a75fa55495f
equal deleted inserted replaced
201:43365a9b78a3 247:d8d70de2bd36
    19 #include "sf_std.h"
    19 #include "sf_std.h"
    20 #include "sf_plugin_priv.h"
    20 #include "sf_plugin_priv.h"
    21 
    21 
    22 CFsObjectCon* FsPluginManager::iPluginFactories = NULL;
    22 CFsObjectCon* FsPluginManager::iPluginFactories = NULL;
    23 CFsObjectCon* FsPluginManager::iPluginConns     = NULL;
    23 CFsObjectCon* FsPluginManager::iPluginConns     = NULL;
    24 RFastLock FsPluginManager::iChainLock;
    24 RReadWriteLock FsPluginManager::iChainLock;
    25 RPointerArray<CFsPlugin> FsPluginManager::iPluginChain;
    25 RPointerArray<CFsPlugin> FsPluginManager::iPluginChain;
    26 CFsSyncMessageScheduler* FsPluginManager::iScheduler = NULL;
    26 CFsSyncMessageScheduler* FsPluginManager::iScheduler = NULL;
    27 
    27 
    28 TBool IsPagableDrive(TInt aDrive)
    28 TBool IsPagableDrive(TInt aDrive)
    29 	{
    29 	{
   151 		{
   151 		{
   152 		pP->Close();
   152 		pP->Close();
   153 		return err;
   153 		return err;
   154 		}
   154 		}
   155 
   155 
   156 	LockChain();
   156 	WriteLockChain();
   157 	err = InsertInPluginStack(pP,aPos);
   157 	err = InsertInPluginStack(pP,aPos);
   158 	UnlockChain();
   158 	UnlockChain();
   159 	if(err != KErrNone)
   159 	if(err != KErrNone)
   160 		{
   160 		{
   161 		pP->Close();
   161 		pP->Close();
   233 
   233 
   234 /**
   234 /**
   235 Transfer any outstanding requests to next/previous plugin depending on
   235 Transfer any outstanding requests to next/previous plugin depending on
   236 if it is post filter or not
   236 if it is post filter or not
   237 
   237 
   238 Must be called with the plugin chain locked.
   238 Must be called with the plugin chain write-locked.
   239 Attains plugin-thread's listlock.
   239 Attains plugin-thread's listlock.
   240 */
   240 */
   241 void FsPluginManager::TransferRequests(CPluginThread* aPluginThread)
   241 void FsPluginManager::TransferRequests(CPluginThread* aPluginThread)
   242 	{
   242 	{
   243 	aPluginThread->iListLock.Wait();
   243 	aPluginThread->iListLock.Wait();
   313 	            }
   313 	            }
   314 
   314 
   315 	        if(pR->IsPostOperation())
   315 	        if(pR->IsPostOperation())
   316 	            {
   316 	            {
   317 	            //[set the plugin to] pass the request backwards in the chain
   317 	            //[set the plugin to] pass the request backwards in the chain
   318 	            PrevPlugin(pR->iCurrentPlugin, &mR, EFalse);
   318 	            PrevPlugin(pR->iCurrentPlugin, &mR);
   319 	            }
   319 	            }
   320 	        else //IsPreOperations
   320 	        else //IsPreOperations
   321 	            {
   321 	            {
   322 	            //[set the plugin to] pass the request forwards in the chain
   322 	            //[set the plugin to] pass the request forwards in the chain
   323 	            NextPlugin(pR->iCurrentPlugin, &mR, EFalse);
   323 	            NextPlugin(pR->iCurrentPlugin, &mR);
   324 	            }
   324 	            }
   325 
   325 
   326 	        if(pR->iCurrentPlugin)
   326 	        if(pR->iCurrentPlugin)
   327 	            {
   327 	            {
   328 	            pR->iCurrentPlugin->iThreadP->DeliverBack(pR);
   328 	            pR->iCurrentPlugin->iThreadP->DeliverBack(pR);
   384 	}
   384 	}
   385 
   385 
   386 /**
   386 /**
   387 Find the next plugin that supports the operation
   387 Find the next plugin that supports the operation
   388 
   388 
       
   389 Must be called with the plugin chain (at least read-) locked.
       
   390 
   389 @param aPlugin - On calling the function this may contain either NULL or the current plugin.
   391 @param aPlugin - On calling the function this may contain either NULL or the current plugin.
   390                  If it is called with NULL, then we start to look for plugins from the beginning of the chain.
   392                  If it is called with NULL, then we start to look for plugins from the beginning of the chain.
   391                  If is is called with a plugin then we start to look after that plugin for the next one.
   393                  If is is called with a plugin then we start to look after that plugin for the next one.
   392                  On return, aPlugin shall contain either a plugin or NULL.
   394                  On return, aPlugin shall contain either a plugin or NULL.
   393                  
   395                  
   394 @param aLock - If this is set to ETRUE, then the function shall lock the plugin chain.
       
   395                If this is set to EFALSE, then the caller of the function MUST already hold the lock.
       
   396 
       
   397 @param aCheckCurrentOperation - Optional, if false, will return the next plugin,
   396 @param aCheckCurrentOperation - Optional, if false, will return the next plugin,
   398  								whether the plugin is currently registered
   397  								whether the plugin is currently registered
   399 								for the current function or not. (so long as mounted on the current drive)
   398 								for the current function or not. (so long as mounted on the current drive)
   400 */
   399 */
   401 TInt FsPluginManager::NextPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest,TBool aLock, TBool aCheckCurrentOperation)
   400 TInt FsPluginManager::NextPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest, TBool aCheckCurrentOperation)
   402 	{
   401 	{
   403 	if(aMsgRequest->DirectToDrive())
   402 	if(aMsgRequest->DirectToDrive())
   404 		{
   403 		{
   405 		aPlugin = NULL;
   404 		aPlugin = NULL;
   406 		return KErrNotFound;
   405 		return KErrNotFound;
   408 
   407 
   409 	TInt start;
   408 	TInt start;
   410 	TInt function = aMsgRequest->Operation()->Function();
   409 	TInt function = aMsgRequest->Operation()->Function();
   411 	TInt drive = aMsgRequest->DriveNumber();
   410 	TInt drive = aMsgRequest->DriveNumber();
   412 
   411 
   413 	if(aLock)
       
   414 	    LockChain();
       
   415 	
       
   416 	//the plugin chain lock must be held by this point.
   412 	//the plugin chain lock must be held by this point.
   417 	TInt count = iPluginChain.Count();
   413 	TInt count = iPluginChain.Count();
   418 
   414 
   419 	if(aPlugin == NULL)
   415 	if(aPlugin == NULL)
   420 		start=0;
   416 		start=0;
   429 				{
   425 				{
   430 				if((function == EFsDismountPlugin) || (iPluginChain[i]->IsMounted(drive))) 
   426 				if((function == EFsDismountPlugin) || (iPluginChain[i]->IsMounted(drive))) 
   431 					{
   427 					{
   432 
   428 
   433 					aPlugin = iPluginChain[i];
   429 					aPlugin = iPluginChain[i];
   434 					if(aLock)
       
   435 					    UnlockChain();
       
   436 					return KErrNone;
   430 					return KErrNone;
   437 					}
   431 					}
   438 				}
   432 				}
   439 			}
   433 			}
   440 		}
   434 		}
   441 	aPlugin = NULL;
   435 	aPlugin = NULL;
   442 	if(aLock)
       
   443 	    UnlockChain();
       
   444 	return KErrNotFound;
   436 	return KErrNotFound;
   445 	}
   437 	}
   446 
   438 
   447 /**
   439 /**
   448 Find the next plugin that supports the operation
   440 Find the next plugin that supports the operation
       
   441 Must be called with the plugin chain (at least read-) locked.
   449 
   442 
   450 @see FsPluginManager::NextPlugin
   443 @see FsPluginManager::NextPlugin
   451 */
   444 */
   452 TInt FsPluginManager::PrevPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest, TBool aLock)
   445 TInt FsPluginManager::PrevPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest)
   453 	{
   446 	{
   454 	if(aMsgRequest->DirectToDrive() && (aMsgRequest->CurrentOperationPtr() != NULL))
   447 	if(aMsgRequest->DirectToDrive() && (aMsgRequest->CurrentOperationPtr() != NULL))
   455 		{
   448 		{
   456 		aPlugin = NULL;
   449 		aPlugin = NULL;
   457 		return KErrNotFound;
   450 		return KErrNotFound;
   458 		}
   451 		}
   459 
   452 
   460 	TInt start;
   453 	TInt start;
   461 	TInt function = aMsgRequest->Operation()->Function();
   454 	TInt function = aMsgRequest->Operation()->Function();
   462 	TInt drive = aMsgRequest->DriveNumber();
   455 	TInt drive = aMsgRequest->DriveNumber();
   463 
       
   464 	if(aLock)
       
   465 	    LockChain();
       
   466 	
   456 	
   467 	//the plugin chain lock must be held by this point.
   457 	//the plugin chain lock must be held by this point.
   468 	TInt count= iPluginChain.Count();
   458 	TInt count= iPluginChain.Count();
   469 
   459 
   470 	if(aPlugin == NULL)
   460 	if(aPlugin == NULL)
   484 				{
   474 				{
   485 				if((function == EFsDismountPlugin) || (iPluginChain[i]->IsMounted(drive))) 
   475 				if((function == EFsDismountPlugin) || (iPluginChain[i]->IsMounted(drive))) 
   486 					{
   476 					{
   487 
   477 
   488 					aPlugin = iPluginChain[i];
   478 					aPlugin = iPluginChain[i];
   489 					if(aLock)
       
   490 					    UnlockChain();
       
   491 					return KErrNone;
   479 					return KErrNone;
   492 					}
   480 					}
   493 				}
   481 				}
   494 			}
   482 			}
   495 		}
   483 		}
   496 	aPlugin = NULL;
   484 	aPlugin = NULL;
   497 	if(aLock)
       
   498 	    UnlockChain();
       
   499 	return KErrNotFound;
   485 	return KErrNotFound;
   500 	}
   486 	}
   501 /**
   487 /**
   502 Inserts the plugin in the stack (chain)
   488 Inserts the plugin in the stack (chain)
   503 
   489 
   582 /**
   568 /**
   583 Finds a plugin by unique position
   569 Finds a plugin by unique position
   584 */
   570 */
   585 CFsPlugin* FsPluginManager::FindByUniquePosition(TInt aUniquePosition)
   571 CFsPlugin* FsPluginManager::FindByUniquePosition(TInt aUniquePosition)
   586 	{
   572 	{
   587 	LockChain();
   573 	ReadLockChain();
   588 	CFsPlugin* plugin = NULL;
   574 	CFsPlugin* plugin = NULL;
   589 	TInt count= iPluginChain.Count();
   575 	TInt count= iPluginChain.Count();
   590 	for(TInt i=0;i<count;i++)
   576 	for(TInt i=0;i<count;i++)
   591 		{
   577 		{
   592 		if(aUniquePosition == iPluginChain[i]->iUniquePos)
   578 		if(aUniquePosition == iPluginChain[i]->iUniquePos)
   669 	aPlugin = iPluginChain[aPos];
   655 	aPlugin = iPluginChain[aPos];
   670 	return KErrNone;
   656 	return KErrNone;
   671 	}
   657 	}
   672 
   658 
   673 /**
   659 /**
   674 Locks the chain
   660 Locks the chain for reading
   675 */
   661 */
   676 void FsPluginManager::LockChain()
   662 void FsPluginManager::ReadLockChain()
   677 	{
   663 	{
   678 	iChainLock.Wait();
   664     iChainLock.ReadLock();
   679 	}
   665 	}
       
   666 
       
   667 /**
       
   668 Locks the chain for writing
       
   669 */
       
   670 void FsPluginManager::WriteLockChain()
       
   671     {
       
   672     iChainLock.WriteLock();
       
   673     }
   680 
   674 
   681 /**
   675 /**
   682 Unlocks the chain
   676 Unlocks the chain
   683 */
   677 */
   684 void FsPluginManager::UnlockChain()
   678 void FsPluginManager::UnlockChain()
   685 	{
   679 	{
   686 	iChainLock.Signal();
   680     iChainLock.Unlock();
   687 	}
   681 	}
   688 
   682 
   689 /**
   683 /**
   690 Gets plugin conn from handle
   684 Gets plugin conn from handle
   691 */
   685 */
   741 	__PRINT2(_L("FsPluginManager::CompleteSessionRequests(%08x, %d)"), aSession, aValue);
   735 	__PRINT2(_L("FsPluginManager::CompleteSessionRequests(%08x, %d)"), aSession, aValue);
   742 
   736 
   743 	// Iterate through all plugins, cancelling outstanding session requests
   737 	// Iterate through all plugins, cancelling outstanding session requests
   744 	aRequest->Set(CancelPluginOp, aSession);
   738 	aRequest->Set(CancelPluginOp, aSession);
   745 
   739 
   746 	FsPluginManager::LockChain();
   740 	FsPluginManager::ReadLockChain();
   747 	TInt count = FsPluginManager::ChainCount();
   741 	TInt count = FsPluginManager::ChainCount();
   748 	TInt oldCount = count;
   742 	TInt oldCount = count;
   749 	TInt i;
   743 	TInt i;
   750 	for(i=0; i<count; i++)
   744 	for(i=0; i<count; i++)
   751 	    {
   745 	    {
   757 	    aRequest->Dispatch();
   751 	    aRequest->Dispatch();
   758 	    //Cancel is delivered to the front of the request queue
   752 	    //Cancel is delivered to the front of the request queue
   759 	    //so hopefully this wont take too long.
   753 	    //so hopefully this wont take too long.
   760 	    FsPluginManager::UnlockChain();
   754 	    FsPluginManager::UnlockChain();
   761 	    User::WaitForRequest(aRequest->Status());
   755 	    User::WaitForRequest(aRequest->Status());
   762 	    FsPluginManager::LockChain();
   756 	    FsPluginManager::ReadLockChain();
   763 	    __ASSERT_ALWAYS(aRequest->Status().Int()==KErrNone||aRequest->Status().Int()==KErrCancel,Fault(ESessionDisconnectThread2));
   757 	    __ASSERT_ALWAYS(aRequest->Status().Int()==KErrNone||aRequest->Status().Int()==KErrCancel,Fault(ESessionDisconnectThread2));
   764 	    count = FsPluginManager::ChainCount();
   758 	    count = FsPluginManager::ChainCount();
   765 	    //If a plugin was removed whilst the chain was unlocked we need to make sure we don't skip any plugins
   759 	    //If a plugin was removed whilst the chain was unlocked we need to make sure we don't skip any plugins
   766 	    if(count != oldCount)
   760 	    if(count != oldCount)
   767 	        {
   761 	        {