зеркало из https://github.com/mozilla/gecko-dev.git
nsCacheEntry now asks nsCacheService to release its data, and therefore no longer holds a strong ref to its event queue. bugscape bug 4890, bugzilla bug 84247 code=gordon,me r=beard,sfraser a=clayton,chofmann
This commit is contained in:
Родитель
b95d9c0083
Коммит
ebf0feed30
|
@ -30,6 +30,7 @@
|
||||||
#include "nsError.h"
|
#include "nsError.h"
|
||||||
#include "nsICacheService.h"
|
#include "nsICacheService.h"
|
||||||
#include "nsCache.h"
|
#include "nsCache.h"
|
||||||
|
#include "nsCacheService.h"
|
||||||
#include "nsCacheDevice.h"
|
#include "nsCacheDevice.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,56 +57,21 @@ nsCacheEntry::nsCacheEntry(nsCString * key,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void* PR_CALLBACK
|
|
||||||
CacheElementReleaseEventHandler(PLEvent *self)
|
|
||||||
{
|
|
||||||
nsISupports * element = (nsISupports *)PL_GetEventOwner(self);
|
|
||||||
NS_RELEASE(element);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void PR_CALLBACK
|
|
||||||
CacheElementReleaseDestroyHandler(PLEvent *self)
|
|
||||||
{
|
|
||||||
delete self;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
nsCacheEntry::~nsCacheEntry()
|
nsCacheEntry::~nsCacheEntry()
|
||||||
{
|
{
|
||||||
delete mKey;
|
delete mKey;
|
||||||
delete mMetaData;
|
delete mMetaData;
|
||||||
|
|
||||||
if (IsStreamData()) return;
|
if (IsStreamData()) return;
|
||||||
|
|
||||||
// proxy release of of memory cache nsISupports objects
|
// proxy release of of memory cache nsISupports objects
|
||||||
if (!mData) {
|
if (!mData) return;
|
||||||
NS_ASSERTION(!mEventQ, "### ~nsCacheEntry: mEventQ but no mData");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mEventQ) {
|
|
||||||
NS_ASSERTION(!mData, "### ~nsCacheEntry: mData, but no eventQ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PLEvent * event = new PLEvent;
|
|
||||||
if (!event) {
|
|
||||||
// XXX warning
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsISupports * data = mData;
|
nsISupports * data = mData;
|
||||||
NS_ADDREF(data); // this reference will be owned by the event
|
NS_ADDREF(data); // this reference will be owned by the proxy
|
||||||
mData = nsnull; // release our reference before switching threads
|
mData = nsnull; // release our reference before switching threads
|
||||||
|
|
||||||
PL_InitEvent(event,
|
nsCacheService::ProxyObjectRelease(data, mThread);
|
||||||
data,
|
|
||||||
CacheElementReleaseEventHandler,
|
|
||||||
CacheElementReleaseDestroyHandler);
|
|
||||||
|
|
||||||
mEventQ->PostEvent(event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -128,6 +94,7 @@ nsCacheEntry::Create( const char * key,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsCacheEntry::Fetched()
|
nsCacheEntry::Fetched()
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,8 +34,6 @@
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsAReadableString.h"
|
#include "nsAReadableString.h"
|
||||||
#include "nsIEventQueue.h"
|
|
||||||
|
|
||||||
|
|
||||||
class nsCacheDevice;
|
class nsCacheDevice;
|
||||||
class nsCacheMetaData;
|
class nsCacheMetaData;
|
||||||
|
@ -93,8 +91,7 @@ public:
|
||||||
|
|
||||||
void TouchData();
|
void TouchData();
|
||||||
|
|
||||||
nsIEventQueue * GetEventQ() { return mEventQ;}
|
void SetThread(PRThread *aThread) { mThread = aThread; }
|
||||||
void SetEventQ(nsIEventQueue * eventQ) { mEventQ = dont_AddRef(eventQ);}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Meta data accessors
|
* Meta data accessors
|
||||||
|
@ -230,7 +227,7 @@ private:
|
||||||
nsCacheDevice * mCacheDevice; // 4
|
nsCacheDevice * mCacheDevice; // 4
|
||||||
nsCOMPtr<nsISupports> mSecurityInfo; //
|
nsCOMPtr<nsISupports> mSecurityInfo; //
|
||||||
nsCOMPtr<nsISupports> mData; //
|
nsCOMPtr<nsISupports> mData; //
|
||||||
nsCOMPtr<nsIEventQueue> mEventQ; // event queue for mData (for mem object cache)
|
PRThread * mThread;
|
||||||
nsCacheMetaData * mMetaData; // 4
|
nsCacheMetaData * mMetaData; // 4
|
||||||
PRCList mRequestQ; // 8
|
PRCList mRequestQ; // 8
|
||||||
PRCList mDescriptorQ; // 8
|
PRCList mDescriptorQ; // 8
|
||||||
|
|
|
@ -234,9 +234,6 @@ nsCacheEntryDescriptor::SetCacheElement(nsISupports * cacheElement)
|
||||||
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
|
||||||
if (mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_STREAM;
|
if (mCacheEntry->IsStreamData()) return NS_ERROR_CACHE_DATA_IS_STREAM;
|
||||||
|
|
||||||
mCacheEntry->SetData(cacheElement);
|
|
||||||
mCacheEntry->TouchData();
|
|
||||||
|
|
||||||
return nsCacheService::GlobalInstance()->SetCacheElement(mCacheEntry, cacheElement);
|
return nsCacheService::GlobalInstance()->SetCacheElement(mCacheEntry, cacheElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ private:
|
||||||
: mKey(key),
|
: mKey(key),
|
||||||
mInfo(0),
|
mInfo(0),
|
||||||
mListener(listener),
|
mListener(listener),
|
||||||
mEventQ(nsnull),
|
mThread(nsnull),
|
||||||
mLock(nsnull),
|
mLock(nsnull),
|
||||||
mCondVar(nsnull)
|
mCondVar(nsnull)
|
||||||
{
|
{
|
||||||
|
@ -170,7 +170,7 @@ private:
|
||||||
nsCString * mKey;
|
nsCString * mKey;
|
||||||
PRUint32 mInfo;
|
PRUint32 mInfo;
|
||||||
nsCOMPtr<nsICacheListener> mListener;
|
nsCOMPtr<nsICacheListener> mListener;
|
||||||
nsCOMPtr<nsIEventQueue> mEventQ;
|
PRThread * mThread;
|
||||||
PRLock * mLock;
|
PRLock * mLock;
|
||||||
PRCondVar * mCondVar;
|
PRCondVar * mCondVar;
|
||||||
};
|
};
|
||||||
|
|
|
@ -514,23 +514,9 @@ nsCacheService::CreateRequest(nsCacheSession * session,
|
||||||
if (!listener) return NS_OK; // we're sync, we're done.
|
if (!listener) return NS_OK; // we're sync, we're done.
|
||||||
|
|
||||||
// get the nsIEventQueue for the request's thread
|
// get the nsIEventQueue for the request's thread
|
||||||
nsresult rv;
|
(*request)->mThread = PR_GetCurrentThread();
|
||||||
rv = mEventQService->ResolveEventQueue(NS_CURRENT_EVENTQ,
|
|
||||||
getter_AddRefs((*request)->mEventQ));
|
|
||||||
if (NS_FAILED(rv)) goto error;
|
|
||||||
|
|
||||||
|
|
||||||
if (!(*request)->mEventQ) {
|
|
||||||
rv = NS_ERROR_NOT_AVAILABLE;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
error:
|
|
||||||
delete *request;
|
|
||||||
*request = nsnull;
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -543,8 +529,11 @@ nsCacheService::NotifyListener(nsCacheRequest * request,
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
nsCOMPtr<nsICacheListener> listenerProxy;
|
nsCOMPtr<nsICacheListener> listenerProxy;
|
||||||
NS_ASSERTION(request->mEventQ, "no event queue for async request!");
|
NS_ASSERTION(request->mThread, "no thread set in async request!");
|
||||||
rv = mProxyObjectManager->GetProxyForObject(request->mEventQ,
|
nsCOMPtr<nsIEventQueue> eventQ;
|
||||||
|
mEventQService->GetThreadEventQueue(request->mThread,
|
||||||
|
getter_AddRefs(eventQ));
|
||||||
|
rv = mProxyObjectManager->GetProxyForObject(eventQ,
|
||||||
NS_GET_IID(nsICacheListener),
|
NS_GET_IID(nsICacheListener),
|
||||||
request->mListener,
|
request->mListener,
|
||||||
PROXY_ASYNC|PROXY_ALWAYS,
|
PROXY_ASYNC|PROXY_ALWAYS,
|
||||||
|
@ -859,6 +848,45 @@ nsCacheService::DoomEntry_Locked(nsCacheEntry * entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void* PR_CALLBACK
|
||||||
|
EventHandler(PLEvent *self)
|
||||||
|
{
|
||||||
|
nsISupports * object = (nsISupports *)PL_GetEventOwner(self);
|
||||||
|
NS_RELEASE(object);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void PR_CALLBACK
|
||||||
|
DestroyHandler(PLEvent *self)
|
||||||
|
{
|
||||||
|
delete self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
nsCacheService::ProxyObjectRelease(nsISupports * object, PRThread * thread)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(gService, "nsCacheService not initialized");
|
||||||
|
NS_ASSERTION(thread, "no thread");
|
||||||
|
// XXX if thread == current thread, we could avoid posting an event,
|
||||||
|
// XXX by add this object to a queue and release it when the cache service is unlocked.
|
||||||
|
|
||||||
|
nsCOMPtr<nsIEventQueue> eventQ;
|
||||||
|
gService->mEventQService->GetThreadEventQueue(thread, getter_AddRefs(eventQ));
|
||||||
|
NS_ASSERTION(eventQ, "no event queue for thread");
|
||||||
|
if (!eventQ) return;
|
||||||
|
|
||||||
|
PLEvent * event = new PLEvent;
|
||||||
|
if (!event) {
|
||||||
|
// XXX warning
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PL_InitEvent(event, object, EventHandler, DestroyHandler);
|
||||||
|
eventQ->PostEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsCacheService::SetCacheDevicesEnabled(PRBool enableDisk, PRBool enableMemory)
|
nsCacheService::SetCacheDevicesEnabled(PRBool enableDisk, PRBool enableMemory)
|
||||||
{
|
{
|
||||||
|
@ -882,12 +910,7 @@ nsCacheService::SetCacheDevicesEnabled(PRBool enableDisk, PRBool enableMemory)
|
||||||
nsresult
|
nsresult
|
||||||
nsCacheService::SetCacheElement(nsCacheEntry * entry, nsISupports * element)
|
nsCacheService::SetCacheElement(nsCacheEntry * entry, nsISupports * element)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
entry->SetThread(PR_GetCurrentThread());
|
||||||
nsIEventQueue * eventQ;
|
|
||||||
rv = mEventQService->ResolveEventQueue(NS_CURRENT_EVENTQ, &eventQ);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
entry->SetEventQ(eventQ);
|
|
||||||
entry->SetData(element);
|
entry->SetData(element);
|
||||||
entry->TouchData();
|
entry->TouchData();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -98,12 +98,15 @@ public:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static
|
static
|
||||||
nsCacheService * GlobalInstance(void) { return gService; };
|
nsCacheService * GlobalInstance() { return gService; };
|
||||||
|
|
||||||
nsresult DoomEntry(nsCacheEntry * entry);
|
nsresult DoomEntry(nsCacheEntry * entry);
|
||||||
|
|
||||||
nsresult DoomEntry_Locked(nsCacheEntry * entry);
|
nsresult DoomEntry_Locked(nsCacheEntry * entry);
|
||||||
|
|
||||||
|
static
|
||||||
|
void ProxyObjectRelease(nsISupports * object, PRThread * thread);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Methods called by nsCachePrefObserver
|
* Methods called by nsCachePrefObserver
|
||||||
*/
|
*/
|
||||||
|
|
Загрузка…
Ссылка в новой задаче