1828 return KErrAccessDenied; |
1828 return KErrAccessDenied; |
1829 |
1829 |
1830 // check if an attempt is made to change the share mode to EFileShareExclusive |
1830 // check if an attempt is made to change the share mode to EFileShareExclusive |
1831 // while the file has multiple readers |
1831 // while the file has multiple readers |
1832 if (newMode == EFileShareExclusive && (currentMode & KFileShareMask) != EFileShareExclusive) |
1832 if (newMode == EFileShareExclusive && (currentMode & KFileShareMask) != EFileShareExclusive) |
1833 { |
1833 { |
1834 // Check no other CFileCB is reading the file. |
1834 // Check that this is the file's only fileshare/client |
1835 FileShares->Lock(); |
1835 TDblQue<CFileShare>& aShareList = (&share->File())->FileShareList(); |
1836 TInt count=FileShares->Count(); |
1836 if (!(aShareList.IsFirst(share) && aShareList.IsLast(share))) |
1837 TBool found=EFalse; |
1837 return KErrAccessDenied; |
1838 while(count--) |
1838 } |
1839 { |
1839 |
1840 CFileShare* fileShare=(CFileShare*)(*FileShares)[count]; |
|
1841 if (&fileShare->File()==&share->File()) |
|
1842 { |
|
1843 if (found) |
|
1844 { |
|
1845 FileShares->Unlock(); |
|
1846 return(KErrAccessDenied); |
|
1847 } |
|
1848 found=ETrue; |
|
1849 } |
|
1850 } |
|
1851 FileShares->Unlock(); |
|
1852 } |
|
1853 share->iMode&=~KFileShareMask; |
1840 share->iMode&=~KFileShareMask; |
1854 share->iMode|=newMode; |
1841 share->iMode|=newMode; |
1855 share->File().SetShare(newMode); |
1842 share->File().SetShare(newMode); |
1856 return(KErrNone); |
1843 return(KErrNone); |
1857 } |
1844 } |
2449 } |
2436 } |
2450 } |
2437 } |
2451 |
2438 |
2452 |
2439 |
2453 void CFileCB::PromoteShare(CFileShare* aShare) |
2440 void CFileCB::PromoteShare(CFileShare* aShare) |
2454 // |
2441 /** |
2455 // Manages share promotion after the share has been added to the FilsShares container. |
2442 Manages share promotion and checks the EFileSequential file mode |
2456 // |
2443 after the share has been added to the FileShares container. |
2457 // - Assumes the share has already been validated using ValidateShare() |
2444 |
2458 // |
2445 It assumes the share has already been validated using ValidateShare(). |
2459 // - The count of promoted shares (ie - non-EFileShareReadersOrWriters) is incremented |
2446 |
2460 // to allow the share mode to be demoted when the last promoted share is closed. |
2447 The count of promoted shares (ie - non-EFileShareReadersOrWriters) is incremented |
2461 // |
2448 to allow the share mode to be demoted when the last promoted share is closed. |
|
2449 |
|
2450 Similarly, the count of non-EFileSequential file modes is incremented to allow |
|
2451 the file mode to be enabled when the last non-EFileSequential share is closed. |
|
2452 */ |
2462 { |
2453 { |
2463 TShare reqShare = (TShare)(aShare->iMode & KFileShareMask); |
2454 TShare reqShare = (TShare)(aShare->iMode & KFileShareMask); |
2464 if(reqShare != EFileShareReadersOrWriters) |
2455 if(reqShare != EFileShareReadersOrWriters) |
2465 { |
2456 { |
2466 iBody->iPromotedShares++; |
2457 iBody->iPromotedShares++; |
2467 iShare = reqShare; |
2458 iShare = reqShare; |
2468 } |
2459 } |
|
2460 |
|
2461 // If the file mode is not EFileSequential, then disable the 'Sequential' flag |
|
2462 if(!(aShare->iMode & EFileSequential)) |
|
2463 { |
|
2464 iBody->iNonSequentialFileModes++; |
|
2465 SetSequentialMode(EFalse); |
|
2466 __PRINT(_L("CFileCB::PromoteShare - FileSequential mode is off")); |
|
2467 } |
2469 } |
2468 } |
2470 |
2469 |
2471 |
2470 |
2472 void CFileCB::DemoteShare(CFileShare* aShare) |
2471 void CFileCB::DemoteShare(CFileShare* aShare) |
2473 // |
2472 /** |
2474 // Manages share demotion after the share has been removed from the FileShares container. |
2473 Manages share demotion and checks the EFileSequential file mode |
2475 // |
2474 after the share has been removed from the FileShares container. |
2476 // - If the share being removed is not EFileShareReadersOrWriters, then the current |
2475 |
2477 // share mode may require demotion back to EFileShareReadersOrWriters. |
2476 If the share being removed is not EFileShareReadersOrWriters, then the current |
2478 // |
2477 share mode may require demotion back to EFileShareReadersOrWriters. |
2479 // - This is determined by the iPromotedShares count, incremented in PromoteShare() |
2478 This is determined by the iPromotedShares count, incremented in PromoteShare(). |
2480 // |
2479 |
2481 { |
2480 Similarly, if the share being removed is non-EFileSequential, |
2482 if((aShare->iMode & KFileShareMask) != EFileShareReadersOrWriters) |
2481 then the EFileSequential flag may need to be enabled, |
2483 { |
2482 which is determined by the iNonSequentialFileModes count. |
2484 if(--iBody->iPromotedShares == 0) |
2483 */ |
2485 { |
2484 { |
2486 // Don't worry if the file has never been opened as EFileShareReadersOrWriters |
2485 if((aShare->iMode & KFileShareMask) != EFileShareReadersOrWriters |
2487 // - in this case the CFileCB object is about to be closed anyway. |
2486 && --iBody->iPromotedShares == 0) |
2488 iShare = EFileShareReadersOrWriters; |
2487 { |
2489 } |
2488 // Don't worry if the file has never been opened as EFileShareReadersOrWriters |
2490 } |
2489 // - in this case the CFileCB object is about to be closed anyway. |
2491 __ASSERT_DEBUG(iBody->iPromotedShares>=0,Fault(EFileShareBadPromoteCount)); |
2490 iShare = EFileShareReadersOrWriters; |
|
2491 } |
|
2492 __ASSERT_DEBUG(iBody->iPromotedShares>=0, Fault(EFileShareBadPromoteCount)); |
|
2493 |
|
2494 if(!(aShare->iMode & EFileSequential) && --iBody->iNonSequentialFileModes == 0) |
|
2495 { |
|
2496 // As above, if the file has never been opened as EFileSequential, |
|
2497 // it implies that the CFileCB object is about to be closed anyway. |
|
2498 SetSequentialMode(ETrue); |
|
2499 __PRINT(_L("CFileCB::PromoteShare - FileSequential mode is enabled")); |
|
2500 } |
|
2501 __ASSERT_DEBUG(iBody->iNonSequentialFileModes>=0, Fault(EFileShareBadPromoteCount)); |
2492 } |
2502 } |
2493 |
2503 |
2494 |
2504 |
2495 RArray<TAsyncReadRequest>& CFileCB::AsyncReadRequests() |
2505 RArray<TAsyncReadRequest>& CFileCB::AsyncReadRequests() |
2496 // |
2506 // |
2721 SetSize64(aSize, EFalse); // assume not locked |
2731 SetSize64(aSize, EFalse); // assume not locked |
2722 } |
2732 } |
2723 |
2733 |
2724 /** |
2734 /** |
2725 Constructor. |
2735 Constructor. |
2726 Locks the mount resource to which the shared file resides. |
2736 Locks the mount resource to which the shared file resides |
|
2737 and adds the share to the file's FileShare List. |
2727 |
2738 |
2728 @param aFileCB File to be shared. |
2739 @param aFileCB File to be shared. |
2729 */ |
2740 */ |
2730 CFileShare::CFileShare(CFileCB* aFileCB) |
2741 CFileShare::CFileShare(CFileCB* aFileCB) |
2731 : iFile(aFileCB) |
2742 : iFile(aFileCB) |
2732 { |
2743 { |
2733 AddResource(iFile->Mount()); |
2744 AddResource(iFile->Mount()); |
|
2745 iFile->AddShare(*this); |
2734 } |
2746 } |
2735 |
2747 |
2736 /** |
2748 /** |
2737 Destructor. |
2749 Destructor. |
2738 |
2750 |
2739 Frees mount resource to which the shared file resides, |
2751 Frees mount resource to which the shared file resides, |
|
2752 removes the share from the file's FileShare List, |
2740 removes share status from the shared file and finally closes |
2753 removes share status from the shared file and finally closes |
2741 the file. |
2754 the file. |
2742 */ |
2755 */ |
2743 CFileShare::~CFileShare() |
2756 CFileShare::~CFileShare() |
2744 { |
2757 { |
2745 // We shouldn't be deleting the file share with a valid request queue or there will be request (& memory) leakage |
2758 // We shouldn't be deleting the file share with a valid request queue or there will be request (& memory) leakage |
2746 __ASSERT_DEBUG(iCurrentRequest == NULL, Fault(ERequestQueueNotEmpty)); |
2759 __ASSERT_DEBUG(iCurrentRequest == NULL, Fault(ERequestQueueNotEmpty)); |
2747 |
2760 |
2748 RemoveResource(iFile->Mount()); |
2761 RemoveResource(iFile->Mount()); |
|
2762 iShareLink.Deque(); |
2749 iFile->RemoveLocks(this); |
2763 iFile->RemoveLocks(this); |
2750 iFile->DemoteShare(this); |
2764 iFile->DemoteShare(this); |
2751 iFile->CancelAsyncReadRequest(this, NULL); |
2765 iFile->CancelAsyncReadRequest(this, NULL); |
2752 iFile->Close(); |
2766 iFile->Close(); |
2753 } |
2767 } |
3584 |
3599 |
3585 return KErrNone; |
3600 return KErrNone; |
3586 } |
3601 } |
3587 |
3602 |
3588 |
3603 |
|
3604 //--------------------------------------------------------------------------------------------------------------------- |
|
3605 /** |
|
3606 Gets the 'Sequential' mode of the file. |
|
3607 |
|
3608 @return ETrue, if the file is in 'Sequential' mode |
|
3609 */ |
|
3610 EXPORT_C TBool CFileCB::IsSequentialMode() const |
|
3611 { |
|
3612 return iBody->iSequential; |
|
3613 } |
|
3614 |
|
3615 /** |
|
3616 Sets the 'Sequential' mode of the file. |
|
3617 */ |
|
3618 void CFileCB::SetSequentialMode(TBool aSequential) |
|
3619 { |
|
3620 iBody->iSequential = aSequential; |
|
3621 } |
|
3622 |
|
3623 //--------------------------------------------------------------------------------------------------------------------- |
|
3624 /** |
|
3625 Gets the list containing the shares associated with the file. |
|
3626 |
|
3627 @return The FileShare List |
|
3628 */ |
|
3629 TDblQue<CFileShare>& CFileCB::FileShareList() const |
|
3630 { |
|
3631 return iBody->iShareList; |
|
3632 } |
|
3633 |
|
3634 /** |
|
3635 Adds the share to the end of the FileShare List. |
|
3636 */ |
|
3637 void CFileCB::AddShare(CFileShare& aFileShare) |
|
3638 { |
|
3639 iBody->iShareList.AddLast(aFileShare); |
|
3640 } |
|
3641 |
|
3642 |
3589 //##################################################################################################################### |
3643 //##################################################################################################################### |
3590 //# TFileShareLock class implementation |
3644 //# TFileShareLock class implementation |
3591 //##################################################################################################################### |
3645 //##################################################################################################################### |
3592 |
3646 |
3593 TFileShareLock::TFileShareLock(const CFileShare* aOwner, TUint64 aPosLow, TUint64 aPosHigh) |
3647 TFileShareLock::TFileShareLock(const CFileShare* aOwner, TUint64 aPosLow, TUint64 aPosHigh) |