Bug 1254730 - ChannelEventQueue must be thread-safe, r=michal, a=ritu

This commit is contained in:
Andrea Marchesini 2016-03-14 17:10:26 +01:00
parent f8809c337c
commit 4a304f9f0d
8 changed files with 181 additions and 272 deletions

View File

@ -12,6 +12,22 @@
namespace mozilla {
namespace net {
ChannelEvent*
ChannelEventQueue::TakeEvent()
{
MutexAutoLock lock(mMutex);
MOZ_ASSERT(mFlushing);
if (mSuspended || mEventQueue.IsEmpty()) {
return nullptr;
}
UniquePtr<ChannelEvent> event(Move(mEventQueue[0]));
mEventQueue.RemoveElementAt(0);
return event.release();
}
void
ChannelEventQueue::FlushQueue()
{
@ -21,30 +37,29 @@ ChannelEventQueue::FlushQueue()
nsCOMPtr<nsISupports> kungFuDeathGrip(mOwner);
// Prevent flushed events from flushing the queue recursively
mFlushing = true;
uint32_t i;
for (i = 0; i < mEventQueue.Length(); i++) {
mEventQueue[i]->Run();
if (mSuspended)
break;
{
MutexAutoLock lock(mMutex);
mFlushing = true;
}
// We will always want to remove at least one finished callback.
if (i < mEventQueue.Length())
i++;
while (true) {
UniquePtr<ChannelEvent> event(TakeEvent());
if (!event) {
break;
}
// It is possible for new callbacks to be enqueued as we are
// flushing the queue, so the queue must not be cleared until
// all callbacks have run.
mEventQueue.RemoveElementsAt(0, i);
event->Run();
}
MutexAutoLock lock(mMutex);
mFlushing = false;
}
void
ChannelEventQueue::Resume()
{
MutexAutoLock lock(mMutex);
// Resuming w/o suspend: error in debug mode, ignore in build
MOZ_ASSERT(mSuspendCount > 0);
if (mSuspendCount <= 0) {
@ -58,7 +73,7 @@ ChannelEventQueue::Resume()
mTargetThread->Dispatch(event, NS_DISPATCH_NORMAL);
} else {
MOZ_RELEASE_ASSERT(NS_IsMainThread());
NS_DispatchToCurrentThread(event);
NS_WARN_IF(NS_FAILED(NS_DispatchToCurrentThread(event)));
}
}
}

View File

@ -10,6 +10,7 @@
#include "nsTArray.h"
#include "nsAutoPtr.h"
#include "mozilla/Mutex.h"
#include "mozilla/UniquePtr.h"
class nsISupports;
@ -43,28 +44,31 @@ class ChannelEventQueue final
, mSuspended(false)
, mForced(false)
, mFlushing(false)
, mOwner(owner) {}
// Checks to determine if an IPDL-generated channel event can be processed
// immediately, or needs to be queued using Enqueue().
inline bool ShouldEnqueue();
, mOwner(owner)
, mMutex("ChannelEventQueue::mMutex")
{}
// Puts IPDL-generated channel event into queue, to be run later
// automatically when EndForcedQueueing and/or Resume is called.
inline void Enqueue(ChannelEvent* callback);
//
// @param aCallback - the ChannelEvent
// @param aAssertWhenNotQueued - this optional param will be used in an
// assertion when the event is executed directly.
inline void RunOrEnqueue(ChannelEvent* aCallback,
bool aAssertWhenNotQueued = true);
inline nsresult PrependEvents(nsTArray<UniquePtr<ChannelEvent>>& aEvents);
// After StartForcedQueueing is called, ShouldEnqueue() will return true and
// no events will be run/flushed until EndForcedQueueing is called.
// After StartForcedQueueing is called, RunOrEnqueue() will start enqueuing
// events that will be run/flushed when EndForcedQueueing is called.
// - Note: queueing may still be required after EndForcedQueueing() (if the
// queue is suspended, etc): always call ShouldEnqueue() to determine
// whether queueing is needed.
// queue is suspended, etc): always call RunOrEnqueue() to avoid race
// conditions.
inline void StartForcedQueueing();
inline void EndForcedQueueing();
// Suspend/resume event queue. ShouldEnqueue() will return true and no events
// will be run/flushed until resume is called. These should be called when
// the channel owning the event queue is suspended/resumed.
// Suspend/resume event queue. RunOrEnqueue() will start enqueuing
// events and they will be run/flushed when resume is called. These should be
// called when the channel owning the event queue is suspended/resumed.
inline void Suspend();
// Resume flushes the queue asynchronously, i.e. items in queue will be
// dispatched in a new event on the current thread.
@ -83,6 +87,8 @@ class ChannelEventQueue final
void FlushQueue();
inline void CompleteResume();
ChannelEvent* TakeEvent();
nsTArray<UniquePtr<ChannelEvent>> mEventQueue;
uint32_t mSuspendCount;
@ -93,45 +99,60 @@ class ChannelEventQueue final
// Keep ptr to avoid refcount cycle: only grab ref during flushing.
nsISupports *mOwner;
Mutex mMutex;
// EventTarget for delivery of events to the correct thread.
nsCOMPtr<nsIEventTarget> mTargetThread;
friend class AutoEventEnqueuer;
};
inline bool
ChannelEventQueue::ShouldEnqueue()
{
bool answer = mForced || mSuspended || mFlushing;
MOZ_ASSERT(answer == true || mEventQueue.IsEmpty(),
"Should always enqueue if ChannelEventQueue not empty");
return answer;
}
inline void
ChannelEventQueue::Enqueue(ChannelEvent* callback)
ChannelEventQueue::RunOrEnqueue(ChannelEvent* aCallback,
bool aAssertWhenNotQueued)
{
mEventQueue.AppendElement(callback);
MOZ_ASSERT(aCallback);
{
MutexAutoLock lock(mMutex);
bool enqueue = mForced || mSuspended || mFlushing;
MOZ_ASSERT(enqueue == true || mEventQueue.IsEmpty(),
"Should always enqueue if ChannelEventQueue not empty");
if (enqueue) {
mEventQueue.AppendElement(aCallback);
return;
}
}
MOZ_RELEASE_ASSERT(aAssertWhenNotQueued);
aCallback->Run();
}
inline void
ChannelEventQueue::StartForcedQueueing()
{
MutexAutoLock lock(mMutex);
mForced = true;
}
inline void
ChannelEventQueue::EndForcedQueueing()
{
mForced = false;
{
MutexAutoLock lock(mMutex);
mForced = false;
}
MaybeFlushQueue();
}
inline nsresult
ChannelEventQueue::PrependEvents(nsTArray<UniquePtr<ChannelEvent>>& aEvents)
{
MutexAutoLock lock(mMutex);
UniquePtr<ChannelEvent>* newEvents =
mEventQueue.InsertElementsAt(0, aEvents.Length());
if (!newEvents) {
@ -141,12 +162,15 @@ ChannelEventQueue::PrependEvents(nsTArray<UniquePtr<ChannelEvent>>& aEvents)
for (uint32_t i = 0; i < aEvents.Length(); i++) {
newEvents[i] = Move(aEvents[i]);
}
return NS_OK;
}
inline void
ChannelEventQueue::Suspend()
{
MutexAutoLock lock(mMutex);
mSuspended = true;
mSuspendCount++;
}
@ -154,14 +178,20 @@ ChannelEventQueue::Suspend()
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();
{
MutexAutoLock lock(mMutex);
// 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
@ -169,13 +199,22 @@ ChannelEventQueue::MaybeFlushQueue()
{
// Don't flush if forced queuing on, we're already being flushed, or
// suspended, or there's nothing to flush
if (!mForced && !mFlushing && !mSuspended && !mEventQueue.IsEmpty())
bool flushQueue = false;
{
MutexAutoLock lock(mMutex);
flushQueue = !mForced && !mFlushing && !mSuspended &&
!mEventQueue.IsEmpty();
}
if (flushQueue) {
FlushQueue();
}
}
// Ensures that ShouldEnqueue() will be true during its lifetime (letting
// caller know incoming IPDL msgs should be queued). Flushes the queue when it
// goes out of scope.
// Ensures that RunOrEnqueue() will be collecting events during its lifetime
// (letting caller know incoming IPDL msgs should be queued). Flushes the queue
// when it goes out of scope.
class MOZ_STACK_CLASS AutoEventEnqueuer
{
public:

View File

@ -284,14 +284,10 @@ FTPChannelChild::RecvOnStartRequest(const nsresult& aChannelStatus,
LOG(("FTPChannelChild::RecvOnStartRequest [this=%p]\n", this));
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new FTPStartRequestEvent(this, aChannelStatus,
aContentLength, aContentType,
aLastModified, aEntityID, aURI));
} else {
DoOnStartRequest(aChannelStatus, aContentLength, aContentType,
aLastModified, aEntityID, aURI);
}
mEventQ->RunOrEnqueue(new FTPStartRequestEvent(this, aChannelStatus,
aContentLength, aContentType,
aLastModified, aEntityID,
aURI));
return true;
}
@ -379,15 +375,10 @@ FTPChannelChild::RecvOnDataAvailable(const nsresult& channelStatus,
LOG(("FTPChannelChild::RecvOnDataAvailable [this=%p]\n", this));
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(
new FTPDataAvailableEvent(this, channelStatus, data, offset, count));
} else {
MOZ_RELEASE_ASSERT(!mDivertingToParent,
"ShouldEnqueue when diverting to parent!");
mEventQ->RunOrEnqueue(new FTPDataAvailableEvent(this, channelStatus, data,
offset, count),
!mDivertingToParent);
DoOnDataAvailable(channelStatus, data, offset, count);
}
return true;
}
@ -504,11 +495,7 @@ FTPChannelChild::RecvOnStopRequest(const nsresult& aChannelStatus)
LOG(("FTPChannelChild::RecvOnStopRequest [this=%p status=%x]\n",
this, aChannelStatus));
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new FTPStopRequestEvent(this, aChannelStatus));
} else {
DoOnStopRequest(aChannelStatus);
}
mEventQ->RunOrEnqueue(new FTPStopRequestEvent(this, aChannelStatus));
return true;
}
@ -593,11 +580,7 @@ FTPChannelChild::RecvFailedAsyncOpen(const nsresult& statusCode)
{
LOG(("FTPChannelChild::RecvFailedAsyncOpen [this=%p status=%x]\n",
this, statusCode));
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new FTPFailedAsyncOpenEvent(this, statusCode));
} else {
DoFailedAsyncOpen(statusCode);
}
mEventQ->RunOrEnqueue(new FTPFailedAsyncOpenEvent(this, statusCode));
return true;
}
@ -649,11 +632,7 @@ FTPChannelChild::RecvFlushedForDiversion()
LOG(("FTPChannelChild::RecvFlushedForDiversion [this=%p]\n", this));
MOZ_ASSERT(mDivertingToParent);
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new FTPFlushedForDiversionEvent(this));
} else {
MOZ_CRASH();
}
mEventQ->RunOrEnqueue(new FTPFlushedForDiversionEvent(this));
return true;
}
@ -699,11 +678,7 @@ class FTPDeleteSelfEvent : public ChannelEvent
bool
FTPChannelChild::RecvDeleteSelf()
{
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new FTPDeleteSelfEvent(this));
} else {
DoDeleteSelf();
}
mEventQ->RunOrEnqueue(new FTPDeleteSelfEvent(this));
return true;
}

View File

@ -290,13 +290,8 @@ FTPChannelParent::RecvDivertOnDataAvailable(const nsCString& data,
return true;
}
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new FTPDivertDataAvailableEvent(this, data, offset,
count));
return true;
}
DivertOnDataAvailable(data, offset, count);
mEventQ->RunOrEnqueue(new FTPDivertDataAvailableEvent(this, data, offset,
count));
return true;
}
@ -372,12 +367,7 @@ FTPChannelParent::RecvDivertOnStopRequest(const nsresult& statusCode)
return false;
}
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new FTPDivertStopRequestEvent(this, statusCode));
return true;
}
DivertOnStopRequest(statusCode);
mEventQ->RunOrEnqueue(new FTPDivertStopRequestEvent(this, statusCode));
return true;
}
@ -434,12 +424,7 @@ FTPChannelParent::RecvDivertComplete()
return false;
}
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new FTPDivertCompleteEvent(this));
return true;
}
DivertComplete();
mEventQ->RunOrEnqueue(new FTPDivertCompleteEvent(this));
return true;
}

View File

@ -280,11 +280,8 @@ HttpChannelChild::RecvAssociateApplicationCache(const nsCString &groupID,
const nsCString &clientID)
{
LOG(("HttpChannelChild::RecvAssociateApplicationCache [this=%p]\n", this));
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new AssociateApplicationCacheEvent(this, groupID, clientID));
} else {
AssociateApplicationCache(groupID, clientID);
}
mEventQ->RunOrEnqueue(new AssociateApplicationCacheEvent(this, groupID,
clientID));
return true;
}
@ -384,19 +381,13 @@ HttpChannelChild::RecvOnStartRequest(const nsresult& channelStatus,
mRedirectCount = redirectCount;
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new StartRequestEvent(this, channelStatus, responseHead,
useResponseHead, requestHeaders,
isFromCache, cacheEntryAvailable,
cacheExpirationTime, cachedCharset,
securityInfoSerialization, selfAddr,
peerAddr, cacheKey));
} else {
OnStartRequest(channelStatus, responseHead, useResponseHead, requestHeaders,
isFromCache, cacheEntryAvailable, cacheExpirationTime,
cachedCharset, securityInfoSerialization, selfAddr,
peerAddr, cacheKey);
}
mEventQ->RunOrEnqueue(new StartRequestEvent(this, channelStatus, responseHead,
useResponseHead, requestHeaders,
isFromCache, cacheEntryAvailable,
cacheExpirationTime,
cachedCharset,
securityInfoSerialization,
selfAddr, peerAddr, cacheKey));
return true;
}
@ -616,18 +607,11 @@ HttpChannelChild::RecvOnTransportAndData(const nsresult& channelStatus,
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
"Should not be receiving any more callbacks from parent!");
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new TransportAndDataEvent(this, channelStatus,
transportStatus, progress,
progressMax, data, offset,
count));
} else {
MOZ_RELEASE_ASSERT(!mDivertingToParent,
"ShouldEnqueue when diverting to parent!");
OnTransportAndData(channelStatus, transportStatus, progress, progressMax,
data, offset, count);
}
mEventQ->RunOrEnqueue(new TransportAndDataEvent(this, channelStatus,
transportStatus, progress,
progressMax, data, offset,
count),
!mDivertingToParent);
return true;
}
@ -826,13 +810,7 @@ HttpChannelChild::RecvOnStopRequest(const nsresult& channelStatus,
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
"Should not be receiving any more callbacks from parent!");
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new StopRequestEvent(this, channelStatus, timing));
} else {
MOZ_ASSERT(!mDivertingToParent, "ShouldEnqueue when diverting to parent!");
OnStopRequest(channelStatus, timing);
}
mEventQ->RunOrEnqueue(new StopRequestEvent(this, channelStatus, timing));
return true;
}
@ -992,11 +970,7 @@ bool
HttpChannelChild::RecvOnProgress(const int64_t& progress,
const int64_t& progressMax)
{
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new ProgressEvent(this, progress, progressMax));
} else {
OnProgress(progress, progressMax);
}
mEventQ->RunOrEnqueue(new ProgressEvent(this, progress, progressMax));
return true;
}
@ -1045,11 +1019,7 @@ class StatusEvent : public ChannelEvent
bool
HttpChannelChild::RecvOnStatus(const nsresult& status)
{
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new StatusEvent(this, status));
} else {
OnStatus(status);
}
mEventQ->RunOrEnqueue(new StatusEvent(this, status));
return true;
}
@ -1096,11 +1066,7 @@ bool
HttpChannelChild::RecvFailedAsyncOpen(const nsresult& status)
{
LOG(("HttpChannelChild::RecvFailedAsyncOpen [this=%p]\n", this));
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new FailedAsyncOpenEvent(this, status));
} else {
FailedAsyncOpen(status);
}
mEventQ->RunOrEnqueue(new FailedAsyncOpenEvent(this, status));
return true;
}
@ -1149,11 +1115,7 @@ bool
HttpChannelChild::RecvDeleteSelf()
{
LOG(("HttpChannelChild::RecvDeleteSelf [this=%p]\n", this));
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new DeleteSelfEvent(this));
} else {
DeleteSelf();
}
mEventQ->RunOrEnqueue(new DeleteSelfEvent(this));
return true;
}
@ -1210,14 +1172,9 @@ HttpChannelChild::RecvRedirect1Begin(const uint32_t& newChannelId,
{
// TODO: handle security info
LOG(("HttpChannelChild::RecvRedirect1Begin [this=%p]\n", this));
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new Redirect1Event(this, newChannelId, newUri,
redirectFlags, responseHead,
securityInfoSerialization));
} else {
Redirect1Begin(newChannelId, newUri, redirectFlags, responseHead,
securityInfoSerialization);
}
mEventQ->RunOrEnqueue(new Redirect1Event(this, newChannelId, newUri,
redirectFlags, responseHead,
securityInfoSerialization));
return true;
}
@ -1355,11 +1312,7 @@ bool
HttpChannelChild::RecvRedirect3Complete()
{
LOG(("HttpChannelChild::RecvRedirect3Complete [this=%p]\n", this));
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new Redirect3Event(this));
} else {
Redirect3Complete();
}
mEventQ->RunOrEnqueue(new Redirect3Event(this));
return true;
}
@ -1385,9 +1338,8 @@ HttpChannelChild::RecvFlushedForDiversion()
{
LOG(("HttpChannelChild::RecvFlushedForDiversion [this=%p]\n", this));
MOZ_RELEASE_ASSERT(mDivertingToParent);
MOZ_RELEASE_ASSERT(mEventQ->ShouldEnqueue());
mEventQ->Enqueue(new HttpFlushedForDiversionEvent(this));
mEventQ->RunOrEnqueue(new HttpFlushedForDiversionEvent(this));
return true;
}

View File

@ -761,12 +761,8 @@ HttpChannelParent::RecvDivertOnDataAvailable(const nsCString& data,
return true;
}
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new DivertDataAvailableEvent(this, data, offset, count));
return true;
}
DivertOnDataAvailable(data, offset, count);
mEventQ->RunOrEnqueue(new DivertDataAvailableEvent(this, data, offset,
count));
return true;
}
@ -846,12 +842,7 @@ HttpChannelParent::RecvDivertOnStopRequest(const nsresult& statusCode)
return false;
}
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new DivertStopRequestEvent(this, statusCode));
return true;
}
DivertOnStopRequest(statusCode);
mEventQ->RunOrEnqueue(new DivertStopRequestEvent(this, statusCode));
return true;
}
@ -909,12 +900,7 @@ HttpChannelParent::RecvDivertComplete()
return false;
}
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new DivertCompleteEvent(this));
return true;
}
DivertComplete();
mEventQ->RunOrEnqueue(new DivertCompleteEvent(this));
return true;
}

View File

@ -214,17 +214,11 @@ WebSocketChannelChild::RecvOnStart(const nsCString& aProtocol,
const nsString& aEffectiveURL,
const bool& aEncrypted)
{
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new EventTargetDispatcher(
new StartEvent(this, aProtocol, aExtensions,
aEffectiveURL, aEncrypted),
mTargetThread));
} else if (mTargetThread) {
DispatchToTargetThread(new StartEvent(this, aProtocol, aExtensions,
aEffectiveURL, aEncrypted));
} else {
OnStart(aProtocol, aExtensions, aEffectiveURL, aEncrypted);
}
mEventQ->RunOrEnqueue(
new EventTargetDispatcher(new StartEvent(this, aProtocol, aExtensions,
aEffectiveURL, aEncrypted),
mTargetThread));
return true;
}
@ -267,14 +261,10 @@ class StopEvent : public ChannelEvent
bool
WebSocketChannelChild::RecvOnStop(const nsresult& aStatusCode)
{
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new EventTargetDispatcher(
new StopEvent(this, aStatusCode), mTargetThread));
} else if (mTargetThread) {
DispatchToTargetThread(new StopEvent(this, aStatusCode));
} else {
OnStop(aStatusCode);
}
mEventQ->RunOrEnqueue(
new EventTargetDispatcher(new StopEvent(this, aStatusCode),
mTargetThread));
return true;
}
@ -316,14 +306,10 @@ class MessageEvent : public ChannelEvent
bool
WebSocketChannelChild::RecvOnMessageAvailable(const nsCString& aMsg)
{
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new EventTargetDispatcher(
new MessageEvent(this, aMsg, false), mTargetThread));
} else if (mTargetThread) {
DispatchToTargetThread(new MessageEvent(this, aMsg, false));
} else {
OnMessageAvailable(aMsg);
}
mEventQ->RunOrEnqueue(
new EventTargetDispatcher(new MessageEvent(this, aMsg, false),
mTargetThread));
return true;
}
@ -340,14 +326,10 @@ WebSocketChannelChild::OnMessageAvailable(const nsCString& aMsg)
bool
WebSocketChannelChild::RecvOnBinaryMessageAvailable(const nsCString& aMsg)
{
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new EventTargetDispatcher(
new MessageEvent(this, aMsg, true), mTargetThread));
} else if (mTargetThread) {
DispatchToTargetThread(new MessageEvent(this, aMsg, true));
} else {
OnBinaryMessageAvailable(aMsg);
}
mEventQ->RunOrEnqueue(
new EventTargetDispatcher(new MessageEvent(this, aMsg, true),
mTargetThread));
return true;
}
@ -383,14 +365,10 @@ class AcknowledgeEvent : public ChannelEvent
bool
WebSocketChannelChild::RecvOnAcknowledge(const uint32_t& aSize)
{
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new EventTargetDispatcher(
new AcknowledgeEvent(this, aSize), mTargetThread));
} else if (mTargetThread) {
DispatchToTargetThread(new AcknowledgeEvent(this, aSize));
} else {
OnAcknowledge(aSize);
}
mEventQ->RunOrEnqueue(
new EventTargetDispatcher(new AcknowledgeEvent(this, aSize),
mTargetThread));
return true;
}
@ -429,15 +407,10 @@ bool
WebSocketChannelChild::RecvOnServerClose(const uint16_t& aCode,
const nsCString& aReason)
{
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new EventTargetDispatcher(
new ServerCloseEvent(this, aCode, aReason),
mTargetThread));
} else if (mTargetThread) {
DispatchToTargetThread(new ServerCloseEvent(this, aCode, aReason));
} else {
OnServerClose(aCode, aReason);
}
mEventQ->RunOrEnqueue(
new EventTargetDispatcher(new ServerCloseEvent(this, aCode, aReason),
mTargetThread));
return true;
}

View File

@ -153,13 +153,9 @@ WyciwygChannelChild::RecvOnStartRequest(const nsresult& statusCode,
const nsCString& charset,
const nsCString& securityInfo)
{
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new WyciwygStartRequestEvent(this, statusCode,
contentLength, source,
charset, securityInfo));
} else {
OnStartRequest(statusCode, contentLength, source, charset, securityInfo);
}
mEventQ->RunOrEnqueue(new WyciwygStartRequestEvent(this, statusCode,
contentLength, source,
charset, securityInfo));
return true;
}
@ -208,11 +204,7 @@ bool
WyciwygChannelChild::RecvOnDataAvailable(const nsCString& data,
const uint64_t& offset)
{
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new WyciwygDataAvailableEvent(this, data, offset));
} else {
OnDataAvailable(data, offset);
}
mEventQ->RunOrEnqueue(new WyciwygDataAvailableEvent(this, data, offset));
return true;
}
@ -270,11 +262,7 @@ private:
bool
WyciwygChannelChild::RecvOnStopRequest(const nsresult& statusCode)
{
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new WyciwygStopRequestEvent(this, statusCode));
} else {
OnStopRequest(statusCode);
}
mEventQ->RunOrEnqueue(new WyciwygStopRequestEvent(this, statusCode));
return true;
}
@ -327,11 +315,7 @@ class WyciwygCancelEvent : public ChannelEvent
bool
WyciwygChannelChild::RecvCancelEarly(const nsresult& statusCode)
{
if (mEventQ->ShouldEnqueue()) {
mEventQ->Enqueue(new WyciwygCancelEvent(this, statusCode));
} else {
CancelEarly(statusCode);
}
mEventQ->RunOrEnqueue(new WyciwygCancelEvent(this, statusCode));
return true;
}