Files
tubestation/xpcom/threads/InputTaskManager.h
Sean Feng 35929d7fef Bug 1662265 - Fix input events handling for sync XHR when both TaskController and e10s are enabled r=smaug
There are two issues in our current setup

1) Input events which are occurring in the same tab are going to be lost
because sync XHR. We have event handling suppression for synx XHR, so input
events are going to be discarded.

2) Input events that are happening in another tab (same process as the
synx XHR tab) are not going to be delayed. This is not correct since
sync XHR should block the Javascript execution.

This patches fixes the above cases for when both TaskController and e10s are
enabled by suspending the InputTaskManager during sync XHR, which
delays the input event handling and keeps the events around.

Differential Revision: https://phabricator.services.mozilla.com/D90780
2020-12-03 03:13:04 +00:00

94 lines
2.7 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_InputTaskManager_h
#define mozilla_InputTaskManager_h
#include "TaskController.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/StaticPrefs_dom.h"
namespace mozilla {
class InputTaskManager : public TaskManager {
public:
int32_t GetPriorityModifierForEventLoopTurn(
const MutexAutoLock& aProofOfLock) final;
void WillRunTask() final;
void DidRunTask() final;
enum InputEventQueueState {
STATE_DISABLED,
STATE_FLUSHING,
STATE_SUSPEND,
STATE_ENABLED
};
void EnableInputEventPrioritization();
void FlushInputEventPrioritization();
void SuspendInputEventPrioritization();
void ResumeInputEventPrioritization();
InputEventQueueState State() { return mInputQueueState; }
void SetState(InputEventQueueState aState) { mInputQueueState = aState; }
TimeStamp InputHandlingStartTime() { return mInputHandlingStartTime; }
void SetInputHandlingStartTime(TimeStamp aStartTime) {
mInputHandlingStartTime = aStartTime;
}
static InputTaskManager* Get() { return gInputTaskManager.get(); }
static void Cleanup() { gInputTaskManager = nullptr; }
static void Init();
bool IsSuspended(const MutexAutoLock& aProofOfLock) override {
MOZ_ASSERT(NS_IsMainThread());
return mIsSuspended;
}
bool IsSuspended() {
MOZ_ASSERT(NS_IsMainThread());
return mIsSuspended;
}
void SetIsSuspended(bool aIsSuspended) {
MOZ_ASSERT(NS_IsMainThread());
mIsSuspended = aIsSuspended;
}
static bool CanSuspendInputEvent() {
// Ensure it's content process because InputTaskManager only
// works in e10s.
//
// Input tasks will have nullptr as their task manager when the
// event queue state is STATE_DISABLED, so we can't suspend
// input events.
return XRE_IsContentProcess() &&
StaticPrefs::dom_input_events_canSuspendInBCG_enabled_AtStartup() &&
InputTaskManager::Get()->State() !=
InputEventQueueState::STATE_DISABLED;
}
private:
InputTaskManager() : mInputQueueState(STATE_DISABLED) {}
TimeStamp mInputHandlingStartTime;
Atomic<InputEventQueueState> mInputQueueState;
AutoTArray<TimeStamp, 4> mStartTimes;
static StaticRefPtr<InputTaskManager> gInputTaskManager;
// Unlike mInputQueueState, mIsSuspended is used by TaskController to
// indicate its status
bool mIsSuspended = false;
};
} // namespace mozilla
#endif // mozilla_InputTaskManager_h