Fixed nsSupportsHashtable behaviour and API to fix leaks in

nsDirectoryService. Fixes bugs #38606 and #39859.

a=waterson; r=rayw,brendan,warren
This commit is contained in:
inaky.gonzalez%intel.com 2000-06-06 22:06:56 +00:00
Родитель 0a5c4f0d3c
Коммит 2b549b6f09
20 изменённых файлов: 148 добавлений и 332 удалений

Просмотреть файл

@ -855,7 +855,7 @@ NS_IMETHODIMP nsChromeRegistry::LoadDataSource(const nsCString &aFileName,
nsCOMPtr<nsISupports> supports = do_QueryInterface(remote);
nsStringKey skey(key);
mDataSourceTable->Put(&skey, (void*)supports.get());
mDataSourceTable->Put(&skey, supports.get());
return NS_OK;
}

Просмотреть файл

@ -2444,8 +2444,7 @@ nsEventStateManager::RegisterAccessKey(nsIFrame * aFrame, nsIContent* aContent,
if (content) {
nsVoidKey key((void*)aKey);
nsIContent* oldContent = NS_STATIC_CAST(nsIContent*, mAccessKeys->Put(&key, content));
NS_IF_RELEASE(oldContent);
mAccessKeys->Put(&key, content);
}
return NS_OK;

Просмотреть файл

@ -126,8 +126,7 @@ nsBindingManager::SetBinding(nsIContent* aContent, nsIXBLBinding* aBinding )
nsISupportsKey key(aContent);
if (aBinding) {
nsIXBLBinding* oldBinding = NS_STATIC_CAST(nsIXBLBinding*, mBindingTable->Put(&key, aBinding));
NS_IF_RELEASE(oldBinding);
mBindingTable->Put (&key, aBinding);
}
else
mBindingTable->Remove(&key);

Просмотреть файл

@ -52,16 +52,14 @@ nsControllerCommandManager::RegisterCommand(const PRUnichar *commandName, nsICon
{
nsStringKey commandKey(commandName);
void* replacedCmd = mCommandsTable.Put(&commandKey, (void*)aCommand);
#if DEBUG
if (replacedCmd)
if (mCommandsTable.Put (&commandKey, aCommand))
{
#if DEBUG
nsCAutoString msg("Replacing existing command -- ");
msg.AppendWithConversion(commandName);
NS_WARNING(msg);
}
#endif
}
return NS_OK;
}
@ -71,8 +69,8 @@ nsControllerCommandManager::UnregisterCommand(const PRUnichar *commandName, nsIC
{
nsStringKey commandKey(commandName);
void* foundCommand = mCommandsTable.Remove(&commandKey);
return (foundCommand) ? NS_OK : NS_ERROR_FAILURE;
PRBool any_object_actually_removed_p = mCommandsTable.Remove (&commandKey);
return any_object_actually_removed_p? NS_OK : NS_ERROR_FAILURE;
}
@ -84,7 +82,7 @@ nsControllerCommandManager::FindCommandHandler(const PRUnichar *aCommandName, ns
*outCommand = NULL;
nsStringKey commandKey(aCommandName);
void* foundCommand = mCommandsTable.Get(&commandKey); // this does the addref
nsISupports* foundCommand = mCommandsTable.Get(&commandKey); // this does the addref
if (!foundCommand) return NS_ERROR_FAILURE;
*outCommand = NS_REINTERPRET_CAST(nsIControllerCommand*, foundCommand);

Просмотреть файл

@ -159,8 +159,9 @@ nsXULPrototypeCache::PutPrototype(nsIXULPrototypeDocument* aDocument)
rv = aDocument->GetURI(getter_AddRefs(uri));
nsIURIKey key(uri);
nsIXULPrototypeDocument* oldproto = NS_STATIC_CAST(nsIXULPrototypeDocument*, mPrototypeTable.Put(&key, aDocument));
NS_IF_RELEASE(oldproto);
// Put() w/o a third parameter with a destination for the
// replaced value releases it
mPrototypeTable.Put(&key, aDocument);
return NS_OK;
}
@ -191,8 +192,7 @@ nsXULPrototypeCache::PutStyleSheet(nsICSSStyleSheet* aStyleSheet)
rv = aStyleSheet->GetURL(*getter_AddRefs(uri));
nsIURIKey key(uri);
nsICSSStyleSheet* oldsheet = NS_STATIC_CAST(nsICSSStyleSheet*, mStyleSheetTable.Put(&key, aStyleSheet));
NS_IF_RELEASE(oldsheet);
mStyleSheetTable.Put(&key, aStyleSheet);
return NS_OK;
}
@ -214,8 +214,7 @@ nsXULPrototypeCache::PutXBLDocument(nsIDocument *aDocument)
uri->GetSpec(&aString);
nsStringKey key(aString);
nsIDocument* olddoc = NS_STATIC_CAST(nsIDocument*, mXBLDocTable.Put(&key, aDocument));
NS_IF_RELEASE(olddoc);
mXBLDocTable.Put(&key, aDocument);
return NS_OK;
}
@ -236,8 +235,7 @@ nsXULPrototypeCache::PutXBLDocScriptAccess(nsIDocument *aDocument)
uri->GetSpec(&aString);
nsStringKey key(aString);
nsIDocument* olddoc = NS_STATIC_CAST(nsIDocument*, mScriptAccessTable.Put(&key, aDocument));
NS_IF_RELEASE(olddoc);
mScriptAccessTable.Put(&key, aDocument);
return NS_OK;
}

Просмотреть файл

@ -115,21 +115,22 @@ nsLayoutHistoryState::AddState(PRUint32 aContentID,
nsIPresState* aState,
nsIStatefulFrame::StateType aStateType)
{
nsresult rv = NS_OK;
HistoryKey key(aContentID, aStateType);
void * res = mStates.Put(&key, (void *) aState);
/* nsHashTable seems to return null when it actually added
* the element in to the table. If another element was already
* present in the table for the key, it seems to return the
* element that was already present. Not sure if that was
* the intended behavior
/*
* nsSupportsHashtable::Put() returns false when no object has been
* replaced when inserting the new one, true if it some one was.
*
*/
if (res) {
//printf("nsLayoutHistoryState::AddState OOPS!. There was already a state in the hash table for the key\n");
rv = NS_OK;
PRBool replaced = mStates.Put (&key, aState);
if (replaced)
{
// done this way by indication of warren@netscape.com [ipg]
#if 0
printf("nsLayoutHistoryState::AddState OOPS!. There was already a state in the hash table for the key\n");
#endif
}
return rv;
return NS_OK;
}
NS_IMETHODIMP
@ -139,13 +140,15 @@ nsLayoutHistoryState::GetState(PRUint32 aContentID,
{
nsresult rv = NS_OK;
HistoryKey key(aContentID, aStateType);
void * state = nsnull;
nsISupports *state = nsnull;
state = mStates.Get(&key);
if (state) {
*aState = (nsIPresState *)state;
}
else {
// printf("nsLayoutHistoryState::GetState, ERROR getting History state for the key\n");
#if 0
printf("nsLayoutHistoryState::GetState, ERROR getting History state for the key\n");
#endif
*aState = nsnull;
rv = NS_OK;
}
@ -158,7 +161,6 @@ nsLayoutHistoryState::RemoveState(PRUint32 aContentID,
{
nsresult rv = NS_OK;
HistoryKey key(aContentID, aStateType);
void * state = nsnull;
state = mStates.Remove(&key);
mStates.Remove(&key);
return rv;
}

Просмотреть файл

@ -115,21 +115,22 @@ nsLayoutHistoryState::AddState(PRUint32 aContentID,
nsIPresState* aState,
nsIStatefulFrame::StateType aStateType)
{
nsresult rv = NS_OK;
HistoryKey key(aContentID, aStateType);
void * res = mStates.Put(&key, (void *) aState);
/* nsHashTable seems to return null when it actually added
* the element in to the table. If another element was already
* present in the table for the key, it seems to return the
* element that was already present. Not sure if that was
* the intended behavior
/*
* nsSupportsHashtable::Put() returns false when no object has been
* replaced when inserting the new one, true if it some one was.
*
*/
if (res) {
//printf("nsLayoutHistoryState::AddState OOPS!. There was already a state in the hash table for the key\n");
rv = NS_OK;
PRBool replaced = mStates.Put (&key, aState);
if (replaced)
{
// done this way by indication of warren@netscape.com [ipg]
#if 0
printf("nsLayoutHistoryState::AddState OOPS!. There was already a state in the hash table for the key\n");
#endif
}
return rv;
return NS_OK;
}
NS_IMETHODIMP
@ -139,13 +140,15 @@ nsLayoutHistoryState::GetState(PRUint32 aContentID,
{
nsresult rv = NS_OK;
HistoryKey key(aContentID, aStateType);
void * state = nsnull;
nsISupports *state = nsnull;
state = mStates.Get(&key);
if (state) {
*aState = (nsIPresState *)state;
}
else {
// printf("nsLayoutHistoryState::GetState, ERROR getting History state for the key\n");
#if 0
printf("nsLayoutHistoryState::GetState, ERROR getting History state for the key\n");
#endif
*aState = nsnull;
rv = NS_OK;
}
@ -158,7 +161,6 @@ nsLayoutHistoryState::RemoveState(PRUint32 aContentID,
{
nsresult rv = NS_OK;
HistoryKey key(aContentID, aStateType);
void * state = nsnull;
state = mStates.Remove(&key);
mStates.Remove(&key);
return rv;
}

Просмотреть файл

@ -2444,8 +2444,7 @@ nsEventStateManager::RegisterAccessKey(nsIFrame * aFrame, nsIContent* aContent,
if (content) {
nsVoidKey key((void*)aKey);
nsIContent* oldContent = NS_STATIC_CAST(nsIContent*, mAccessKeys->Put(&key, content));
NS_IF_RELEASE(oldContent);
mAccessKeys->Put(&key, content);
}
return NS_OK;

Просмотреть файл

@ -126,8 +126,7 @@ nsBindingManager::SetBinding(nsIContent* aContent, nsIXBLBinding* aBinding )
nsISupportsKey key(aContent);
if (aBinding) {
nsIXBLBinding* oldBinding = NS_STATIC_CAST(nsIXBLBinding*, mBindingTable->Put(&key, aBinding));
NS_IF_RELEASE(oldBinding);
mBindingTable->Put (&key, aBinding);
}
else
mBindingTable->Remove(&key);

Просмотреть файл

@ -132,7 +132,13 @@ nsresult nsMsgDatabase::RemoveHdrFromCache(nsIMsgDBHdr *hdr, nsMsgKey key)
nsCAutoString strKey;
strKey.AppendInt(key, 10);
nsStringKey hashKey(strKey.GetBuffer());
nsIMsgDBHdr *removedHdr = (nsIMsgDBHdr *) m_cachedHeaders->Remove(&hashKey); // does this release, or do I have to?
/*
* this does release on the held object, unless you don't
* want it to, by passing as third argument a non-null pointer
* where to store it; this way you would get the ownership
* of the reference held by the table for that object.
*/
m_cachedHeaders->Remove(&hashKey);
}
return NS_OK;
}

Просмотреть файл

@ -609,7 +609,7 @@ nsDNSLookup::InitiateLookup(void)
// XXX remove from hashtable and release - for now
nsStringKey key(mHostName);
(void) nsDNSService::gService->mLookups.Remove(&key);
nsDNSService::gService->mLookups.Remove(&key);
#endif /* XP_UNIX */
@ -1149,7 +1149,6 @@ nsDNSService::GetLookupEntry(const char* hostName,
nsDNSLookup* *result)
{
nsresult rv;
void* prev;
nsAutoMonitor mon(mMonitor);
@ -1176,9 +1175,11 @@ nsDNSService::GetLookupEntry(const char* hostName,
rv = lookup->Init(hostName);
if (NS_FAILED(rv)) goto done;
NS_ADDREF(lookup);
prev = mLookups.Put(&key, lookup);
NS_ASSERTION(prev == nsnull, "already a nsDNSLookup entry");
NS_ADDREF(lookup); // reference for the caller
if (mLookups.Put(&key, lookup))
{
NS_ASSERTION (0, "already a nsDNSLookup entry");
}
*result = lookup;
done:

Просмотреть файл

@ -855,7 +855,7 @@ NS_IMETHODIMP nsChromeRegistry::LoadDataSource(const nsCString &aFileName,
nsCOMPtr<nsISupports> supports = do_QueryInterface(remote);
nsStringKey skey(key);
mDataSourceTable->Put(&skey, (void*)supports.get());
mDataSourceTable->Put(&skey, supports.get());
return NS_OK;
}

Просмотреть файл

@ -1,212 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsControllerCommandManager.h"
// prototype;
nsresult
NS_NewControllerCommandManager(nsIControllerCommandManager** aResult);
// this value is used to size the hash table. Just a sensible upper bound
#define NUM_COMMANDS_BOUNDS 64
nsControllerCommandManager::nsControllerCommandManager()
: mCommandsTable(NUM_COMMANDS_BOUNDS, PR_FALSE)
{
NS_INIT_REFCNT();
}
nsControllerCommandManager::~nsControllerCommandManager()
{
}
NS_IMPL_ISUPPORTS2(nsControllerCommandManager, nsIControllerCommandManager, nsISupportsWeakReference);
NS_IMETHODIMP
nsControllerCommandManager::RegisterCommand(const PRUnichar *commandName, nsIControllerCommand *aCommand)
{
nsStringKey commandKey(commandName);
void* replacedCmd = mCommandsTable.Put(&commandKey, (void*)aCommand);
#if DEBUG
if (replacedCmd)
{
nsCAutoString msg("Replacing existing command -- ");
msg.AppendWithConversion(commandName);
NS_WARNING(msg);
}
#endif
return NS_OK;
}
NS_IMETHODIMP
nsControllerCommandManager::UnregisterCommand(const PRUnichar *commandName, nsIControllerCommand *aCommand)
{
nsStringKey commandKey(commandName);
void* foundCommand = mCommandsTable.Remove(&commandKey);
return (foundCommand) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsControllerCommandManager::FindCommandHandler(const PRUnichar *aCommandName, nsIControllerCommand **outCommand)
{
NS_ENSURE_ARG_POINTER(outCommand);
*outCommand = NULL;
nsStringKey commandKey(aCommandName);
void* foundCommand = mCommandsTable.Get(&commandKey); // this does the addref
if (!foundCommand) return NS_ERROR_FAILURE;
*outCommand = NS_REINTERPRET_CAST(nsIControllerCommand*, foundCommand);
return NS_OK;
}
/* boolean isCommandEnabled (in wstring command); */
NS_IMETHODIMP
nsControllerCommandManager::IsCommandEnabled(const PRUnichar *aCommandName, nsISupports *aCommandRefCon, PRBool *aResult)
{
NS_ENSURE_ARG_POINTER(aCommandName);
NS_ENSURE_ARG_POINTER(aResult);
*aResult = PR_FALSE;
// find the command
nsCOMPtr<nsIControllerCommand> commandHandler;
FindCommandHandler(aCommandName, getter_AddRefs(commandHandler));
if (!commandHandler)
{
#if DEBUG
nsCAutoString msg("Controller command manager asked about a command that it does not handle -- ");
msg.AppendWithConversion(aCommandName);
NS_WARNING(msg);
#endif
return NS_OK; // we don't handle this command
}
return commandHandler->IsCommandEnabled(aCommandName, aCommandRefCon, aResult);
}
NS_IMETHODIMP
nsControllerCommandManager::UpdateCommandState(const PRUnichar *aCommandName, nsISupports *aCommandRefCon)
{
NS_ENSURE_ARG_POINTER(aCommandName);
// find the command
nsCOMPtr<nsIControllerCommand> commandHandler;
FindCommandHandler(aCommandName, getter_AddRefs(commandHandler));
if (!commandHandler)
{
#if DEBUG
nsCAutoString msg("Controller command manager asked to update the state of a command that it does not handle -- ");
msg.AppendWithConversion(aCommandName);
NS_WARNING(msg);
#endif
return NS_OK; // we don't handle this command
}
nsCOMPtr<nsIStateUpdatingControllerCommand> stateCommand = do_QueryInterface(commandHandler);
if (!stateCommand)
{
#if DEBUG
nsCAutoString msg("Controller command manager asked to update the state of a command that doesn't do state updating -- ");
msg.AppendWithConversion(aCommandName);
NS_WARNING(msg);
#endif
return NS_ERROR_NO_INTERFACE;
}
return stateCommand->UpdateCommandState(aCommandName, aCommandRefCon);
}
NS_IMETHODIMP
nsControllerCommandManager::SupportsCommand(const PRUnichar *aCommandName, nsISupports *aCommandRefCon, PRBool *aResult)
{
NS_ENSURE_ARG_POINTER(aCommandName);
NS_ENSURE_ARG_POINTER(aResult);
// XXX: need to check the readonly and disabled states
*aResult = PR_FALSE;
// find the command
nsCOMPtr<nsIControllerCommand> commandHandler;
FindCommandHandler(aCommandName, getter_AddRefs(commandHandler));
*aResult = (commandHandler.get() != nsnull);
return NS_OK;
}
/* void doCommand (in wstring command); */
NS_IMETHODIMP
nsControllerCommandManager::DoCommand(const PRUnichar *aCommandName, nsISupports *aCommandRefCon)
{
NS_ENSURE_ARG_POINTER(aCommandName);
// find the command
nsCOMPtr<nsIControllerCommand> commandHandler;
FindCommandHandler(aCommandName, getter_AddRefs(commandHandler));
if (!commandHandler)
{
#if DEBUG
nsCAutoString msg("Controller command manager asked to do a command that it does not handle -- ");
msg.AppendWithConversion(aCommandName);
NS_WARNING(msg);
#endif
return NS_OK; // we don't handle this command
}
return commandHandler->DoCommand(aCommandName, aCommandRefCon);
}
nsresult
NS_NewControllerCommandManager(nsIControllerCommandManager** aResult)
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
nsControllerCommandManager* newCommandManager = new nsControllerCommandManager();
if (! newCommandManager)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(newCommandManager);
*aResult = newCommandManager;
return NS_OK;
}

Просмотреть файл

@ -159,8 +159,9 @@ nsXULPrototypeCache::PutPrototype(nsIXULPrototypeDocument* aDocument)
rv = aDocument->GetURI(getter_AddRefs(uri));
nsIURIKey key(uri);
nsIXULPrototypeDocument* oldproto = NS_STATIC_CAST(nsIXULPrototypeDocument*, mPrototypeTable.Put(&key, aDocument));
NS_IF_RELEASE(oldproto);
// Put() w/o a third parameter with a destination for the
// replaced value releases it
mPrototypeTable.Put(&key, aDocument);
return NS_OK;
}
@ -191,8 +192,7 @@ nsXULPrototypeCache::PutStyleSheet(nsICSSStyleSheet* aStyleSheet)
rv = aStyleSheet->GetURL(*getter_AddRefs(uri));
nsIURIKey key(uri);
nsICSSStyleSheet* oldsheet = NS_STATIC_CAST(nsICSSStyleSheet*, mStyleSheetTable.Put(&key, aStyleSheet));
NS_IF_RELEASE(oldsheet);
mStyleSheetTable.Put(&key, aStyleSheet);
return NS_OK;
}
@ -214,8 +214,7 @@ nsXULPrototypeCache::PutXBLDocument(nsIDocument *aDocument)
uri->GetSpec(&aString);
nsStringKey key(aString);
nsIDocument* olddoc = NS_STATIC_CAST(nsIDocument*, mXBLDocTable.Put(&key, aDocument));
NS_IF_RELEASE(olddoc);
mXBLDocTable.Put(&key, aDocument);
return NS_OK;
}
@ -236,8 +235,7 @@ nsXULPrototypeCache::PutXBLDocScriptAccess(nsIDocument *aDocument)
uri->GetSpec(&aString);
nsStringKey key(aString);
nsIDocument* olddoc = NS_STATIC_CAST(nsIDocument*, mScriptAccessTable.Put(&key, aDocument));
NS_IF_RELEASE(olddoc);
mScriptAccessTable.Put(&key, aDocument);
return NS_OK;
}

Просмотреть файл

@ -42,7 +42,7 @@ nsDOMViewerObject::SetTarget(nsIRDFResource *aProperty,
nsIRDFNode *aValue)
{
nsISupportsKey propKey(aProperty);
targets.Put(&propKey, (void *)aValue);
targets.Put(&propKey, aValue);
return NS_OK;
}

Просмотреть файл

@ -385,8 +385,8 @@ nsObjectHashtable::RemoveAndDelete(nsHashKey *aKey)
////////////////////////////////////////////////////////////////////////////////
// nsSupportsHashtable: an nsHashtable where the elements are nsISupports*
static PRBool PR_CALLBACK
_ReleaseElement(nsHashKey *aKey, void *aData, void* closure)
PRBool PR_CALLBACK
nsSupportsHashtable::ReleaseElement(nsHashKey *aKey, void *aData, void* closure)
{
nsISupports* element = NS_STATIC_CAST(nsISupports*, aData);
NS_IF_RELEASE(element);
@ -395,18 +395,25 @@ _ReleaseElement(nsHashKey *aKey, void *aData, void* closure)
nsSupportsHashtable::~nsSupportsHashtable()
{
Enumerate(_ReleaseElement, nsnull);
Enumerate(ReleaseElement, nsnull);
}
void*
nsSupportsHashtable::Put(nsHashKey *aKey, void *aData)
// Return if we overwrote something
PRBool
nsSupportsHashtable::Put (nsHashKey *aKey, nsISupports* aData, nsISupports **value)
{
nsISupports* element = NS_REINTERPRET_CAST(nsISupports*, aData);
NS_IF_ADDREF(element);
return nsHashtable::Put(aKey, aData);
NS_IF_ADDREF(aData);
void *prev = nsHashtable::Put(aKey, aData);
nsISupports *old = NS_REINTERPRET_CAST(nsISupports *, prev);
if (value) // pass own the ownership to the caller
*value = old;
else // the caller doesn't care, we do
NS_IF_RELEASE(old);
return prev != nsnull;
}
void*
nsISupports *
nsSupportsHashtable::Get(nsHashKey *aKey)
{
void* data = nsHashtable::Get(aKey);
@ -414,22 +421,25 @@ nsSupportsHashtable::Get(nsHashKey *aKey)
return nsnull;
nsISupports* element = NS_REINTERPRET_CAST(nsISupports*, data);
NS_IF_ADDREF(element);
return data;
return element;
}
void*
nsSupportsHashtable::Remove(nsHashKey *aKey)
// Return if we found something (useful for checks)
PRBool
nsSupportsHashtable::Remove(nsHashKey *aKey, nsISupports **value)
{
void* data = nsHashtable::Remove(aKey);
if (!data)
return nsnull;
nsISupports* element = NS_STATIC_CAST(nsISupports*, data);
if (value) // caller wants it
*value = element;
else // caller doesn't care, we do
NS_IF_RELEASE(element);
return data;
return data != nsnull;
}
static PRIntn PR_CALLBACK
_hashEnumerateCopy(PLHashEntry *he, PRIntn i, void *arg)
PRIntn PR_CALLBACK
nsSupportsHashtable::EnumerateCopy(PLHashEntry *he, PRIntn i, void *arg)
{
nsHashtable *newHashtable = (nsHashtable *)arg;
nsISupports* element = NS_STATIC_CAST(nsISupports*, he->value);
@ -447,14 +457,14 @@ nsSupportsHashtable::Clone()
nsSupportsHashtable* newHashTable =
new nsSupportsHashtable(hashtable->nentries, threadSafe);
PL_HashTableEnumerateEntries(hashtable, _hashEnumerateCopy, newHashTable);
PL_HashTableEnumerateEntries(hashtable, EnumerateCopy, newHashTable);
return newHashTable;
}
void
nsSupportsHashtable::Reset()
{
Enumerate(_ReleaseElement, nsnull);
Enumerate(ReleaseElement, nsnull);
nsHashtable::Reset();
}

Просмотреть файл

@ -59,7 +59,7 @@ protected:
public:
nsHashtable(PRUint32 aSize = 256, PRBool threadSafe = PR_FALSE);
~nsHashtable();
virtual ~nsHashtable();
PRInt32 Count(void) { return hashtable->nentries; }
PRBool Exists(nsHashKey *aKey);
@ -103,17 +103,41 @@ protected:
////////////////////////////////////////////////////////////////////////////////
// nsSupportsHashtable: an nsHashtable where the elements are nsISupports*
class NS_COM nsSupportsHashtable : public nsHashtable {
class nsISupports;
class NS_COM nsSupportsHashtable
: private nsHashtable
{
public:
typedef PRBool (* PR_CALLBACK EnumFunc) (nsHashKey *aKey, void *aData, void* closure);
nsSupportsHashtable(PRUint32 aSize = 256, PRBool threadSafe = PR_FALSE)
: nsHashtable(aSize, threadSafe) {}
~nsSupportsHashtable();
void *Put(nsHashKey *aKey, void *aData);
void *Get(nsHashKey *aKey);
void *Remove(nsHashKey *aKey);
PRInt32 Count (void)
{
return nsHashtable::Count();
}
PRBool Exists (nsHashKey *aKey)
{
return nsHashtable::Exists (aKey);
}
PRBool Put (nsHashKey *aKey,
nsISupports *aData,
nsISupports **value = NULL);
nsISupports* Get (nsHashKey *aKey);
PRBool Remove (nsHashKey *aKey, nsISupports **value = NULL);
nsHashtable *Clone();
void Enumerate (EnumFunc aEnumFunc, void* closure = NULL)
{
nsHashtable::Enumerate (aEnumFunc, closure);
}
void Reset();
private:
static PRBool PR_CALLBACK ReleaseElement (nsHashKey *, void *, void *);
static PRIntn PR_CALLBACK EnumerateCopy (PLHashEntry *, PRIntn, void *);
};
////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -100,12 +100,11 @@ NS_IMETHODIMP
nsStopwatchService::Define(const char *prop, nsISupports *initialValue)
{
nsStringKey key(prop);
nsCOMPtr<nsIStopwatch> prev = (nsStopwatch*)mStopwatches.Get(&key);
NS_ASSERTION(prev == nsnull, "stopwatch redefinition");
if (prev != nsnull)
if (mStopwatches.Put(&key, initialValue))
{
NS_ASSERTION(0, "stopwatch redefinition");
return NS_ERROR_FAILURE;
mStopwatches.Put(&key, initialValue);
}
return NS_OK;
}
@ -113,12 +112,11 @@ NS_IMETHODIMP
nsStopwatchService::Undefine(const char *prop)
{
nsStringKey key(prop);
nsCOMPtr<nsIStopwatch> prev = (nsStopwatch*)mStopwatches.Get(&key);
NS_ASSERTION(prev != nsnull, "stopwatch undefined");
if (prev == nsnull)
if (!mStopwatches.Remove(&key))
{
NS_ASSERTION(0, "stopwatch undefined");
return NS_ERROR_FAILURE;
mStopwatches.Remove(&key);
}
return NS_OK;
}
@ -137,12 +135,11 @@ NS_IMETHODIMP
nsStopwatchService::Set(const char *prop, nsISupports *value)
{
nsStringKey key(prop);
nsCOMPtr<nsISupports> prev = (nsStopwatch*)mStopwatches.Get(&key);
NS_ASSERTION(prev != nsnull, "stopwatch undefined");
if (prev == nsnull)
if (!mStopwatches.Put(&key, value))
{
NS_ASSERTION (0, "stopwatch undefined");
return NS_ERROR_FAILURE;
mStopwatches.Put(&key, value);
}
return NS_OK;
}

Просмотреть файл

@ -506,8 +506,7 @@ nsDirectoryService::Undefine(const char* prop)
if (!mHashtable->Exists(&key))
return NS_ERROR_FAILURE;
nsISupports* prevValue = (nsISupports*)mHashtable->Remove(&key);
NS_IF_RELEASE(prevValue);
mHashtable->Remove (&key);
return NS_OK;
}
@ -566,7 +565,7 @@ nsDirectoryService::Get(const char* prop, const nsIID & uuid, void* *result)
if (mHashtable->Exists(&key))
{
nsCOMPtr<nsIFile> ourFile;
nsISupports* value = (nsISupports*)mHashtable->Get(&key);
nsCOMPtr<nsISupports> value = getter_AddRefs (mHashtable->Get(&key));
if (value && NS_SUCCEEDED(value->QueryInterface(NS_GET_IID(nsIFile), getter_AddRefs(ourFile))))
{
@ -590,12 +589,9 @@ nsDirectoryService::Set(const char* prop, nsISupports* value)
value->QueryInterface(NS_GET_IID(nsIFile), getter_AddRefs(ourFile));
if (ourFile)
{
nsIFile* cloneFile;
ourFile->Clone(&cloneFile);
nsISupports* prevValue = (nsISupports*)mHashtable->Put(&key,
NS_STATIC_CAST(nsISupports*,cloneFile));
NS_IF_RELEASE(prevValue);
nsCOMPtr<nsIFile> cloneFile;
ourFile->Clone (getter_AddRefs (cloneFile));
mHashtable->Put(&key, cloneFile);
return NS_OK;
}
return NS_ERROR_FAILURE;

Просмотреть файл

@ -53,7 +53,7 @@ class nsDirectoryService : public nsIDirectoryService, public nsIProperties, pub
private:
static nsDirectoryService* mService;
static PRBool PR_CALLBACK ReleaseValues(nsHashKey* key, void* data, void* closure);
nsHashtable* mHashtable;
nsSupportsHashtable* mHashtable;
nsCOMPtr<nsISupportsArray> mProviders;
static nsIAtom *sCurrentProcess;