mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 622657 - catch invalid bookmark items and delete them when syncing bookmarks. r=rnewman (bd91e14c9a) - Bug 1166853 - Sync "hangs" when trying to apply a livemark to a reconciled folder. r=rnewman (94a6a19753) - Bug 1012597 - Part 1: provide a way to invalidate the Places GUIDs cache. r=rnewman (66f43cb831) - Bug 1012597 - Part 2: ensure Sync invalidates the Places GUIDs cache when needed. r=rnewman (2a67b0dfa8) - Bug 1182366 - avoid an invalid bookmark from preventing all bookmarks syncing. r=rnewman (df895d4c35) - let -> var (e9c382c761) - Bug 1188170 - log the url string when the Sync bookmarks engine fails to get a URI. r=rnewman (424e5405f7) - Bug 1195603 - prevent Sync from blocking app shutdown. r=rnewman (94c3091f9c) - Bug 1183934 - only log an error saving JSON if an error actually occurred. r=rnewman (6b4358035c) - Bug 1198385 - Use MFBT guard macros in the editor guard objects; r=froydnj (72e5e9f66f) - Bug 1198385 follow-up: Fix the build bustage on a CLOSED TREE (d626e56e92) - Bug 1177013 - Use CancelCurrentTransaction to avoid crashes (r=dvander) (362e5fc343) - Bug 1154990 - Better error messages when IPC send fails (r=bent) (b311fb94aa) - Bug 1177013 - Avoid memory leaks when returning errors from IPC Send (r=dvander) (f453a8feb5) - Bug 1176096 - Ensure we don't do self-moves in move assignment (r=bent) (31aca4ad89) - Bug 1177013 - Crash in IPC situations where we don't know what to do (r=dvander) (0e86cc437e) - Bug 1185639 - Allow deferred message processing to happen between consecutive IPC message dispatches. r=jimm (7782c9caaf)
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include "mozilla/DebugOnly.h"
|
||||
|
||||
#include "WindowsMessageLoop.h"
|
||||
#include "Neutering.h"
|
||||
#include "MessageChannel.h"
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
@@ -862,6 +863,81 @@ IsTimeoutExpired(PRIntervalTime aStart, PRIntervalTime aTimeout)
|
||||
(aTimeout <= (PR_IntervalNow() - aStart));
|
||||
}
|
||||
|
||||
static HHOOK gWindowHook;
|
||||
|
||||
static inline void
|
||||
StartNeutering()
|
||||
{
|
||||
MOZ_ASSERT(gUIThreadId);
|
||||
MOZ_ASSERT(!gWindowHook);
|
||||
NS_ASSERTION(!MessageChannel::IsPumpingMessages(),
|
||||
"Shouldn't be pumping already!");
|
||||
MessageChannel::SetIsPumpingMessages(true);
|
||||
gWindowHook = ::SetWindowsHookEx(WH_CALLWNDPROC, CallWindowProcedureHook,
|
||||
nullptr, gUIThreadId);
|
||||
NS_ASSERTION(gWindowHook, "Failed to set hook!");
|
||||
}
|
||||
|
||||
static void
|
||||
StopNeutering()
|
||||
{
|
||||
MOZ_ASSERT(MessageChannel::IsPumpingMessages());
|
||||
::UnhookWindowsHookEx(gWindowHook);
|
||||
gWindowHook = NULL;
|
||||
::UnhookNeuteredWindows();
|
||||
// Before returning we need to set a hook to run any deferred messages that
|
||||
// we received during the IPC call. The hook will unset itself as soon as
|
||||
// someone else calls GetMessage, PeekMessage, or runs code that generates
|
||||
// a "nonqueued" message.
|
||||
::ScheduleDeferredMessageRun();
|
||||
MessageChannel::SetIsPumpingMessages(false);
|
||||
}
|
||||
|
||||
NeuteredWindowRegion::NeuteredWindowRegion(bool aDoNeuter MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
: mNeuteredByThis(!gWindowHook)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
if (aDoNeuter && mNeuteredByThis) {
|
||||
StartNeutering();
|
||||
}
|
||||
}
|
||||
|
||||
NeuteredWindowRegion::~NeuteredWindowRegion()
|
||||
{
|
||||
if (gWindowHook && mNeuteredByThis) {
|
||||
StopNeutering();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NeuteredWindowRegion::PumpOnce()
|
||||
{
|
||||
MSG msg = {0};
|
||||
// Pump any COM messages so that we don't hang due to STA marshaling.
|
||||
if (gCOMWindow && ::PeekMessageW(&msg, gCOMWindow, 0, 0, PM_REMOVE)) {
|
||||
::TranslateMessage(&msg);
|
||||
::DispatchMessageW(&msg);
|
||||
}
|
||||
// Expunge any nonqueued messages on the current thread.
|
||||
::PeekMessageW(&msg, nullptr, 0, 0, PM_NOREMOVE);
|
||||
}
|
||||
|
||||
DeneuteredWindowRegion::DeneuteredWindowRegion(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
|
||||
: mReneuter(gWindowHook != NULL)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
if (mReneuter) {
|
||||
StopNeutering();
|
||||
}
|
||||
}
|
||||
|
||||
DeneuteredWindowRegion::~DeneuteredWindowRegion()
|
||||
{
|
||||
if (mReneuter) {
|
||||
StartNeutering();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
MessageChannel::WaitForSyncNotify()
|
||||
{
|
||||
@@ -916,15 +992,6 @@ MessageChannel::WaitForSyncNotify()
|
||||
NS_ASSERTION(timerId, "SetTimer failed!");
|
||||
}
|
||||
|
||||
// Setup deferred processing of native events while we wait for a response.
|
||||
NS_ASSERTION(!MessageChannel::IsPumpingMessages(),
|
||||
"Shouldn't be pumping already!");
|
||||
|
||||
MessageChannel::SetIsPumpingMessages(true);
|
||||
HHOOK windowHook = SetWindowsHookEx(WH_CALLWNDPROC, CallWindowProcedureHook,
|
||||
nullptr, gUIThreadId);
|
||||
NS_ASSERTION(windowHook, "Failed to set hook!");
|
||||
|
||||
{
|
||||
while (1) {
|
||||
MSG msg = { 0 };
|
||||
@@ -998,25 +1065,11 @@ MessageChannel::WaitForSyncNotify()
|
||||
}
|
||||
}
|
||||
|
||||
// Unhook the neutered window procedure hook.
|
||||
UnhookWindowsHookEx(windowHook);
|
||||
|
||||
// Unhook any neutered windows procedures so messages can be delivered
|
||||
// normally.
|
||||
UnhookNeuteredWindows();
|
||||
|
||||
// Before returning we need to set a hook to run any deferred messages that
|
||||
// we received during the IPC call. The hook will unset itself as soon as
|
||||
// someone else calls GetMessage, PeekMessage, or runs code that generates
|
||||
// a "nonqueued" message.
|
||||
ScheduleDeferredMessageRun();
|
||||
|
||||
if (timerId) {
|
||||
KillTimer(nullptr, timerId);
|
||||
timerId = 0;
|
||||
}
|
||||
|
||||
MessageChannel::SetIsPumpingMessages(false);
|
||||
|
||||
return WaitResponse(timedout);
|
||||
}
|
||||
|
||||
@@ -1050,56 +1103,28 @@ MessageChannel::WaitForInterruptNotify()
|
||||
UINT_PTR timerId = 0;
|
||||
TimeoutData timeoutData = { 0 };
|
||||
|
||||
// windowHook is used as a flag variable for the loop below: if it is set
|
||||
// gWindowHook is used as a flag variable for the loop below: if it is set
|
||||
// and we start to spin a nested event loop, we need to clear the hook and
|
||||
// process deferred/pending messages.
|
||||
// If windowHook is nullptr, MessageChannel::IsPumpingMessages should be false.
|
||||
HHOOK windowHook = nullptr;
|
||||
|
||||
while (1) {
|
||||
NS_ASSERTION((!!windowHook) == MessageChannel::IsPumpingMessages(),
|
||||
"windowHook out of sync with reality");
|
||||
NS_ASSERTION((!!gWindowHook) == MessageChannel::IsPumpingMessages(),
|
||||
"gWindowHook out of sync with reality");
|
||||
|
||||
if (mTopFrame->mSpinNestedEvents) {
|
||||
if (windowHook) {
|
||||
UnhookWindowsHookEx(windowHook);
|
||||
windowHook = nullptr;
|
||||
|
||||
if (timerId) {
|
||||
KillTimer(nullptr, timerId);
|
||||
timerId = 0;
|
||||
}
|
||||
|
||||
// Used by widget to assert on incoming native events
|
||||
MessageChannel::SetIsPumpingMessages(false);
|
||||
|
||||
// Unhook any neutered windows procedures so messages can be delievered
|
||||
// normally.
|
||||
UnhookNeuteredWindows();
|
||||
|
||||
// Send all deferred "nonqueued" message to the intended receiver.
|
||||
// We're dropping into SpinInternalEventLoop so we should be fairly
|
||||
// certain these will get delivered soohn.
|
||||
ScheduleDeferredMessageRun();
|
||||
if (gWindowHook && timerId) {
|
||||
KillTimer(nullptr, timerId);
|
||||
timerId = 0;
|
||||
}
|
||||
DeneuteredWindowRegion deneuteredRgn;
|
||||
SpinInternalEventLoop();
|
||||
ResetEvent(mEvent);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!windowHook) {
|
||||
MessageChannel::SetIsPumpingMessages(true);
|
||||
windowHook = SetWindowsHookEx(WH_CALLWNDPROC, CallWindowProcedureHook,
|
||||
nullptr, gUIThreadId);
|
||||
NS_ASSERTION(windowHook, "Failed to set hook!");
|
||||
|
||||
NS_ASSERTION(!timerId, "Timer already initialized?");
|
||||
|
||||
if (mTimeoutMs != kNoTimeout) {
|
||||
InitTimeoutData(&timeoutData, mTimeoutMs);
|
||||
timerId = SetTimer(nullptr, 0, mTimeoutMs, nullptr);
|
||||
NS_ASSERTION(timerId, "SetTimer failed!");
|
||||
}
|
||||
if (mTimeoutMs != kNoTimeout && !timerId) {
|
||||
InitTimeoutData(&timeoutData, mTimeoutMs);
|
||||
timerId = SetTimer(nullptr, 0, mTimeoutMs, nullptr);
|
||||
NS_ASSERTION(timerId, "SetTimer failed!");
|
||||
}
|
||||
|
||||
MSG msg = { 0 };
|
||||
@@ -1151,27 +1176,11 @@ MessageChannel::WaitForInterruptNotify()
|
||||
}
|
||||
}
|
||||
|
||||
if (windowHook) {
|
||||
// Unhook the neutered window procedure hook.
|
||||
UnhookWindowsHookEx(windowHook);
|
||||
|
||||
// Unhook any neutered windows procedures so messages can be delivered
|
||||
// normally.
|
||||
UnhookNeuteredWindows();
|
||||
|
||||
// Before returning we need to set a hook to run any deferred messages that
|
||||
// we received during the IPC call. The hook will unset itself as soon as
|
||||
// someone else calls GetMessage, PeekMessage, or runs code that generates
|
||||
// a "nonqueued" message.
|
||||
ScheduleDeferredMessageRun();
|
||||
|
||||
if (timerId) {
|
||||
KillTimer(nullptr, timerId);
|
||||
}
|
||||
if (timerId) {
|
||||
KillTimer(nullptr, timerId);
|
||||
timerId = 0;
|
||||
}
|
||||
|
||||
MessageChannel::SetIsPumpingMessages(false);
|
||||
|
||||
return WaitResponse(timedout);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user