/* -*- 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/. */
using JSListeners = ListenerCollection<RefPtr<PlacesEventCallback>>; using WeakJSListeners = ListenerCollection<WeakPtr<PlacesWeakCallbackWrapper>>; using WeakNativeListeners =
ListenerCollection<WeakPtr<places::INativePlacesEventCallback>>;
// Even if NotifyListeners is called any timing, we mange the notifications with // adding to this queue, then sending in sequence. This avoids sending nested // notifications while previous ones are still being sent.
MOZ_RUNINIT static nsTArray<Sequence<OwningNonNull<PlacesEvent>>>
gNotificationQueue;
void PlacesObservers::NotifyListeners( const Sequence<OwningNonNull<PlacesEvent>>& aEvents) {
MOZ_ASSERT(aEvents.Length() > 0, "Must pass a populated array of events"); if (aEvents.Length() == 0) { return;
}
EnsureCountsInitialized(); for (constauto& event : aEvents) {
DebugOnly<nsresult> rv = sCounts->Increment(event->Type());
MOZ_ASSERT(NS_SUCCEEDED(rv));
} #ifdef DEBUG if (!gNotificationQueue.IsEmpty()) {
NS_WARNING( "Avoid nested Places notifications if possible, the order of events " "cannot be guaranteed");
nsCOMPtr<nsIXPConnect> xpc = nsIXPConnect::XPConnect();
Unused << xpc->DebugDumpJSStack(false, false, false);
} #endif
gNotificationQueue.AppendElement(aEvents);
// If gNotificationQueue has only the events we added now, start to notify. // Otherwise, as it already started the notification processing, // rely on the processing. if (gNotificationQueue.Length() == 1) {
NotifyNext();
}
}
// Send up to the number of current listeners, to avoid handling listeners // added during this notification. unsignedlong jsListenersLength = JSListeners::GetListeners()->Length(); unsignedlong weakNativeListenersLength =
WeakNativeListeners::GetListeners()->Length(); unsignedlong weakJSListenersLength =
WeakJSListeners::GetListeners()->Length();
CallListeners<RefPtr<PlacesEventCallback>, RefPtr<PlacesEventCallback>,
JSListeners>(
flags, events, jsListenersLength, [](auto& cb) { return cb; }, // MOZ_CAN_RUN_SCRIPT_BOUNDARY because on Windows this gets called from // some internals of the std::function implementation that we can't // annotate. We handle this by annotating CallListeners and making sure // it holds a strong ref to the callback.
[&](auto& cb, constauto& events)
MOZ_CAN_RUN_SCRIPT_BOUNDARY { MOZ_KnownLive(cb)->Call(events); });
CallListeners<WeakPtr<PlacesWeakCallbackWrapper>,
RefPtr<PlacesWeakCallbackWrapper>, WeakJSListeners>(
flags, events, weakJSListenersLength, [](auto& cb) { return cb.get(); }, // MOZ_CAN_RUN_SCRIPT_BOUNDARY because on Windows this gets called from // some internals of the std::function implementation that we can't // annotate. We handle this by annotating CallListeners and making sure // it holds a strong ref to the callback.
[&](auto& cb, constauto& events) MOZ_CAN_RUN_SCRIPT_BOUNDARY {
RefPtr<PlacesEventCallback> callback(cb->mCallback);
callback->Call(events);
});
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.