mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-29 20:07:30 +09:00
Refactor PerformanceObserver to use hash tables for entry type validation and improve ThrottleInputStream state management
This commit is contained in:
parent
cd020e380d
commit
a2a4c62a9b
4 changed files with 55 additions and 12 deletions
|
|
@ -10,9 +10,11 @@
|
||||||
#include "mozilla/dom/PerformanceEntryBinding.h"
|
#include "mozilla/dom/PerformanceEntryBinding.h"
|
||||||
#include "mozilla/dom/PerformanceObserverBinding.h"
|
#include "mozilla/dom/PerformanceObserverBinding.h"
|
||||||
#include "nsIScriptError.h"
|
#include "nsIScriptError.h"
|
||||||
|
#include "nsHashKeys.h"
|
||||||
#include "nsPIDOMWindow.h"
|
#include "nsPIDOMWindow.h"
|
||||||
#include "nsQueryObject.h"
|
#include "nsQueryObject.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
|
#include "nsTHashtable.h"
|
||||||
#include "PerformanceEntry.h"
|
#include "PerformanceEntry.h"
|
||||||
#include "PerformanceObserverEntryList.h"
|
#include "PerformanceObserverEntryList.h"
|
||||||
#include "WorkerPrivate.h"
|
#include "WorkerPrivate.h"
|
||||||
|
|
@ -225,19 +227,28 @@ void PerformanceObserver::Observe(const PerformanceObserverInit& aOptions,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 3.3.1.5.2 */
|
/* 3.3.1.5.2 */
|
||||||
|
nsTHashtable<nsStringHashKey> requestedTypes(entryTypes.Length());
|
||||||
|
for (const auto& type : entryTypes) {
|
||||||
|
requestedTypes.PutEntry(type);
|
||||||
|
}
|
||||||
|
|
||||||
nsTArray<nsString> validEntryTypes;
|
nsTArray<nsString> validEntryTypes;
|
||||||
for (const char16_t* name : sValidTypeNames) {
|
for (const char16_t* name : sValidTypeNames) {
|
||||||
nsDependentString validTypeName(name);
|
nsDependentString validTypeName(name);
|
||||||
if (entryTypes.Contains<nsString>(validTypeName) &&
|
if (requestedTypes.GetEntry(validTypeName)) {
|
||||||
!validEntryTypes.Contains<nsString>(validTypeName)) {
|
|
||||||
validEntryTypes.AppendElement(validTypeName);
|
validEntryTypes.AppendElement(validTypeName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsTHashtable<nsStringHashKey> validTypeSet(validEntryTypes.Length());
|
||||||
|
for (const auto& validType : validEntryTypes) {
|
||||||
|
validTypeSet.PutEntry(validType);
|
||||||
|
}
|
||||||
|
|
||||||
nsAutoString invalidTypesJoined;
|
nsAutoString invalidTypesJoined;
|
||||||
bool addComma = false;
|
bool addComma = false;
|
||||||
for (const auto& type : entryTypes) {
|
for (const auto& type : entryTypes) {
|
||||||
if (!validEntryTypes.Contains<nsString>(type)) {
|
if (!validTypeSet.GetEntry(type)) {
|
||||||
if (addComma) {
|
if (addComma) {
|
||||||
invalidTypesJoined.AppendLiteral(", ");
|
invalidTypesJoined.AppendLiteral(", ");
|
||||||
}
|
}
|
||||||
|
|
@ -289,13 +300,13 @@ void PerformanceObserver::Observe(const PerformanceObserverInit& aOptions,
|
||||||
|
|
||||||
/* 3.3.1.6.4, 3.3.1.6.4 */
|
/* 3.3.1.6.4, 3.3.1.6.4 */
|
||||||
bool didUpdateOptionsList = false;
|
bool didUpdateOptionsList = false;
|
||||||
nsTArray<PerformanceObserverInit> updatedOptionsList;
|
nsTArray<PerformanceObserverInit> updatedOptionsList(mOptions.Length() + 1);
|
||||||
for (auto& option : mOptions) {
|
for (auto& option : mOptions) {
|
||||||
if (option.mType.WasPassed() && option.mType.Value() == type) {
|
if (option.mType.WasPassed() && option.mType.Value() == type) {
|
||||||
updatedOptionsList.AppendElement(aOptions);
|
updatedOptionsList.AppendElement(aOptions);
|
||||||
didUpdateOptionsList = true;
|
didUpdateOptionsList = true;
|
||||||
} else {
|
} else {
|
||||||
updatedOptionsList.AppendElement(option);
|
updatedOptionsList.AppendElement(Move(option));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!didUpdateOptionsList) {
|
if (!didUpdateOptionsList) {
|
||||||
|
|
|
||||||
|
|
@ -103,13 +103,23 @@ static LayerSortOrder CompareDepth(Layer* aOne, Layer* aTwo) {
|
||||||
// Could we just check Contains() on the bounds rects. ie, is it possible
|
// Could we just check Contains() on the bounds rects. ie, is it possible
|
||||||
// for layers to overlap without intersections (in 2d space) and yet still
|
// for layers to overlap without intersections (in 2d space) and yet still
|
||||||
// have their bounds rects not completely enclose each other?
|
// have their bounds rects not completely enclose each other?
|
||||||
nsTArray<gfxPoint> points;
|
AutoTArray<gfxPoint, 24> points;
|
||||||
|
auto appendUniquePoint = [&points](const gfxPoint& aPoint) {
|
||||||
|
static const gfxFloat kDuplicateEpsilon = 0.01;
|
||||||
|
for (const auto& point : points) {
|
||||||
|
if (fabs(point.x - aPoint.x) < kDuplicateEpsilon &&
|
||||||
|
fabs(point.y - aPoint.y) < kDuplicateEpsilon) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
points.AppendElement(aPoint);
|
||||||
|
};
|
||||||
for (uint32_t i = 0; i < 4; i++) {
|
for (uint32_t i = 0; i < 4; i++) {
|
||||||
if (ourTransformedRect.Contains(otherTransformedRect.mPoints[i])) {
|
if (ourTransformedRect.Contains(otherTransformedRect.mPoints[i])) {
|
||||||
points.AppendElement(otherTransformedRect.mPoints[i]);
|
appendUniquePoint(otherTransformedRect.mPoints[i]);
|
||||||
}
|
}
|
||||||
if (otherTransformedRect.Contains(ourTransformedRect.mPoints[i])) {
|
if (otherTransformedRect.Contains(ourTransformedRect.mPoints[i])) {
|
||||||
points.AppendElement(ourTransformedRect.mPoints[i]);
|
appendUniquePoint(ourTransformedRect.mPoints[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -123,7 +133,7 @@ static LayerSortOrder CompareDepth(Layer* aOne, Layer* aTwo) {
|
||||||
gfxLineSegment two(otherTransformedRect.mPoints[j],
|
gfxLineSegment two(otherTransformedRect.mPoints[j],
|
||||||
otherTransformedRect.mPoints[(j + 1) % 4]);
|
otherTransformedRect.mPoints[(j + 1) % 4]);
|
||||||
if (one.Intersects(two, intersection)) {
|
if (one.Intersects(two, intersection)) {
|
||||||
points.AppendElement(intersection);
|
appendUniquePoint(intersection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@ public:
|
||||||
NS_DECL_NSIASYNCINPUTSTREAM
|
NS_DECL_NSIASYNCINPUTSTREAM
|
||||||
|
|
||||||
void AllowInput();
|
void AllowInput();
|
||||||
|
bool IsQueued() const;
|
||||||
|
void SetQueued(bool aQueued);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
@ -41,6 +43,7 @@ private:
|
||||||
|
|
||||||
nsCOMPtr<nsIInputStreamCallback> mCallback;
|
nsCOMPtr<nsIInputStreamCallback> mCallback;
|
||||||
nsCOMPtr<nsIEventTarget> mEventTarget;
|
nsCOMPtr<nsIEventTarget> mEventTarget;
|
||||||
|
bool mIsQueued;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(ThrottleInputStream, nsIAsyncInputStream, nsIInputStream, nsISeekableStream)
|
NS_IMPL_ISUPPORTS(ThrottleInputStream, nsIAsyncInputStream, nsIInputStream, nsISeekableStream)
|
||||||
|
|
@ -49,6 +52,7 @@ ThrottleInputStream::ThrottleInputStream(nsIInputStream *aStream, ThrottleQueue*
|
||||||
: mStream(aStream)
|
: mStream(aStream)
|
||||||
, mQueue(aQueue)
|
, mQueue(aQueue)
|
||||||
, mClosedStatus(NS_OK)
|
, mClosedStatus(NS_OK)
|
||||||
|
, mIsQueued(false)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aQueue != nullptr);
|
MOZ_ASSERT(aQueue != nullptr);
|
||||||
}
|
}
|
||||||
|
|
@ -233,6 +237,18 @@ ThrottleInputStream::AllowInput()
|
||||||
callbackEvent->OnInputStreamReady(this);
|
callbackEvent->OnInputStreamReady(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ThrottleInputStream::IsQueued() const
|
||||||
|
{
|
||||||
|
return mIsQueued;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ThrottleInputStream::SetQueued(bool aQueued)
|
||||||
|
{
|
||||||
|
mIsQueued = aQueued;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(ThrottleQueue, nsIInputChannelThrottleQueue, nsITimerCallback)
|
NS_IMPL_ISUPPORTS(ThrottleQueue, nsIInputChannelThrottleQueue, nsITimerCallback)
|
||||||
|
|
@ -348,6 +364,7 @@ ThrottleQueue::Notify(nsITimer* aTimer)
|
||||||
// Optimistically notify all the waiting readers, and then let them
|
// Optimistically notify all the waiting readers, and then let them
|
||||||
// requeue if there isn't enough bandwidth.
|
// requeue if there isn't enough bandwidth.
|
||||||
for (size_t i = 0; i < events.Length(); ++i) {
|
for (size_t i = 0; i < events.Length(); ++i) {
|
||||||
|
events[i]->SetQueued(false);
|
||||||
events[i]->AllowInput();
|
events[i]->AllowInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -359,7 +376,8 @@ void
|
||||||
ThrottleQueue::QueueStream(ThrottleInputStream* aStream)
|
ThrottleQueue::QueueStream(ThrottleInputStream* aStream)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
if (mAsyncEvents.IndexOf(aStream) == mAsyncEvents.NoIndex) {
|
if (!aStream->IsQueued()) {
|
||||||
|
aStream->SetQueued(true);
|
||||||
mAsyncEvents.AppendElement(aStream);
|
mAsyncEvents.AppendElement(aStream);
|
||||||
|
|
||||||
if (!mTimerArmed) {
|
if (!mTimerArmed) {
|
||||||
|
|
@ -386,7 +404,12 @@ void
|
||||||
ThrottleQueue::DequeueStream(ThrottleInputStream* aStream)
|
ThrottleQueue::DequeueStream(ThrottleInputStream* aStream)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||||
|
if (!aStream->IsQueued()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mAsyncEvents.RemoveElement(aStream);
|
mAsyncEvents.RemoveElement(aStream);
|
||||||
|
aStream->SetQueued(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -354,8 +354,7 @@ TimerThread::Shutdown()
|
||||||
// might potentially call some code reentering the same lock
|
// might potentially call some code reentering the same lock
|
||||||
// that leads to unexpected behavior or deadlock.
|
// that leads to unexpected behavior or deadlock.
|
||||||
// See bug 422472.
|
// See bug 422472.
|
||||||
timers.AppendElements(mTimers);
|
timers.SwapElements(mTimers);
|
||||||
mTimers.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t timersCount = timers.Length();
|
uint32_t timersCount = timers.Length();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue