From c3d778e5d4981710c8bc8da424cef3afcd03d81c Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Tue, 2 Sep 2014 09:27:26 +0900 Subject: [PATCH] Bug 1052343 part.6 Don't destroy nsTextStore instance during it's locking the document r=emk --- widget/windows/nsTextStore.cpp | 23 +++++++++++++++++++---- widget/windows/nsTextStore.h | 3 +++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/widget/windows/nsTextStore.cpp b/widget/windows/nsTextStore.cpp index 2f01034488d5..3a9af420cb4c 100644 --- a/widget/windows/nsTextStore.cpp +++ b/widget/windows/nsTextStore.cpp @@ -1177,6 +1177,7 @@ nsTextStore::nsTextStore() , mIsRecordingActionsWithoutLock(false) , mPendingOnSelectionChange(false) , mPendingOnLayoutChange(false) + , mPendingDestroy(false) , mNativeCaretIsCreated(false) { for (int32_t i = 0; i < NUM_OF_SUPPORTED_ATTRS; i++) { @@ -1258,8 +1259,15 @@ bool nsTextStore::Destroy() { PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, - ("TSF: 0x%p nsTextStore::Destroy(), mComposition.IsComposing()=%s", - this, GetBoolName(mComposition.IsComposing()))); + ("TSF: 0x%p nsTextStore::Destroy(), mLock=%s, " + "mComposition.IsComposing()=%s", + this, GetLockFlagNameStr(mLock).get(), + GetBoolName(mComposition.IsComposing()))); + + if (mLock) { + mPendingDestroy = true; + return true; + } // If there is composition, TSF keeps the composition even after the text // store destroyed. So, we should clear the composition here. @@ -1430,6 +1438,9 @@ nsTextStore::RequestLock(DWORD dwLockFlags, ("TSF: 0x%p Locking (%s) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", this, GetLockFlagNameStr(mLock).get())); + // Don't release this instance during this lock because this is called by + // TSF but they don't grab us during this call. + nsRefPtr kungFuDeathGrip(this); *phrSession = mSink->OnLockGranted(mLock); PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, ("TSF: 0x%p Unlocked (%s) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" @@ -1454,7 +1465,7 @@ nsTextStore::RequestLock(DWORD dwLockFlags, // The document is now completely unlocked. mLock = 0; - if (mPendingOnLayoutChange) { + if (!mPendingDestroy && mPendingOnLayoutChange) { mPendingOnLayoutChange = false; if (mSink) { PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, @@ -1478,7 +1489,7 @@ nsTextStore::RequestLock(DWORD dwLockFlags, } } - if (mPendingOnSelectionChange) { + if (!mPendingDestroy && mPendingOnSelectionChange) { mPendingOnSelectionChange = false; if (mSink) { PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, @@ -1488,6 +1499,10 @@ nsTextStore::RequestLock(DWORD dwLockFlags, } } + if (mPendingDestroy) { + Destroy(); + } + PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, ("TSF: 0x%p nsTextStore::RequestLock() succeeded: *phrSession=%s", this, GetTextStoreReturnValueName(*phrSession))); diff --git a/widget/windows/nsTextStore.h b/widget/windows/nsTextStore.h index 27a0fbf37236..d6782f3385a6 100644 --- a/widget/windows/nsTextStore.h +++ b/widget/windows/nsTextStore.h @@ -732,6 +732,9 @@ protected: // ITfContextOwnerServices::OnLayoutChange() after the layout is fixed and // the document is unlocked. bool mPendingOnLayoutChange; + // During the documet is locked, we shouldn't destroy the instance. + // If this is true, the instance will be destroyed after unlocked. + bool mPendingDestroy; // While there is native caret, this is true. Otherwise, false. bool mNativeCaretIsCreated;