Bug 714256 - Remove locking from the transaction manager; r=roc

This commit is contained in:
Ehsan Akhgari 2012-01-01 17:35:11 -05:00
parent 33f140a55b
commit 85d8c3fb24
2 changed files with 6 additions and 153 deletions

View File

@ -46,23 +46,13 @@
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#define LOCK_TX_MANAGER(mgr) (mgr)->Lock()
#define UNLOCK_TX_MANAGER(mgr) (mgr)->Unlock()
nsTransactionManager::nsTransactionManager(PRInt32 aMaxTransactionCount) nsTransactionManager::nsTransactionManager(PRInt32 aMaxTransactionCount)
: mMaxTransactionCount(aMaxTransactionCount) : mMaxTransactionCount(aMaxTransactionCount)
{ {
mMonitor = ::PR_NewMonitor();
} }
nsTransactionManager::~nsTransactionManager() nsTransactionManager::~nsTransactionManager()
{ {
if (mMonitor)
{
::PR_DestroyMonitor(mMonitor);
mMonitor = 0;
}
} }
NS_IMPL_CYCLE_COLLECTION_CLASS(nsTransactionManager) NS_IMPL_CYCLE_COLLECTION_CLASS(nsTransactionManager)
@ -97,19 +87,15 @@ nsTransactionManager::DoTransaction(nsITransaction *aTransaction)
NS_ENSURE_TRUE(aTransaction, NS_ERROR_NULL_POINTER); NS_ENSURE_TRUE(aTransaction, NS_ERROR_NULL_POINTER);
LOCK_TX_MANAGER(this);
bool doInterrupt = false; bool doInterrupt = false;
result = WillDoNotify(aTransaction, &doInterrupt); result = WillDoNotify(aTransaction, &doInterrupt);
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
if (doInterrupt) { if (doInterrupt) {
UNLOCK_TX_MANAGER(this);
return NS_OK; return NS_OK;
} }
@ -117,7 +103,6 @@ nsTransactionManager::DoTransaction(nsITransaction *aTransaction)
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
DidDoNotify(aTransaction, result); DidDoNotify(aTransaction, result);
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
@ -128,8 +113,6 @@ nsTransactionManager::DoTransaction(nsITransaction *aTransaction)
if (NS_SUCCEEDED(result)) if (NS_SUCCEEDED(result))
result = result2; result = result2;
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
@ -139,8 +122,6 @@ nsTransactionManager::UndoTransaction()
nsresult result = NS_OK; nsresult result = NS_OK;
nsRefPtr<nsTransactionItem> tx; nsRefPtr<nsTransactionItem> tx;
LOCK_TX_MANAGER(this);
// It is illegal to call UndoTransaction() while the transaction manager is // It is illegal to call UndoTransaction() while the transaction manager is
// executing a transaction's DoTransaction() method! If this happens, // executing a transaction's DoTransaction() method! If this happens,
// the UndoTransaction() request is ignored, and we return NS_ERROR_FAILURE. // the UndoTransaction() request is ignored, and we return NS_ERROR_FAILURE.
@ -148,12 +129,10 @@ nsTransactionManager::UndoTransaction()
result = mDoStack.Peek(getter_AddRefs(tx)); result = mDoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
if (tx) { if (tx) {
UNLOCK_TX_MANAGER(this);
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@ -162,13 +141,11 @@ nsTransactionManager::UndoTransaction()
result = mUndoStack.Peek(getter_AddRefs(tx)); result = mUndoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
// Bail if there's nothing on the stack. // Bail if there's nothing on the stack.
if (!tx) { if (!tx) {
UNLOCK_TX_MANAGER(this);
return NS_OK; return NS_OK;
} }
@ -177,7 +154,6 @@ nsTransactionManager::UndoTransaction()
result = tx->GetTransaction(getter_AddRefs(t)); result = tx->GetTransaction(getter_AddRefs(t));
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
@ -186,12 +162,10 @@ nsTransactionManager::UndoTransaction()
result = WillUndoNotify(t, &doInterrupt); result = WillUndoNotify(t, &doInterrupt);
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
if (doInterrupt) { if (doInterrupt) {
UNLOCK_TX_MANAGER(this);
return NS_OK; return NS_OK;
} }
@ -209,8 +183,6 @@ nsTransactionManager::UndoTransaction()
if (NS_SUCCEEDED(result)) if (NS_SUCCEEDED(result))
result = result2; result = result2;
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
@ -220,8 +192,6 @@ nsTransactionManager::RedoTransaction()
nsresult result = NS_OK; nsresult result = NS_OK;
nsRefPtr<nsTransactionItem> tx; nsRefPtr<nsTransactionItem> tx;
LOCK_TX_MANAGER(this);
// It is illegal to call RedoTransaction() while the transaction manager is // It is illegal to call RedoTransaction() while the transaction manager is
// executing a transaction's DoTransaction() method! If this happens, // executing a transaction's DoTransaction() method! If this happens,
// the RedoTransaction() request is ignored, and we return NS_ERROR_FAILURE. // the RedoTransaction() request is ignored, and we return NS_ERROR_FAILURE.
@ -229,12 +199,10 @@ nsTransactionManager::RedoTransaction()
result = mDoStack.Peek(getter_AddRefs(tx)); result = mDoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
if (tx) { if (tx) {
UNLOCK_TX_MANAGER(this);
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@ -243,13 +211,11 @@ nsTransactionManager::RedoTransaction()
result = mRedoStack.Peek(getter_AddRefs(tx)); result = mRedoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
// Bail if there's nothing on the stack. // Bail if there's nothing on the stack.
if (!tx) { if (!tx) {
UNLOCK_TX_MANAGER(this);
return NS_OK; return NS_OK;
} }
@ -258,7 +224,6 @@ nsTransactionManager::RedoTransaction()
result = tx->GetTransaction(getter_AddRefs(t)); result = tx->GetTransaction(getter_AddRefs(t));
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
@ -267,12 +232,10 @@ nsTransactionManager::RedoTransaction()
result = WillRedoNotify(t, &doInterrupt); result = WillRedoNotify(t, &doInterrupt);
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
if (doInterrupt) { if (doInterrupt) {
UNLOCK_TX_MANAGER(this);
return NS_OK; return NS_OK;
} }
@ -290,8 +253,6 @@ nsTransactionManager::RedoTransaction()
if (NS_SUCCEEDED(result)) if (NS_SUCCEEDED(result))
result = result2; result = result2;
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
@ -300,19 +261,14 @@ nsTransactionManager::Clear()
{ {
nsresult result; nsresult result;
LOCK_TX_MANAGER(this);
result = ClearRedoStack(); result = ClearRedoStack();
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
result = ClearUndoStack(); result = ClearUndoStack();
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
@ -326,19 +282,15 @@ nsTransactionManager::BeginBatch()
// will be popped off the do stack, and then pushed on the undo stack // will be popped off the do stack, and then pushed on the undo stack
// in EndBatch(). // in EndBatch().
LOCK_TX_MANAGER(this);
bool doInterrupt = false; bool doInterrupt = false;
result = WillBeginBatchNotify(&doInterrupt); result = WillBeginBatchNotify(&doInterrupt);
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
if (doInterrupt) { if (doInterrupt) {
UNLOCK_TX_MANAGER(this);
return NS_OK; return NS_OK;
} }
@ -349,8 +301,6 @@ nsTransactionManager::BeginBatch()
if (NS_SUCCEEDED(result)) if (NS_SUCCEEDED(result))
result = result2; result = result2;
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
@ -361,8 +311,6 @@ nsTransactionManager::EndBatch()
nsCOMPtr<nsITransaction> ti; nsCOMPtr<nsITransaction> ti;
nsresult result; nsresult result;
LOCK_TX_MANAGER(this);
// XXX: Need to add some mechanism to detect the case where the transaction // XXX: Need to add some mechanism to detect the case where the transaction
// at the top of the do stack isn't the dummy transaction, so we can // at the top of the do stack isn't the dummy transaction, so we can
// throw an error!! This can happen if someone calls EndBatch() within // throw an error!! This can happen if someone calls EndBatch() within
@ -377,7 +325,6 @@ nsTransactionManager::EndBatch()
result = mDoStack.Peek(getter_AddRefs(tx)); result = mDoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
@ -385,7 +332,6 @@ nsTransactionManager::EndBatch()
tx->GetTransaction(getter_AddRefs(ti)); tx->GetTransaction(getter_AddRefs(ti));
if (!tx || ti) { if (!tx || ti) {
UNLOCK_TX_MANAGER(this);
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@ -394,12 +340,10 @@ nsTransactionManager::EndBatch()
result = WillEndBatchNotify(&doInterrupt); result = WillEndBatchNotify(&doInterrupt);
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
if (doInterrupt) { if (doInterrupt) {
UNLOCK_TX_MANAGER(this);
return NS_OK; return NS_OK;
} }
@ -410,33 +354,19 @@ nsTransactionManager::EndBatch()
if (NS_SUCCEEDED(result)) if (NS_SUCCEEDED(result))
result = result2; result = result2;
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsTransactionManager::GetNumberOfUndoItems(PRInt32 *aNumItems) nsTransactionManager::GetNumberOfUndoItems(PRInt32 *aNumItems)
{ {
nsresult result; return mUndoStack.GetSize(aNumItems);
LOCK_TX_MANAGER(this);
result = mUndoStack.GetSize(aNumItems);
UNLOCK_TX_MANAGER(this);
return result;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsTransactionManager::GetNumberOfRedoItems(PRInt32 *aNumItems) nsTransactionManager::GetNumberOfRedoItems(PRInt32 *aNumItems)
{ {
nsresult result; return mRedoStack.GetSize(aNumItems);
LOCK_TX_MANAGER(this);
result = mRedoStack.GetSize(aNumItems);
UNLOCK_TX_MANAGER(this);
return result;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -444,9 +374,7 @@ nsTransactionManager::GetMaxTransactionCount(PRInt32 *aMaxCount)
{ {
NS_ENSURE_TRUE(aMaxCount, NS_ERROR_NULL_POINTER); NS_ENSURE_TRUE(aMaxCount, NS_ERROR_NULL_POINTER);
LOCK_TX_MANAGER(this);
*aMaxCount = mMaxTransactionCount; *aMaxCount = mMaxTransactionCount;
UNLOCK_TX_MANAGER(this);
return NS_OK; return NS_OK;
} }
@ -458,8 +386,6 @@ nsTransactionManager::SetMaxTransactionCount(PRInt32 aMaxCount)
nsRefPtr<nsTransactionItem> tx; nsRefPtr<nsTransactionItem> tx;
nsresult result; nsresult result;
LOCK_TX_MANAGER(this);
// It is illegal to call SetMaxTransactionCount() while the transaction // It is illegal to call SetMaxTransactionCount() while the transaction
// manager is executing a transaction's DoTransaction() method because // manager is executing a transaction's DoTransaction() method because
// the undo and redo stacks might get pruned! If this happens, the // the undo and redo stacks might get pruned! If this happens, the
@ -469,12 +395,10 @@ nsTransactionManager::SetMaxTransactionCount(PRInt32 aMaxCount)
result = mDoStack.Peek(getter_AddRefs(tx)); result = mDoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
if (tx) { if (tx) {
UNLOCK_TX_MANAGER(this);
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@ -483,21 +407,18 @@ nsTransactionManager::SetMaxTransactionCount(PRInt32 aMaxCount)
if (aMaxCount < 0) { if (aMaxCount < 0) {
mMaxTransactionCount = -1; mMaxTransactionCount = -1;
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
result = mUndoStack.GetSize(&numUndoItems); result = mUndoStack.GetSize(&numUndoItems);
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
result = mRedoStack.GetSize(&numRedoItems); result = mRedoStack.GetSize(&numRedoItems);
if (NS_FAILED(result)) { if (NS_FAILED(result)) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
@ -509,7 +430,6 @@ nsTransactionManager::SetMaxTransactionCount(PRInt32 aMaxCount)
if (aMaxCount > total ) { if (aMaxCount > total ) {
mMaxTransactionCount = aMaxCount; mMaxTransactionCount = aMaxCount;
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
@ -520,7 +440,6 @@ nsTransactionManager::SetMaxTransactionCount(PRInt32 aMaxCount)
result = mUndoStack.PopBottom(getter_AddRefs(tx)); result = mUndoStack.PopBottom(getter_AddRefs(tx));
if (NS_FAILED(result) || !tx) { if (NS_FAILED(result) || !tx) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
@ -534,7 +453,6 @@ nsTransactionManager::SetMaxTransactionCount(PRInt32 aMaxCount)
result = mRedoStack.PopBottom(getter_AddRefs(tx)); result = mRedoStack.PopBottom(getter_AddRefs(tx));
if (NS_FAILED(result) || !tx) { if (NS_FAILED(result) || !tx) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
@ -543,8 +461,6 @@ nsTransactionManager::SetMaxTransactionCount(PRInt32 aMaxCount)
mMaxTransactionCount = aMaxCount; mMaxTransactionCount = aMaxCount;
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
@ -558,19 +474,14 @@ nsTransactionManager::PeekUndoStack(nsITransaction **aTransaction)
*aTransaction = 0; *aTransaction = 0;
LOCK_TX_MANAGER(this);
result = mUndoStack.Peek(getter_AddRefs(tx)); result = mUndoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result) || !tx) { if (NS_FAILED(result) || !tx) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
result = tx->GetTransaction(aTransaction); result = tx->GetTransaction(aTransaction);
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
@ -584,19 +495,14 @@ nsTransactionManager::PeekRedoStack(nsITransaction **aTransaction)
*aTransaction = 0; *aTransaction = 0;
LOCK_TX_MANAGER(this);
result = mRedoStack.Peek(getter_AddRefs(tx)); result = mRedoStack.Peek(getter_AddRefs(tx));
if (NS_FAILED(result) || !tx) { if (NS_FAILED(result) || !tx) {
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
result = tx->GetTransaction(aTransaction); result = tx->GetTransaction(aTransaction);
UNLOCK_TX_MANAGER(this);
return result; return result;
} }
@ -629,13 +535,7 @@ nsTransactionManager::AddListener(nsITransactionListener *aListener)
{ {
NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER); NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER);
LOCK_TX_MANAGER(this); return mListeners.AppendObject(aListener) ? NS_OK : NS_ERROR_FAILURE;
nsresult rv = mListeners.AppendObject(aListener) ? NS_OK : NS_ERROR_FAILURE;
UNLOCK_TX_MANAGER(this);
return rv;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -643,37 +543,19 @@ nsTransactionManager::RemoveListener(nsITransactionListener *aListener)
{ {
NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER); NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER);
LOCK_TX_MANAGER(this); return mListeners.RemoveObject(aListener) ? NS_OK : NS_ERROR_FAILURE;
nsresult rv = mListeners.RemoveObject(aListener) ? NS_OK : NS_ERROR_FAILURE;
UNLOCK_TX_MANAGER(this);
return rv;
} }
nsresult nsresult
nsTransactionManager::ClearUndoStack() nsTransactionManager::ClearUndoStack()
{ {
nsresult result; return mUndoStack.Clear();
LOCK_TX_MANAGER(this);
result = mUndoStack.Clear();
UNLOCK_TX_MANAGER(this);
return result;
} }
nsresult nsresult
nsTransactionManager::ClearRedoStack() nsTransactionManager::ClearRedoStack()
{ {
nsresult result; return mRedoStack.Clear();
LOCK_TX_MANAGER(this);
result = mRedoStack.Clear();
UNLOCK_TX_MANAGER(this);
return result;
} }
nsresult nsresult
@ -912,9 +794,6 @@ nsTransactionManager::BeginTransaction(nsITransaction *aTransaction)
{ {
nsresult result = NS_OK; nsresult result = NS_OK;
// No need for LOCK/UNLOCK_TX_MANAGER() calls since the calling routine
// should have done this already!
// XXX: POSSIBLE OPTIMIZATION // XXX: POSSIBLE OPTIMIZATION
// We could use a factory that pre-allocates/recycles transaction items. // We could use a factory that pre-allocates/recycles transaction items.
nsRefPtr<nsTransactionItem> tx = new nsTransactionItem(aTransaction); nsRefPtr<nsTransactionItem> tx = new nsTransactionItem(aTransaction);
@ -946,9 +825,6 @@ nsTransactionManager::EndTransaction()
nsRefPtr<nsTransactionItem> tx; nsRefPtr<nsTransactionItem> tx;
nsresult result = NS_OK; nsresult result = NS_OK;
// No need for LOCK/UNLOCK_TX_MANAGER() calls since the calling routine
// should have done this already!
result = mDoStack.Pop(getter_AddRefs(tx)); result = mDoStack.Pop(getter_AddRefs(tx));
if (NS_FAILED(result) || !tx) if (NS_FAILED(result) || !tx)
@ -1077,21 +953,3 @@ nsTransactionManager::EndTransaction()
return result; return result;
} }
nsresult
nsTransactionManager::Lock()
{
if (mMonitor)
PR_EnterMonitor(mMonitor);
return NS_OK;
}
nsresult
nsTransactionManager::Unlock()
{
if (mMonitor)
PR_ExitMonitor(mMonitor);
return NS_OK;
}

View File

@ -38,7 +38,6 @@
#ifndef nsTransactionManager_h__ #ifndef nsTransactionManager_h__
#define nsTransactionManager_h__ #define nsTransactionManager_h__
#include "prmon.h"
#include "nsWeakReference.h" #include "nsWeakReference.h"
#include "nsITransactionManager.h" #include "nsITransactionManager.h"
#include "nsCOMArray.h" #include "nsCOMArray.h"
@ -65,8 +64,6 @@ private:
nsTransactionRedoStack mRedoStack; nsTransactionRedoStack mRedoStack;
nsCOMArray<nsITransactionListener> mListeners; nsCOMArray<nsITransactionListener> mListeners;
PRMonitor *mMonitor;
public: public:
/** The default constructor. /** The default constructor.
@ -112,8 +109,6 @@ private:
/* nsTransactionManager specific private methods. */ /* nsTransactionManager specific private methods. */
virtual nsresult BeginTransaction(nsITransaction *aTransaction); virtual nsresult BeginTransaction(nsITransaction *aTransaction);
virtual nsresult EndTransaction(void); virtual nsresult EndTransaction(void);
virtual nsresult Lock(void);
virtual nsresult Unlock(void);
}; };
#endif // nsTransactionManager_h__ #endif // nsTransactionManager_h__