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 { |
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; |
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) |
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) |
622 |
608 |
623 /** |
609 /** |
624 Create a plugin thread |
610 Create a plugin thread |
625 Should only by called from main file server thread with plugin thread unavailable |
611 Should only by called from main file server thread with plugin thread unavailable |
626 */ |
612 */ |
627 TInt FsPluginManager::InitPlugin(CFsPlugin& aPlugin) |
613 TInt FsPluginManager::InitPlugin(CFsPlugin& aPlugin, RLibrary aLibrary) |
628 { |
614 { |
629 TInt err = KErrNone; |
615 TInt err = KErrNone; |
630 |
616 |
631 if(!aPlugin.iThreadP) |
617 if(!aPlugin.iThreadP) |
632 { |
618 { |
633 TRAP(err,aPlugin.iThreadP=CPluginThread::NewL(aPlugin)); |
619 TRAP(err,aPlugin.iThreadP=CPluginThread::NewL(aPlugin, aLibrary)); |
634 if(err!=KErrNone) |
620 if(err!=KErrNone) |
635 return err; |
621 return err; |
636 } |
622 } |
637 |
623 |
638 aPlugin.iThreadId = aPlugin.iThreadP->StartL(); |
624 aPlugin.iThreadId = aPlugin.iThreadP->StartL(); |
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 { |