зеркало из https://github.com/mozilla/gecko-dev.git
Bug 870564 - Youtube video freezes after a long time r=jdm
This commit is contained in:
Родитель
34288bd4dd
Коммит
c36b0246a8
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <nsTArray.h>
|
#include <nsTArray.h>
|
||||||
#include <nsAutoPtr.h>
|
#include <nsAutoPtr.h>
|
||||||
|
#include <nsThreadUtils.h>
|
||||||
|
|
||||||
class nsISupports;
|
class nsISupports;
|
||||||
|
|
||||||
|
@ -35,10 +36,13 @@ class AutoEventEnqueuerBase;
|
||||||
|
|
||||||
class ChannelEventQueue
|
class ChannelEventQueue
|
||||||
{
|
{
|
||||||
|
NS_INLINE_DECL_REFCOUNTING(ChannelEventQueue)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ChannelEventQueue(nsISupports *owner)
|
ChannelEventQueue(nsISupports *owner)
|
||||||
: mForced(false)
|
: mSuspendCount(0)
|
||||||
, mSuspended(false)
|
, mSuspended(false)
|
||||||
|
, mForced(false)
|
||||||
, mFlushing(false)
|
, mFlushing(false)
|
||||||
, mOwner(owner) {}
|
, mOwner(owner) {}
|
||||||
|
|
||||||
|
@ -63,22 +67,21 @@ class ChannelEventQueue
|
||||||
// Suspend/resume event queue. ShouldEnqueue() will return true and no events
|
// Suspend/resume event queue. ShouldEnqueue() will return true and no events
|
||||||
// will be run/flushed until resume is called. These should be called when
|
// will be run/flushed until resume is called. These should be called when
|
||||||
// the channel owning the event queue is suspended/resumed.
|
// the channel owning the event queue is suspended/resumed.
|
||||||
// - Note: these suspend/resume functions are NOT meant to be called
|
|
||||||
// recursively: call them only at initial suspend, and actual resume).
|
|
||||||
// - Note: Resume flushes the queue and invokes any pending callbacks
|
|
||||||
// immediately--caller must arrange any needed asynchronicity vis a vis
|
|
||||||
// the channel's own Resume() method.
|
|
||||||
inline void Suspend();
|
inline void Suspend();
|
||||||
|
// Resume flushes the queue asynchronously, i.e. items in queue will be
|
||||||
|
// dispatched in a new event on the current thread.
|
||||||
inline void Resume();
|
inline void Resume();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline void MaybeFlushQueue();
|
inline void MaybeFlushQueue();
|
||||||
void FlushQueue();
|
void FlushQueue();
|
||||||
|
inline void CompleteResume();
|
||||||
|
|
||||||
nsTArray<nsAutoPtr<ChannelEvent> > mEventQueue;
|
nsTArray<nsAutoPtr<ChannelEvent> > mEventQueue;
|
||||||
|
|
||||||
|
uint32_t mSuspendCount;
|
||||||
|
bool mSuspended;
|
||||||
bool mForced;
|
bool mForced;
|
||||||
bool mSuspended;
|
|
||||||
bool mFlushing;
|
bool mFlushing;
|
||||||
|
|
||||||
// Keep ptr to avoid refcount cycle: only grab ref during flushing.
|
// Keep ptr to avoid refcount cycle: only grab ref during flushing.
|
||||||
|
@ -120,20 +123,37 @@ ChannelEventQueue::EndForcedQueueing()
|
||||||
inline void
|
inline void
|
||||||
ChannelEventQueue::Suspend()
|
ChannelEventQueue::Suspend()
|
||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(!mSuspended,
|
|
||||||
"ChannelEventQueue::Suspend called recursively");
|
|
||||||
|
|
||||||
mSuspended = true;
|
mSuspended = true;
|
||||||
|
mSuspendCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
ChannelEventQueue::CompleteResume()
|
||||||
|
{
|
||||||
|
// channel may have been suspended again since Resume fired event to call this.
|
||||||
|
if (!mSuspendCount) {
|
||||||
|
// we need to remain logically suspended (for purposes of queuing incoming
|
||||||
|
// messages) until this point, else new incoming messages could run before
|
||||||
|
// queued ones.
|
||||||
|
mSuspended = false;
|
||||||
|
MaybeFlushQueue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
ChannelEventQueue::Resume()
|
ChannelEventQueue::Resume()
|
||||||
{
|
{
|
||||||
NS_ABORT_IF_FALSE(mSuspended,
|
// Resuming w/o suspend: error in debug mode, ignore in build
|
||||||
"ChannelEventQueue::Resume called when not suspended!");
|
MOZ_ASSERT(mSuspendCount > 0);
|
||||||
|
if (mSuspendCount <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mSuspended = false;
|
if (!--mSuspendCount) {
|
||||||
MaybeFlushQueue();
|
nsRefPtr<nsRunnableMethod<ChannelEventQueue> > event =
|
||||||
|
NS_NewRunnableMethod(this, &ChannelEventQueue::CompleteResume);
|
||||||
|
NS_DispatchToCurrentThread(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
@ -151,14 +171,14 @@ ChannelEventQueue::MaybeFlushQueue()
|
||||||
class AutoEventEnqueuer
|
class AutoEventEnqueuer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AutoEventEnqueuer(ChannelEventQueue &queue) : mEventQueue(queue) {
|
AutoEventEnqueuer(ChannelEventQueue *queue) : mEventQueue(queue) {
|
||||||
mEventQueue.StartForcedQueueing();
|
mEventQueue->StartForcedQueueing();
|
||||||
}
|
}
|
||||||
~AutoEventEnqueuer() {
|
~AutoEventEnqueuer() {
|
||||||
mEventQueue.EndForcedQueueing();
|
mEventQueue->EndForcedQueueing();
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
ChannelEventQueue &mEventQueue;
|
ChannelEventQueue* mEventQueue;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ namespace net {
|
||||||
|
|
||||||
FTPChannelChild::FTPChannelChild(nsIURI* uri)
|
FTPChannelChild::FTPChannelChild(nsIURI* uri)
|
||||||
: mIPCOpen(false)
|
: mIPCOpen(false)
|
||||||
, ALLOW_THIS_IN_INITIALIZER_LIST(mEventQ(static_cast<nsIFTPChannel*>(this)))
|
|
||||||
, mCanceled(false)
|
, mCanceled(false)
|
||||||
, mSuspendCount(0)
|
, mSuspendCount(0)
|
||||||
, mIsPending(false)
|
, mIsPending(false)
|
||||||
|
@ -42,6 +41,7 @@ FTPChannelChild::FTPChannelChild(nsIURI* uri)
|
||||||
// grab a reference to the handler to ensure that it doesn't go away.
|
// grab a reference to the handler to ensure that it doesn't go away.
|
||||||
NS_ADDREF(gFtpHandler);
|
NS_ADDREF(gFtpHandler);
|
||||||
SetURI(uri);
|
SetURI(uri);
|
||||||
|
mEventQ = new ChannelEventQueue(static_cast<nsIFTPChannel*>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
FTPChannelChild::~FTPChannelChild()
|
FTPChannelChild::~FTPChannelChild()
|
||||||
|
@ -242,9 +242,9 @@ FTPChannelChild::RecvOnStartRequest(const int64_t& aContentLength,
|
||||||
const nsCString& aEntityID,
|
const nsCString& aEntityID,
|
||||||
const URIParams& aURI)
|
const URIParams& aURI)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new FTPStartRequestEvent(this, aContentLength, aContentType,
|
mEventQ->Enqueue(new FTPStartRequestEvent(this, aContentLength, aContentType,
|
||||||
aLastModified, aEntityID, aURI));
|
aLastModified, aEntityID, aURI));
|
||||||
} else {
|
} else {
|
||||||
DoOnStartRequest(aContentLength, aContentType, aLastModified,
|
DoOnStartRequest(aContentLength, aContentType, aLastModified,
|
||||||
aEntityID, aURI);
|
aEntityID, aURI);
|
||||||
|
@ -296,8 +296,8 @@ FTPChannelChild::RecvOnDataAvailable(const nsCString& data,
|
||||||
const uint64_t& offset,
|
const uint64_t& offset,
|
||||||
const uint32_t& count)
|
const uint32_t& count)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new FTPDataAvailableEvent(this, data, offset, count));
|
mEventQ->Enqueue(new FTPDataAvailableEvent(this, data, offset, count));
|
||||||
} else {
|
} else {
|
||||||
DoOnDataAvailable(data, offset, count);
|
DoOnDataAvailable(data, offset, count);
|
||||||
}
|
}
|
||||||
|
@ -351,8 +351,8 @@ class FTPStopRequestEvent : public ChannelEvent
|
||||||
bool
|
bool
|
||||||
FTPChannelChild::RecvOnStopRequest(const nsresult& statusCode)
|
FTPChannelChild::RecvOnStopRequest(const nsresult& statusCode)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new FTPStopRequestEvent(this, statusCode));
|
mEventQ->Enqueue(new FTPStopRequestEvent(this, statusCode));
|
||||||
} else {
|
} else {
|
||||||
DoOnStopRequest(statusCode);
|
DoOnStopRequest(statusCode);
|
||||||
}
|
}
|
||||||
|
@ -399,8 +399,8 @@ class FTPFailedAsyncOpenEvent : public ChannelEvent
|
||||||
bool
|
bool
|
||||||
FTPChannelChild::RecvFailedAsyncOpen(const nsresult& statusCode)
|
FTPChannelChild::RecvFailedAsyncOpen(const nsresult& statusCode)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new FTPFailedAsyncOpenEvent(this, statusCode));
|
mEventQ->Enqueue(new FTPFailedAsyncOpenEvent(this, statusCode));
|
||||||
} else {
|
} else {
|
||||||
DoFailedAsyncOpen(statusCode);
|
DoFailedAsyncOpen(statusCode);
|
||||||
}
|
}
|
||||||
|
@ -443,8 +443,8 @@ class FTPDeleteSelfEvent : public ChannelEvent
|
||||||
bool
|
bool
|
||||||
FTPChannelChild::RecvDeleteSelf()
|
FTPChannelChild::RecvDeleteSelf()
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new FTPDeleteSelfEvent(this));
|
mEventQ->Enqueue(new FTPDeleteSelfEvent(this));
|
||||||
} else {
|
} else {
|
||||||
DoDeleteSelf();
|
DoDeleteSelf();
|
||||||
}
|
}
|
||||||
|
@ -477,32 +477,12 @@ FTPChannelChild::Suspend()
|
||||||
NS_ENSURE_TRUE(mIPCOpen, NS_ERROR_NOT_AVAILABLE);
|
NS_ENSURE_TRUE(mIPCOpen, NS_ERROR_NOT_AVAILABLE);
|
||||||
if (!mSuspendCount++) {
|
if (!mSuspendCount++) {
|
||||||
SendSuspend();
|
SendSuspend();
|
||||||
mEventQ.Suspend();
|
|
||||||
}
|
}
|
||||||
|
mEventQ->Suspend();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
FTPChannelChild::AsyncCall(void (FTPChannelChild::*funcPtr)(),
|
|
||||||
nsRunnableMethod<FTPChannelChild> **retval)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
nsRefPtr<nsRunnableMethod<FTPChannelChild> > event = NS_NewRunnableMethod(this, funcPtr);
|
|
||||||
rv = NS_DispatchToCurrentThread(event);
|
|
||||||
if (NS_SUCCEEDED(rv) && retval) {
|
|
||||||
*retval = event;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
FTPChannelChild::CompleteResume()
|
|
||||||
{
|
|
||||||
mEventQ.Resume();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
FTPChannelChild::Resume()
|
FTPChannelChild::Resume()
|
||||||
{
|
{
|
||||||
|
@ -510,8 +490,9 @@ FTPChannelChild::Resume()
|
||||||
|
|
||||||
if (!--mSuspendCount) {
|
if (!--mSuspendCount) {
|
||||||
SendResume();
|
SendResume();
|
||||||
AsyncCall(&FTPChannelChild::CompleteResume);
|
|
||||||
}
|
}
|
||||||
|
mEventQ->Resume();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,15 +100,10 @@ protected:
|
||||||
friend class FTPDeleteSelfEvent;
|
friend class FTPDeleteSelfEvent;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Called asynchronously from Resume: continues any pending calls into client.
|
|
||||||
void CompleteResume();
|
|
||||||
nsresult AsyncCall(void (FTPChannelChild::*funcPtr)(),
|
|
||||||
nsRunnableMethod<FTPChannelChild> **retval = nullptr);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIInputStream> mUploadStream;
|
nsCOMPtr<nsIInputStream> mUploadStream;
|
||||||
|
|
||||||
bool mIPCOpen;
|
bool mIPCOpen;
|
||||||
ChannelEventQueue mEventQ;
|
nsRefPtr<ChannelEventQueue> mEventQ;
|
||||||
bool mCanceled;
|
bool mCanceled;
|
||||||
uint32_t mSuspendCount;
|
uint32_t mSuspendCount;
|
||||||
bool mIsPending;
|
bool mIsPending;
|
||||||
|
|
|
@ -38,9 +38,10 @@ HttpChannelChild::HttpChannelChild()
|
||||||
, mSendResumeAt(false)
|
, mSendResumeAt(false)
|
||||||
, mIPCOpen(false)
|
, mIPCOpen(false)
|
||||||
, mKeptAlive(false)
|
, mKeptAlive(false)
|
||||||
, ALLOW_THIS_IN_INITIALIZER_LIST(mEventQ(static_cast<nsIHttpChannel*>(this)))
|
|
||||||
{
|
{
|
||||||
LOG(("Creating HttpChannelChild @%x\n", this));
|
LOG(("Creating HttpChannelChild @%x\n", this));
|
||||||
|
|
||||||
|
mEventQ = new ChannelEventQueue(static_cast<nsIHttpChannel*>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpChannelChild::~HttpChannelChild()
|
HttpChannelChild::~HttpChannelChild()
|
||||||
|
@ -141,8 +142,8 @@ bool
|
||||||
HttpChannelChild::RecvAssociateApplicationCache(const nsCString &groupID,
|
HttpChannelChild::RecvAssociateApplicationCache(const nsCString &groupID,
|
||||||
const nsCString &clientID)
|
const nsCString &clientID)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new AssociateApplicationCacheEvent(this, groupID, clientID));
|
mEventQ->Enqueue(new AssociateApplicationCacheEvent(this, groupID, clientID));
|
||||||
} else {
|
} else {
|
||||||
AssociateApplicationCache(groupID, clientID);
|
AssociateApplicationCache(groupID, clientID);
|
||||||
}
|
}
|
||||||
|
@ -222,8 +223,8 @@ HttpChannelChild::RecvOnStartRequest(const nsHttpResponseHead& responseHead,
|
||||||
const NetAddr& selfAddr,
|
const NetAddr& selfAddr,
|
||||||
const NetAddr& peerAddr)
|
const NetAddr& peerAddr)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new StartRequestEvent(this, responseHead, useResponseHead,
|
mEventQ->Enqueue(new StartRequestEvent(this, responseHead, useResponseHead,
|
||||||
requestHeaders, isFromCache,
|
requestHeaders, isFromCache,
|
||||||
cacheEntryAvailable,
|
cacheEntryAvailable,
|
||||||
cacheExpirationTime, cachedCharset,
|
cacheExpirationTime, cachedCharset,
|
||||||
|
@ -331,8 +332,8 @@ HttpChannelChild::RecvOnTransportAndData(const nsresult& status,
|
||||||
const uint64_t& offset,
|
const uint64_t& offset,
|
||||||
const uint32_t& count)
|
const uint32_t& count)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new TransportAndDataEvent(this, status, progress,
|
mEventQ->Enqueue(new TransportAndDataEvent(this, status, progress,
|
||||||
progressMax, data, offset,
|
progressMax, data, offset,
|
||||||
count));
|
count));
|
||||||
} else {
|
} else {
|
||||||
|
@ -427,8 +428,8 @@ class StopRequestEvent : public ChannelEvent
|
||||||
bool
|
bool
|
||||||
HttpChannelChild::RecvOnStopRequest(const nsresult& statusCode)
|
HttpChannelChild::RecvOnStopRequest(const nsresult& statusCode)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new StopRequestEvent(this, statusCode));
|
mEventQ->Enqueue(new StopRequestEvent(this, statusCode));
|
||||||
} else {
|
} else {
|
||||||
OnStopRequest(statusCode);
|
OnStopRequest(statusCode);
|
||||||
}
|
}
|
||||||
|
@ -491,8 +492,8 @@ bool
|
||||||
HttpChannelChild::RecvOnProgress(const uint64_t& progress,
|
HttpChannelChild::RecvOnProgress(const uint64_t& progress,
|
||||||
const uint64_t& progressMax)
|
const uint64_t& progressMax)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new ProgressEvent(this, progress, progressMax));
|
mEventQ->Enqueue(new ProgressEvent(this, progress, progressMax));
|
||||||
} else {
|
} else {
|
||||||
OnProgress(progress, progressMax);
|
OnProgress(progress, progressMax);
|
||||||
}
|
}
|
||||||
|
@ -544,8 +545,8 @@ class StatusEvent : public ChannelEvent
|
||||||
bool
|
bool
|
||||||
HttpChannelChild::RecvOnStatus(const nsresult& status)
|
HttpChannelChild::RecvOnStatus(const nsresult& status)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new StatusEvent(this, status));
|
mEventQ->Enqueue(new StatusEvent(this, status));
|
||||||
} else {
|
} else {
|
||||||
OnStatus(status);
|
OnStatus(status);
|
||||||
}
|
}
|
||||||
|
@ -594,8 +595,8 @@ class FailedAsyncOpenEvent : public ChannelEvent
|
||||||
bool
|
bool
|
||||||
HttpChannelChild::RecvFailedAsyncOpen(const nsresult& status)
|
HttpChannelChild::RecvFailedAsyncOpen(const nsresult& status)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new FailedAsyncOpenEvent(this, status));
|
mEventQ->Enqueue(new FailedAsyncOpenEvent(this, status));
|
||||||
} else {
|
} else {
|
||||||
FailedAsyncOpen(status);
|
FailedAsyncOpen(status);
|
||||||
}
|
}
|
||||||
|
@ -641,8 +642,8 @@ class DeleteSelfEvent : public ChannelEvent
|
||||||
bool
|
bool
|
||||||
HttpChannelChild::RecvDeleteSelf()
|
HttpChannelChild::RecvDeleteSelf()
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new DeleteSelfEvent(this));
|
mEventQ->Enqueue(new DeleteSelfEvent(this));
|
||||||
} else {
|
} else {
|
||||||
DeleteSelf();
|
DeleteSelf();
|
||||||
}
|
}
|
||||||
|
@ -688,8 +689,8 @@ HttpChannelChild::RecvRedirect1Begin(const uint32_t& newChannelId,
|
||||||
const uint32_t& redirectFlags,
|
const uint32_t& redirectFlags,
|
||||||
const nsHttpResponseHead& responseHead)
|
const nsHttpResponseHead& responseHead)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new Redirect1Event(this, newChannelId, newUri,
|
mEventQ->Enqueue(new Redirect1Event(this, newChannelId, newUri,
|
||||||
redirectFlags, responseHead));
|
redirectFlags, responseHead));
|
||||||
} else {
|
} else {
|
||||||
Redirect1Begin(newChannelId, newUri, redirectFlags, responseHead);
|
Redirect1Begin(newChannelId, newUri, redirectFlags, responseHead);
|
||||||
|
@ -763,8 +764,8 @@ class Redirect3Event : public ChannelEvent
|
||||||
bool
|
bool
|
||||||
HttpChannelChild::RecvRedirect3Complete()
|
HttpChannelChild::RecvRedirect3Complete()
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new Redirect3Event(this));
|
mEventQ->Enqueue(new Redirect3Event(this));
|
||||||
} else {
|
} else {
|
||||||
Redirect3Complete();
|
Redirect3Complete();
|
||||||
}
|
}
|
||||||
|
@ -931,24 +932,12 @@ HttpChannelChild::Suspend()
|
||||||
NS_ENSURE_TRUE(RemoteChannelExists(), NS_ERROR_NOT_AVAILABLE);
|
NS_ENSURE_TRUE(RemoteChannelExists(), NS_ERROR_NOT_AVAILABLE);
|
||||||
if (!mSuspendCount++) {
|
if (!mSuspendCount++) {
|
||||||
SendSuspend();
|
SendSuspend();
|
||||||
mEventQ.Suspend();
|
|
||||||
}
|
}
|
||||||
|
mEventQ->Suspend();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
HttpChannelChild::CompleteResume()
|
|
||||||
{
|
|
||||||
if (mCallOnResume) {
|
|
||||||
(this->*mCallOnResume)();
|
|
||||||
mCallOnResume = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't resume event queue until now, else queued events could get
|
|
||||||
// flushed/called before mCallOnResume, which needs to run first.
|
|
||||||
mEventQ.Resume();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpChannelChild::Resume()
|
HttpChannelChild::Resume()
|
||||||
{
|
{
|
||||||
|
@ -959,8 +948,13 @@ HttpChannelChild::Resume()
|
||||||
|
|
||||||
if (!--mSuspendCount) {
|
if (!--mSuspendCount) {
|
||||||
SendResume();
|
SendResume();
|
||||||
rv = AsyncCall(&HttpChannelChild::CompleteResume);
|
if (mCallOnResume) {
|
||||||
|
AsyncCall(mCallOnResume);
|
||||||
|
mCallOnResume = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
mEventQ->Resume();
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,7 @@ private:
|
||||||
|
|
||||||
bool mIPCOpen;
|
bool mIPCOpen;
|
||||||
bool mKeptAlive; // IPC kept open, but only for security info
|
bool mKeptAlive; // IPC kept open, but only for security info
|
||||||
ChannelEventQueue mEventQ;
|
nsRefPtr<ChannelEventQueue> mEventQ;
|
||||||
|
|
||||||
// true after successful AsyncOpen until OnStopRequest completes.
|
// true after successful AsyncOpen until OnStopRequest completes.
|
||||||
bool RemoteChannelExists() { return mIPCOpen && !mKeptAlive; }
|
bool RemoteChannelExists() { return mIPCOpen && !mKeptAlive; }
|
||||||
|
@ -173,9 +173,6 @@ private:
|
||||||
void Redirect3Complete();
|
void Redirect3Complete();
|
||||||
void DeleteSelf();
|
void DeleteSelf();
|
||||||
|
|
||||||
// Called asynchronously from Resume: continues any pending calls into client.
|
|
||||||
void CompleteResume();
|
|
||||||
|
|
||||||
friend class AssociateApplicationCacheEvent;
|
friend class AssociateApplicationCacheEvent;
|
||||||
friend class StartRequestEvent;
|
friend class StartRequestEvent;
|
||||||
friend class StopRequestEvent;
|
friend class StopRequestEvent;
|
||||||
|
|
|
@ -49,11 +49,11 @@ NS_INTERFACE_MAP_BEGIN(WebSocketChannelChild)
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
WebSocketChannelChild::WebSocketChannelChild(bool aSecure)
|
WebSocketChannelChild::WebSocketChannelChild(bool aSecure)
|
||||||
: ALLOW_THIS_IN_INITIALIZER_LIST(mEventQ(static_cast<nsIWebSocketChannel*>(this)))
|
: mIPCOpen(false)
|
||||||
, mIPCOpen(false)
|
|
||||||
{
|
{
|
||||||
LOG(("WebSocketChannelChild::WebSocketChannelChild() %p\n", this));
|
LOG(("WebSocketChannelChild::WebSocketChannelChild() %p\n", this));
|
||||||
BaseWebSocketChannel::mEncrypted = aSecure;
|
BaseWebSocketChannel::mEncrypted = aSecure;
|
||||||
|
mEventQ = new ChannelEventQueue(static_cast<nsIWebSocketChannel*>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
WebSocketChannelChild::~WebSocketChannelChild()
|
WebSocketChannelChild::~WebSocketChannelChild()
|
||||||
|
@ -102,8 +102,8 @@ bool
|
||||||
WebSocketChannelChild::RecvOnStart(const nsCString& aProtocol,
|
WebSocketChannelChild::RecvOnStart(const nsCString& aProtocol,
|
||||||
const nsCString& aExtensions)
|
const nsCString& aExtensions)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new StartEvent(this, aProtocol, aExtensions));
|
mEventQ->Enqueue(new StartEvent(this, aProtocol, aExtensions));
|
||||||
} else {
|
} else {
|
||||||
OnStart(aProtocol, aExtensions);
|
OnStart(aProtocol, aExtensions);
|
||||||
}
|
}
|
||||||
|
@ -145,8 +145,8 @@ class StopEvent : public ChannelEvent
|
||||||
bool
|
bool
|
||||||
WebSocketChannelChild::RecvOnStop(const nsresult& aStatusCode)
|
WebSocketChannelChild::RecvOnStop(const nsresult& aStatusCode)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new StopEvent(this, aStatusCode));
|
mEventQ->Enqueue(new StopEvent(this, aStatusCode));
|
||||||
} else {
|
} else {
|
||||||
OnStop(aStatusCode);
|
OnStop(aStatusCode);
|
||||||
}
|
}
|
||||||
|
@ -191,8 +191,8 @@ class MessageEvent : public ChannelEvent
|
||||||
bool
|
bool
|
||||||
WebSocketChannelChild::RecvOnMessageAvailable(const nsCString& aMsg)
|
WebSocketChannelChild::RecvOnMessageAvailable(const nsCString& aMsg)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new MessageEvent(this, aMsg, false));
|
mEventQ->Enqueue(new MessageEvent(this, aMsg, false));
|
||||||
} else {
|
} else {
|
||||||
OnMessageAvailable(aMsg);
|
OnMessageAvailable(aMsg);
|
||||||
}
|
}
|
||||||
|
@ -212,8 +212,8 @@ WebSocketChannelChild::OnMessageAvailable(const nsCString& aMsg)
|
||||||
bool
|
bool
|
||||||
WebSocketChannelChild::RecvOnBinaryMessageAvailable(const nsCString& aMsg)
|
WebSocketChannelChild::RecvOnBinaryMessageAvailable(const nsCString& aMsg)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new MessageEvent(this, aMsg, true));
|
mEventQ->Enqueue(new MessageEvent(this, aMsg, true));
|
||||||
} else {
|
} else {
|
||||||
OnBinaryMessageAvailable(aMsg);
|
OnBinaryMessageAvailable(aMsg);
|
||||||
}
|
}
|
||||||
|
@ -251,8 +251,8 @@ class AcknowledgeEvent : public ChannelEvent
|
||||||
bool
|
bool
|
||||||
WebSocketChannelChild::RecvOnAcknowledge(const uint32_t& aSize)
|
WebSocketChannelChild::RecvOnAcknowledge(const uint32_t& aSize)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new AcknowledgeEvent(this, aSize));
|
mEventQ->Enqueue(new AcknowledgeEvent(this, aSize));
|
||||||
} else {
|
} else {
|
||||||
OnAcknowledge(aSize);
|
OnAcknowledge(aSize);
|
||||||
}
|
}
|
||||||
|
@ -294,8 +294,8 @@ bool
|
||||||
WebSocketChannelChild::RecvOnServerClose(const uint16_t& aCode,
|
WebSocketChannelChild::RecvOnServerClose(const uint16_t& aCode,
|
||||||
const nsCString& aReason)
|
const nsCString& aReason)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new ServerCloseEvent(this, aCode, aReason));
|
mEventQ->Enqueue(new ServerCloseEvent(this, aCode, aReason));
|
||||||
} else {
|
} else {
|
||||||
OnServerClose(aCode, aReason);
|
OnServerClose(aCode, aReason);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ class WebSocketChannelChild : public BaseWebSocketChannel,
|
||||||
void OnServerClose(const uint16_t& aCode, const nsCString& aReason);
|
void OnServerClose(const uint16_t& aCode, const nsCString& aReason);
|
||||||
void AsyncOpenFailed();
|
void AsyncOpenFailed();
|
||||||
|
|
||||||
ChannelEventQueue mEventQ;
|
nsRefPtr<ChannelEventQueue> mEventQ;
|
||||||
bool mIPCOpen;
|
bool mIPCOpen;
|
||||||
|
|
||||||
friend class StartEvent;
|
friend class StartEvent;
|
||||||
|
|
|
@ -41,9 +41,9 @@ WyciwygChannelChild::WyciwygChannelChild()
|
||||||
, mState(WCC_NEW)
|
, mState(WCC_NEW)
|
||||||
, mIPCOpen(false)
|
, mIPCOpen(false)
|
||||||
, mSentAppData(false)
|
, mSentAppData(false)
|
||||||
, ALLOW_THIS_IN_INITIALIZER_LIST(mEventQ(NS_ISUPPORTS_CAST(nsIWyciwygChannel*, this)))
|
|
||||||
{
|
{
|
||||||
LOG(("Creating WyciwygChannelChild @%x\n", this));
|
LOG(("Creating WyciwygChannelChild @%x\n", this));
|
||||||
|
mEventQ = new ChannelEventQueue(NS_ISUPPORTS_CAST(nsIWyciwygChannel*, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
WyciwygChannelChild::~WyciwygChannelChild()
|
WyciwygChannelChild::~WyciwygChannelChild()
|
||||||
|
@ -117,8 +117,8 @@ WyciwygChannelChild::RecvOnStartRequest(const nsresult& statusCode,
|
||||||
const nsCString& charset,
|
const nsCString& charset,
|
||||||
const nsCString& securityInfo)
|
const nsCString& securityInfo)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new WyciwygStartRequestEvent(this, statusCode,
|
mEventQ->Enqueue(new WyciwygStartRequestEvent(this, statusCode,
|
||||||
contentLength, source,
|
contentLength, source,
|
||||||
charset, securityInfo));
|
charset, securityInfo));
|
||||||
} else {
|
} else {
|
||||||
|
@ -172,8 +172,8 @@ bool
|
||||||
WyciwygChannelChild::RecvOnDataAvailable(const nsCString& data,
|
WyciwygChannelChild::RecvOnDataAvailable(const nsCString& data,
|
||||||
const uint64_t& offset)
|
const uint64_t& offset)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new WyciwygDataAvailableEvent(this, data, offset));
|
mEventQ->Enqueue(new WyciwygDataAvailableEvent(this, data, offset));
|
||||||
} else {
|
} else {
|
||||||
OnDataAvailable(data, offset);
|
OnDataAvailable(data, offset);
|
||||||
}
|
}
|
||||||
|
@ -233,8 +233,8 @@ private:
|
||||||
bool
|
bool
|
||||||
WyciwygChannelChild::RecvOnStopRequest(const nsresult& statusCode)
|
WyciwygChannelChild::RecvOnStopRequest(const nsresult& statusCode)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new WyciwygStopRequestEvent(this, statusCode));
|
mEventQ->Enqueue(new WyciwygStopRequestEvent(this, statusCode));
|
||||||
} else {
|
} else {
|
||||||
OnStopRequest(statusCode);
|
OnStopRequest(statusCode);
|
||||||
}
|
}
|
||||||
|
@ -290,8 +290,8 @@ class WyciwygCancelEvent : public ChannelEvent
|
||||||
bool
|
bool
|
||||||
WyciwygChannelChild::RecvCancelEarly(const nsresult& statusCode)
|
WyciwygChannelChild::RecvCancelEarly(const nsresult& statusCode)
|
||||||
{
|
{
|
||||||
if (mEventQ.ShouldEnqueue()) {
|
if (mEventQ->ShouldEnqueue()) {
|
||||||
mEventQ.Enqueue(new WyciwygCancelEvent(this, statusCode));
|
mEventQ->Enqueue(new WyciwygCancelEvent(this, statusCode));
|
||||||
} else {
|
} else {
|
||||||
CancelEarly(statusCode);
|
CancelEarly(statusCode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ private:
|
||||||
|
|
||||||
bool mIPCOpen;
|
bool mIPCOpen;
|
||||||
bool mSentAppData;
|
bool mSentAppData;
|
||||||
ChannelEventQueue mEventQ;
|
nsRefPtr<ChannelEventQueue> mEventQ;
|
||||||
|
|
||||||
friend class WyciwygStartRequestEvent;
|
friend class WyciwygStartRequestEvent;
|
||||||
friend class WyciwygDataAvailableEvent;
|
friend class WyciwygDataAvailableEvent;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче