зеркало из https://github.com/mozilla/pjs.git
Bug 605327 - Add proper cancellation to e10s wyciwyg channels. r=dwitte a=blocking-fennec
This commit is contained in:
Родитель
a95966cc22
Коммит
c0aaec5ffa
|
@ -61,6 +61,7 @@ parent:
|
|||
CloseCacheEntry(nsresult reason);
|
||||
SetCharsetAndSource(PRInt32 source, nsCString charset);
|
||||
SetSecurityInfo(nsCString securityInfo);
|
||||
Cancel(nsresult status);
|
||||
|
||||
child:
|
||||
OnStartRequest(nsresult statusCode,
|
||||
|
@ -73,6 +74,8 @@ child:
|
|||
PRUint32 offset);
|
||||
|
||||
OnStopRequest(nsresult statusCode);
|
||||
|
||||
CancelEarly(nsresult statusCode);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ WyciwygChannelChild::WyciwygChannelChild()
|
|||
: ChannelEventQueue<WyciwygChannelChild>(this)
|
||||
, mStatus(NS_OK)
|
||||
, mIsPending(PR_FALSE)
|
||||
, mCanceled(false)
|
||||
, mLoadFlags(LOAD_NORMAL)
|
||||
, mContentLength(-1)
|
||||
, mCharsetSource(kCharsetUninitialized)
|
||||
|
@ -169,12 +170,8 @@ WyciwygChannelChild::OnStartRequest(const nsresult& statusCode,
|
|||
AutoEventEnqueuer ensureSerialDispatch(this);
|
||||
|
||||
nsresult rv = mListener->OnStartRequest(this, mListenerContext);
|
||||
if (NS_FAILED(rv)) {
|
||||
// TODO: Cancel request:
|
||||
// - Send Cancel msg to parent
|
||||
// - drop any in flight OnDataAvail msgs we receive
|
||||
// - make sure we do call OnStopRequest eventually
|
||||
}
|
||||
if (NS_FAILED(rv))
|
||||
Cancel(rv);
|
||||
}
|
||||
|
||||
class WyciwygDataAvailableEvent : public ChannelEvent
|
||||
|
@ -209,6 +206,9 @@ WyciwygChannelChild::OnDataAvailable(const nsCString& data,
|
|||
{
|
||||
LOG(("WyciwygChannelChild::RecvOnDataAvailable [this=%x]\n", this));
|
||||
|
||||
if (mCanceled)
|
||||
return;
|
||||
|
||||
mState = WCC_ONDATA;
|
||||
|
||||
// NOTE: the OnDataAvailable contract requires the client to read all the data
|
||||
|
@ -222,16 +222,16 @@ WyciwygChannelChild::OnDataAvailable(const nsCString& data,
|
|||
data.Length(),
|
||||
NS_ASSIGNMENT_DEPEND);
|
||||
if (NS_FAILED(rv)) {
|
||||
// TODO: what to do here? Cancel request? Very unlikely to fail.
|
||||
Cancel(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
AutoEventEnqueuer ensureSerialDispatch(this);
|
||||
|
||||
rv = mListener->OnDataAvailable(this, mListenerContext,
|
||||
stringStream, offset, data.Length());
|
||||
if (NS_FAILED(rv)) {
|
||||
// TODO: Cancel request: see notes in OnStartRequest
|
||||
}
|
||||
if (NS_FAILED(rv))
|
||||
Cancel(rv);
|
||||
|
||||
if (mProgressSink && NS_SUCCEEDED(rv) && !(mLoadFlags & LOAD_BACKGROUND))
|
||||
mProgressSink->OnProgress(this, nsnull, PRUint64(offset + data.Length()),
|
||||
|
@ -274,7 +274,9 @@ WyciwygChannelChild::OnStopRequest(const nsresult& statusCode)
|
|||
mState = WCC_ONSTOP;
|
||||
|
||||
mIsPending = PR_FALSE;
|
||||
mStatus = statusCode;
|
||||
|
||||
if (!mCanceled)
|
||||
mStatus = statusCode;
|
||||
|
||||
mListener->OnStopRequest(this, mListenerContext, statusCode);
|
||||
|
||||
|
@ -292,6 +294,54 @@ WyciwygChannelChild::OnStopRequest(const nsresult& statusCode)
|
|||
PWyciwygChannelChild::Send__delete__(this);
|
||||
}
|
||||
|
||||
class WyciwygCancelEvent : public ChannelEvent
|
||||
{
|
||||
public:
|
||||
WyciwygCancelEvent(WyciwygChannelChild* child, const nsresult& status)
|
||||
: mChild(child)
|
||||
, mStatus(status) {}
|
||||
|
||||
void Run() { mChild->CancelEarly(mStatus); }
|
||||
private:
|
||||
WyciwygChannelChild* mChild;
|
||||
nsresult mStatus;
|
||||
};
|
||||
|
||||
bool
|
||||
WyciwygChannelChild::RecvCancelEarly(const nsresult& statusCode)
|
||||
{
|
||||
if (ShouldEnqueue()) {
|
||||
EnqueueEvent(new WyciwygCancelEvent(this, statusCode));
|
||||
} else {
|
||||
CancelEarly(statusCode);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void WyciwygChannelChild::CancelEarly(const nsresult& statusCode)
|
||||
{
|
||||
LOG(("WyciwygChannelChild::CancelEarly [this=%x]\n", this));
|
||||
|
||||
if (mCanceled)
|
||||
return;
|
||||
|
||||
mCanceled = true;
|
||||
mStatus = statusCode;
|
||||
|
||||
mIsPending = false;
|
||||
if (mLoadGroup)
|
||||
mLoadGroup->RemoveRequest(this, nsnull, mStatus);
|
||||
|
||||
if (mListener) {
|
||||
mListener->OnStartRequest(this, mListenerContext);
|
||||
mListener->OnStopRequest(this, mListenerContext, mStatus);
|
||||
}
|
||||
mListener = nsnull;
|
||||
mListenerContext = nsnull;
|
||||
|
||||
if (mIPCOpen)
|
||||
PWyciwygChannelChild::Send__delete__(this);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsIRequest
|
||||
|
@ -324,7 +374,14 @@ WyciwygChannelChild::GetStatus(nsresult *aStatus)
|
|||
NS_IMETHODIMP
|
||||
WyciwygChannelChild::Cancel(nsresult aStatus)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (mCanceled)
|
||||
return NS_OK;
|
||||
|
||||
mCanceled = true;
|
||||
mStatus = aStatus;
|
||||
if (mIPCOpen)
|
||||
SendCancel(aStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void suspend (); */
|
||||
|
|
|
@ -94,6 +94,7 @@ protected:
|
|||
bool RecvOnDataAvailable(const nsCString& data,
|
||||
const PRUint32& offset);
|
||||
bool RecvOnStopRequest(const nsresult& statusCode);
|
||||
bool RecvCancelEarly(const nsresult& statusCode);
|
||||
|
||||
void OnStartRequest(const nsresult& statusCode,
|
||||
const PRInt32& contentLength,
|
||||
|
@ -103,10 +104,12 @@ protected:
|
|||
void OnDataAvailable(const nsCString& data,
|
||||
const PRUint32& offset);
|
||||
void OnStopRequest(const nsresult& statusCode);
|
||||
void CancelEarly(const nsresult& statusCode);
|
||||
|
||||
private:
|
||||
nsresult mStatus;
|
||||
PRBool mIsPending;
|
||||
bool mCanceled;
|
||||
PRUint32 mLoadFlags;
|
||||
PRInt32 mContentLength;
|
||||
PRInt32 mCharsetSource;
|
||||
|
@ -129,6 +132,7 @@ private:
|
|||
friend class WyciwygStartRequestEvent;
|
||||
friend class WyciwygDataAvailableEvent;
|
||||
friend class WyciwygStopRequestEvent;
|
||||
friend class WyciwygCancelEvent;
|
||||
};
|
||||
|
||||
inline bool
|
||||
|
|
|
@ -90,21 +90,21 @@ WyciwygChannelParent::RecvInit(const IPC::URI& aURI)
|
|||
|
||||
nsCString uriSpec;
|
||||
uri->GetSpec(uriSpec);
|
||||
LOG(("WyciwygChannelParent RecvAsyncOpen [this=%x uri=%s]\n",
|
||||
LOG(("WyciwygChannelParent RecvInit [this=%x uri=%s]\n",
|
||||
this, uriSpec.get()));
|
||||
|
||||
nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
|
||||
if (NS_FAILED(rv))
|
||||
return false; // TODO: send fail msg to child, return true
|
||||
return SendCancelEarly(rv);
|
||||
|
||||
nsCOMPtr<nsIChannel> chan;
|
||||
rv = NS_NewChannel(getter_AddRefs(chan), uri, ios);
|
||||
if (NS_FAILED(rv))
|
||||
return false; // TODO: send fail msg to child, return true
|
||||
return SendCancelEarly(rv);
|
||||
|
||||
mChannel = do_QueryInterface(chan, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return false; // TODO: send fail msg to child, return true
|
||||
return SendCancelEarly(rv);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -115,19 +115,21 @@ WyciwygChannelParent::RecvAsyncOpen(const IPC::URI& aOriginal,
|
|||
{
|
||||
nsCOMPtr<nsIURI> original(aOriginal);
|
||||
|
||||
LOG(("WyciwygChannelParent RecvAsyncOpen [this=%x]\n", this));
|
||||
|
||||
nsresult rv;
|
||||
|
||||
rv = mChannel->SetOriginalURI(original);
|
||||
if (NS_FAILED(rv))
|
||||
return false; // TODO: send fail msg to child, return true
|
||||
return SendCancelEarly(rv);
|
||||
|
||||
rv = mChannel->SetLoadFlags(aLoadFlags);
|
||||
if (NS_FAILED(rv))
|
||||
return false; // TODO: send fail msg to child, return true
|
||||
return SendCancelEarly(rv);
|
||||
|
||||
rv = mChannel->AsyncOpen(this, nsnull);
|
||||
if (NS_FAILED(rv))
|
||||
return false; // TODO: send fail msg to child, return true
|
||||
return SendCancelEarly(rv);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -163,6 +165,14 @@ WyciwygChannelParent::RecvSetSecurityInfo(const nsCString& aSecurityInfo)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WyciwygChannelParent::RecvCancel(const nsresult& aStatusCode)
|
||||
{
|
||||
if (mChannel)
|
||||
mChannel->Cancel(aStatusCode);
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// WyciwygChannelParent::nsIRequestObserver
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -67,6 +67,7 @@ protected:
|
|||
virtual bool RecvSetCharsetAndSource(const PRInt32& source,
|
||||
const nsCString& charset);
|
||||
virtual bool RecvSetSecurityInfo(const nsCString& securityInfo);
|
||||
virtual bool RecvCancel(const nsresult& statusCode);
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче