mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 18:08:58 +00:00
Backed out changeset 97c2d1419843 (bug 1423833) for assertion failures on WinWindowOcclusionTracker.cpp. CLOSED TREE
This commit is contained in:
parent
3c392b55f3
commit
507ccc820b
@ -18,6 +18,7 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/DataMutex.h"
|
||||
#include "mozilla/gfx/Logging.h"
|
||||
#include "mozilla/layers/SynchronousTask.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/StaticPrefs_widget.h"
|
||||
@ -335,30 +336,21 @@ void WinWindowOcclusionTracker::Ensure() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
LOG(LogLevel::Info, "WinWindowOcclusionTracker::Ensure()");
|
||||
|
||||
base::Thread::Options options;
|
||||
options.message_loop_type = MessageLoop::TYPE_UI;
|
||||
|
||||
if (sTracker) {
|
||||
// Try to reuse the thread, which involves stopping and restarting it.
|
||||
sTracker->mThread->Stop();
|
||||
if (sTracker->mThread->StartWithOptions(options)) {
|
||||
// Success!
|
||||
return;
|
||||
}
|
||||
// Restart failed, so null out our sTracker and try again with a new
|
||||
// thread. This will cause the old singleton instance to be deallocated,
|
||||
// which will destroy its mThread as well.
|
||||
sTracker = nullptr;
|
||||
}
|
||||
|
||||
UniquePtr<base::Thread> thread =
|
||||
MakeUnique<base::Thread>("WinWindowOcclusionCalc");
|
||||
|
||||
if (!thread->StartWithOptions(options)) {
|
||||
return;
|
||||
}
|
||||
|
||||
sTracker = new WinWindowOcclusionTracker(std::move(thread));
|
||||
base::Thread* thread = new base::Thread("WinWindowOcclusionCalc");
|
||||
|
||||
base::Thread::Options options;
|
||||
options.message_loop_type = MessageLoop::TYPE_UI;
|
||||
|
||||
if (!thread->StartWithOptions(options)) {
|
||||
delete thread;
|
||||
return;
|
||||
}
|
||||
|
||||
sTracker = new WinWindowOcclusionTracker(thread);
|
||||
WindowOcclusionCalculator::CreateInstance();
|
||||
|
||||
RefPtr<Runnable> runnable =
|
||||
@ -370,46 +362,34 @@ void WinWindowOcclusionTracker::Ensure() {
|
||||
|
||||
/* static */
|
||||
void WinWindowOcclusionTracker::ShutDown() {
|
||||
if (!sTracker) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(sTracker);
|
||||
LOG(LogLevel::Info, "WinWindowOcclusionTracker::ShutDown()");
|
||||
|
||||
sTracker->Destroy();
|
||||
|
||||
// Our thread could hang while we're waiting for it to stop.
|
||||
// Since we're shutting down, that's not a critical problem.
|
||||
// We set a reasonable amount of time to wait for shutdown,
|
||||
// and if it succeeds within that time, we correctly stop
|
||||
// our thread by nulling out the refptr, which will cause it
|
||||
// to be deallocated and join the thread. If it times out,
|
||||
// we do nothing, which means that the thread will not be
|
||||
// joined and sTracker memory will leak.
|
||||
static const TimeDuration TIMEOUT = TimeDuration::FromSeconds(2.0);
|
||||
// Our shutdown task could hang. Since we're shutting down,
|
||||
// that's not a critical problem. We set a reasonable amount
|
||||
// of time to wait for shutdown, and if it succeeds within
|
||||
// that time, we correctly stop our tracker thread. If it
|
||||
// times out, we just leak the memory and proceed.
|
||||
static const PRIntervalTime TIMEOUT = PR_TicksPerSecond() * 2;
|
||||
layers::SynchronousTask task("WinWindowOcclusionTracker");
|
||||
RefPtr<Runnable> runnable =
|
||||
WrapRunnable(RefPtr<WindowOcclusionCalculator>(
|
||||
WindowOcclusionCalculator::GetInstance()),
|
||||
&WindowOcclusionCalculator::Shutdown);
|
||||
&WindowOcclusionCalculator::Shutdown, &task);
|
||||
OcclusionCalculatorLoop()->PostTask(runnable.forget());
|
||||
|
||||
CVStatus status;
|
||||
{
|
||||
MonitorAutoLock lock(sTracker->mMonitor);
|
||||
|
||||
// Monitor uses SleepConditionVariableSRW, which can have
|
||||
// spurious wakeups which are reported as timeouts, so we
|
||||
// check timestamps to ensure that we've waited as long we
|
||||
// intended to.
|
||||
TimeStamp timeStart = TimeStamp::NowLoRes();
|
||||
do {
|
||||
status = sTracker->mMonitor.Wait(TIMEOUT);
|
||||
} while ((status == CVStatus::Timeout) &&
|
||||
((TimeStamp::NowLoRes() - timeStart) < TIMEOUT));
|
||||
nsresult rv = task.Wait(TIMEOUT);
|
||||
if (rv == NS_OK) {
|
||||
sTracker->mThread->Stop();
|
||||
}
|
||||
|
||||
if (status == CVStatus::NoTimeout) {
|
||||
WindowOcclusionCalculator::ClearInstance();
|
||||
sTracker = nullptr;
|
||||
}
|
||||
WindowOcclusionCalculator::ClearInstance();
|
||||
sTracker = nullptr;
|
||||
}
|
||||
|
||||
void WinWindowOcclusionTracker::Destroy() {
|
||||
@ -506,9 +486,8 @@ void WinWindowOcclusionTracker::OnWindowVisibilityChanged(nsBaseWidget* aWindow,
|
||||
mSerializedTaskDispatcher->PostTaskToCalculator(runnable.forget());
|
||||
}
|
||||
|
||||
WinWindowOcclusionTracker::WinWindowOcclusionTracker(
|
||||
UniquePtr<base::Thread> aThread)
|
||||
: mThread(std::move(aThread)), mMonitor("WinWindowOcclusionTracker") {
|
||||
WinWindowOcclusionTracker::WinWindowOcclusionTracker(base::Thread* aThread)
|
||||
: mThread(aThread) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
LOG(LogLevel::Info, "WinWindowOcclusionTracker::WinWindowOcclusionTracker()");
|
||||
|
||||
@ -527,6 +506,7 @@ WinWindowOcclusionTracker::~WinWindowOcclusionTracker() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
LOG(LogLevel::Info,
|
||||
"WinWindowOcclusionTracker::~WinWindowOcclusionTracker()");
|
||||
delete mThread;
|
||||
}
|
||||
|
||||
// static
|
||||
@ -835,8 +815,7 @@ StaticRefPtr<WinWindowOcclusionTracker::WindowOcclusionCalculator>
|
||||
WinWindowOcclusionTracker::WindowOcclusionCalculator::sCalculator;
|
||||
|
||||
WinWindowOcclusionTracker::WindowOcclusionCalculator::
|
||||
WindowOcclusionCalculator()
|
||||
: mMonitor(WinWindowOcclusionTracker::Get()->mMonitor) {
|
||||
WindowOcclusionCalculator() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
LOG(LogLevel::Info, "WindowOcclusionCalculator()");
|
||||
|
||||
@ -880,20 +859,19 @@ void WinWindowOcclusionTracker::WindowOcclusionCalculator::Initialize() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void WinWindowOcclusionTracker::WindowOcclusionCalculator::Shutdown() {
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
void WinWindowOcclusionTracker::WindowOcclusionCalculator::Shutdown(
|
||||
layers::SynchronousTask* aTask) {
|
||||
MOZ_ASSERT(IsInWinWindowOcclusionThread());
|
||||
CALC_LOG(LogLevel::Info, "Shutdown()");
|
||||
|
||||
layers::AutoCompleteTask complete(aTask);
|
||||
|
||||
UnregisterEventHooks();
|
||||
if (mOcclusionUpdateRunnable) {
|
||||
mOcclusionUpdateRunnable->Cancel();
|
||||
mOcclusionUpdateRunnable = nullptr;
|
||||
}
|
||||
mVirtualDesktopManager = nullptr;
|
||||
|
||||
mMonitor.NotifyAll();
|
||||
}
|
||||
|
||||
void WinWindowOcclusionTracker::WindowOcclusionCalculator::
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <vector>
|
||||
|
||||
#include "nsIWeakReferenceUtils.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "mozilla/ThreadSafeWeakPtr.h"
|
||||
#include "mozilla/widget/WindowOcclusionState.h"
|
||||
#include "mozilla/widget/WinEventObserver.h"
|
||||
@ -29,6 +28,10 @@ class Thread;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace layers {
|
||||
class SynchronousTask;
|
||||
}
|
||||
|
||||
namespace widget {
|
||||
|
||||
class OcclusionUpdateRunnable;
|
||||
@ -86,7 +89,7 @@ class WinWindowOcclusionTracker final : public DisplayStatusListener,
|
||||
friend class ::WinWindowOcclusionTrackerTest;
|
||||
friend class ::WinWindowOcclusionTrackerInteractiveTest;
|
||||
|
||||
explicit WinWindowOcclusionTracker(UniquePtr<base::Thread> aThread);
|
||||
explicit WinWindowOcclusionTracker(base::Thread* aThread);
|
||||
virtual ~WinWindowOcclusionTracker();
|
||||
|
||||
// This class computes the occlusion state of the tracked windows.
|
||||
@ -105,7 +108,7 @@ class WinWindowOcclusionTracker final : public DisplayStatusListener,
|
||||
static WindowOcclusionCalculator* GetInstance() { return sCalculator; }
|
||||
|
||||
void Initialize();
|
||||
void Shutdown();
|
||||
void Shutdown(layers::SynchronousTask* aTask);
|
||||
|
||||
void EnableOcclusionTrackingForWindow(HWND hwnd);
|
||||
void DisableOcclusionTrackingForWindow(HWND hwnd);
|
||||
@ -249,10 +252,6 @@ class WinWindowOcclusionTracker final : public DisplayStatusListener,
|
||||
// Used to serialize tasks related to mRootWindowHwndsOcclusionState.
|
||||
RefPtr<SerializedTaskDispatcher> mSerializedTaskDispatcher;
|
||||
|
||||
// This is an alias to the singleton WinWindowOcclusionTracker mMonitor,
|
||||
// and is used in ShutDown().
|
||||
Monitor& mMonitor;
|
||||
|
||||
friend class OcclusionUpdateRunnable;
|
||||
};
|
||||
|
||||
@ -291,8 +290,7 @@ class WinWindowOcclusionTracker final : public DisplayStatusListener,
|
||||
static StaticRefPtr<WinWindowOcclusionTracker> sTracker;
|
||||
|
||||
// "WinWindowOcclusionCalc" thread.
|
||||
UniquePtr<base::Thread> mThread;
|
||||
Monitor mMonitor;
|
||||
base::Thread* const mThread;
|
||||
|
||||
// Map of HWND to widget. Maintained on main thread, and used to send
|
||||
// occlusion state notifications to Windows from
|
||||
|
Loading…
Reference in New Issue
Block a user