Bug 458322 - 'Workers: Don't run queued XHR events if Abort/Open have since been called'. r+sr=sicking.

This commit is contained in:
Ben Turner 2008-10-14 11:16:37 -07:00
Родитель 1bf4edef4e
Коммит 6a088e5649
3 изменённых файлов: 92 добавлений и 104 удалений

Просмотреть файл

@ -96,78 +96,6 @@
_arg2 mArg2; \
}
#define MAKE_PROXIED_FUNCTION3(_name, _arg1, _arg2, _arg3) \
class _name : public SyncEventCapturingRunnable \
{ \
public: \
_name (nsDOMWorkerXHRProxy* aXHR, SyncEventQueue* aQueue, _arg1 aArg1, \
_arg2 aArg2, _arg3 aArg3) \
: SyncEventCapturingRunnable(aXHR, aQueue), mArg1(aArg1), mArg2(aArg2), \
mArg3(aArg3) { } \
\
virtual nsresult RunInternal() \
{ \
nsCOMPtr<nsIXMLHttpRequest> xhr = mXHR->GetXMLHttpRequest(); \
if (xhr) { \
return xhr-> _name (mArg1, mArg2, mArg3); \
} \
return NS_OK; \
} \
private: \
_arg1 mArg1; \
_arg2 mArg2; \
_arg3 mArg3; \
}
#define MAKE_PROXIED_FUNCTION4(_name, _arg1, _arg2, _arg3, _arg4) \
class _name : public SyncEventCapturingRunnable \
{ \
public: \
_name (nsDOMWorkerXHRProxy* aXHR, SyncEventQueue* aQueue, _arg1 aArg1, \
_arg2 aArg2, _arg3 aArg3, _arg4 aArg4) \
: SyncEventCapturingRunnable(aXHR, aQueue), mArg1(aArg1), mArg2(aArg2), \
mArg3(aArg3), mArg4(aArg4) { } \
\
virtual nsresult RunInternal() \
{ \
nsCOMPtr<nsIXMLHttpRequest> xhr = mXHR->GetXMLHttpRequest(); \
if (xhr) { \
return xhr-> _name (mArg1, mArg2, mArg3, mArg4); \
} \
return NS_OK; \
} \
private: \
_arg1 mArg1; \
_arg2 mArg2; \
_arg3 mArg3; \
_arg4 mArg4; \
}
#define MAKE_PROXIED_FUNCTION5(_name, _arg1, _arg2, _arg3, _arg4, _arg5) \
class _name : public SyncEventCapturingRunnable \
{ \
public: \
_name (nsDOMWorkerXHRProxy* aXHR, SyncEventQueue* aQueue, _arg1 aArg1, \
_arg2 aArg2, _arg3 aArg3, _arg4 aArg4, _arg5 aArg5) \
: SyncEventCapturingRunnable(aXHR, aQueue), mArg1(aArg1), mArg2(aArg2), \
mArg3(aArg3), mArg4(aArg4), mArg5(aArg5) { } \
\
virtual nsresult RunInternal() \
{ \
nsCOMPtr<nsIXMLHttpRequest> xhr = mXHR->GetXMLHttpRequest(); \
if (xhr) { \
return xhr-> _name (mArg1, mArg2, mArg3, mArg4, mArg5); \
} \
return NS_OK; \
} \
private: \
_arg1 mArg1; \
_arg2 mArg2; \
_arg3 mArg3; \
_arg4 mArg4; \
_arg5 mArg5; \
}
#define RUN_PROXIED_FUNCTION(_name, _args) \
PR_BEGIN_MACRO \
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!"); \
@ -238,13 +166,32 @@ namespace nsDOMWorkerProxiedXHRFunctions
}
};
class OpenRequest : public SyncEventCapturingRunnable
{
public:
OpenRequest(nsDOMWorkerXHRProxy* aXHR, SyncEventQueue* aQueue,
const nsACString& aMethod, const nsACString& aUrl,
PRBool aAsync, const nsAString& aUser,
const nsAString& aPassword)
: SyncEventCapturingRunnable(aXHR, aQueue), mMethod(aMethod), mUrl(aUrl),
mAsync(aAsync), mUser(aUser), mPassword(aPassword) { }
virtual nsresult RunInternal() {
return mXHR->OpenRequest(mMethod, mUrl, mAsync, mUser, mPassword);
}
private:
nsCString mMethod;
nsCString mUrl;
PRBool mAsync;
nsString mUser;
nsString mPassword;
};
MAKE_PROXIED_FUNCTION1(GetAllResponseHeaders, char**);
MAKE_PROXIED_FUNCTION2(GetResponseHeader, const nsACString&, nsACString&);
MAKE_PROXIED_FUNCTION5(OpenRequest, const nsACString&, const nsACString&,
PRBool, const nsAString&, const nsAString&);
MAKE_PROXIED_FUNCTION1(Send, nsIVariant*);
MAKE_PROXIED_FUNCTION1(SendAsBinary, const nsAString&);

Просмотреть файл

@ -156,6 +156,7 @@ protected:
PRInt32 mReadyState;
PRUint32 mLoaded;
PRUint32 mTotal;
PRInt32 mChannelID;
PRPackedBool mBubbles;
PRPackedBool mCancelable;
PRPackedBool mUploadEvent;
@ -172,6 +173,7 @@ nsDOMWorkerXHREvent::nsDOMWorkerXHREvent(nsDOMWorkerXHRProxy* aXHRProxy)
mReadyState(0),
mLoaded(0),
mTotal(0),
mChannelID(-1),
mBubbles(PR_FALSE),
mCancelable(PR_FALSE),
mUploadEvent(PR_FALSE),
@ -201,6 +203,8 @@ nsDOMWorkerXHREvent::Init(nsIDOMEvent* aEvent)
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(aEvent, "Don't pass null here!");
mChannelID = mXHRProxy->ChannelID();
nsresult rv = aEvent->GetType(mTypeString);
NS_ENSURE_SUCCESS(rv, rv);
@ -443,6 +447,7 @@ nsDOMWorkerXHRProxy::nsDOMWorkerXHRProxy(nsDOMWorkerXHR* aWorkerXHR)
mConcreteXHR(nsnull),
mUpload(nsnull),
mSyncEventQueue(nsnull),
mChannelID(-1),
mOwnedByXHR(PR_FALSE),
mCanceled(PR_FALSE)
{
@ -767,6 +772,10 @@ nsDOMWorkerXHRProxy::HandleWorkerEvent(nsDOMWorkerXHREvent* aEvent,
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(aEvent, "Should not be null!");
if (aEvent->mChannelID != -1 && aEvent->mChannelID != mChannelID) {
return NS_OK;
}
mLastXHREvent = aEvent;
nsresult rv = HandleEventInternal(aEvent->mType, aEvent, aUploadEvent);
@ -914,6 +923,9 @@ nsDOMWorkerXHRProxy::HandleEvent(nsIDOMEvent* aEvent)
// place this event in the queue. Otherwise schedule it for the worker via
// the thread service.
if (mSyncEventQueue) {
// Always run this event!
newEvent->mChannelID = -1;
nsCOMPtr<nsIRunnable>* newElement =
mSyncEventQueue->AppendElement(newEvent);
NS_ENSURE_TRUE(newElement, NS_ERROR_OUT_OF_MEMORY);
@ -929,20 +941,54 @@ nsDOMWorkerXHRProxy::HandleEvent(nsIDOMEvent* aEvent)
nsresult
nsDOMWorkerXHRProxy::Abort()
{
if (NS_IsMainThread()) {
if (mCanceled) {
return NS_ERROR_ABORT;
}
nsCOMPtr<nsIXMLHttpRequest> xhr = mXHR;
if (mOwnedByXHR) {
FlipOwnership();
}
return xhr->Abort();
if (!NS_IsMainThread()) {
RUN_PROXIED_FUNCTION(Abort, (this, &queue));
return NS_OK;
}
RUN_PROXIED_FUNCTION(Abort, (this, &queue));
if (mCanceled) {
return NS_ERROR_ABORT;
}
nsCOMPtr<nsIXMLHttpRequest> xhr = mXHR;
if (mOwnedByXHR) {
FlipOwnership();
}
nsresult rv = xhr->Abort();
NS_ENSURE_SUCCESS(rv, rv);
// Don't allow further events from this channel.
mChannelID++;
return NS_OK;
}
nsresult
nsDOMWorkerXHRProxy::OpenRequest(const nsACString& aMethod,
const nsACString& aUrl,
PRBool aAsync,
const nsAString& aUser,
const nsAString& aPassword)
{
if (!NS_IsMainThread()) {
RUN_PROXIED_FUNCTION(OpenRequest, (this, &queue, aMethod, aUrl, aAsync,
aUser, aPassword));
return NS_OK;
}
if (mCanceled) {
return NS_ERROR_ABORT;
}
nsresult rv = mXHR->OpenRequest(aMethod, aUrl, aAsync, aUser, aPassword);
NS_ENSURE_SUCCESS(rv, rv);
// Do this after OpenRequest is called so that we will continue to run events
// from the old channel if OpenRequest fails. Any events generated by the
// OpenRequest method will always run regardless of channel ID.
mChannelID++;
return NS_OK;
}
@ -970,18 +1016,6 @@ nsDOMWorkerXHRProxy::GetResponseHeader(const nsACString& aHeader,
return NS_OK;
}
nsresult
nsDOMWorkerXHRProxy::OpenRequest(const nsACString& aMethod,
const nsACString& aUrl,
PRBool aAsync,
const nsAString& aUser,
const nsAString& aPassword)
{
RUN_PROXIED_FUNCTION(OpenRequest, (this, &queue, aMethod, aUrl, aAsync, aUser,
aPassword));
return NS_OK;
}
nsresult
nsDOMWorkerXHRProxy::Send(nsIVariant* aBody)
{

Просмотреть файл

@ -94,8 +94,18 @@ public:
nsresult Abort();
nsresult OpenRequest(const nsACString& aMethod,
const nsACString& aUrl,
PRBool aAsync,
const nsAString& aUser,
const nsAString& aPassword);
SyncEventQueue* SetSyncEventQueue(SyncEventQueue* aQueue);
PRInt32 ChannelID() {
return mChannelID;
}
protected:
nsresult InitInternal();
void DestroyInternal();
@ -130,11 +140,6 @@ protected:
nsresult GetAllResponseHeaders(char** _retval);
nsresult GetResponseHeader(const nsACString& aHeader,
nsACString& _retval);
nsresult OpenRequest(const nsACString& aMethod,
const nsACString& aUrl,
PRBool aAsync,
const nsAString& aUser,
const nsAString& aPassword);
nsresult Send(nsIVariant* aBody);
nsresult SendAsBinary(const nsAString& aBody);
nsresult GetResponseText(nsAString& _retval);
@ -169,6 +174,8 @@ protected:
SyncEventQueue* mSyncEventQueue;
PRInt32 mChannelID;
// Whether or not this object is owned by the real XHR object.
PRPackedBool mOwnedByXHR;