/* -*- 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/. */
class ThrottleInputStream final : public nsIAsyncInputStream, public nsISeekableStream { public:
ThrottleInputStream(nsIInputStream* aStream, ThrottleQueue* aQueue);
NS_IMETHODIMP
ThrottleQueue::Available(uint32_t aRemaining, uint32_t* aAvailable) {
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
TimeStamp now = TimeStamp::Now();
TimeStamp oneSecondAgo = now - TimeDuration::FromSeconds(1);
size_t i;
// Remove all stale events. for (i = 0; i < mReadEvents.Length(); ++i) { if (mReadEvents[i].mTime >= oneSecondAgo) { break;
}
}
mReadEvents.RemoveElementsAt(0, i);
uint32_t totalBytes = 0; for (i = 0; i < mReadEvents.Length(); ++i) {
totalBytes += mReadEvents[i].mBytesRead;
}
NS_IMETHODIMP
ThrottleQueue::Init(uint32_t aMeanBytesPerSecond, uint32_t aMaxBytesPerSecond) { // Can be called on any thread. if (aMeanBytesPerSecond == 0 || aMaxBytesPerSecond == 0 ||
aMaxBytesPerSecond < aMeanBytesPerSecond) { return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
ThrottleQueue::WrapStream(nsIInputStream* aInputStream,
nsIAsyncInputStream** aResult) {
nsCOMPtr<nsIAsyncInputStream> result = new ThrottleInputStream(aInputStream, this);
result.forget(aResult); return NS_OK;
}
NS_IMETHODIMP
ThrottleQueue::Notify(nsITimer* aTimer) {
MOZ_ASSERT(OnSocketThread(), "not on socket thread"); // A notified reader may need to push itself back on the queue. // Swap out the list of readers so that this works properly.
nsTArray<RefPtr<ThrottleInputStream>> events = std::move(mAsyncEvents);
// Optimistically notify all the waiting readers, and then let them // requeue if there isn't enough bandwidth. for (size_t i = 0; i < events.Length(); ++i) {
events[i]->AllowInput();
}
void ThrottleQueue::QueueStream(ThrottleInputStream* aStream) {
MOZ_ASSERT(OnSocketThread(), "not on socket thread"); if (mAsyncEvents.IndexOf(aStream) ==
nsTArray<RefPtr<mozilla::net::ThrottleInputStream>>::NoIndex) {
mAsyncEvents.AppendElement(aStream);
if (!mTimerArmed) {
uint32_t ms = 1000; if (mReadEvents.Length() > 0) {
TimeStamp t = mReadEvents[0].mTime + TimeDuration::FromSeconds(1);
TimeStamp now = TimeStamp::Now();
if (t > now) {
ms = static_cast<uint32_t>((t - now).ToMilliseconds());
} else {
ms = 1;
}
}
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.