userlibandfileserver/fileserver/sfile/sf_plugin_man.cpp
branchRCL_3
changeset 257 3e88ff8f41d5
parent 256 c1f20ce4abcf
equal deleted inserted replaced
256:c1f20ce4abcf 257:3e88ff8f41d5
    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 RReadWriteLock FsPluginManager::iChainLock;
    24 RFastLock 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 	WriteLockChain();
   156 	LockChain();
   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();
   162 		return err;
   162 		return err;
   163 		}
   163 		}
   164 
   164 
   165 	err = InitPlugin(*pP, aPluginFactory.Library());
   165 	err = InitPlugin(*pP);
   166 	if(err != KErrNone)
   166 	if(err != KErrNone)
   167 		{
   167 		{
   168 		return err;
   168 		return err;
   169 		}
   169 		}
   170  	aPluginFactory.IncrementMounted();
   170  	aPluginFactory.IncrementMounted();
   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 write-locked.
   238 Must be called with the plugin chain 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);
   318 	            PrevPlugin(pR->iCurrentPlugin, &mR, EFalse);
   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);
   323 	            NextPlugin(pR->iCurrentPlugin, &mR, EFalse);
   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 
       
   391 @param aPlugin - On calling the function this may contain either NULL or the current plugin.
   389 @param aPlugin - On calling the function this may contain either NULL or the current plugin.
   392                  If it is called with NULL, then we start to look for plugins from the beginning of the chain.
   390                  If it is called with NULL, then we start to look for plugins from the beginning of the chain.
   393                  If is is called with a plugin then we start to look after that plugin for the next one.
   391                  If is is called with a plugin then we start to look after that plugin for the next one.
   394                  On return, aPlugin shall contain either a plugin or NULL.
   392                  On return, aPlugin shall contain either a plugin or NULL.
   395                  
   393                  
       
   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 
   396 @param aCheckCurrentOperation - Optional, if false, will return the next plugin,
   397 @param aCheckCurrentOperation - Optional, if false, will return the next plugin,
   397  								whether the plugin is currently registered
   398  								whether the plugin is currently registered
   398 								for the current function or not. (so long as mounted on the current drive)
   399 								for the current function or not. (so long as mounted on the current drive)
   399 */
   400 */
   400 TInt FsPluginManager::NextPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest, TBool aCheckCurrentOperation)
   401 TInt FsPluginManager::NextPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest,TBool aLock, TBool aCheckCurrentOperation)
   401 	{
   402 	{
   402 	if(aMsgRequest->DirectToDrive())
   403 	if(aMsgRequest->DirectToDrive())
   403 		{
   404 		{
   404 		aPlugin = NULL;
   405 		aPlugin = NULL;
   405 		return KErrNotFound;
   406 		return KErrNotFound;
   407 
   408 
   408 	TInt start;
   409 	TInt start;
   409 	TInt function = aMsgRequest->Operation()->Function();
   410 	TInt function = aMsgRequest->Operation()->Function();
   410 	TInt drive = aMsgRequest->DriveNumber();
   411 	TInt drive = aMsgRequest->DriveNumber();
   411 
   412 
       
   413 	if(aLock)
       
   414 	    LockChain();
       
   415 	
   412 	//the plugin chain lock must be held by this point.
   416 	//the plugin chain lock must be held by this point.
   413 	TInt count = iPluginChain.Count();
   417 	TInt count = iPluginChain.Count();
   414 
   418 
   415 	if(aPlugin == NULL)
   419 	if(aPlugin == NULL)
   416 		start=0;
   420 		start=0;
   425 				{
   429 				{
   426 				if((function == EFsDismountPlugin) || (iPluginChain[i]->IsMounted(drive))) 
   430 				if((function == EFsDismountPlugin) || (iPluginChain[i]->IsMounted(drive))) 
   427 					{
   431 					{
   428 
   432 
   429 					aPlugin = iPluginChain[i];
   433 					aPlugin = iPluginChain[i];
       
   434 					if(aLock)
       
   435 					    UnlockChain();
   430 					return KErrNone;
   436 					return KErrNone;
   431 					}
   437 					}
   432 				}
   438 				}
   433 			}
   439 			}
   434 		}
   440 		}
   435 	aPlugin = NULL;
   441 	aPlugin = NULL;
       
   442 	if(aLock)
       
   443 	    UnlockChain();
   436 	return KErrNotFound;
   444 	return KErrNotFound;
   437 	}
   445 	}
   438 
   446 
   439 /**
   447 /**
   440 Find the next plugin that supports the operation
   448 Find the next plugin that supports the operation
   441 Must be called with the plugin chain (at least read-) locked.
       
   442 
   449 
   443 @see FsPluginManager::NextPlugin
   450 @see FsPluginManager::NextPlugin
   444 */
   451 */
   445 TInt FsPluginManager::PrevPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest)
   452 TInt FsPluginManager::PrevPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest, TBool aLock)
   446 	{
   453 	{
   447 	if(aMsgRequest->DirectToDrive() && (aMsgRequest->CurrentOperationPtr() != NULL))
   454 	if(aMsgRequest->DirectToDrive() && (aMsgRequest->CurrentOperationPtr() != NULL))
   448 		{
   455 		{
   449 		aPlugin = NULL;
   456 		aPlugin = NULL;
   450 		return KErrNotFound;
   457 		return KErrNotFound;
   451 		}
   458 		}
   452 
   459 
   453 	TInt start;
   460 	TInt start;
   454 	TInt function = aMsgRequest->Operation()->Function();
   461 	TInt function = aMsgRequest->Operation()->Function();
   455 	TInt drive = aMsgRequest->DriveNumber();
   462 	TInt drive = aMsgRequest->DriveNumber();
       
   463 
       
   464 	if(aLock)
       
   465 	    LockChain();
   456 	
   466 	
   457 	//the plugin chain lock must be held by this point.
   467 	//the plugin chain lock must be held by this point.
   458 	TInt count= iPluginChain.Count();
   468 	TInt count= iPluginChain.Count();
   459 
   469 
   460 	if(aPlugin == NULL)
   470 	if(aPlugin == NULL)
   474 				{
   484 				{
   475 				if((function == EFsDismountPlugin) || (iPluginChain[i]->IsMounted(drive))) 
   485 				if((function == EFsDismountPlugin) || (iPluginChain[i]->IsMounted(drive))) 
   476 					{
   486 					{
   477 
   487 
   478 					aPlugin = iPluginChain[i];
   488 					aPlugin = iPluginChain[i];
       
   489 					if(aLock)
       
   490 					    UnlockChain();
   479 					return KErrNone;
   491 					return KErrNone;
   480 					}
   492 					}
   481 				}
   493 				}
   482 			}
   494 			}
   483 		}
   495 		}
   484 	aPlugin = NULL;
   496 	aPlugin = NULL;
       
   497 	if(aLock)
       
   498 	    UnlockChain();
   485 	return KErrNotFound;
   499 	return KErrNotFound;
   486 	}
   500 	}
   487 /**
   501 /**
   488 Inserts the plugin in the stack (chain)
   502 Inserts the plugin in the stack (chain)
   489 
   503 
   568 /**
   582 /**
   569 Finds a plugin by unique position
   583 Finds a plugin by unique position
   570 */
   584 */
   571 CFsPlugin* FsPluginManager::FindByUniquePosition(TInt aUniquePosition)
   585 CFsPlugin* FsPluginManager::FindByUniquePosition(TInt aUniquePosition)
   572 	{
   586 	{
   573 	ReadLockChain();
   587 	LockChain();
   574 	CFsPlugin* plugin = NULL;
   588 	CFsPlugin* plugin = NULL;
   575 	TInt count= iPluginChain.Count();
   589 	TInt count= iPluginChain.Count();
   576 	for(TInt i=0;i<count;i++)
   590 	for(TInt i=0;i<count;i++)
   577 		{
   591 		{
   578 		if(aUniquePosition == iPluginChain[i]->iUniquePos)
   592 		if(aUniquePosition == iPluginChain[i]->iUniquePos)
   608 
   622 
   609 /**
   623 /**
   610 Create a plugin thread
   624 Create a plugin thread
   611 Should only by called from main file server thread with plugin thread unavailable
   625 Should only by called from main file server thread with plugin thread unavailable
   612 */
   626 */
   613 TInt FsPluginManager::InitPlugin(CFsPlugin& aPlugin, RLibrary aLibrary)
   627 TInt FsPluginManager::InitPlugin(CFsPlugin& aPlugin)
   614 	{
   628 	{
   615 	TInt err = KErrNone;
   629 	TInt err = KErrNone;
   616 
   630 
   617 	if(!aPlugin.iThreadP)
   631 	if(!aPlugin.iThreadP)
   618 		{
   632 		{
   619 		TRAP(err,aPlugin.iThreadP=CPluginThread::NewL(aPlugin, aLibrary));
   633 		TRAP(err,aPlugin.iThreadP=CPluginThread::NewL(aPlugin));
   620 		if(err!=KErrNone)
   634 		if(err!=KErrNone)
   621 			return err;
   635 			return err;
   622 		}
   636 		}
   623 
   637 
   624 	aPlugin.iThreadId = aPlugin.iThreadP->StartL();
   638 	aPlugin.iThreadId = aPlugin.iThreadP->StartL();
   655 	aPlugin = iPluginChain[aPos];
   669 	aPlugin = iPluginChain[aPos];
   656 	return KErrNone;
   670 	return KErrNone;
   657 	}
   671 	}
   658 
   672 
   659 /**
   673 /**
   660 Locks the chain for reading
   674 Locks the chain
   661 */
   675 */
   662 void FsPluginManager::ReadLockChain()
   676 void FsPluginManager::LockChain()
   663 	{
   677 	{
   664     iChainLock.ReadLock();
   678 	iChainLock.Wait();
   665 	}
   679 	}
   666 
       
   667 /**
       
   668 Locks the chain for writing
       
   669 */
       
   670 void FsPluginManager::WriteLockChain()
       
   671     {
       
   672     iChainLock.WriteLock();
       
   673     }
       
   674 
   680 
   675 /**
   681 /**
   676 Unlocks the chain
   682 Unlocks the chain
   677 */
   683 */
   678 void FsPluginManager::UnlockChain()
   684 void FsPluginManager::UnlockChain()
   679 	{
   685 	{
   680     iChainLock.Unlock();
   686 	iChainLock.Signal();
   681 	}
   687 	}
   682 
   688 
   683 /**
   689 /**
   684 Gets plugin conn from handle
   690 Gets plugin conn from handle
   685 */
   691 */
   735 	__PRINT2(_L("FsPluginManager::CompleteSessionRequests(%08x, %d)"), aSession, aValue);
   741 	__PRINT2(_L("FsPluginManager::CompleteSessionRequests(%08x, %d)"), aSession, aValue);
   736 
   742 
   737 	// Iterate through all plugins, cancelling outstanding session requests
   743 	// Iterate through all plugins, cancelling outstanding session requests
   738 	aRequest->Set(CancelPluginOp, aSession);
   744 	aRequest->Set(CancelPluginOp, aSession);
   739 
   745 
   740 	FsPluginManager::ReadLockChain();
   746 	FsPluginManager::LockChain();
   741 	TInt count = FsPluginManager::ChainCount();
   747 	TInt count = FsPluginManager::ChainCount();
   742 	TInt oldCount = count;
   748 	TInt oldCount = count;
   743 	TInt i;
   749 	TInt i;
   744 	for(i=0; i<count; i++)
   750 	for(i=0; i<count; i++)
   745 	    {
   751 	    {
   751 	    aRequest->Dispatch();
   757 	    aRequest->Dispatch();
   752 	    //Cancel is delivered to the front of the request queue
   758 	    //Cancel is delivered to the front of the request queue
   753 	    //so hopefully this wont take too long.
   759 	    //so hopefully this wont take too long.
   754 	    FsPluginManager::UnlockChain();
   760 	    FsPluginManager::UnlockChain();
   755 	    User::WaitForRequest(aRequest->Status());
   761 	    User::WaitForRequest(aRequest->Status());
   756 	    FsPluginManager::ReadLockChain();
   762 	    FsPluginManager::LockChain();
   757 	    __ASSERT_ALWAYS(aRequest->Status().Int()==KErrNone||aRequest->Status().Int()==KErrCancel,Fault(ESessionDisconnectThread2));
   763 	    __ASSERT_ALWAYS(aRequest->Status().Int()==KErrNone||aRequest->Status().Int()==KErrCancel,Fault(ESessionDisconnectThread2));
   758 	    count = FsPluginManager::ChainCount();
   764 	    count = FsPluginManager::ChainCount();
   759 	    //If a plugin was removed whilst the chain was unlocked we need to make sure we don't skip any plugins
   765 	    //If a plugin was removed whilst the chain was unlocked we need to make sure we don't skip any plugins
   760 	    if(count != oldCount)
   766 	    if(count != oldCount)
   761 	        {
   767 	        {