now holds a strong reference to its chrome data source (mComposite). consequent circular reference is broken with stupid refcounting tricks. bug 44621 r=hyatt

This commit is contained in:
danm%netscape.com 2000-07-19 23:39:50 +00:00
Родитель bf04473aff
Коммит a53490a2d1
4 изменённых файлов: 62 добавлений и 10 удалений

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

@ -1,3 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
@ -50,7 +51,7 @@ static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
nsChromeUIDataSource::nsChromeUIDataSource(nsIRDFDataSource* aComposite)
{
NS_INIT_REFCNT();
NS_INIT_REFCNT();
mComposite = aComposite;
mComposite->AddObserver(this);
@ -65,7 +66,8 @@ nsChromeUIDataSource::nsChromeUIDataSource(nsIRDFDataSource* aComposite)
nsChromeUIDataSource::~nsChromeUIDataSource()
{
mComposite->RemoveObserver(this);
if (mComposite)
mComposite->RemoveObserver(this);
mRDFService->UnregisterDataSource(this);
@ -75,7 +77,32 @@ nsChromeUIDataSource::~nsChromeUIDataSource()
}
}
NS_IMPL_ISUPPORTS2(nsChromeUIDataSource, nsIRDFDataSource, nsIRDFObserver);
// 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");
// delete if the last reference is our strong circular reference
if (mComposite && PRInt32(mRefCnt) == 1) {
++mRefCnt;
nsCOMPtr<nsIRDFDataSource> composite = mComposite;
mComposite = 0; // release
composite->RemoveObserver(this);
--mRefCnt;
}
if (mRefCnt == 0) {
delete this;
return 0;
}
return mRefCnt;
}
//----------------------------------------------------------------------

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

@ -24,7 +24,6 @@
*/
class nsIRDFService;
class nsIRDFDataSource;
class nsIRDFResource;
class nsICSSLoader;
class nsISimpleEnumerator;
@ -52,7 +51,7 @@ public:
virtual ~nsChromeUIDataSource();
protected:
nsIRDFDataSource* mComposite; // [WEAK] We observe the composite source, which holds on to us strongly.
nsCOMPtr<nsIRDFDataSource> mComposite;
nsCOMPtr<nsISupportsArray> mObservers;
nsIRDFService* mRDFService;
};

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

@ -1,3 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
@ -50,7 +51,7 @@ static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
nsChromeUIDataSource::nsChromeUIDataSource(nsIRDFDataSource* aComposite)
{
NS_INIT_REFCNT();
NS_INIT_REFCNT();
mComposite = aComposite;
mComposite->AddObserver(this);
@ -65,7 +66,8 @@ nsChromeUIDataSource::nsChromeUIDataSource(nsIRDFDataSource* aComposite)
nsChromeUIDataSource::~nsChromeUIDataSource()
{
mComposite->RemoveObserver(this);
if (mComposite)
mComposite->RemoveObserver(this);
mRDFService->UnregisterDataSource(this);
@ -75,7 +77,32 @@ nsChromeUIDataSource::~nsChromeUIDataSource()
}
}
NS_IMPL_ISUPPORTS2(nsChromeUIDataSource, nsIRDFDataSource, nsIRDFObserver);
// 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");
// delete if the last reference is our strong circular reference
if (mComposite && PRInt32(mRefCnt) == 1) {
++mRefCnt;
nsCOMPtr<nsIRDFDataSource> composite = mComposite;
mComposite = 0; // release
composite->RemoveObserver(this);
--mRefCnt;
}
if (mRefCnt == 0) {
delete this;
return 0;
}
return mRefCnt;
}
//----------------------------------------------------------------------

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

@ -24,7 +24,6 @@
*/
class nsIRDFService;
class nsIRDFDataSource;
class nsIRDFResource;
class nsICSSLoader;
class nsISimpleEnumerator;
@ -52,7 +51,7 @@ public:
virtual ~nsChromeUIDataSource();
protected:
nsIRDFDataSource* mComposite; // [WEAK] We observe the composite source, which holds on to us strongly.
nsCOMPtr<nsIRDFDataSource> mComposite;
nsCOMPtr<nsISupportsArray> mObservers;
nsIRDFService* mRDFService;
};