--- a/browser/components/bookmarks/src/nsBookmarksService.cpp
+++ b/browser/components/bookmarks/src/nsBookmarksService.cpp
@@ -1657,17 +1657,16 @@ BookmarkParser::AssertTime(nsIRDFResourc
}
return rv;
}
////////////////////////////////////////////////////////////////////////
// nsBookmarksService implementation
nsBookmarksService::nsBookmarksService() :
- mInner(nsnull),
mUpdateBatchNest(0),
mBookmarksAvailable(PR_FALSE),
mDirty(PR_FALSE),
mNeedBackupUpdate(PR_FALSE)
{ }
nsBookmarksService::~nsBookmarksService()
{
@@ -1682,17 +1681,16 @@ nsBookmarksService::~nsBookmarksService(
// Unregister ourselves from the RDF service
if (gRDF)
gRDF->UnregisterDataSource(this);
// Note: can't flush in the DTOR, as the RDF service
// has probably already been destroyed
// Flush();
bm_ReleaseGlobals();
- NS_IF_RELEASE(mInner);
}
nsresult
nsBookmarksService::Init()
{
nsresult rv;
rv = bm_AddRefGlobals();
if (NS_FAILED(rv)) return rv;
@@ -2514,52 +2512,43 @@ NS_IMETHODIMP nsBookmarksService::Observ
return rv;
}
////////////////////////////////////////////////////////////////////////
// nsISupports methods
-NS_IMPL_ADDREF(nsBookmarksService)
-
-NS_IMETHODIMP_(nsrefcnt)
-nsBookmarksService::Release()
-{
- // We need a special implementation of Release() because our mInner
- // holds a Circular References back to us.
- NS_PRECONDITION(PRInt32(mRefCnt) > 0, "duplicate release");
- --mRefCnt;
- NS_LOG_RELEASE(this, mRefCnt, "nsBookmarksService");
-
- if (mInner && mRefCnt == 1) {
- nsIRDFDataSource* tmp = mInner;
- mInner = nsnull;
- NS_IF_RELEASE(tmp);
- return 0;
- }
- else if (mRefCnt == 0) {
- delete this;
- return 0;
- }
- else {
- return mRefCnt;
- }
-}
-
-NS_IMPL_QUERY_INTERFACE9(nsBookmarksService,
- nsIBookmarksService,
- nsIRDFDataSource,
- nsIRDFRemoteDataSource,
- nsIRDFObserver,
- nsIStreamListener,
- nsIRequestObserver,
- nsICharsetResolver,
- nsIObserver,
- nsISupportsWeakReference)
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsBookmarksService)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsBookmarksService)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mObservers)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsBookmarksService)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mInner)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mObservers)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsBookmarksService,
+ nsIBookmarksService)
+NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsBookmarksService,
+ nsIBookmarksService)
+
+NS_INTERFACE_MAP_BEGIN(nsBookmarksService)
+ NS_INTERFACE_MAP_ENTRY(nsIBookmarksService)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFRemoteDataSource)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFObserver)
+ NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
+ NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
+ NS_INTERFACE_MAP_ENTRY(nsICharsetResolver)
+ NS_INTERFACE_MAP_ENTRY(nsIObserver)
+ NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIBookmarksService)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsBookmarksService)
+NS_INTERFACE_MAP_END
////////////////////////////////////////////////////////////////////////
// nsIBookmarksService
nsresult
nsBookmarksService::InsertResource(nsIRDFResource* aResource,
nsIRDFResource* aParentFolder, PRInt32 aIndex)
@@ -4590,20 +4579,19 @@ nsBookmarksService::ReadBookmarks(PRBool
return NS_OK;
}
nsresult
nsBookmarksService::InitDataSource()
{
// the profile manager might call Readbookmarks() in certain circumstances
// so we need to forget about any previous bookmarks
- NS_IF_RELEASE(mInner);
-
// don't change this to an xml-ds, it will cause serious perf problems
- nsresult rv = CallCreateInstance(kRDFInMemoryDataSourceCID, &mInner);
+ nsresult rv;
+ mInner = do_CreateInstance(kRDFInMemoryDataSourceCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = mInner->AddObserver(this);
if (NS_FAILED(rv)) return rv;
rv = gRDFC->MakeSeq(mInner, kNC_BookmarksTopRoot, nsnull);
NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to make NC:BookmarksTopRoot a sequence");
if (NS_FAILED(rv)) return rv;
--- a/browser/components/bookmarks/src/nsBookmarksService.h
+++ b/browser/components/bookmarks/src/nsBookmarksService.h
@@ -53,16 +53,17 @@
#include "nsIObserver.h"
#include "nsWeakReference.h"
#include "nsCOMArray.h"
#include "nsIIOService.h"
#include "nsICacheService.h"
#include "nsICacheSession.h"
#include "nsIPrefBranch.h"
#include "nsICharsetResolver.h"
+#include "nsCycleCollectionParticipant.h"
class nsIOutputStream;
#ifdef DEBUG
#ifdef XP_MACOSX
#include <Timer.h>
#endif
#endif
@@ -72,17 +73,17 @@ class nsBookmarksService : public nsIBoo
public nsIRDFRemoteDataSource,
public nsIStreamListener,
public nsICharsetResolver,
public nsIRDFObserver,
public nsIObserver,
public nsSupportsWeakReference
{
protected:
- nsIRDFDataSource* mInner;
+ nsCOMPtr<nsIRDFDataSource> mInner;
nsCOMPtr<nsIRDFResource> busyResource;
nsCOMArray<nsIRDFObserver> mObservers;
nsCOMPtr<nsIStringBundle> mBundle;
nsCOMPtr<nsITimer> mTimer;
nsCOMPtr<nsIIOService> mNetService;
nsCOMPtr<nsICacheService> mCacheService;
nsCOMPtr<nsICacheSession> mCacheSession;
@@ -192,17 +193,19 @@ public:
virtual ~nsBookmarksService();
nsresult Init();
// we really need to figure out our public/private interface story
void RemoveBookmark(nsIRDFResource* aBookmark);
nsresult ClearBookmarksContainer(nsIRDFResource* aContainer);
// nsISupports
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsBookmarksService,
+ nsIBookmarksService)
// nsIBookmarksService
NS_DECL_NSIBOOKMARKSSERVICE
// nsIRDFDataSource
NS_IMETHOD GetURI(char* *uri);
NS_IMETHOD GetSource(nsIRDFResource* property,
--- a/browser/components/bookmarks/src/nsForwardProxyDataSource.cpp
+++ b/browser/components/bookmarks/src/nsForwardProxyDataSource.cpp
@@ -132,65 +132,36 @@ nsForwardProxyDataSource::GetRealSource(
return NS_OK;
}
//----------------------------------------------------------------------
//
// nsISupports interface
//
-NS_IMPL_ADDREF(nsForwardProxyDataSource)
-
-//
-// Use a custom Release() for the same reasons one is used in the
-// Composite DS; we have circular relationships with our child DS.
-
-NS_IMETHODIMP_(nsrefcnt)
-nsForwardProxyDataSource::Release()
-{
- NS_PRECONDITION(PRInt32(mRefCnt) > 0, "duplicate release");
- nsrefcnt count = --mRefCnt;
-
- if (count == 0) {
- NS_LOG_RELEASE(this, count, "nsForwardProxyDataSource");
- mRefCnt = 1;
- NS_DELETEXPCOM(this);
- return 0;
- }
- else if (mDS && (PRInt32(count) == 1)) {
- // if the count is 1, the only ref is from our nested data
- // source, which holds on to us as an observer.
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsForwardProxyDataSource)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsForwardProxyDataSource)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mObservers)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsForwardProxyDataSource)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDS)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mObservers)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
- // We must add 1 here because otherwise the nested releases
- // on this object will enter this same code path.
- ++mRefCnt;
-
- mDS->RemoveObserver(this);
- mDS = nsnull;
-
- // In CompositeDataSource, there's a comment here that we call
- // ourselves again instead of just doing a delete in case
- // something might have added a ref count in the meantime.
- // However, if that happens, this object will be in an
- // inconsistent state, because we'll have removed the Observer
- // from mDS. Hence the assertion.
- NS_ASSERTION(mRefCnt >= 1, "bad mRefCnt");
- return Release();
- }
- else {
- NS_LOG_RELEASE(this, count, "nsForwardProxyDataSource");
- return count;
- }
-}
+NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsForwardProxyDataSource,
+ nsIRDFInferDataSource)
+NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsForwardProxyDataSource,
+ nsIRDFInferDataSource)
NS_INTERFACE_MAP_BEGIN(nsForwardProxyDataSource)
NS_INTERFACE_MAP_ENTRY(nsIRDFInferDataSource)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIRDFDataSource, nsIRDFInferDataSource)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRDFInferDataSource)
NS_INTERFACE_MAP_ENTRY(nsIRDFObserver)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsForwardProxyDataSource)
NS_INTERFACE_MAP_END
//----------------------------------------------------------------------
//
// nsIRDFDataSource interface
//
// methods which need no proxying
--- a/browser/components/bookmarks/src/nsForwardProxyDataSource.h
+++ b/browser/components/bookmarks/src/nsForwardProxyDataSource.h
@@ -37,27 +37,30 @@
#ifndef FORWARDPROXYDATASOURCE___H___
#define FORWARDPROXYDATASOURCE___H___
#include "nsCOMArray.h"
#include "nsIRDFService.h"
#include "nsIRDFInferDataSource.h"
#include "nsIRDFDataSource.h"
+#include "nsCycleCollectionParticipant.h"
class nsForwardProxyDataSource : public nsIRDFInferDataSource,
public nsIRDFObserver
{
public:
nsForwardProxyDataSource();
nsresult Init(void);
// nsISupports interface
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsForwardProxyDataSource,
+ nsIRDFInferDataSource)
// nsIRDFDataSource interface
NS_DECL_NSIRDFDATASOURCE
// nsIRDFObserver interface
NS_DECL_NSIRDFOBSERVER
// nsIRDFInferDataSource interface
--- a/content/xul/templates/src/nsXULTemplateBuilder.cpp
+++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp
@@ -243,18 +243,23 @@ TraverseMatchList(nsISupports* aKey, nsT
cb->NoteXPCOMChild(match->mResult);
match = match->mNext;
}
return PL_DHASH_NEXT;
}
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTemplateBuilder)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsXULTemplateBuilder)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULTemplateBuilder)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDB)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCompDB)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULTemplateBuilder)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDB)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCompDB)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRoot)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRootResult)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mListeners)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mQueryProcessor)
if (tmp->mMatchMap.IsInitialized())
tmp->mMatchMap.EnumerateRead(TraverseMatchList, &cb);
{
PRUint32 i, count = tmp->mQuerySets.Length();
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
+++ b/content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
@@ -124,16 +124,17 @@ RuleToBindingTraverser(nsISupports* key,
NS_STATIC_CAST(nsCycleCollectionTraversalCallback*, userArg);
cb->NoteXPCOMChild(key);
return PL_DHASH_NEXT;
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULTemplateQueryProcessorRDF)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDB)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLastRef)
if (tmp->mBindingDependencies.IsInitialized()) {
tmp->mBindingDependencies.EnumerateRead(BindingDependenciesTraverser,
&cb);
}
if (tmp->mMemoryElementToResultMap.IsInitialized()) {
tmp->mMemoryElementToResultMap.EnumerateRead(MemoryElementTraverser,
&cb);
--- a/rdf/base/src/nsCompositeDataSource.cpp
+++ b/rdf/base/src/nsCompositeDataSource.cpp
@@ -71,16 +71,17 @@
#include "nsIRDFObserver.h"
#include "nsIRDFRemoteDataSource.h"
#include "nsFixedSizeAllocator.h"
#include "nsVoidArray.h"
#include "nsCOMArray.h"
#include "nsArrayEnumerator.h"
#include "nsXPIDLString.h"
#include "rdf.h"
+#include "nsCycleCollectionParticipant.h"
#include "nsEnumeratorUtils.h"
#ifdef NS_DEBUG
#include "prlog.h"
#include "prprf.h"
#include <stdio.h>
PRLogModuleInfo* nsRDFLog = nsnull;
@@ -100,17 +101,19 @@ class CompositeAssertionEnumeratorImpl;
class CompositeDataSourceImpl : public nsIRDFCompositeDataSource,
public nsIRDFObserver
{
public:
CompositeDataSourceImpl(void);
CompositeDataSourceImpl(char** dataSources);
// nsISupports interface
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(CompositeDataSourceImpl,
+ nsIRDFCompositeDataSource)
// nsIRDFDataSource interface
NS_DECL_NSIRDFDATASOURCE
// nsIRDFCompositeDataSource interface
NS_DECL_NSIRDFCOMPOSITEDATASOURCE
// nsIRDFObserver interface
@@ -641,87 +644,44 @@ CompositeDataSourceImpl::CompositeDataSo
#endif
}
//----------------------------------------------------------------------
//
// nsISupports interface
//
-NS_IMPL_THREADSAFE_ADDREF(CompositeDataSourceImpl)
-
-NS_IMETHODIMP_(nsrefcnt)
-CompositeDataSourceImpl::Release()
-{
- // We need a special implementation of Release() because the
- // composite datasource holds a reference to each datasource that
- // it "composes", and each database that the composite datasource
- // observes holds a reference _back_ to the composite datasource.
- NS_PRECONDITION(PRInt32(mRefCnt) > 0, "duplicate release");
- nsrefcnt count =
- PR_AtomicDecrement(NS_REINTERPRET_CAST(PRInt32 *, &mRefCnt));
-
- // When the number of references == the number of datasources,
- // then we know that all that remains are the circular
- // references from those datasources back to us. Release them.
- if (count == 0) {
- NS_LOG_RELEASE(this, count, "CompositeDataSourceImpl");
- mRefCnt = 1;
- NS_DELETEXPCOM(this);
- return 0;
+NS_IMPL_CYCLE_COLLECTION_CLASS(CompositeDataSourceImpl)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CompositeDataSourceImpl)
+ PRUint32 i, count = tmp->mDataSources.Count();
+ for (i = count; i > 0; --i) {
+ tmp->mDataSources[i - 1]->RemoveObserver(tmp);
+ tmp->mDataSources.RemoveObjectAt(i - 1);
}
- else if (PRInt32(count) == mDataSources.Count()) {
- // We must add 1 here because otherwise the nested releases
- // on this object will enter this same code path.
- PR_AtomicIncrement(NS_REINTERPRET_CAST(PRInt32 *, &mRefCnt));
-
- PRInt32 dsCount;
- while (0 != (dsCount = mDataSources.Count())) {
- // Take ref so it won't die before its time.
- nsCOMPtr<nsIRDFDataSource> ds = mDataSources[dsCount-1];
- mDataSources.RemoveObjectAt(dsCount-1);
- ds->RemoveObserver(this);
- }
- // Nest into Release to deal with the one last reference we added above.
- // We don't want to assume that we can 'delete this' because an
- // extra reference might have been added by other code while we were
- // calling out.
- NS_ASSERTION(mRefCnt >= 1, "bad mRefCnt");
- return Release();
- }
- else {
- NS_LOG_RELEASE(this, count, "CompositeDataSourceImpl");
- return count;
- }
-}
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mObservers);
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CompositeDataSourceImpl)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mObservers)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mDataSources)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
-NS_IMETHODIMP
-CompositeDataSourceImpl::QueryInterface(REFNSIID iid, void** result)
-{
- if (! result)
- return NS_ERROR_NULL_POINTER;
+NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(CompositeDataSourceImpl,
+ nsIRDFCompositeDataSource)
+NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(CompositeDataSourceImpl,
+ nsIRDFCompositeDataSource)
- if (iid.Equals(NS_GET_IID(nsIRDFCompositeDataSource)) ||
- iid.Equals(NS_GET_IID(nsIRDFDataSource)) ||
- iid.Equals(kISupportsIID)) {
- *result = NS_STATIC_CAST(nsIRDFCompositeDataSource*, this);
- NS_ADDREF(this);
- return NS_OK;
- }
- else if (iid.Equals(NS_GET_IID(nsIRDFObserver))) {
- *result = NS_STATIC_CAST(nsIRDFObserver*, this);
- NS_ADDREF(this);
- return NS_OK;
- }
- else {
- *result = nsnull;
- return NS_NOINTERFACE;
- }
-}
-
+NS_INTERFACE_MAP_BEGIN(CompositeDataSourceImpl)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFCompositeDataSource)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFObserver)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFCompositeDataSource)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRDFCompositeDataSource)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(CompositeDataSourceImpl)
+NS_INTERFACE_MAP_END
//----------------------------------------------------------------------
//
// nsIRDFDataSource interface
//
NS_IMETHODIMP
--- a/rdf/base/src/nsInMemoryDataSource.cpp
+++ b/rdf/base/src/nsInMemoryDataSource.cpp
@@ -343,17 +343,18 @@ protected:
InMemoryDataSource(nsISupports* aOuter);
virtual ~InMemoryDataSource();
nsresult Init();
friend NS_IMETHODIMP
NS_NewRDFInMemoryDataSource(nsISupports* aOuter, const nsIID& aIID, void** aResult);
public:
- NS_DECL_AGGREGATED
+ NS_DECL_CYCLE_COLLECTING_AGGREGATED
+ NS_DECL_AGGREGATED_CYCLE_COLLECTION_CLASS(InMemoryDataSource)
// nsIRDFDataSource methods
NS_DECL_NSIRDFDATASOURCE
// nsIRDFInMemoryDataSource methods
NS_DECL_NSIRDFINMEMORYDATASOURCE
// nsIRDFPropagatableDataSource methods
@@ -969,23 +970,32 @@ InMemoryDataSource::DeleteForwardArcsEnt
doomed->Release(*allocator);
}
return PL_DHASH_NEXT;
}
////////////////////////////////////////////////////////////////////////
-NS_IMPL_AGGREGATED(InMemoryDataSource)
+NS_IMPL_CYCLE_COLLECTION_CLASS(InMemoryDataSource)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(InMemoryDataSource)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mObservers)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_AGGREGATED(InMemoryDataSource)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mObservers)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTING_AGGREGATED(InMemoryDataSource)
NS_INTERFACE_MAP_BEGIN_AGGREGATED(InMemoryDataSource)
NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
NS_INTERFACE_MAP_ENTRY(nsIRDFInMemoryDataSource)
NS_INTERFACE_MAP_ENTRY(nsIRDFPropagatableDataSource)
NS_INTERFACE_MAP_ENTRY(nsIRDFPurgeableDataSource)
NS_INTERFACE_MAP_ENTRY(rdfIDataSource)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION_AGGREGATED(InMemoryDataSource)
NS_INTERFACE_MAP_END
////////////////////////////////////////////////////////////////////////
#ifdef PR_LOGGING
void
InMemoryDataSource::LogOperation(const char* aOperation,
--- a/rdf/base/src/nsRDFXMLDataSource.cpp
+++ b/rdf/base/src/nsRDFXMLDataSource.cpp
@@ -117,16 +117,17 @@
#include "plstr.h"
#include "prio.h"
#include "prthread.h"
#include "rdf.h"
#include "rdfutil.h"
#include "prlog.h"
#include "nsNameSpaceMap.h"
#include "nsCRT.h"
+#include "nsCycleCollectionParticipant.h"
#include "rdfIDataSource.h"
//----------------------------------------------------------------------
static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID);
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
@@ -149,17 +150,17 @@ class RDFXMLDataSourceImpl : public nsIR
protected:
enum LoadState {
eLoadState_Unloaded,
eLoadState_Pending,
eLoadState_Loading,
eLoadState_Loaded
};
- nsIRDFDataSource* mInner; // OWNER
+ nsCOMPtr<nsIRDFDataSource> mInner;
PRPackedBool mIsWritable; // true if the document can be written back
PRPackedBool mIsDirty; // true if the document should be written back
LoadState mLoadState; // what we're doing now
nsCOMArray<nsIRDFXMLSinkObserver> mObservers;
nsCOMPtr<nsIURI> mURL;
nsCOMPtr<nsIStreamListener> mListener;
nsNameSpaceMap mNameSpaces;
@@ -177,17 +178,19 @@ protected:
inline PRBool IsLoading() {
return (mLoadState == eLoadState_Pending) ||
(mLoadState == eLoadState_Loading);
}
public:
// nsISupports
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(RDFXMLDataSourceImpl,
+ nsIRDFDataSource)
// nsIRDFDataSource
NS_IMETHOD GetURI(char* *uri);
NS_IMETHOD GetSource(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFResource** source) {
@@ -408,33 +411,32 @@ NS_NewRDFXMLDataSource(nsIRDFDataSource*
NS_ADDREF(datasource);
*aResult = datasource;
return NS_OK;
}
RDFXMLDataSourceImpl::RDFXMLDataSourceImpl(void)
- : mInner(nsnull),
- mIsWritable(PR_TRUE),
+ : mIsWritable(PR_TRUE),
mIsDirty(PR_FALSE),
mLoadState(eLoadState_Unloaded)
{
#ifdef PR_LOGGING
if (! gLog)
gLog = PR_NewLogModule("nsRDFXMLDataSource");
#endif
}
nsresult
RDFXMLDataSourceImpl::Init()
{
nsresult rv;
- rv = CallCreateInstance(kRDFInMemoryDataSourceCID, &mInner);
+ mInner = do_CreateInstance(kRDFInMemoryDataSourceCID, &rv);
if (NS_FAILED(rv)) return rv;
if (gRefCnt++ == 0) {
rv = CallGetService(kRDFServiceCID, &gRDFService);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get RDF service");
if (NS_FAILED(rv)) return rv;
}
@@ -451,31 +453,42 @@ RDFXMLDataSourceImpl::~RDFXMLDataSourceI
rv = gRDFService->UnregisterDataSource(this);
// Now flush contents
rv = Flush();
// Release RDF/XML sink observers
mObservers.Clear();
- NS_RELEASE(mInner);
-
if (--gRefCnt == 0)
NS_IF_RELEASE(gRDFService);
}
+NS_IMPL_CYCLE_COLLECTION_CLASS(RDFXMLDataSourceImpl)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_0(RDFXMLDataSourceImpl)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(RDFXMLDataSourceImpl)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mInner)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-NS_IMPL_ISUPPORTS7(RDFXMLDataSourceImpl,
- nsIRDFDataSource,
- nsIRDFRemoteDataSource,
- nsIRDFXMLSink,
- nsIRDFXMLSource,
- nsIRequestObserver,
- nsIStreamListener,
- rdfIDataSource)
+NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(RDFXMLDataSourceImpl,
+ nsIRDFDataSource)
+NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(RDFXMLDataSourceImpl,
+ nsIRDFDataSource)
+
+NS_INTERFACE_MAP_BEGIN(RDFXMLDataSourceImpl)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFRemoteDataSource)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFXMLSink)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFXMLSource)
+ NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
+ NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
+ NS_INTERFACE_MAP_ENTRY(rdfIDataSource)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRDFDataSource)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(RDFXMLDataSourceImpl)
+NS_INTERFACE_MAP_END
nsresult
RDFXMLDataSourceImpl::BlockingParse(nsIURI* aURL, nsIStreamListener* aConsumer)
{
nsresult rv;
// XXX I really hate the way that we're spoon-feeding this stuff
--- a/rdf/chrome/src/nsChromeUIDataSource.cpp
+++ b/rdf/chrome/src/nsChromeUIDataSource.cpp
@@ -75,40 +75,40 @@ nsChromeUIDataSource::nsChromeUIDataSour
nsChromeUIDataSource::~nsChromeUIDataSource()
{
mRDFService->UnregisterDataSource(this);
NS_IF_RELEASE(mRDFService);
}
-// we require a special implementation of Release, which knows about
-// a circular strong reference
-NS_IMPL_ADDREF(nsChromeUIDataSource)
-NS_IMPL_QUERY_INTERFACE2(nsChromeUIDataSource, nsIRDFDataSource, nsIRDFObserver)
-
-NS_IMETHODIMP_(nsrefcnt)
-nsChromeUIDataSource::Release()
-{
- NS_PRECONDITION(PRInt32(mRefCnt) > 0, "duplicate release");
- --mRefCnt;
- NS_LOG_RELEASE(this, mRefCnt, "nsChromeUIDataSource");
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsChromeUIDataSource)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsChromeUIDataSource)
+ if (tmp->mComposite) {
+ tmp->mComposite->RemoveObserver(tmp);
+ tmp->mComposite = nsnull;
+ }
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mObservers);
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsChromeUIDataSource)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mComposite)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mObservers)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
- // delete if the last reference is our strong circular reference
- if (mComposite && PRInt32(mRefCnt) == 1) {
- mComposite->RemoveObserver(this);
- return 0;
- }
- else if (mRefCnt == 0) {
- delete this;
- return 0;
- }
- return mRefCnt;
-}
+NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsChromeUIDataSource,
+ nsIRDFDataSource)
+NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsChromeUIDataSource,
+ nsIRDFDataSource)
+NS_INTERFACE_MAP_BEGIN(nsChromeUIDataSource)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFObserver)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRDFDataSource)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsChromeUIDataSource)
+NS_INTERFACE_MAP_END
//----------------------------------------------------------------------
//
// nsIRDFDataSource interface
//
NS_IMETHODIMP
nsChromeUIDataSource::GetURI(char** aURI)
--- a/rdf/chrome/src/nsChromeUIDataSource.h
+++ b/rdf/chrome/src/nsChromeUIDataSource.h
@@ -43,21 +43,24 @@ class nsISimpleEnumerator;
class nsSupportsHashtable;
class nsIRDFContainer;
class nsIDOMWindowInternal;
class nsIDocument;
#include "nsIRDFDataSource.h"
#include "nsIRDFObserver.h"
#include "nsCOMArray.h"
+#include "nsCycleCollectionParticipant.h"
class nsChromeUIDataSource : public nsIRDFDataSource, public nsIRDFObserver
{
public:
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsChromeUIDataSource,
+ nsIRDFDataSource)
// nsIRDFDataSource methods
NS_DECL_NSIRDFDATASOURCE
// nsIRDFObserver methods
NS_DECL_NSIRDFOBSERVER
// nsChromeUIDataSource methods:
--- a/rdf/datasource/src/nsFileSystemDataSource.cpp
+++ b/rdf/datasource/src/nsFileSystemDataSource.cpp
@@ -818,44 +818,25 @@ FileSystemDataSource::GetAllResources(ns
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
FileSystemDataSource::AddObserver(nsIRDFObserver *n)
{
- NS_PRECONDITION(n != nsnull, "null ptr");
- if (! n)
- return NS_ERROR_NULL_POINTER;
-
- if (! mObservers)
- {
- nsresult rv;
- rv = NS_NewISupportsArray(getter_AddRefs(mObservers));
- if (NS_FAILED(rv)) return rv;
- }
- mObservers->AppendElement(n);
- return NS_OK;
+ return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
FileSystemDataSource::RemoveObserver(nsIRDFObserver *n)
{
- NS_PRECONDITION(n != nsnull, "null ptr");
- if (! n)
- return NS_ERROR_NULL_POINTER;
-
- if (! mObservers)
- return NS_OK;
-
- mObservers->RemoveElement(n);
- return NS_OK;
+ return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
FileSystemDataSource::GetAllCmds(nsIRDFResource* source,
nsISimpleEnumerator/*<nsIRDFResource>*/** commands)
{
--- a/rdf/datasource/src/nsFileSystemDataSource.h
+++ b/rdf/datasource/src/nsFileSystemDataSource.h
@@ -71,17 +71,16 @@ private:
PRBool isDirURI(nsIRDFResource* aSource);
nsresult GetVolumeList(nsISimpleEnumerator **aResult);
nsresult GetFolderList(nsIRDFResource *source, PRBool allowHidden, PRBool onlyFirst, nsISimpleEnumerator **aResult);
nsresult GetName(nsIRDFResource *source, nsIRDFLiteral** aResult);
nsresult GetURL(nsIRDFResource *source, PRBool *isFavorite, nsIRDFLiteral** aResult);
nsresult GetFileSize(nsIRDFResource *source, nsIRDFInt** aResult);
nsresult GetLastMod(nsIRDFResource *source, nsIRDFDate** aResult);
- nsCOMPtr<nsISupportsArray> mObservers;
nsCOMPtr<nsIRDFService> mRDFService;
// pseudo-constants
nsCOMPtr<nsIRDFResource> mNC_FileSystemRoot;
nsCOMPtr<nsIRDFResource> mNC_Child;
nsCOMPtr<nsIRDFResource> mNC_Name;
nsCOMPtr<nsIRDFResource> mNC_URL;
nsCOMPtr<nsIRDFResource> mNC_Icon;
--- a/rdf/datasource/src/nsLocalStore.cpp
+++ b/rdf/datasource/src/nsLocalStore.cpp
@@ -80,17 +80,16 @@ protected:
LocalStoreImpl();
virtual ~LocalStoreImpl();
nsresult Init();
nsresult LoadData();
friend NS_IMETHODIMP
NS_NewLocalStore(nsISupports* aOuter, REFNSIID aIID, void** aResult);
- nsCOMPtr<nsISupportsArray> mObservers;
nsCOMPtr<nsIRDFService> mRDFService;
public:
// nsISupports interface
NS_DECL_ISUPPORTS
// nsILocalStore interface
@@ -157,33 +156,21 @@ public:
nsIRDFResource* aProperty,
nsIRDFNode* aTarget,
PRBool aTruthValue,
PRBool* hasAssertion) {
return mInner->HasAssertion(aSource, aProperty, aTarget, aTruthValue, hasAssertion);
}
NS_IMETHOD AddObserver(nsIRDFObserver* aObserver) {
- // Observers are _never_ notified, but we still have to play
- // nice.
- if (! mObservers) {
- nsresult rv;
- rv = NS_NewISupportsArray(getter_AddRefs(mObservers));
- if (NS_FAILED(rv)) return rv;
- }
-
- mObservers->AppendElement(aObserver);
- return NS_OK;
+ return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD RemoveObserver(nsIRDFObserver* aObserver) {
- if (mObservers) {
- mObservers->RemoveElement(aObserver);
- }
- return NS_OK;
+ return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, PRBool *_retval) {
return mInner->HasArcIn(aNode, aArc, _retval);
}
NS_IMETHOD HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, PRBool *_retval) {
return mInner->HasArcOut(aSource, aArc, _retval);
--- a/toolkit/components/downloads/src/nsDownloadManager.cpp
+++ b/toolkit/components/downloads/src/nsDownloadManager.cpp
@@ -1581,17 +1581,34 @@ nsXPIProgressListener::AssertProgressInf
// XXXben I'm making this datasource proxy its own object now and passing
// IconURL requests through it so that the framework is in place by
// 0.9 when the time comes to upgrade to the Magical World of Mork.
//
// Eventually I want to abstract away almost all direct dealings with
// this datasource into functions on this object, to simplify the
// code in the download manager service and front end.
-NS_IMPL_ISUPPORTS2(nsDownloadsDataSource, nsIRDFDataSource, nsIRDFRemoteDataSource)
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsDownloadsDataSource)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsDownloadsDataSource)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDownloadsDataSource)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mInner)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsDownloadsDataSource,
+ nsIRDFDataSource)
+NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsDownloadsDataSource,
+ nsIRDFDataSource)
+
+NS_INTERFACE_MAP_BEGIN(nsDownloadsDataSource)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFRemoteDataSource)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRDFDataSource)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsDownloadsDataSource)
+NS_INTERFACE_MAP_END
nsresult
nsDownloadsDataSource::LoadDataSource()
{
nsCOMPtr<nsIFile> downloadsFile;
nsresult rv = NS_GetSpecialDirectory(NS_APP_DOWNLOADS_50_FILE, getter_AddRefs(downloadsFile));
if (NS_FAILED(rv)) return rv;
--- a/toolkit/components/downloads/src/nsDownloadManager.h
+++ b/toolkit/components/downloads/src/nsDownloadManager.h
@@ -60,16 +60,17 @@
#include "nsIRequest.h"
#include "nsIObserver.h"
#include "nsIStringBundle.h"
#include "nsISupportsPrimitives.h"
#include "nsIProgressDialog.h"
#include "nsIMIMEInfo.h"
#include "nsITimer.h"
#include "nsIAlertsService.h"
+#include "nsCycleCollectionParticipant.h"
typedef PRInt16 DownloadState;
typedef PRInt16 DownloadType;
class nsXPIProgressListener;
class nsDownload;
class nsDownloadManager : public nsIDownloadManager,
@@ -177,17 +178,19 @@ private:
};
class nsDownloadsDataSource : public nsIRDFDataSource,
public nsIRDFRemoteDataSource
{
public:
NS_DECL_NSIRDFDATASOURCE
NS_DECL_NSIRDFREMOTEDATASOURCE
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDownloadsDataSource,
+ nsIRDFDataSource)
nsDownloadsDataSource() { };
virtual ~nsDownloadsDataSource() { };
nsresult LoadDataSource();
private:
nsCOMPtr<nsIRDFDataSource> mInner;
--- a/toolkit/components/history/src/nsGlobalHistory.cpp
+++ b/toolkit/components/history/src/nsGlobalHistory.cpp
@@ -542,29 +542,39 @@ nsGlobalHistory::~nsGlobalHistory()
//----------------------------------------------------------------------
//
// nsGlobalHistory
//
// nsISupports methods
-NS_IMPL_ADDREF(nsGlobalHistory)
-NS_IMPL_RELEASE(nsGlobalHistory)
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalHistory)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalHistory)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mObservers)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGlobalHistory)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mObservers)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsGlobalHistory, nsIBrowserHistory)
+NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsGlobalHistory, nsIBrowserHistory)
NS_INTERFACE_MAP_BEGIN(nsGlobalHistory)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIGlobalHistory2, nsIGlobalHistory3)
NS_INTERFACE_MAP_ENTRY(nsIGlobalHistory3)
NS_INTERFACE_MAP_ENTRY(nsIBrowserHistory)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
NS_INTERFACE_MAP_ENTRY(nsIRDFRemoteDataSource)
NS_INTERFACE_MAP_ENTRY(nsIAutoCompleteSearch)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIBrowserHistory)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsGlobalHistory)
NS_INTERFACE_MAP_END
//----------------------------------------------------------------------
//
// nsGlobalHistory
//
// nsIGlobalHistory2 methods
//
@@ -2291,36 +2301,28 @@ nsGlobalHistory::HasAssertion(nsIRDFReso
NS_IMETHODIMP
nsGlobalHistory::AddObserver(nsIRDFObserver* aObserver)
{
NS_PRECONDITION(aObserver != nsnull, "null ptr");
if (! aObserver)
return NS_ERROR_NULL_POINTER;
- if (! mObservers) {
- nsresult rv;
- rv = NS_NewISupportsArray(getter_AddRefs(mObservers));
- if (NS_FAILED(rv)) return rv;
- }
- mObservers->AppendElement(aObserver);
+ mObservers.AppendObject(aObserver);
return NS_OK;
}
NS_IMETHODIMP
nsGlobalHistory::RemoveObserver(nsIRDFObserver* aObserver)
{
NS_PRECONDITION(aObserver != nsnull, "null ptr");
if (! aObserver)
return NS_ERROR_NULL_POINTER;
- if (! mObservers)
- return NS_OK;
-
- mObservers->RemoveElement(aObserver);
+ mObservers.RemoveObject(aObserver);
return NS_OK;
}
NS_IMETHODIMP
nsGlobalHistory::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, PRBool *result)
{
NS_PRECONDITION(aNode != nsnull, "null ptr");
@@ -2482,65 +2484,33 @@ nsGlobalHistory::GetAllResources(nsISimp
NS_IMETHODIMP
nsGlobalHistory::BeginUpdateBatch()
{
nsresult rv = NS_OK;
++mBatchesInProgress;
- // we could call mObservers->EnumerateForwards() here
- // to save the addref/release on each observer, but
- // it's unlikely that anyone but the tree builder
- // is observing us
- if (mObservers) {
- PRUint32 count;
- rv = mObservers->Count(&count);
- if (NS_FAILED(rv)) return rv;
-
- for (PRInt32 i = 0; i < PRInt32(count); ++i) {
- nsIRDFObserver* observer = NS_STATIC_CAST(nsIRDFObserver*, mObservers->ElementAt(i));
-
- NS_ASSERTION(observer != nsnull, "null ptr");
- if (! observer)
- continue;
-
- rv = observer->OnBeginUpdateBatch(this);
- NS_RELEASE(observer);
- }
+ PRUint32 i = mObservers.Length();
+ while (i > 0) {
+ rv = mObservers[i--]->OnBeginUpdateBatch(this);
}
return rv;
}
NS_IMETHODIMP
nsGlobalHistory::EndUpdateBatch()
{
nsresult rv = NS_OK;
--mBatchesInProgress;
- // we could call mObservers->EnumerateForwards() here
- // to save the addref/release on each observer, but
- // it's unlikely that anyone but the tree builder
- // is observing us
- if (mObservers) {
- PRUint32 count;
- rv = mObservers->Count(&count);
- if (NS_FAILED(rv)) return rv;
-
- for (PRInt32 i = 0; i < PRInt32(count); ++i) {
- nsIRDFObserver* observer = NS_STATIC_CAST(nsIRDFObserver*, mObservers->ElementAt(i));
-
- NS_ASSERTION(observer != nsnull, "null ptr");
- if (! observer)
- continue;
-
- rv = observer->OnEndUpdateBatch(this);
- NS_RELEASE(observer);
- }
+ PRUint32 i = mObservers.Length();
+ while (i > 0) {
+ rv = mObservers[i--]->OnEndUpdateBatch(this);
}
return rv;
}
////////////////////////////////////////////////////////////////////////
// nsIRDFRemoteDataSource
@@ -3204,91 +3174,49 @@ nsGlobalHistory::IsURLInHistory(nsIRDFRe
}
nsresult
nsGlobalHistory::NotifyAssert(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aValue)
{
- nsresult rv;
-
- if (mObservers) {
- PRUint32 count;
- rv = mObservers->Count(&count);
- if (NS_FAILED(rv)) return rv;
-
- for (PRInt32 i = 0; i < PRInt32(count); ++i) {
- nsIRDFObserver* observer = NS_STATIC_CAST(nsIRDFObserver*, mObservers->ElementAt(i));
-
- NS_ASSERTION(observer != nsnull, "null ptr");
- if (! observer)
- continue;
-
- rv = observer->OnAssert(this, aSource, aProperty, aValue);
- NS_RELEASE(observer);
- }
+ PRUint32 i = mObservers.Length();
+ while (i > 0) {
+ mObservers[i--]->OnAssert(this, aSource, aProperty, aValue);
}
return NS_OK;
}
nsresult
nsGlobalHistory::NotifyUnassert(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aValue)
{
- nsresult rv;
-
- if (mObservers) {
- PRUint32 count;
- rv = mObservers->Count(&count);
- if (NS_FAILED(rv)) return rv;
-
- for (PRInt32 i = 0; i < PRInt32(count); ++i) {
- nsIRDFObserver* observer = NS_STATIC_CAST(nsIRDFObserver*, mObservers->ElementAt(i));
-
- NS_ASSERTION(observer != nsnull, "null ptr");
- if (! observer)
- continue;
-
- rv = observer->OnUnassert(this, aSource, aProperty, aValue);
- NS_RELEASE(observer);
- }
+ PRUint32 i = mObservers.Length();
+ while (i > 0) {
+ mObservers[i--]->OnUnassert(this, aSource, aProperty, aValue);
}
return NS_OK;
}
nsresult
nsGlobalHistory::NotifyChange(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aOldValue,
nsIRDFNode* aNewValue)
{
- nsresult rv;
-
- if (mObservers) {
- PRUint32 count;
- rv = mObservers->Count(&count);
- if (NS_FAILED(rv)) return rv;
-
- for (PRInt32 i = 0; i < PRInt32(count); ++i) {
- nsIRDFObserver* observer = NS_STATIC_CAST(nsIRDFObserver*, mObservers->ElementAt(i));
-
- NS_ASSERTION(observer != nsnull, "null ptr");
- if (! observer)
- continue;
-
- rv = observer->OnChange(this, aSource, aProperty, aOldValue, aNewValue);
- NS_RELEASE(observer);
- }
+ PRUint32 i = mObservers.Length();
+ while (i > 0) {
+ mObservers[i--]->OnChange(this, aSource, aProperty, aOldValue, aNewValue);
}
return NS_OK;
}
//
// this just generates a static list of find-style queries
// only returns queries that currently have matches in global history
--- a/toolkit/components/history/src/nsGlobalHistory.h
+++ b/toolkit/components/history/src/nsGlobalHistory.h
@@ -56,16 +56,18 @@
#include "nsHashtable.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsITimer.h"
#include "nsIAutoCompleteSearch.h"
#include "nsIAutoCompleteResult.h"
#include "nsIAutoCompleteResultTypes.h"
#include "nsHashSets.h"
+#include "nsCOMArray.h"
+#include "nsCycleCollectionParticipant.h"
//----------------------------------------------------------------------
//
// nsMdbTableEnumerator
//
// An nsISimpleEnumerator implementation that returns the value of
// a column as an nsISupports. Allows for some simple selection.
//
@@ -132,17 +134,19 @@ class nsGlobalHistory : nsSupportsWeakRe
public nsIObserver,
public nsIRDFDataSource,
public nsIRDFRemoteDataSource,
public nsIAutoCompleteSearch,
public nsIGlobalHistory3
{
public:
// nsISupports methods
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsGlobalHistory,
+ nsIBrowserHistory)
NS_DECL_NSIGLOBALHISTORY2
NS_DECL_NSIGLOBALHISTORY3
NS_DECL_NSIBROWSERHISTORY
NS_DECL_NSIOBSERVER
NS_DECL_NSIRDFDATASOURCE
NS_DECL_NSIRDFREMOTEDATASOURCE
NS_DECL_NSIAUTOCOMPLETESEARCH
@@ -261,17 +265,17 @@ protected:
nsresult SetDirty();
static void fireSyncTimer(nsITimer *aTimer, void *aClosure)
{((nsGlobalHistory *)aClosure)->Sync(); }
//
// RDF stuff
//
- nsCOMPtr<nsISupportsArray> mObservers;
+ nsCOMArray<nsIRDFObserver> mObservers;
PRBool IsURLInHistory(nsIRDFResource* aResource);
nsresult NotifyAssert(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aValue);
nsresult NotifyUnassert(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aValue);
nsresult NotifyChange(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aOldValue, nsIRDFNode* aNewValue);
//
--- a/xpcom/base/nsAgg.h
+++ b/xpcom/base/nsAgg.h
@@ -34,37 +34,50 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsAgg_h___
#define nsAgg_h___
#include "nsISupports.h"
+#include "nsCycleCollectionParticipant.h"
////////////////////////////////////////////////////////////////////////////////
-// Put this in your class's declaration:
+// Put NS_DECL_AGGREGATED or NS_DECL_CYCLE_COLLECTING_AGGREGATED in your class's
+// declaration.
#define NS_DECL_AGGREGATED \
NS_DECL_ISUPPORTS \
- \
+ NS_DECL_AGGREGATED_HELPER
+
+#define NS_DECL_CYCLE_COLLECTING_AGGREGATED \
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS \
+ NS_DECL_AGGREGATED_HELPER
+
+#define NS_DECL_AGGREGATED_HELPER \
public: \
\
/** \
* Returns the nsISupports pointer of the inner object (aka the \
* aggregatee). This pointer is really only useful to the outer object \
* (aka the aggregator), which can use it to hold on to the inner \
* object. Anything else wants the nsISupports pointer of the outer \
* object (gotten by QI'ing inner or outer to nsISupports). This method \
* returns a non-addrefed pointer. \
* @return the nsISupports pointer of the inner object \
*/ \
nsISupports* InnerObject(void) { return &fAggregated; } \
\
+ /** \
+ * Returns PR_TRUE if this object is part of an aggregated object. \
+ */ \
+ PRBool IsPartOfAggregated(void) { return fOuter != InnerObject(); } \
+ \
private: \
\
/* You must implement this operation instead of the nsISupports */ \
/* methods. */ \
nsresult \
AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr); \
\
class Internal : public nsISupports { \
@@ -80,50 +93,49 @@ private:
\
friend class Internal; \
\
nsISupports* fOuter; \
Internal fAggregated; \
\
public: \
+#define NS_DECL_AGGREGATED_CYCLE_COLLECTION_CLASS(_class) \
+class NS_CYCLE_COLLECTION_INNERCLASS \
+ : public nsCycleCollectionParticipant \
+{ \
+public: \
+ NS_IMETHOD Unlink(nsISupports *p); \
+ NS_IMETHOD Traverse(nsISupports *p, \
+ nsCycleCollectionTraversalCallback &cb); \
+ NS_IMETHOD_(void) UnmarkPurple(nsISupports *p) \
+ { \
+ Downcast(p)->UnmarkPurple(); \
+ } \
+ static _class* Downcast(nsISupports* s) \
+ { \
+ return (_class*)((char*)(s) - offsetof(_class, fAggregated)); \
+ } \
+ static nsISupports* Upcast(_class *p) \
+ { \
+ return p->InnerObject(); \
+ } \
+};
// Put this in your class's constructor:
#define NS_INIT_AGGREGATED(outer) \
PR_BEGIN_MACRO \
fOuter = outer ? outer : &fAggregated; \
PR_END_MACRO
// Put this in your class's implementation file:
#define NS_IMPL_AGGREGATED(_class) \
-NS_IMETHODIMP \
-_class::QueryInterface(const nsIID& aIID, void** aInstancePtr) \
-{ \
- return fOuter->QueryInterface(aIID, aInstancePtr); \
-} \
\
-NS_IMETHODIMP_(nsrefcnt) \
-_class::AddRef(void) \
-{ \
- return fOuter->AddRef(); \
-} \
- \
-NS_IMETHODIMP_(nsrefcnt) \
-_class::Release(void) \
-{ \
- return fOuter->Release(); \
-} \
- \
-NS_IMETHODIMP \
-_class::Internal::QueryInterface(const nsIID& aIID, void** aInstancePtr) \
-{ \
- _class* agg = (_class*)((char*)(this) - offsetof(_class, fAggregated)); \
- return agg->AggregatedQueryInterface(aIID, aInstancePtr); \
-} \
+NS_IMPL_AGGREGATED_HELPER(_class) \
\
NS_IMETHODIMP_(nsrefcnt) \
_class::Internal::AddRef(void) \
{ \
_class* agg = (_class*)((char*)(this) - offsetof(_class, fAggregated)); \
NS_PRECONDITION(PRInt32(agg->mRefCnt) >= 0, "illegal refcnt"); \
++agg->mRefCnt; \
NS_LOG_ADDREF(this, agg->mRefCnt, #_class, sizeof(*this)); \
@@ -140,34 +152,165 @@ NS_IMETHODIMP_(nsrefcnt)
if (agg->mRefCnt == 0) { \
agg->mRefCnt = 1; /* stabilize */ \
NS_DELETEXPCOM(agg); \
return 0; \
} \
return agg->mRefCnt; \
} \
+#define NS_IMPL_CYCLE_COLLECTING_AGGREGATED(_class) \
+ \
+NS_IMPL_AGGREGATED_HELPER(_class) \
+ \
+NS_IMETHODIMP_(nsrefcnt) \
+_class::Internal::AddRef(void) \
+{ \
+ _class* agg = NS_CYCLE_COLLECTION_CLASSNAME(_class)::Downcast(this); \
+ NS_PRECONDITION(PRInt32(agg->mRefCnt) >= 0, "illegal refcnt"); \
+ NS_CheckThreadSafe(agg->_mOwningThread.GetThread(), \
+ #_class " not thread-safe"); \
+ nsrefcnt count = agg->mRefCnt.incr(this); \
+ NS_LOG_ADDREF(this, count, #_class, sizeof(*agg)); \
+ return count; \
+} \
+ \
+NS_IMETHODIMP_(nsrefcnt) \
+_class::Internal::Release(void) \
+{ \
+ _class* agg = NS_CYCLE_COLLECTION_CLASSNAME(_class)::Downcast(this); \
+ NS_PRECONDITION(0 != agg->mRefCnt, "dup release"); \
+ NS_CheckThreadSafe(agg->_mOwningThread.GetThread(), \
+ #_class " not thread-safe"); \
+ nsrefcnt count = agg->mRefCnt.decr(this); \
+ NS_LOG_RELEASE(this, count, #_class); \
+ if (count == 0) { \
+ agg->mRefCnt.stabilizeForDeletion(this); \
+ NS_DELETEXPCOM(agg); \
+ return 0; \
+ } \
+ return count; \
+}
+
+#define NS_IMPL_AGGREGATED_HELPER(_class) \
+NS_IMETHODIMP \
+_class::QueryInterface(const nsIID& aIID, void** aInstancePtr) \
+{ \
+ return fOuter->QueryInterface(aIID, aInstancePtr); \
+} \
+ \
+NS_IMETHODIMP_(nsrefcnt) \
+_class::AddRef(void) \
+{ \
+ return fOuter->AddRef(); \
+} \
+ \
+NS_IMETHODIMP_(nsrefcnt) \
+_class::Release(void) \
+{ \
+ return fOuter->Release(); \
+} \
+ \
+NS_IMETHODIMP \
+_class::Internal::QueryInterface(const nsIID& aIID, void** aInstancePtr) \
+{ \
+ _class* agg = (_class*)((char*)(this) - offsetof(_class, fAggregated)); \
+ return agg->AggregatedQueryInterface(aIID, aInstancePtr); \
+} \
+
+/**
+ * To make aggregated objects participate in cycle collection we need to enable
+ * the outer object (aggregator) to traverse/unlink the objects held by the
+ * inner object (the aggregatee). We can't just make the inner object QI'able to
+ * NS_CYCLECOLLECTIONPARTICIPANT_IID, we don't want to return the inner object's
+ * nsCycleCollectionParticipant for the outer object (which will happen if the
+ * outer object doesn't participate in cycle collection itself).
+ * NS_AGGREGATED_CYCLECOLLECTIONPARTICIPANT_IID enables the outer object to get
+ * the inner objects nsCycleCollectionParticipant.
+ *
+ * There are three cases:
+ * - No aggregation
+ * QI'ing to NS_CYCLECOLLECTIONPARTICIPANT_IID will return the inner
+ * object's nsCycleCollectionParticipant.
+ *
+ * - Aggregation and outer object does not participate in cycle collection
+ * QI'ing to NS_CYCLECOLLECTIONPARTICIPANT_IID will not return anything.
+ *
+ * - Aggregation and outer object does participate in cycle collection
+ * QI'ing to NS_CYCLECOLLECTIONPARTICIPANT_IID will return the outer
+ * object's nsCycleCollectionParticipant. The outer object's
+ * nsCycleCollectionParticipant can then QI the inner object to
+ * NS_AGGREGATED_CYCLECOLLECTIONPARTICIPANT_IID to get the inner object's
+ * nsCycleCollectionParticipant, which it can use to traverse/unlink the
+ * objects reachable from the inner object.
+ */
+#define NS_AGGREGATED_CYCLECOLLECTIONPARTICIPANT_IID \
+{ \
+ 0x32889b7e, \
+ 0xe4fe, \
+ 0x43f4, \
+ { 0x85, 0x31, 0xb5, 0x28, 0x23, 0xa2, 0xe9, 0xfc } \
+}
+
+/**
+ * Just holds the IID so NS_GET_IID works.
+ */
+class nsAggregatedCycleCollectionParticipant
+{
+public:
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_AGGREGATED_CYCLECOLLECTIONPARTICIPANT_IID)
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsAggregatedCycleCollectionParticipant,
+ NS_AGGREGATED_CYCLECOLLECTIONPARTICIPANT_IID)
+
// for use with QI macros in nsISupportsUtils.h:
#define NS_INTERFACE_MAP_BEGIN_AGGREGATED(_class) \
NS_IMPL_AGGREGATED_QUERY_HEAD(_class)
+#define NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION_AGGREGATED(_class) \
+ NS_IMPL_QUERY_CYCLE_COLLECTION(_class)
+
+#define NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION_AGGREGATED(_class) \
+ NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION_AGGREGATED(_class) \
+ NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION_ISUPPORTS(_class)
+
#define NS_IMPL_AGGREGATED_QUERY_HEAD(_class) \
nsresult \
_class::AggregatedQueryInterface(REFNSIID aIID, void** aInstancePtr) \
{ \
NS_ASSERTION(aInstancePtr, \
"AggregatedQueryInterface requires a non-NULL result ptr!"); \
if ( !aInstancePtr ) \
return NS_ERROR_NULL_POINTER; \
nsISupports* foundInterface; \
if ( aIID.Equals(NS_GET_IID(nsISupports)) ) \
foundInterface = InnerObject(); \
else
+#define NS_IMPL_AGGREGATED_QUERY_CYCLE_COLLECTION(_class) \
+ if (aIID.Equals(IsPartOfAggregated() ? \
+ NS_GET_IID(nsCycleCollectionParticipant) : \
+ NS_GET_IID(nsAggregatedCycleCollectionParticipant))) \
+ foundInterface = & NS_CYCLE_COLLECTION_NAME(_class); \
+ else
+
+#define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_AGGREGATED(_class) \
+ NS_IMETHODIMP \
+ NS_CYCLE_COLLECTION_CLASSNAME(_class)::Traverse \
+ (nsISupports *p, \
+ nsCycleCollectionTraversalCallback &cb) \
+ { \
+ NS_ASSERTION(CheckForRightISupports(p), \
+ "not the nsISupports pointer we expect"); \
+ _class *tmp = NS_STATIC_CAST(_class*, Downcast(p)); \
+ if (!tmp->IsPartOfAggregated()) \
+ NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class)
+
#define NS_GENERIC_AGGREGATED_CONSTRUCTOR(_InstanceClass) \
static NS_METHOD \
_InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \
void **aResult) \
{ \
*aResult = nsnull; \
\
NS_ENSURE_PROPER_AGGREGATION(aOuter, aIID); \
--- a/xpfe/components/intl/nsCharsetMenu.cpp
+++ b/xpfe/components/intl/nsCharsetMenu.cpp
@@ -60,16 +60,17 @@
#include "nsIObserver.h"
#include "nsStringEnumerator.h"
#include "nsVoidArray.h"
#include "nsIObserverService.h"
#include "nsIRequestObserver.h"
#include "nsITimelineService.h"
#include "nsCRT.h"
#include "prmem.h"
+#include "nsCycleCollectionParticipant.h"
//----------------------------------------------------------------------------
// Global functions and data [declaration]
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID);
static NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID);
static NS_DEFINE_CID(kRDFContainerCID, NS_RDFCONTAINER_CID);
@@ -148,17 +149,18 @@ public:
*
* God, our GUI programming disgusts me.
*
* @created 23/Nov/1999
* @author Catalin Rotaru [CATA]
*/
class nsCharsetMenu : public nsIRDFDataSource, public nsICurrentCharsetListener
{
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsCharsetMenu, nsIRDFDataSource)
private:
static nsIRDFResource * kNC_BrowserAutodetMenuRoot;
static nsIRDFResource * kNC_BrowserCharsetMenuRoot;
static nsIRDFResource * kNC_BrowserMoreCharsetMenuRoot;
static nsIRDFResource * kNC_BrowserMore1CharsetMenuRoot;
static nsIRDFResource * kNC_BrowserMore2CharsetMenuRoot;
static nsIRDFResource * kNC_BrowserMore3CharsetMenuRoot;
@@ -460,17 +462,30 @@ NS_IMETHODIMP nsCharsetMenuObserver::Obs
NS_TIMELINE_STOP_TIMER("nsCharsetMenu:Observe");
NS_TIMELINE_MARK_TIMER("nsCharsetMenu:Observe");
return rv;
}
//----------------------------------------------------------------------------
// Class nsCharsetMenu [implementation]
-NS_IMPL_ISUPPORTS2(nsCharsetMenu, nsIRDFDataSource, nsICurrentCharsetListener)
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsCharsetMenu)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsCharsetMenu)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCharsetMenu)
+ cb.NoteXPCOMChild(nsCharsetMenu::mInner);
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsCharsetMenu, nsIRDFDataSource)
+NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsCharsetMenu, nsIRDFDataSource)
+NS_INTERFACE_MAP_BEGIN(nsCharsetMenu)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
+ NS_INTERFACE_MAP_ENTRY(nsICurrentCharsetListener)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRDFDataSource)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsCharsetMenu)
+NS_INTERFACE_MAP_END
nsIRDFDataSource * nsCharsetMenu::mInner = NULL;
nsIRDFResource * nsCharsetMenu::kNC_BrowserAutodetMenuRoot = NULL;
nsIRDFResource * nsCharsetMenu::kNC_BrowserCharsetMenuRoot = NULL;
nsIRDFResource * nsCharsetMenu::kNC_BrowserMoreCharsetMenuRoot = NULL;
nsIRDFResource * nsCharsetMenu::kNC_BrowserMore1CharsetMenuRoot = NULL;
nsIRDFResource * nsCharsetMenu::kNC_BrowserMore2CharsetMenuRoot = NULL;
nsIRDFResource * nsCharsetMenu::kNC_BrowserMore3CharsetMenuRoot = NULL;
--- a/xpfe/components/related/src/nsRelatedLinksHandler.cpp
+++ b/xpfe/components/related/src/nsRelatedLinksHandler.cpp
@@ -653,17 +653,33 @@ RelatedLinksHandlerImpl::Init()
mInner = do_CreateInstance(kRDFInMemoryDataSourceCID, &rv);
return rv;
}
// nsISupports interface
-NS_IMPL_ISUPPORTS2(RelatedLinksHandlerImpl, nsIRelatedLinksHandler, nsIRDFDataSource)
+NS_IMPL_CYCLE_COLLECTION_CLASS(RelatedLinksHandlerImpl)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_0(RelatedLinksHandlerImpl)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(RelatedLinksHandlerImpl)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mInner)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(RelatedLinksHandlerImpl,
+ nsIRelatedLinksHandler)
+NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(RelatedLinksHandlerImpl,
+ nsIRelatedLinksHandler)
+
+NS_INTERFACE_MAP_BEGIN(RelatedLinksHandlerImpl)
+ NS_INTERFACE_MAP_ENTRY(nsIRelatedLinksHandler)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRelatedLinksHandler)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(RelatedLinksHandlerImpl)
+NS_INTERFACE_MAP_END
// nsIRelatedLinksHandler interface
NS_IMETHODIMP
RelatedLinksHandlerImpl::GetURL(char** aURL)
{
NS_PRECONDITION(aURL != nsnull, "null ptr");
if (! aURL)
--- a/xpfe/components/related/src/nsRelatedLinksHandlerImpl.h
+++ b/xpfe/components/related/src/nsRelatedLinksHandlerImpl.h
@@ -39,16 +39,17 @@
#define relatedlinkshandler____h____
#include "nsString.h"
#include "nsIRDFService.h"
#include "nsIRelatedLinksHandler.h"
#include "nsIRDFResource.h"
#include "nsCOMPtr.h"
#include "nsIRDFDataSource.h"
+#include "nsCycleCollectionParticipant.h"
////////////////////////////////////////////////////////////////////////
// RelatedLinksHandlerImpl
class RelatedLinksHandlerImpl : public nsIRelatedLinksHandler,
public nsIRDFDataSource
{
private:
@@ -66,14 +67,16 @@ private:
nsCOMPtr<nsIRDFDataSource> mInner;
public:
RelatedLinksHandlerImpl();
virtual ~RelatedLinksHandlerImpl();
nsresult Init();
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(RelatedLinksHandlerImpl,
+ nsIRelatedLinksHandler)
NS_DECL_NSIRELATEDLINKSHANDLER
NS_DECL_NSIRDFDATASOURCE
};
#endif // relatedlinkshandler____h____
--- a/xpfe/components/search/src/nsLocalSearchService.cpp
+++ b/xpfe/components/search/src/nsLocalSearchService.cpp
@@ -880,49 +880,25 @@ LocalSearchDataSource::GetAllResources(n
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
LocalSearchDataSource::AddObserver(nsIRDFObserver *n)
{
- NS_PRECONDITION(n != nsnull, "null ptr");
- if (! n)
- return NS_ERROR_NULL_POINTER;
-
- if (! mObservers)
- {
- nsresult rv;
- rv = NS_NewISupportsArray(getter_AddRefs(mObservers));
- if (NS_FAILED(rv)) return rv;
- }
- return mObservers->AppendElement(n) ? NS_OK : NS_ERROR_FAILURE;
+ return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
LocalSearchDataSource::RemoveObserver(nsIRDFObserver *n)
{
- NS_PRECONDITION(n != nsnull, "null ptr");
- if (! n)
- return NS_ERROR_NULL_POINTER;
-
- if (! mObservers)
- return(NS_OK);
-
-#ifdef DEBUG
- PRBool ok =
-#endif
- mObservers->RemoveElement(n);
-
- NS_ASSERTION(ok, "observer not present");
-
- return(NS_OK);
+ return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
LocalSearchDataSource::GetAllCmds(nsIRDFResource* source, nsISimpleEnumerator/*<nsIRDFResource>*/** commands)
{
return(NS_NewEmptyEnumerator(commands));
--- a/xpfe/components/search/src/nsLocalSearchService.h
+++ b/xpfe/components/search/src/nsLocalSearchService.h
@@ -51,18 +51,16 @@ typedef struct _findTokenStruct
const char *token;
nsString value;
} findTokenStruct, *findTokenPtr;
class LocalSearchDataSource : public nsIRDFDataSource
{
private:
- nsCOMPtr<nsISupportsArray> mObservers;
-
static PRInt32 gRefCnt;
// pseudo-constants
static nsIRDFResource *kNC_Child;
static nsIRDFResource *kNC_Name;
static nsIRDFResource *kNC_URL;
static nsIRDFResource *kNC_FindObject;
static nsIRDFResource *kNC_pulse;
--- a/xpfe/components/windowds/nsWindowDataSource.cpp
+++ b/xpfe/components/windowds/nsWindowDataSource.cpp
@@ -124,54 +124,36 @@ nsWindowDataSource::Observe(nsISupports
// to us
mContainer = nsnull;
mInner = nsnull;
}
return NS_OK;
}
-#if 0
-NS_IMETHODIMP_(nsrefcnt)
-nsWindowMediator::Release()
-{
- // We need a special implementation of Release() due to having
- // two circular references: mInner and mContainer
-
- NS_PRECONDITION(PRInt32(mRefCnt) > 0, "duplicate release");
- --mRefCnt;
- NS_LOG_RELEASE(this, mRefCnt, "nsWindowMediator");
-
- if (mInner && mRefCnt == 2)
- {
- NS_IF_RELEASE(mContainer);
- mContainer = nsnull;
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsWindowDataSource)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsWindowDataSource)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsWindowDataSource)
+ // XXX mContainer?
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mInner)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
- nsIRDFDataSource* tmp = mInner;
- mInner = nsnull;
- NS_IF_RELEASE(tmp);
- return(0);
- }
- else if (mRefCnt == 0)
- {
- mRefCnt = 1;
- delete this;
- return(0);
- }
- return(mRefCnt);
-}
+NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsWindowDataSource,
+ nsIObserver)
+NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsWindowDataSource,
+ nsIObserver)
-#endif
-
-
-NS_IMPL_ISUPPORTS4(nsWindowDataSource,
- nsIObserver,
- nsIWindowMediatorListener,
- nsIWindowDataSource,
- nsIRDFDataSource)
+NS_INTERFACE_MAP_BEGIN(nsWindowDataSource)
+ NS_INTERFACE_MAP_ENTRY(nsIObserver)
+ NS_INTERFACE_MAP_ENTRY(nsIWindowMediatorListener)
+ NS_INTERFACE_MAP_ENTRY(nsIWindowDataSource)
+ NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsWindowDataSource)
+NS_INTERFACE_MAP_END
// nsIWindowMediatorListener implementation
// handle notifications from the window mediator and reflect them into
// RDF
/* void onWindowTitleChange (in nsIXULWindow window, in wstring newTitle); */
NS_IMETHODIMP
nsWindowDataSource::OnWindowTitleChange(nsIXULWindow *window,
--- a/xpfe/components/windowds/nsWindowDataSource.h
+++ b/xpfe/components/windowds/nsWindowDataSource.h
@@ -41,16 +41,17 @@
#include "nsIRDFDataSource.h"
#include "nsIWindowMediatorListener.h"
#include "nsIWindowDataSource.h"
#include "nsIObserver.h"
#include "nsIRDFService.h"
#include "nsIRDFContainer.h"
#include "nsHashtable.h"
+#include "nsCycleCollectionParticipant.h"
// {C744CA3D-840B-460a-8D70-7CE63C51C958}
#define NS_WINDOWDATASOURCE_CID \
{ 0xc744ca3d, 0x840b, 0x460a, \
{ 0x8d, 0x70, 0x7c, 0xe6, 0x3c, 0x51, 0xc9, 0x58 } }
class nsWindowDataSource : public nsIRDFDataSource,
@@ -59,17 +60,19 @@ class nsWindowDataSource : public nsIRDF
public nsIWindowDataSource
{
public:
nsWindowDataSource() { }
virtual ~nsWindowDataSource();
nsresult Init();
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsWindowDataSource,
+ nsIRDFDataSource)
NS_DECL_NSIOBSERVER
NS_DECL_NSIWINDOWMEDIATORLISTENER
NS_DECL_NSIWINDOWDATASOURCE
NS_DECL_NSIRDFDATASOURCE
private:
// mapping of window -> RDF resource