sl@0: // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // f32\sfile\sf_file_cache.h sl@0: // sl@0: // sl@0: sl@0: /** sl@0: @file sl@0: @internalTechnology sl@0: */ sl@0: sl@0: sl@0: #if !defined(__SF_FILE_CACHE_H__) sl@0: #define __SF_FILE_CACHE_H__ sl@0: sl@0: #include "sf_cache_client.h" sl@0: sl@0: //#define _DEBUG_READ_AHEAD sl@0: sl@0: sl@0: NONSHARABLE_CLASS(CFileCache) : public CFsDispatchObject sl@0: { sl@0: public: sl@0: static CFileCache* NewL(CFileShare& aShare); sl@0: CFileCache* ReNewL(CFileShare& aShare); sl@0: ~CFileCache(); sl@0: void Init(CFileShare& aShare); sl@0: sl@0: CMountCB& Mount() const; sl@0: sl@0: CFileCB* FileCB(); sl@0: sl@0: void ReadAhead(CFsMessageRequest& aMsgRequest, TUint aMode); sl@0: void ResetReadAhead(); sl@0: sl@0: static TInt CompleteRead(CFsRequest* aMsgRequest); sl@0: static TInt CompleteWrite(CFsRequest* aMsgRequest); sl@0: TInt ReadBuffered(CFsMessageRequest& aMsgRequest, TUint aMode); sl@0: TInt WriteBuffered(CFsMessageRequest& aMsgRequest, TUint aMode); sl@0: sl@0: inline TBool IsDirty() {return iDirtyDataOwner != NULL;} sl@0: TInt FlushDirty(CFsRequest* aOldRequest = NULL); sl@0: void Purge(TBool aPurgeDirty = EFalse); sl@0: sl@0: // from CFsObject sl@0: void Close(); sl@0: sl@0: inline TInt64 Size64() const {return iSize64;} sl@0: sl@0: // Sets 64 bit (cached) file size sl@0: void SetSize64(TInt64 aSize); sl@0: sl@0: TDrive& Drive() const; sl@0: TUint32 NameHash() const; sl@0: HBufC& FileNameF() const; sl@0: sl@0: void MarkFileClean(); sl@0: sl@0: private: sl@0: void ConstructL(CFileShare& aShare); sl@0: CFileCache(); sl@0: sl@0: void SetFileCacheFlags(CFileShare& aShare); sl@0: sl@0: TInt DoReadBuffered(CFsMessageRequest& aMsgRequest, TUint aMode, CFsClientMessageRequest*& aNewRequest); sl@0: TInt DoWriteBuffered(CFsMessageRequest& aMsgRequest, CFsClientMessageRequest*& aNewRequest, TUint aMode); sl@0: TInt DoFlushDirty(CFsClientMessageRequest*& aNewRequest, CFsRequest* aOldRequest, TBool aFlushAll); sl@0: sl@0: sl@0: inline TInt SegmentSize() const; sl@0: inline TInt SegmentSizeLog2() const; sl@0: inline TInt64 SegmentSizeMask() const; sl@0: sl@0: inline void UpdateSharePosition(CFsMessageRequest& aMsgRequest, TMsgOperation& aCurrentOperation); sl@0: sl@0: static TInt CompleteFlushDirty(CFsRequest* aMsgRequest); sl@0: TInt FlushDirtySm(CFsMessageRequest& aMsgRequest); sl@0: sl@0: TInt AllocateRequest(CFsClientMessageRequest*& aNewRequest, TBool aWrite, CSessionFs* aSession = NULL); sl@0: sl@0: void DoReadAhead(CFsMessageRequest& aMsgRequest, TUint aMode); sl@0: sl@0: void FileDirty(CFsMessageRequest& aMsgRequest); sl@0: sl@0: sl@0: sl@0: TInt HandleWriteDirtyError(TInt aError); sl@0: void PropagateFlushErrorToAllFileShares(); sl@0: sl@0: static TInt ClosedTimerEvent(TAny* aFileCache); sl@0: static TInt DirtyTimerEvent(TAny* aFileCache); sl@0: sl@0: TBool IsDriveThread(); sl@0: sl@0: private: sl@0: sl@0: CCacheClient* iCacheClient; sl@0: sl@0: TInt iMaxReadAheadLen; sl@0: TInt iCacheSize; sl@0: sl@0: TInt32 iClosedFileKeepAliveTime; // in microseconds sl@0: TInt32 iDirtyDataFlushTime; // in microseconds sl@0: sl@0: CFileCB* iFileCB; sl@0: sl@0: RFastLock iLock; sl@0: sl@0: TInt iFlushError; sl@0: TBool iFlushBusy; sl@0: sl@0: CDriveThread* iDriveThread; sl@0: TInt iDriveNum; sl@0: sl@0: // closed queue eject timer sl@0: TThreadTimer iClosedTimer; sl@0: sl@0: // dirty data flush timer sl@0: TThreadTimer iDirtyTimer; sl@0: // The last session writing to this file. If non-NULL indicates cache contains dirty data sl@0: CSessionFs* iDirtyDataOwner; sl@0: sl@0: // The size of the file. sl@0: TInt64 iSize64; sl@0: sl@0: // The size of the file at the start of a write request sl@0: TInt64 iInitialSize; sl@0: sl@0: // The full name of the file, including drive and extensions - Folded. This is "stolen" sl@0: // from the owning CFileCB when the CFileCB destructor calls CFileCache::Close(). sl@0: HBufC* iFileNameF; sl@0: sl@0: TUint32 iNameHash; sl@0: sl@0: TDrive* iDrive; sl@0: sl@0: CMountCB* iMount; sl@0: sl@0: // Read-ahead sl@0: TInt iSequentialReads; sl@0: TInt iReadAheadLen; sl@0: TInt64 iReadAheadPos; sl@0: TInt64 iLastReadPos; sl@0: TInt iLastReadLen; sl@0: TBool iFileCacheReadAsync; sl@0: CFsClientMessageRequest* iReadAheadRequest; sl@0: sl@0: friend class TClosedFileUtils; sl@0: friend class TFsFileWriteDirty; sl@0: }; sl@0: sl@0: sl@0: class TFileCacheSettings sl@0: { sl@0: public: sl@0: class TFileCacheConfig sl@0: { sl@0: public: sl@0: TFileCacheConfig(TInt aDrive); sl@0: static TFileCacheFlags ConvertEnumToFlags(const TInt aFileCacheRead, const TInt aFileCacheReadAhead, const TInt aFileCacheWrite); sl@0: public: sl@0: TInt iDrive; sl@0: TFileCacheFlags iFlags; sl@0: sl@0: TBool iFileCacheReadAsync; sl@0: TInt32 iFairSchedulingLen; // in bytes sl@0: TInt32 iCacheSize; // in bytes sl@0: TInt32 iMaxReadAheadLen; // in bytes sl@0: TInt32 iClosedFileKeepAliveTime; // in microseconds sl@0: TInt32 iDirtyDataFlushTime; // in microseconds sl@0: }; sl@0: sl@0: public: sl@0: static TInt ReadPropertiesFile(TInt aDriveNumber); sl@0: static void SetFlags(TInt aDrive, TFileCacheFlags alags); sl@0: static TFileCacheFlags Flags(TInt aDrive); sl@0: sl@0: sl@0: static TInt FileCacheReadAsync(TInt aDrive); sl@0: static TInt FairSchedulingLen(TInt aDrive); sl@0: static TInt MaxReadAheadLen(TInt aDrive); sl@0: static TInt CacheSize(TInt aDrive); sl@0: static TInt ClosedFileKeepAliveTime(TInt aDrive); sl@0: static TInt DirtyDataFlushTime(TInt aDrive); sl@0: static TInt GetFileCacheConfig(TInt aDrive, TFileCacheConfig*& aConfig); sl@0: private: sl@0: static void Init(); sl@0: static void ReadEnum(const TDesC8& aSection, const TDesC8& aProperty, TInt32& aEnumVal, const TPtrC8* aEnumStrings); sl@0: sl@0: private: sl@0: static RArray* iFileCacheSettings; sl@0: }; sl@0: sl@0: sl@0: class TClosedFileUtils sl@0: { sl@0: public: sl@0: static void InitL(); sl@0: sl@0: static TInt Count(); sl@0: static CFileCache* At(TInt aIndex); sl@0: static TBool IsClosed(CFileCache* aFileCache); sl@0: sl@0: static void AddL(CFileCache* aFileCache, TBool aLock); sl@0: sl@0: static void Remove(); sl@0: static void Remove(TInt aDrvNumber); sl@0: static void Remove(CFileCache* aFileCache); sl@0: sl@0: static void Lock(); sl@0: static void Unlock(); sl@0: sl@0: static void ReOpen(CFileCache* aFileCache, TBool aLock); sl@0: private: sl@0: typedef TBool (*TTestFunc)(CFileCache& aFileCache, TAny* aVal); sl@0: static void RemoveFiles(TTestFunc aTestFunc, TAny* aTestVal); sl@0: sl@0: static TBool TestDrive(CFileCache& aFileCache, TAny* aVal); sl@0: static TBool TestFile(CFileCache& aFileCache, TAny* aVal); sl@0: sl@0: private: sl@0: static CFsObjectCon* iClosedFiles; sl@0: }; sl@0: sl@0: sl@0: sl@0: #endif