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 { |
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; |
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) |
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 { |