Bug 449006, r+sr=peterv

This commit is contained in:
Olli Pettay 2008-12-10 18:46:36 +02:00
parent bf7026dd65
commit 42dd80712f
7 changed files with 109 additions and 130 deletions

View File

@ -40,6 +40,7 @@
#include "nsTransactionManager.h"
#include "nsTransactionItem.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
nsTransactionItem::nsTransactionItem(nsITransaction *aTransaction)
: mTransaction(aTransaction), mUndoStack(0), mRedoStack(0)
@ -53,8 +54,27 @@ nsTransactionItem::~nsTransactionItem()
if (mUndoStack)
delete mUndoStack;
}
NS_IF_RELEASE(mTransaction);
nsrefcnt
nsTransactionItem::AddRef()
{
++mRefCnt;
NS_LOG_ADDREF(this, mRefCnt, "nsTransactionItem",
sizeof(nsTransactionItem));
return mRefCnt;
}
nsrefcnt
nsTransactionItem::Release() {
--mRefCnt;
NS_LOG_RELEASE(this, mRefCnt, "nsTransactionItem");
if (mRefCnt == 0) {
mRefCnt = 1;
delete this;
return 0;
}
return mRefCnt;
}
nsresult
@ -80,7 +100,7 @@ nsTransactionItem::GetTransaction(nsITransaction **aTransaction)
if (!aTransaction)
return NS_ERROR_NULL_POINTER;
*aTransaction = mTransaction;
NS_IF_ADDREF(*aTransaction = mTransaction);
return NS_OK;
}
@ -207,7 +227,7 @@ nsTransactionItem::UndoTransaction(nsTransactionManager *aTxMgr)
nsresult
nsTransactionItem::UndoChildren(nsTransactionManager *aTxMgr)
{
nsTransactionItem *item;
nsRefPtr<nsTransactionItem> item;
nsresult result = NS_OK;
PRInt32 sz = 0;
@ -225,15 +245,15 @@ nsTransactionItem::UndoChildren(nsTransactionManager *aTxMgr)
return result;
while (sz-- > 0) {
result = mUndoStack->Peek(&item);
result = mUndoStack->Peek(getter_AddRefs(item));
if (NS_FAILED(result)) {
return result;
}
nsITransaction *t = 0;
nsCOMPtr<nsITransaction> t;
result = item->GetTransaction(&t);
result = item->GetTransaction(getter_AddRefs(t));
if (NS_FAILED(result)) {
return result;
@ -254,7 +274,7 @@ nsTransactionItem::UndoChildren(nsTransactionManager *aTxMgr)
result = item->UndoTransaction(aTxMgr);
if (NS_SUCCEEDED(result)) {
result = mUndoStack->Pop(&item);
result = mUndoStack->Pop(getter_AddRefs(item));
if (NS_SUCCEEDED(result)) {
result = mRedoStack->Push(item);
@ -281,6 +301,7 @@ nsTransactionItem::RedoTransaction(nsTransactionManager *aTxMgr)
{
nsresult result;
nsCOMPtr<nsITransaction> kungfuDeathGrip(mTransaction);
if (mTransaction) {
result = mTransaction->RedoTransaction();
@ -301,7 +322,7 @@ nsTransactionItem::RedoTransaction(nsTransactionManager *aTxMgr)
nsresult
nsTransactionItem::RedoChildren(nsTransactionManager *aTxMgr)
{
nsTransactionItem *item;
nsRefPtr<nsTransactionItem> item;
nsresult result = NS_OK;
PRInt32 sz = 0;
@ -316,15 +337,15 @@ nsTransactionItem::RedoChildren(nsTransactionManager *aTxMgr)
while (sz-- > 0) {
result = mRedoStack->Peek(&item);
result = mRedoStack->Peek(getter_AddRefs(item));
if (NS_FAILED(result)) {
return result;
}
nsITransaction *t = 0;
nsCOMPtr<nsITransaction> t;
result = item->GetTransaction(&t);
result = item->GetTransaction(getter_AddRefs(t));
if (NS_FAILED(result)) {
return result;
@ -345,7 +366,7 @@ nsTransactionItem::RedoChildren(nsTransactionManager *aTxMgr)
result = item->RedoTransaction(aTxMgr);
if (NS_SUCCEEDED(result)) {
result = mRedoStack->Pop(&item);
result = mRedoStack->Pop(getter_AddRefs(item));
if (NS_SUCCEEDED(result)) {
result = mUndoStack->Push(item);

View File

@ -38,21 +38,26 @@
#ifndef nsTransactionItem_h__
#define nsTransactionItem_h__
class nsITransaction;
#include "nsITransaction.h"
#include "nsCOMPtr.h"
class nsTransactionStack;
class nsTransactionRedoStack;
class nsTransactionManager;
class nsTransactionItem
{
nsITransaction *mTransaction;
nsTransactionStack *mUndoStack;
nsTransactionRedoStack *mRedoStack;
nsCOMPtr<nsITransaction> mTransaction;
nsTransactionStack *mUndoStack;
nsTransactionRedoStack *mRedoStack;
nsAutoRefCnt mRefCnt;
public:
nsTransactionItem(nsITransaction *aTransaction);
virtual ~nsTransactionItem();
nsrefcnt AddRef();
nsrefcnt Release();
virtual nsresult AddChild(nsTransactionItem *aTransactionItem);
virtual nsresult GetTransaction(nsITransaction **aTransaction);

View File

@ -100,14 +100,14 @@ NS_IMETHODIMP nsTransactionList::ItemIsBatch(PRInt32 aIndex, PRBool *aIsBatch)
if (!txMgr)
return NS_ERROR_FAILURE;
nsTransactionItem *item = 0;
nsRefPtr<nsTransactionItem> item;
nsresult result = NS_ERROR_FAILURE;
if (mTxnStack)
result = mTxnStack->GetItem(aIndex, &item);
result = mTxnStack->GetItem(aIndex, getter_AddRefs(item));
else if (mTxnItem)
result = mTxnItem->GetChild(aIndex, &item);
result = mTxnItem->GetChild(aIndex, getter_AddRefs(item));
if (NS_FAILED(result))
return result;
@ -131,14 +131,14 @@ NS_IMETHODIMP nsTransactionList::GetItem(PRInt32 aIndex, nsITransaction **aItem)
if (!txMgr)
return NS_ERROR_FAILURE;
nsTransactionItem *item = 0;
nsRefPtr<nsTransactionItem> item;
nsresult result = NS_ERROR_FAILURE;
if (mTxnStack)
result = mTxnStack->GetItem(aIndex, &item);
result = mTxnStack->GetItem(aIndex, getter_AddRefs(item));
else if (mTxnItem)
result = mTxnItem->GetChild(aIndex, &item);
result = mTxnItem->GetChild(aIndex, getter_AddRefs(item));
if (NS_FAILED(result))
return result;
@ -146,14 +146,7 @@ NS_IMETHODIMP nsTransactionList::GetItem(PRInt32 aIndex, nsITransaction **aItem)
if (!item)
return NS_ERROR_FAILURE;
result = item->GetTransaction(aItem);
if (NS_FAILED(result))
return result;
NS_IF_ADDREF(*aItem);
return NS_OK;
return item->GetTransaction(aItem);
}
/* long getNumChildrenForItem (in long aIndex); */
@ -169,14 +162,14 @@ NS_IMETHODIMP nsTransactionList::GetNumChildrenForItem(PRInt32 aIndex, PRInt32 *
if (!txMgr)
return NS_ERROR_FAILURE;
nsTransactionItem *item = 0;
nsRefPtr<nsTransactionItem> item;
nsresult result = NS_ERROR_FAILURE;
if (mTxnStack)
result = mTxnStack->GetItem(aIndex, &item);
result = mTxnStack->GetItem(aIndex, getter_AddRefs(item));
else if (mTxnItem)
result = mTxnItem->GetChild(aIndex, &item);
result = mTxnItem->GetChild(aIndex, getter_AddRefs(item));
if (NS_FAILED(result))
return result;
@ -200,14 +193,14 @@ NS_IMETHODIMP nsTransactionList::GetChildListForItem(PRInt32 aIndex, nsITransact
if (!txMgr)
return NS_ERROR_FAILURE;
nsTransactionItem *item = 0;
nsRefPtr<nsTransactionItem> item;
nsresult result = NS_ERROR_FAILURE;
if (mTxnStack)
result = mTxnStack->GetItem(aIndex, &item);
result = mTxnStack->GetItem(aIndex, getter_AddRefs(item));
else if (mTxnItem)
result = mTxnItem->GetChild(aIndex, &item);
result = mTxnItem->GetChild(aIndex, getter_AddRefs(item));
if (NS_FAILED(result))
return result;

View File

@ -40,10 +40,11 @@
#include "nsWeakReference.h"
#include "nsITransactionList.h"
#include "nsTransactionItem.h"
#include "nsAutoPtr.h"
class nsITransaction;
class nsITransactionManager;
class nsTransactionItem;
class nsTransactionStack;
class nsTransactionRedoStack;
@ -54,9 +55,9 @@ class nsTransactionList : public nsITransactionList
{
private:
nsWeakPtr mTxnMgr;
nsTransactionStack *mTxnStack;
nsTransactionItem *mTxnItem;
nsWeakPtr mTxnMgr;
nsTransactionStack *mTxnStack;
nsRefPtr<nsTransactionItem> mTxnItem;
public:

View File

@ -43,7 +43,7 @@
#include "nsVoidArray.h"
#include "nsTransactionManager.h"
#include "nsTransactionList.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#define LOCK_TX_MANAGER(mgr) (mgr)->Lock()
@ -153,7 +153,7 @@ NS_IMETHODIMP
nsTransactionManager::UndoTransaction()
{
nsresult result = NS_OK;
nsTransactionItem *tx = 0;
nsRefPtr<nsTransactionItem> tx;
LOCK_TX_MANAGER(this);
@ -161,7 +161,7 @@ nsTransactionManager::UndoTransaction()
// executing a transaction's DoTransaction() method! If this happens,
// the UndoTransaction() request is ignored, and we return NS_ERROR_FAILURE.
result = mDoStack.Peek(&tx);
result = mDoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
@ -175,7 +175,7 @@ nsTransactionManager::UndoTransaction()
// Peek at the top of the undo stack. Don't remove the transaction
// until it has successfully completed.
result = mUndoStack.Peek(&tx);
result = mUndoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
@ -188,9 +188,9 @@ nsTransactionManager::UndoTransaction()
return NS_OK;
}
nsITransaction *t = 0;
nsCOMPtr<nsITransaction> t;
result = tx->GetTransaction(&t);
result = tx->GetTransaction(getter_AddRefs(t));
if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
@ -214,7 +214,7 @@ nsTransactionManager::UndoTransaction()
result = tx->UndoTransaction(this);
if (NS_SUCCEEDED(result)) {
result = mUndoStack.Pop(&tx);
result = mUndoStack.Pop(getter_AddRefs(tx));
if (NS_SUCCEEDED(result))
result = mRedoStack.Push(tx);
@ -234,7 +234,7 @@ NS_IMETHODIMP
nsTransactionManager::RedoTransaction()
{
nsresult result = NS_OK;
nsTransactionItem *tx = 0;
nsRefPtr<nsTransactionItem> tx;
LOCK_TX_MANAGER(this);
@ -242,7 +242,7 @@ nsTransactionManager::RedoTransaction()
// executing a transaction's DoTransaction() method! If this happens,
// the RedoTransaction() request is ignored, and we return NS_ERROR_FAILURE.
result = mDoStack.Peek(&tx);
result = mDoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
@ -256,7 +256,7 @@ nsTransactionManager::RedoTransaction()
// Peek at the top of the redo stack. Don't remove the transaction
// until it has successfully completed.
result = mRedoStack.Peek(&tx);
result = mRedoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
@ -269,9 +269,9 @@ nsTransactionManager::RedoTransaction()
return NS_OK;
}
nsITransaction *t = 0;
nsCOMPtr<nsITransaction> t;
result = tx->GetTransaction(&t);
result = tx->GetTransaction(getter_AddRefs(t));
if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
@ -295,7 +295,7 @@ nsTransactionManager::RedoTransaction()
result = tx->RedoTransaction(this);
if (NS_SUCCEEDED(result)) {
result = mRedoStack.Pop(&tx);
result = mRedoStack.Pop(getter_AddRefs(tx));
if (NS_SUCCEEDED(result))
result = mUndoStack.Push(tx);
@ -373,8 +373,8 @@ nsTransactionManager::BeginBatch()
NS_IMETHODIMP
nsTransactionManager::EndBatch()
{
nsTransactionItem *tx = 0;
nsITransaction *ti = 0;
nsRefPtr<nsTransactionItem> tx;
nsCOMPtr<nsITransaction> ti;
nsresult result;
LOCK_TX_MANAGER(this);
@ -390,7 +390,7 @@ nsTransactionManager::EndBatch()
// future when we allow users to execute a transaction when beginning
// a batch!!!!
result = mDoStack.Peek(&tx);
result = mDoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
@ -398,7 +398,7 @@ nsTransactionManager::EndBatch()
}
if (tx)
tx->GetTransaction(&ti);
tx->GetTransaction(getter_AddRefs(ti));
if (!tx || ti) {
UNLOCK_TX_MANAGER(this);
@ -472,7 +472,7 @@ NS_IMETHODIMP
nsTransactionManager::SetMaxTransactionCount(PRInt32 aMaxCount)
{
PRInt32 numUndoItems = 0, numRedoItems = 0, total = 0;
nsTransactionItem *tx = 0;
nsRefPtr<nsTransactionItem> tx;
nsresult result;
LOCK_TX_MANAGER(this);
@ -483,7 +483,7 @@ nsTransactionManager::SetMaxTransactionCount(PRInt32 aMaxCount)
// SetMaxTransactionCount() request is ignored, and we return
// NS_ERROR_FAILURE.
result = mDoStack.Peek(&tx);
result = mDoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
@ -534,16 +534,13 @@ nsTransactionManager::SetMaxTransactionCount(PRInt32 aMaxCount)
// the bottom of the stack and pop towards the top.
while (numUndoItems > 0 && (numRedoItems + numUndoItems) > aMaxCount) {
tx = 0;
result = mUndoStack.PopBottom(&tx);
result = mUndoStack.PopBottom(getter_AddRefs(tx));
if (NS_FAILED(result) || !tx) {
UNLOCK_TX_MANAGER(this);
return result;
}
delete tx;
--numUndoItems;
}
@ -551,16 +548,13 @@ nsTransactionManager::SetMaxTransactionCount(PRInt32 aMaxCount)
// the bottom of the stack and pop towards the top.
while (numRedoItems > 0 && (numRedoItems + numUndoItems) > aMaxCount) {
tx = 0;
result = mRedoStack.PopBottom(&tx);
result = mRedoStack.PopBottom(getter_AddRefs(tx));
if (NS_FAILED(result) || !tx) {
UNLOCK_TX_MANAGER(this);
return result;
}
delete tx;
--numRedoItems;
}
@ -574,7 +568,7 @@ nsTransactionManager::SetMaxTransactionCount(PRInt32 aMaxCount)
NS_IMETHODIMP
nsTransactionManager::PeekUndoStack(nsITransaction **aTransaction)
{
nsTransactionItem *tx = 0;
nsRefPtr<nsTransactionItem> tx;
nsresult result;
if (!aTransaction)
@ -584,7 +578,7 @@ nsTransactionManager::PeekUndoStack(nsITransaction **aTransaction)
LOCK_TX_MANAGER(this);
result = mUndoStack.Peek(&tx);
result = mUndoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result) || !tx) {
UNLOCK_TX_MANAGER(this);
@ -595,15 +589,13 @@ nsTransactionManager::PeekUndoStack(nsITransaction **aTransaction)
UNLOCK_TX_MANAGER(this);
NS_IF_ADDREF(*aTransaction);
return result;
}
NS_IMETHODIMP
nsTransactionManager::PeekRedoStack(nsITransaction **aTransaction)
{
nsTransactionItem *tx = 0;
nsRefPtr<nsTransactionItem> tx;
nsresult result;
if (!aTransaction)
@ -613,7 +605,7 @@ nsTransactionManager::PeekRedoStack(nsITransaction **aTransaction)
LOCK_TX_MANAGER(this);
result = mRedoStack.Peek(&tx);
result = mRedoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result) || !tx) {
UNLOCK_TX_MANAGER(this);
@ -624,8 +616,6 @@ nsTransactionManager::PeekRedoStack(nsITransaction **aTransaction)
UNLOCK_TX_MANAGER(this);
NS_IF_ADDREF(*aTransaction);
return result;
}
@ -1044,35 +1034,29 @@ nsTransactionManager::DidMergeNotify(nsITransaction *aTop,
nsresult
nsTransactionManager::BeginTransaction(nsITransaction *aTransaction)
{
nsTransactionItem *tx;
nsresult result = NS_OK;
// No need for LOCK/UNLOCK_TX_MANAGER() calls since the calling routine
// should have done this already!
NS_IF_ADDREF(aTransaction);
// XXX: POSSIBLE OPTIMIZATION
// We could use a factory that pre-allocates/recycles transaction items.
tx = new nsTransactionItem(aTransaction);
nsRefPtr<nsTransactionItem> tx = new nsTransactionItem(aTransaction);
if (!tx) {
NS_IF_RELEASE(aTransaction);
return NS_ERROR_OUT_OF_MEMORY;
}
result = mDoStack.Push(tx);
if (NS_FAILED(result)) {
delete tx;
return result;
}
result = tx->DoTransaction();
if (NS_FAILED(result)) {
mDoStack.Pop(&tx);
delete tx;
mDoStack.Pop(getter_AddRefs(tx));
return result;
}
@ -1082,19 +1066,19 @@ nsTransactionManager::BeginTransaction(nsITransaction *aTransaction)
nsresult
nsTransactionManager::EndTransaction()
{
nsITransaction *tint = 0;
nsTransactionItem *tx = 0;
nsCOMPtr<nsITransaction> tint;
nsRefPtr<nsTransactionItem> tx;
nsresult result = NS_OK;
// No need for LOCK/UNLOCK_TX_MANAGER() calls since the calling routine
// should have done this already!
result = mDoStack.Pop(&tx);
result = mDoStack.Pop(getter_AddRefs(tx));
if (NS_FAILED(result) || !tx)
return result;
result = tx->GetTransaction(&tint);
result = tx->GetTransaction(getter_AddRefs(tint));
if (NS_FAILED(result)) {
// XXX: What do we do with the transaction item at this point?
@ -1110,7 +1094,6 @@ nsTransactionManager::EndTransaction()
tx->GetNumberOfChildren(&nc);
if (!nc) {
delete tx;
return result;
}
}
@ -1126,17 +1109,16 @@ nsTransactionManager::EndTransaction()
if (NS_FAILED(result) || isTransient || !mMaxTransactionCount) {
// XXX: Should we be clearing the redo stack if the transaction
// is transient and there is nothing on the do stack?
delete tx;
return result;
}
nsTransactionItem *top = 0;
nsRefPtr<nsTransactionItem> top;
// Check if there is a transaction on the do stack. If there is,
// the current transaction is a "sub" transaction, and should
// be added to the transaction at the top of the do stack.
result = mDoStack.Peek(&top);
result = mDoStack.Peek(getter_AddRefs(top));
if (top) {
result = top->AddChild(tx);
@ -1157,13 +1139,13 @@ nsTransactionManager::EndTransaction()
// of the undo stack.
top = 0;
result = mUndoStack.Peek(&top);
result = mUndoStack.Peek(getter_AddRefs(top));
if (tint && top) {
PRBool didMerge = PR_FALSE;
nsITransaction *topTransaction = 0;
nsCOMPtr<nsITransaction> topTransaction;
result = top->GetTransaction(&topTransaction);
result = top->GetTransaction(getter_AddRefs(topTransaction));
if (topTransaction) {
@ -1187,7 +1169,6 @@ nsTransactionManager::EndTransaction()
}
if (didMerge) {
delete tx;
return result;
}
}
@ -1202,14 +1183,11 @@ nsTransactionManager::EndTransaction()
result = mUndoStack.GetSize(&sz);
if (mMaxTransactionCount > 0 && sz >= mMaxTransactionCount) {
nsTransactionItem *overflow = 0;
nsRefPtr<nsTransactionItem> overflow;
result = mUndoStack.PopBottom(&overflow);
result = mUndoStack.PopBottom(getter_AddRefs(overflow));
// XXX: What do we do in the case where this fails?
if (overflow)
delete overflow;
}
// Push the transaction on the undo stack:

View File

@ -39,12 +39,11 @@
#include "nsTransactionItem.h"
#include "nsTransactionStack.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
nsTransactionStack::nsTransactionStack()
: mQue(0)
{
nsTransactionReleaseFunctor* theFunctor=new nsTransactionReleaseFunctor();
mQue.SetDeallocator(theFunctor);
}
nsTransactionStack::~nsTransactionStack()
@ -61,6 +60,7 @@ nsTransactionStack::Push(nsTransactionItem *aTransaction)
/* nsDeque's Push() method adds new items at the back
* of the deque.
*/
NS_ADDREF(aTransaction);
mQue.Push(aTransaction);
return NS_OK;
@ -105,7 +105,7 @@ nsTransactionStack::Peek(nsTransactionItem **aTransaction)
return NS_OK;
}
*aTransaction = (nsTransactionItem *)(mQue.Last());
NS_IF_ADDREF(*aTransaction = static_cast<nsTransactionItem*>(mQue.Last()));
return NS_OK;
}
@ -119,7 +119,8 @@ nsTransactionStack::GetItem(PRInt32 aIndex, nsTransactionItem **aTransaction)
if (aIndex < 0 || aIndex >= mQue.GetSize())
return NS_ERROR_FAILURE;
*aTransaction = (nsTransactionItem *)(mQue.ObjectAt(aIndex));
NS_IF_ADDREF(*aTransaction =
static_cast<nsTransactionItem*>(mQue.ObjectAt(aIndex)));
return NS_OK;
}
@ -127,20 +128,18 @@ nsTransactionStack::GetItem(PRInt32 aIndex, nsTransactionItem **aTransaction)
nsresult
nsTransactionStack::Clear(void)
{
nsTransactionItem *tx = 0;
nsRefPtr<nsTransactionItem> tx;
nsresult result = NS_OK;
/* Pop all transactions off the stack and release them. */
result = Pop(&tx);
result = Pop(getter_AddRefs(tx));
if (NS_FAILED(result))
return result;
while (tx) {
delete tx;
result = Pop(&tx);
result = Pop(getter_AddRefs(tx));
if (NS_FAILED(result))
return result;
@ -168,22 +167,20 @@ nsTransactionRedoStack::~nsTransactionRedoStack()
nsresult
nsTransactionRedoStack::Clear(void)
{
nsTransactionItem *tx = 0;
nsRefPtr<nsTransactionItem> tx;
nsresult result = NS_OK;
/* When clearing a Redo stack, we have to clear from the
* bottom of the stack towards the top!
*/
result = PopBottom(&tx);
result = PopBottom(getter_AddRefs(tx));
if (NS_FAILED(result))
return result;
while (tx) {
delete tx;
result = PopBottom(&tx);
result = PopBottom(getter_AddRefs(tx));
if (NS_FAILED(result))
return result;
@ -192,10 +189,3 @@ nsTransactionRedoStack::Clear(void)
return NS_OK;
}
void *
nsTransactionReleaseFunctor::operator()(void *aObject)
{
nsTransactionItem *item = (nsTransactionItem *)aObject;
delete item;
return 0;
}

View File

@ -42,15 +42,6 @@
class nsTransactionItem;
class nsTransactionReleaseFunctor : public nsDequeFunctor
{
public:
nsTransactionReleaseFunctor() {}
virtual ~nsTransactionReleaseFunctor() {}
virtual void *operator()(void *aObject);
};
class nsTransactionStack
{
nsDeque mQue;