--- a/webengine/osswebengine/cache/src/HttpCacheFileWriteHandler.cpp Thu Aug 27 07:44:59 2009 +0300
+++ b/webengine/osswebengine/cache/src/HttpCacheFileWriteHandler.cpp Thu Sep 24 12:53:48 2009 +0300
@@ -22,6 +22,7 @@
#include "HttpCacheStreamHandler.h"
#include "HttpCachePostponeWriteUtilities.h"
#include "HttpCacheUtil.h"
+#include "HttpCacheObserver.h"
#include <HttpCacheManagerInternalCRKeys.h>
#include <centralrepository.h>
#include <hal.h>
@@ -69,7 +70,7 @@
// -----------------------------------------------------------------------------
//
CHttpCacheFileWriteHandler::CHttpCacheFileWriteHandler(CHttpCacheHandler* aHandler, CHttpCacheStreamHandler* aStreamHandler, RFs& aRfs)
- : CActive(EPriorityHigh),
+ : CActive(EPriorityIdle),
iCacheHandler( aHandler ),
iCacheStreamHandler(aStreamHandler),
iFs(aRfs)
@@ -81,14 +82,17 @@
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
-void CHttpCacheFileWriteHandler::ConstructL(const TInt aWriteTimeout)
+void CHttpCacheFileWriteHandler::ConstructL(const THttpCachePostponeParameters& aParams)
{
iObjectQueue.Reset();
iObjectQueue.ReserveL(32);
- iWaitTimer = CHttpCacheWriteTimeout::NewL( aWriteTimeout );
+ iWaitTimer = CHttpCacheWriteTimeout::NewL( aParams.iWriteTimeout );
CActiveScheduler::Add(this);
+ iFreeRamThreshold = aParams.iFreeRamThreshold;
+ iImmediateWriteThreshold = aParams.iImmediateWriteThreshold;
+
MemoryManager::AddCollector(this);
}
@@ -97,14 +101,13 @@
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
-CHttpCacheFileWriteHandler* CHttpCacheFileWriteHandler::NewL(CHttpCacheHandler* aHandler, CHttpCacheStreamHandler* aStreamHandler, RFs& aRfs, const TInt aWriteTimeout)
+CHttpCacheFileWriteHandler* CHttpCacheFileWriteHandler::NewL(CHttpCacheHandler* aHandler, CHttpCacheStreamHandler* aStreamHandler, RFs& aRfs, const THttpCachePostponeParameters& aParams)
{
CHttpCacheFileWriteHandler* self = new( ELeave ) CHttpCacheFileWriteHandler(aHandler, aStreamHandler, aRfs);
CleanupStack::PushL( self );
- self->ConstructL(aWriteTimeout);
+ self->ConstructL(aParams);
CleanupStack::Pop();
-
return self;
}
@@ -141,6 +144,7 @@
for ( TInt i=0; i < iObjectQueue.Count(); i++ )
{
iCacheStreamHandler->Flush(*iObjectQueue[i]);
+ iObjectQueue[i]->ClearDeleteObserver();
}
iObjectQueue.Reset();
#ifdef __CACHELOG__
@@ -185,15 +189,22 @@
return;
}
+ TInt skip = 0;
TInt count = KMaxCollectCount;
while ( aRequired && count && iObjectQueue.Count() )
{
- count--;
- CHttpCacheEntry* entry = iObjectQueue[0];
- iObjectQueue.Remove(0);
- TInt size = entry->BodySize();
- iCacheStreamHandler->Flush(*entry);
- aRequired -= size;
+ CHttpCacheEntry* entry = iObjectQueue[skip];
+ if(entry != iObjectFlushing)
+ {
+ count--;
+ iObjectQueue.Remove(skip);
+ entry->ClearDeleteObserver();
+ TInt size = entry->BodySize();
+ iCacheStreamHandler->Flush(*entry);
+ aRequired -= size;
+ }
+ else
+ skip++;
}
}
@@ -247,29 +258,46 @@
// if we get here, we're not in low memory state any more.
iLowMemoryState = EFalse;
+ // If we re-request an item on the page which was non-cacheable, we will update it's content
+ // and add it back to the cache here, even though we have reused the same CHttpCache object.
+
+ // check for re-adding pre-existing objects with updated content - size may differ, so need to remove and reinsert.
+ TInt index = iObjectQueue.Find( aEntry );
+ if( index >= 0)
+ {
+ iObjectQueue.Remove( index );
+ }
// add entry to queue
- TInt err = iObjectQueue.InsertInOrderAllowRepeats(aEntry, TLinearOrder<CHttpCacheEntry>(CompareHttpCacheEntrySize));
+ TInt err = iObjectQueue.Append( aEntry );
- #ifdef __CACHELOG__
- HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: CHttpCacheFileWriteHandler: Added object %08x to postpone queue."), aEntry);
- OutputQueueContentToDebug();
-#endif
+ // sort by size
+ iObjectQueue.Sort(CompareHttpCacheEntrySize);
+
+ switch( err )
+ {
+ case KErrNone:
- // reset timer
- if ( err == KErrNone )
- {
- aAddStatus = EAddedOk;
- iWaitTimer->Start( CHttpCacheFileWriteHandler::WriteTimeout, this );
+ // set up notification of delete operation
+ aEntry->SetDeleteObserver(this);
+
+ #ifdef __CACHELOG__
+ HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: CHttpCacheFileWriteHandler: Added object %08x to postpone queue."), aEntry);
+ OutputQueueContentToDebug();
+ #endif
+
+ aAddStatus = EAddedOk;
+ iWaitTimer->Start( CHttpCacheFileWriteHandler::WriteTimeout, this );
+ break;
+ case KErrNoMemory:
+ aAddStatus = ENotEnoughFreeMemory;
+ break;
+ default:
+ aAddStatus = ECheckReturn;
+ break;
}
- else
- {
- aAddStatus = ECheckReturn;
- }
-
#ifdef __CACHELOG__
HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: <<FileWriteHandler::AddEntry"));
#endif
-
return err;
}
@@ -305,6 +333,8 @@
if ( index >= 0 )
{
iObjectQueue.Remove( index );
+ aEntry->ClearDeleteObserver();
+
if ( !iObjectQueue.Count() )
{
#ifdef __CACHELOG__
@@ -330,6 +360,11 @@
void CHttpCacheFileWriteHandler::RemoveAll()
{
// empty list - note that HttpCacheEntries aren't owned.
+ // deregister for delete events.
+ for(TInt index = 0; index < iObjectQueue.Count(); index++)
+ {
+ iObjectQueue[index]->ClearDeleteObserver();
+ }
iObjectQueue.Reset();
// stop us if we're active
Cancel();
@@ -363,6 +398,19 @@
if ( !IsActive() )
{
+#ifdef HTTPCACHE_FILEWRITEDEBUG_ALWAYS_FIRE_OBSERVER
+ // trigger index.dat observer
+ RFile tempIndexFile;
+ TInt err = tempIndexFile.Open(iFs, _L("C:\\system\\cache\\index.dat"), EFileWrite);
+ if(err == KErrNone)
+ {
+ tempIndexFile.Seek(ESeekEnd, err);
+ _LIT8(KIndexGarbage, "blahblah");
+ tempIndexFile.Write(KIndexGarbage());
+ tempIndexFile.Flush();
+ tempIndexFile.Close();
+ }
+#endif
#ifdef __CACHELOG__
HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: Setting FileWriteHandler %08x to active."), this);
#endif
@@ -424,6 +472,8 @@
#endif
// the object might not exist in the queue.. how can this happen?
iObjectQueue.Remove(index);
+ iObjectFlushing->ClearDeleteObserver();
+
//
if ( result != KErrNone )
{
@@ -453,21 +503,33 @@
// remove any items from the top of the queue which have no body data.
while ( iObjectQueue.Count() && iObjectQueue[0]->BodySize() == 0 )
{
+ iObjectQueue[0]->ClearDeleteObserver();
iObjectQueue.Remove(0);
};
+ TBool goIdle = ETrue;
// check to see if there is anything ready to write out
if ( iObjectQueue.Count() )
{
- SetActive();
- iStatus = KRequestPending;
- iCacheStreamHandler->FlushAsync( *iObjectQueue[0], iStatus );
- iObjectFlushing = iObjectQueue[0];
-#ifdef __CACHELOG__
- HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: FileWriteHandler::RunL continue cache flush, Starting object %08x."), iObjectFlushing);
-#endif
+ // merge index if it's changed
+ if(iCacheHandler->iHttpCacheObserver->Updated())
+ iCacheHandler->iHttpCacheObserver->RunL();
+
+ // check again, merge may have removed all items
+ if( iObjectQueue.Count() && !IsActive() ) // Collect could be triggered during RunL execution and already have made this object active, we can't tell in 'collect' if we were in here or not.
+ {
+ iStatus = KRequestPending;
+ SetActive();
+ iCacheStreamHandler->FlushAsync( *iObjectQueue[0], iStatus );
+ iObjectFlushing = iObjectQueue[0];
+ goIdle = EFalse;
+ #ifdef __CACHELOG__
+ HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: FileWriteHandler::RunL continue cache flush, Starting object %08x."), iObjectFlushing);
+ #endif
+ }
}
- else
+
+ if(goIdle)
{ // nothing left to write, go idle.
#ifdef __CACHELOG__
HttpCacheUtil::WriteLog(0, _L("CACHEPOSTPONE: FileWriteHandler::RunL complete with nothing else to write."));
@@ -542,4 +604,9 @@
return EFalse;
}
+
+void CHttpCacheFileWriteHandler::EntryDeleted(CHttpCacheEntry *aEntry)
+ {
+ RemoveEntry(aEntry);
+ }
// End of File