Files
sousa-gecko/xpcom/tests/gtest/TestAutoOwningEventTarget.cpp
Andreas Pehrson 4bfa0a6de2 Bug 1993981 - Introduce an atomicity policy for tail dispatch. r=karlt,xpcom-reviewers,nika,webrtc-reviewers,bwc,media-playback-reviewers
For MediaTrackGraph to be able to switch its manual batching of control
messages to tail dispatch, the message atomicity guarantee it provides needs to
be retained. This patch introduces an atomicity mode for tail dispatch to
support the graph.

To tidy up the AbstractThread API, the old boolean aSupportsTailDispatch flag
passed at construction is changed to a new TailDispatchPolicy enum. Converting
callers which passed that flag is the bulk of the change.

Differential Revision: https://phabricator.services.mozilla.com/D277181
2026-08-17 22:16:23 +00:00

119 lines
3.3 KiB
C++

/* 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/SyncRunnable.h"
#include "mozilla/TaskQueue.h"
#include "mozilla/gtest/MozAssertions.h"
#include "nsCOMPtr.h"
#include "nsISupportsImpl.h"
#include "nsNetCID.h"
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
namespace TestAutoOwningEventTarget {
using namespace mozilla;
#ifdef MOZ_THREAD_SAFETY_OWNERSHIP_CHECKS_SUPPORTED
namespace {
static MozExternalRefCountType GetRefCount(nsISupports* aSupports) {
aSupports->AddRef();
return aSupports->Release();
}
void CheckAutoOwningEventTarget(
nsISerialEventTarget* aSerialEventTarget,
const nsAutoOwningEventTarget& aAutoOwningEventTarget,
const bool aIsCurrent) {
ASSERT_TRUE(aSerialEventTarget);
ASSERT_EQ(aAutoOwningEventTarget.IsCurrentThread(), aIsCurrent);
{
const auto refCountBefore = GetRefCount(aSerialEventTarget);
{
nsAutoOwningEventTarget copyConstructedEventTarget(
aAutoOwningEventTarget);
ASSERT_EQ(copyConstructedEventTarget.IsCurrentThread(), aIsCurrent);
}
const auto refCountAfter = GetRefCount(aSerialEventTarget);
ASSERT_GE(refCountAfter, refCountBefore);
ASSERT_EQ(refCountAfter - refCountBefore, 0u);
}
{
const auto refCountBefore = GetRefCount(aSerialEventTarget);
{
nsAutoOwningEventTarget copyAssignedEventTarget;
ASSERT_TRUE(copyAssignedEventTarget.IsCurrentThread());
copyAssignedEventTarget = aAutoOwningEventTarget;
ASSERT_EQ(copyAssignedEventTarget.IsCurrentThread(), aIsCurrent);
}
const auto refCountAfter = GetRefCount(aSerialEventTarget);
ASSERT_GE(refCountAfter, refCountBefore);
ASSERT_EQ(refCountAfter - refCountBefore, 0u);
}
}
} // namespace
TEST(TestAutoOwningEventTarget, Simple)
{
{
nsAutoOwningEventTarget autoOwningEventTarget;
ASSERT_NO_FATAL_FAILURE(CheckAutoOwningEventTarget(
GetCurrentSerialEventTarget(), autoOwningEventTarget,
/* aIsCurrent */ true));
}
}
TEST(TestAutoOwningEventTarget, TaskQueue)
{
nsresult rv;
nsCOMPtr<nsIEventTarget> threadPool =
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
ASSERT_NS_SUCCEEDED(rv);
auto taskQueue = TaskQueue::Create(threadPool.forget(), "TestTaskQueue",
TailDispatchPolicy::NoTailDispatch);
nsAutoOwningEventTarget autoOwningEventTarget;
// XXX This call can't be wrapped with ASSERT_NS_SUCCEEDED directly because
// base-toolchains builds fail with: error: duplicate label
// 'gtest_label_testnofatal_111'
rv = SyncRunnable::DispatchToThread(
taskQueue,
NS_NewRunnableFunction(
"TestRunnable", [taskQueue, &autoOwningEventTarget] {
{
ASSERT_NO_FATAL_FAILURE(CheckAutoOwningEventTarget(
taskQueue, autoOwningEventTarget, /* aIsCurrent */ false));
}
{
nsAutoOwningEventTarget autoOwningEventTarget;
ASSERT_NO_FATAL_FAILURE(CheckAutoOwningEventTarget(
taskQueue, autoOwningEventTarget, /* aIsCurrent */ true));
}
}));
ASSERT_NS_SUCCEEDED(rv);
}
#endif
} // namespace TestAutoOwningEventTarget