userlibandfileserver/fileserver/sfile/sf_file.cpp
changeset 109 b3a1d9898418
parent 90 947f0dc9f7a8
child 152 657f875b013e
equal deleted inserted replaced
102:ef2a444a7410 109:b3a1d9898418
  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 	}
  3025 	}
  3039 	}
  3026 
  3040 
  3027 CFileBody::CFileBody(CFileCB* aFileCB, CFileCB::MExtendedFileInterface* aExtendedFileInterface)
  3041 CFileBody::CFileBody(CFileCB* aFileCB, CFileCB::MExtendedFileInterface* aExtendedFileInterface)
  3028   : iFileCB(aFileCB),
  3042   : iFileCB(aFileCB),
  3029 	iExtendedFileInterface(aExtendedFileInterface ? aExtendedFileInterface : this),
  3043 	iExtendedFileInterface(aExtendedFileInterface ? aExtendedFileInterface : this),
       
  3044 	iShareList(_FOFF(CFileShare,iShareLink)),
  3030 	iSizeHigh(0)
  3045 	iSizeHigh(0)
  3031 	{
  3046 	{
  3032 	iFairSchedulingLen = TFileCacheSettings::FairSchedulingLen(iFileCB->DriveNumber());
  3047 	iFairSchedulingLen = TFileCacheSettings::FairSchedulingLen(iFileCB->DriveNumber());
  3033     iMaxSupportedFileSize = KMaxSupportedFileSize;
  3048     iMaxSupportedFileSize = KMaxSupportedFileSize;
  3034 	}
  3049 	}
  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)