mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1074557 - Remove the lock in nsWindowMediator. r=Neil
This commit is contained in:
parent
bc4244f5a9
commit
08a6fc02ef
@ -53,8 +53,7 @@ nsWindowMediator::GetDOMWindow(nsIXULWindow* inWindow,
|
||||
|
||||
nsWindowMediator::nsWindowMediator() :
|
||||
mEnumeratorList(), mOldestWindow(nullptr), mTopmostWindow(nullptr),
|
||||
mTimeStamp(0), mSortingZOrder(false), mReady(false),
|
||||
mListLock("nsWindowMediator.mListLock")
|
||||
mTimeStamp(0), mSortingZOrder(false), mReady(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -79,6 +78,7 @@ nsresult nsWindowMediator::Init()
|
||||
|
||||
NS_IMETHODIMP nsWindowMediator::RegisterWindow(nsIXULWindow* inWindow)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_STATE(mReady);
|
||||
|
||||
if (GetInfoFor(inWindow)) {
|
||||
@ -96,7 +96,6 @@ NS_IMETHODIMP nsWindowMediator::RegisterWindow(nsIXULWindow* inWindow)
|
||||
WindowTitleData winData = { inWindow, nullptr };
|
||||
mListeners.EnumerateForwards(notifyOpenWindow, &winData);
|
||||
|
||||
MutexAutoLock lock(mListLock);
|
||||
if (mOldestWindow)
|
||||
windowInfo->InsertAfter(mOldestWindow->mOlder, nullptr);
|
||||
else
|
||||
@ -108,8 +107,8 @@ NS_IMETHODIMP nsWindowMediator::RegisterWindow(nsIXULWindow* inWindow)
|
||||
NS_IMETHODIMP
|
||||
nsWindowMediator::UnregisterWindow(nsIXULWindow* inWindow)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_STATE(mReady);
|
||||
MutexAutoLock lock(mListLock);
|
||||
nsWindowInfo *info = GetInfoFor(inWindow);
|
||||
if (info)
|
||||
return UnregisterWindow(info);
|
||||
@ -192,9 +191,10 @@ nsWindowMediator::GetInfoFor(nsIWidget *aWindow)
|
||||
NS_IMETHODIMP
|
||||
nsWindowMediator::GetEnumerator(const char16_t* inType, nsISimpleEnumerator** outEnumerator)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG_POINTER(outEnumerator);
|
||||
NS_ENSURE_STATE(mReady);
|
||||
MutexAutoLock lock(mListLock);
|
||||
|
||||
nsAppShellWindowEnumerator *enumerator = new nsASDOMWindowEarlyToLateEnumerator(inType, *this);
|
||||
if (enumerator)
|
||||
return enumerator->QueryInterface(NS_GET_IID(nsISimpleEnumerator) , (void**)outEnumerator);
|
||||
@ -205,9 +205,10 @@ nsWindowMediator::GetEnumerator(const char16_t* inType, nsISimpleEnumerator** ou
|
||||
NS_IMETHODIMP
|
||||
nsWindowMediator::GetXULWindowEnumerator(const char16_t* inType, nsISimpleEnumerator** outEnumerator)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG_POINTER(outEnumerator);
|
||||
NS_ENSURE_STATE(mReady);
|
||||
MutexAutoLock lock(mListLock);
|
||||
|
||||
nsAppShellWindowEnumerator *enumerator = new nsASXULWindowEarlyToLateEnumerator(inType, *this);
|
||||
if (enumerator)
|
||||
return enumerator->QueryInterface(NS_GET_IID(nsISimpleEnumerator) , (void**)outEnumerator);
|
||||
@ -220,9 +221,10 @@ nsWindowMediator::GetZOrderDOMWindowEnumerator(
|
||||
const char16_t *aWindowType, bool aFrontToBack,
|
||||
nsISimpleEnumerator **_retval)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
NS_ENSURE_STATE(mReady);
|
||||
MutexAutoLock lock(mListLock);
|
||||
|
||||
nsAppShellWindowEnumerator *enumerator;
|
||||
if (aFrontToBack)
|
||||
enumerator = new nsASDOMWindowFrontToBackEnumerator(aWindowType, *this);
|
||||
@ -239,9 +241,10 @@ nsWindowMediator::GetZOrderXULWindowEnumerator(
|
||||
const char16_t *aWindowType, bool aFrontToBack,
|
||||
nsISimpleEnumerator **_retval)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
NS_ENSURE_STATE(mReady);
|
||||
MutexAutoLock lock(mListLock);
|
||||
|
||||
nsAppShellWindowEnumerator *enumerator;
|
||||
if (aFrontToBack)
|
||||
enumerator = new nsASXULWindowFrontToBackEnumerator(aWindowType, *this);
|
||||
@ -270,6 +273,7 @@ nsWindowMediator::RemoveEnumerator(nsAppShellWindowEnumerator * inEnumerator)
|
||||
NS_IMETHODIMP
|
||||
nsWindowMediator::GetMostRecentWindow(const char16_t* inType, nsIDOMWindow** outWindow)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG_POINTER(outWindow);
|
||||
*outWindow = nullptr;
|
||||
if (!mReady)
|
||||
@ -277,10 +281,7 @@ nsWindowMediator::GetMostRecentWindow(const char16_t* inType, nsIDOMWindow** out
|
||||
|
||||
// Find the most window with the highest time stamp that matches
|
||||
// the requested type
|
||||
|
||||
MutexAutoLock lock(mListLock);
|
||||
nsWindowInfo *info = MostRecentWindowInfo(inType);
|
||||
|
||||
if (info && info->mWindow) {
|
||||
nsCOMPtr<nsIDOMWindow> DOMWindow;
|
||||
if (NS_SUCCEEDED(GetDOMWindow(info->mWindow, DOMWindow))) {
|
||||
@ -356,8 +357,8 @@ nsWindowMediator::GetCurrentInnerWindowWithId(uint64_t aWindowID,
|
||||
NS_IMETHODIMP
|
||||
nsWindowMediator::UpdateWindowTimeStamp(nsIXULWindow* inWindow)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_STATE(mReady);
|
||||
MutexAutoLock lock(mListLock);
|
||||
nsWindowInfo *info = GetInfoFor(inWindow);
|
||||
if (info) {
|
||||
// increment the window's time stamp
|
||||
@ -371,8 +372,8 @@ NS_IMETHODIMP
|
||||
nsWindowMediator::UpdateWindowTitle(nsIXULWindow* inWindow,
|
||||
const char16_t* inTitle)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_STATE(mReady);
|
||||
MutexAutoLock lock(mListLock);
|
||||
if (GetInfoFor(inWindow)) {
|
||||
WindowTitleData winData = { inWindow, inTitle };
|
||||
mListeners.EnumerateForwards(notifyWindowTitleChange, &winData);
|
||||
@ -396,6 +397,7 @@ nsWindowMediator::CalculateZPosition(
|
||||
nsIWidget **outBelow,
|
||||
bool *outAltered)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG_POINTER(outBelow);
|
||||
NS_ENSURE_STATE(mReady);
|
||||
|
||||
@ -426,8 +428,6 @@ nsWindowMediator::CalculateZPosition(
|
||||
uint32_t inZ;
|
||||
GetZLevel(inWindow, &inZ);
|
||||
|
||||
MutexAutoLock lock(mListLock);
|
||||
|
||||
if (inPosition == nsIWindowMediator::zLevelBelow) {
|
||||
// locate inBelow. use topmost if it can't be found or isn't in the
|
||||
// z-order list
|
||||
@ -526,6 +526,7 @@ nsWindowMediator::SetZPosition(
|
||||
uint32_t inPosition,
|
||||
nsIXULWindow *inBelow)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
nsWindowInfo *inInfo,
|
||||
*belowInfo;
|
||||
|
||||
@ -540,7 +541,6 @@ nsWindowMediator::SetZPosition(
|
||||
return NS_OK;
|
||||
|
||||
NS_ENSURE_STATE(mReady);
|
||||
MutexAutoLock lock(mListLock);
|
||||
|
||||
/* Locate inWindow and unlink it from the z-order list.
|
||||
It's important we look for it in the age list, not the z-order list.
|
||||
@ -597,8 +597,8 @@ nsWindowMediator::GetZLevel(nsIXULWindow *aWindow, uint32_t *_retval)
|
||||
NS_IMETHODIMP
|
||||
nsWindowMediator::SetZLevel(nsIXULWindow *aWindow, uint32_t aZLevel)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_STATE(mReady);
|
||||
MutexAutoLock lock(mListLock);
|
||||
|
||||
nsWindowInfo *info = GetInfoFor(aWindow);
|
||||
NS_ASSERTION(info, "setting z level of unregistered window");
|
||||
@ -622,7 +622,7 @@ nsWindowMediator::SetZLevel(nsIXULWindow *aWindow, uint32_t aZLevel)
|
||||
has been changed, so one window is potentially out of place. Such a sort
|
||||
is most efficiently done in a particular direction. Use this one
|
||||
if a window's z level has just been reduced, so the sort is most efficiently
|
||||
done front to back. Assumes caller has locked mListLock.
|
||||
done front to back.
|
||||
Note it's hardly worth going to all the trouble to write two versions
|
||||
of this method except that if we choose the inefficient sorting direction,
|
||||
on slow systems windows could visibly bubble around the window that
|
||||
@ -777,19 +777,9 @@ nsWindowMediator::Observe(nsISupports* aSubject,
|
||||
const char16_t* aData)
|
||||
{
|
||||
if (!strcmp(aTopic, "xpcom-shutdown") && mReady) {
|
||||
// Unregistering a window may cause its destructor to run, causing it to
|
||||
// call into the window mediator, try to acquire mListLock, and deadlock.
|
||||
// Our solution is to hold strong refs to all windows until we release
|
||||
// mListLock.
|
||||
nsTArray<nsCOMPtr<nsIXULWindow> > windows;
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mListLock);
|
||||
while (mOldestWindow) {
|
||||
windows.AppendElement(mOldestWindow->mWindow);
|
||||
UnregisterWindow(mOldestWindow);
|
||||
}
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
while (mOldestWindow)
|
||||
UnregisterWindow(mOldestWindow);
|
||||
mReady = false;
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -6,7 +6,6 @@
|
||||
#ifndef nsWindowMediator_h_
|
||||
#define nsWindowMediator_h_
|
||||
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIWindowMediator.h"
|
||||
#include "nsIObserver.h"
|
||||
@ -24,7 +23,6 @@ class nsASDOMWindowBackToFrontEnumerator;
|
||||
class nsASXULWindowBackToFrontEnumerator;
|
||||
class nsIWindowMediatorListener;
|
||||
struct nsWindowInfo;
|
||||
struct PRLock;
|
||||
|
||||
class nsWindowMediator :
|
||||
public nsIWindowMediator,
|
||||
@ -71,7 +69,6 @@ private:
|
||||
int32_t mTimeStamp;
|
||||
bool mSortingZOrder;
|
||||
bool mReady;
|
||||
mozilla::Mutex mListLock;
|
||||
|
||||
nsCOMArray<nsIWindowMediatorListener> mListeners;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user