зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 2 changesets (bug 1792203) for causing Gtest failures. CLOSED TREE
Backed out changeset b597f145ec59 (bug 1792203) Backed out changeset 862f59a3f38c (bug 1792203)
This commit is contained in:
Родитель
b704dcf231
Коммит
3d14ccb418
|
@ -7,7 +7,6 @@
|
|||
#ifndef mozilla_ipc_AsyncBlockers_h
|
||||
#define mozilla_ipc_AsyncBlockers_h
|
||||
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/ThreadSafety.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
|
@ -29,21 +28,32 @@ class AsyncBlockers {
|
|||
mPromise(new GenericPromise::Private(__func__)) {}
|
||||
void Register(void* aBlocker) {
|
||||
MutexAutoLock lock(mLock);
|
||||
if (mResolved) {
|
||||
// Too late.
|
||||
return;
|
||||
}
|
||||
mBlockers.InsertElementSorted(aBlocker);
|
||||
}
|
||||
void Deregister(void* aBlocker) {
|
||||
MutexAutoLock lock(mLock);
|
||||
if (mResolved) {
|
||||
// Too late.
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mBlockers.ContainsSorted(aBlocker));
|
||||
MOZ_ALWAYS_TRUE(mBlockers.RemoveElementSorted(aBlocker));
|
||||
MaybeResolve();
|
||||
}
|
||||
RefPtr<GenericPromise> WaitUntilClear(uint32_t aTimeOutInMs = 0) {
|
||||
{
|
||||
if (!aTimeOutInMs) {
|
||||
// We don't need to wait, resolve the promise right away.
|
||||
MutexAutoLock lock(mLock);
|
||||
MaybeResolve();
|
||||
}
|
||||
|
||||
if (aTimeOutInMs > 0) {
|
||||
if (!mResolved) {
|
||||
mPromise->Resolve(true, __func__);
|
||||
mResolved = true;
|
||||
}
|
||||
} else {
|
||||
GetCurrentEventTarget()->DelayedDispatch(
|
||||
NS_NewRunnableFunction("AsyncBlockers::WaitUntilClear",
|
||||
[promise = mPromise]() {
|
||||
|
@ -58,22 +68,30 @@ class AsyncBlockers {
|
|||
}),
|
||||
aTimeOutInMs);
|
||||
}
|
||||
|
||||
return mPromise;
|
||||
}
|
||||
|
||||
virtual ~AsyncBlockers() { mPromise->Resolve(true, __func__); }
|
||||
virtual ~AsyncBlockers() {
|
||||
if (!mResolved) {
|
||||
mPromise->Resolve(true, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void MaybeResolve() MOZ_REQUIRES(mLock) {
|
||||
mLock.AssertCurrentThreadOwns();
|
||||
if (mResolved) {
|
||||
return;
|
||||
}
|
||||
if (!mBlockers.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
mPromise->Resolve(true, __func__);
|
||||
mResolved = true;
|
||||
}
|
||||
Mutex mLock;
|
||||
nsTArray<void*> mBlockers MOZ_GUARDED_BY(mLock);
|
||||
bool mResolved MOZ_GUARDED_BY(mLock) = false;
|
||||
const RefPtr<GenericPromise::Private> mPromise;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,179 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "mozilla/SpinEventLoopUntil.h"
|
||||
#include "mozilla/ipc/AsyncBlockers.h"
|
||||
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsINamed.h"
|
||||
#include "nsICrashReporter.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
#define PROCESS_EVENTS_UNTIL(_done) \
|
||||
SpinEventLoopUntil("TestAsyncBlockers"_ns, [&]() { return _done; });
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
// This global variable is defined in toolkit/xre/nsSigHandlers.cpp.
|
||||
extern unsigned int _gdb_sleep_duration;
|
||||
#endif // defined(XP_UNIX)
|
||||
|
||||
class TestAsyncBlockers : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
#if defined(XP_UNIX)
|
||||
mOldSleepDuration = ::_gdb_sleep_duration;
|
||||
::_gdb_sleep_duration = 0;
|
||||
#endif // defined(XP_UNIX)
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
void TearDown() final { ::_gdb_sleep_duration = mOldSleepDuration; }
|
||||
|
||||
private:
|
||||
unsigned int mOldSleepDuration = 0;
|
||||
#endif // defined(XP_UNIX)
|
||||
};
|
||||
|
||||
class Blocker {};
|
||||
|
||||
static void DisableCrashReporter() {
|
||||
nsCOMPtr<nsICrashReporter> crashreporter =
|
||||
do_GetService("@mozilla.org/toolkit/crash-reporter;1");
|
||||
if (crashreporter) {
|
||||
crashreporter->SetEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TestAsyncBlockers, Register) {
|
||||
AsyncBlockers blockers;
|
||||
Blocker* blocker = new Blocker();
|
||||
blockers.Register(blocker);
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
|
||||
TEST_F(TestAsyncBlockers, Register_Deregister) {
|
||||
AsyncBlockers blockers;
|
||||
Blocker* blocker = new Blocker();
|
||||
blockers.Register(blocker);
|
||||
blockers.Deregister(blocker);
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
|
||||
TEST_F(TestAsyncBlockers, Register_WaitUntilClear) {
|
||||
AsyncBlockers blockers;
|
||||
bool done = false;
|
||||
|
||||
Blocker* blocker = new Blocker();
|
||||
blockers.Register(blocker);
|
||||
|
||||
blockers.WaitUntilClear(5 * 1000)->Then(GetCurrentSerialEventTarget(),
|
||||
__func__, [&]() {
|
||||
EXPECT_TRUE(true);
|
||||
done = true;
|
||||
});
|
||||
|
||||
NS_ProcessPendingEvents(nullptr);
|
||||
|
||||
blockers.Deregister(blocker);
|
||||
|
||||
PROCESS_EVENTS_UNTIL(done);
|
||||
}
|
||||
|
||||
class AsyncBlockerTimerCallback : public nsITimerCallback, public nsINamed {
|
||||
protected:
|
||||
virtual ~AsyncBlockerTimerCallback();
|
||||
|
||||
public:
|
||||
explicit AsyncBlockerTimerCallback() {}
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
NS_DECL_NSINAMED
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(AsyncBlockerTimerCallback, nsITimerCallback, nsINamed)
|
||||
|
||||
AsyncBlockerTimerCallback::~AsyncBlockerTimerCallback() = default;
|
||||
|
||||
NS_IMETHODIMP
|
||||
AsyncBlockerTimerCallback::Notify(nsITimer* timer) {
|
||||
// If we resolve through this, it means
|
||||
// blockers.WaitUntilClear() started to wait for
|
||||
// the completion of the timeout which is not
|
||||
// good.
|
||||
EXPECT_TRUE(false);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AsyncBlockerTimerCallback::GetName(nsACString& aName) {
|
||||
aName.AssignLiteral("AsyncBlockerTimerCallback");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
TEST_F(TestAsyncBlockers, NoRegister_WaitUntilClear) {
|
||||
AsyncBlockers blockers;
|
||||
bool done = false;
|
||||
|
||||
nsCOMPtr<nsITimer> timer = NS_NewTimer();
|
||||
ASSERT_TRUE(timer);
|
||||
|
||||
RefPtr<AsyncBlockerTimerCallback> timerCb = new AsyncBlockerTimerCallback();
|
||||
timer->InitWithCallback(timerCb, 1 * 1000, nsITimer::TYPE_ONE_SHOT);
|
||||
|
||||
blockers.WaitUntilClear(10 * 1000)->Then(GetCurrentSerialEventTarget(),
|
||||
__func__, [&]() {
|
||||
// If we resolve through this
|
||||
// before the nsITimer it means we
|
||||
// have been resolved before the 5s
|
||||
// timeout
|
||||
EXPECT_TRUE(true);
|
||||
timer->Cancel();
|
||||
done = true;
|
||||
});
|
||||
|
||||
PROCESS_EVENTS_UNTIL(done);
|
||||
}
|
||||
|
||||
TEST_F(TestAsyncBlockers, Register_WaitUntilClear_0s) {
|
||||
AsyncBlockers blockers;
|
||||
bool done = false;
|
||||
|
||||
Blocker* blocker = new Blocker();
|
||||
blockers.Register(blocker);
|
||||
|
||||
blockers.WaitUntilClear(0)->Then(GetCurrentSerialEventTarget(), __func__,
|
||||
[&]() {
|
||||
EXPECT_TRUE(true);
|
||||
done = true;
|
||||
});
|
||||
|
||||
NS_ProcessPendingEvents(nullptr);
|
||||
|
||||
blockers.Deregister(blocker);
|
||||
|
||||
PROCESS_EVENTS_UNTIL(done);
|
||||
}
|
||||
|
||||
static void DeregisterEmpty_Test() {
|
||||
DisableCrashReporter();
|
||||
|
||||
AsyncBlockers blockers;
|
||||
Blocker* blocker = new Blocker();
|
||||
blockers.Deregister(blocker);
|
||||
}
|
||||
|
||||
TEST_F(TestAsyncBlockers, DeregisterEmpty) {
|
||||
ASSERT_DEATH_IF_SUPPORTED(DeregisterEmpty_Test(), "");
|
||||
}
|
||||
|
||||
#undef PROCESS_EVENTS_UNTIL
|
|
@ -133,5 +133,3 @@ TEST_F(UtilityProcess, DestroyProcess) {
|
|||
|
||||
WAIT_FOR_EVENTS;
|
||||
}
|
||||
|
||||
#undef WAIT_FOR_EVENTS
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
Library("ipcgluetest")
|
||||
|
||||
UNIFIED_SOURCES = [
|
||||
"TestAsyncBlockers.cpp",
|
||||
"TestUtilityProcess.cpp",
|
||||
]
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче