bug 887995 - allow nsiprotocolproxyservice::asyncresolve() to be called re-entrantly

bug 887995 - allow nsiprotocolproxyservice::asyncresolve() to be called re-entrantly r=jduell
This commit is contained in:
Patrick McManus 2013-06-27 17:02:04 -04:00
Родитель 670f349522
Коммит 142ed6ca77
4 изменённых файлов: 65 добавлений и 13 удалений

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

@ -9,7 +9,7 @@
/**
* An extension of nsIProtocolProxyService
*/
[scriptable, uuid(bed3702d-9374-4804-a20f-32baed8e2954)]
[scriptable, uuid(bb52e571-4a0e-4363-83d0-52034910dd14)]
interface nsIProtocolProxyService2 : nsIProtocolProxyService
{
/**
@ -26,4 +26,13 @@ interface nsIProtocolProxyService2 : nsIProtocolProxyService
* No documentation - it is deprecated!
**/
nsIProxyInfo deprecatedBlockingResolve(in nsIURI aURI, in unsigned long aFlags);
/**
* This method is identical to asyncResolve() except it may execute the
* callback function immediately (i.e from the stack of asyncResolve2()) if
* it is immediately ready to run. The nsICancelable return value will be
* null in that case.
*/
nsICancelable asyncResolve2(in nsIURI aURI, in unsigned long aFlags,
in nsIProtocolProxyCallback aCallback);
};

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

@ -1087,15 +1087,16 @@ nsProtocolProxyService::DeprecatedBlockingResolve(nsIURI *aURI,
return NS_OK;
}
// nsIProtocolProxyService
NS_IMETHODIMP
nsProtocolProxyService::AsyncResolve(nsIURI *uri, uint32_t flags,
nsIProtocolProxyCallback *callback,
nsICancelable **result)
nsresult
nsProtocolProxyService::AsyncResolveInternal(nsIURI *uri, uint32_t flags,
nsIProtocolProxyCallback *callback,
nsICancelable **result,
bool isSyncOK)
{
NS_ENSURE_ARG_POINTER(uri);
NS_ENSURE_ARG_POINTER(callback);
*result = nullptr;
nsRefPtr<nsAsyncResolveRequest> ctx =
new nsAsyncResolveRequest(this, uri, flags, callback);
@ -1119,19 +1120,42 @@ nsProtocolProxyService::AsyncResolve(nsIURI *uri, uint32_t flags,
// we can do it locally
ApplyFilters(uri, info, pi);
ctx->SetResult(NS_OK, pi);
return ctx->DispatchCallback();
if (isSyncOK) {
ctx->Run();
return NS_OK;
}
rv = ctx->DispatchCallback();
if (NS_SUCCEEDED(rv))
ctx.forget(result);
return rv;
}
// else kick off a PAC thread query
rv = mPACMan->AsyncGetProxyForURI(uri, ctx, true);
if (NS_SUCCEEDED(rv)) {
*result = ctx;
NS_ADDREF(*result);
}
if (NS_SUCCEEDED(rv))
ctx.forget(result);
return rv;
}
// nsIProtocolProxyService
NS_IMETHODIMP
nsProtocolProxyService::AsyncResolve2(nsIURI *uri, uint32_t flags,
nsIProtocolProxyCallback *callback,
nsICancelable **result)
{
return AsyncResolveInternal(uri, flags, callback, result, true);
}
NS_IMETHODIMP
nsProtocolProxyService::AsyncResolve(nsIURI *uri, uint32_t flags,
nsIProtocolProxyCallback *callback,
nsICancelable **result)
{
return AsyncResolveInternal(uri, flags, callback, result, false);
}
NS_IMETHODIMP
nsProtocolProxyService::NewProxyInfo(const nsACString &aType,
const nsACString &aHost,

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

@ -363,6 +363,13 @@ protected:
PRTime mSessionStart;
nsFailedProxyTable mFailedProxies;
int32_t mFailedProxyTimeout;
private:
nsresult AsyncResolveInternal(nsIURI *uri, uint32_t flags,
nsIProtocolProxyCallback *callback,
nsICancelable **result,
bool isSyncOK);
};
#endif // !nsProtocolProxyService_h__

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

@ -19,6 +19,7 @@
#include "nsIStreamListenerTee.h"
#include "nsISeekableStream.h"
#include "nsILoadGroupChild.h"
#include "nsIProtocolProxyService2.h"
#include "nsMimeTypes.h"
#include "nsNetUtil.h"
#include "prprf.h"
@ -1775,8 +1776,19 @@ nsHttpChannel::ResolveProxy()
if (NS_FAILED(rv))
return rv;
return pps->AsyncResolve(mProxyURI ? mProxyURI : mURI, mProxyResolveFlags,
this, getter_AddRefs(mProxyRequest));
// using the nsIProtocolProxyService2 allows a minor performance
// optimization, but if an add-on has only provided the original interface
// then it is ok to use that version.
nsCOMPtr<nsIProtocolProxyService2> pps2 = do_QueryInterface(pps);
if (pps2) {
rv = pps2->AsyncResolve2(mProxyURI ? mProxyURI : mURI, mProxyResolveFlags,
this, getter_AddRefs(mProxyRequest));
} else {
rv = pps->AsyncResolve(mProxyURI ? mProxyURI : mURI, mProxyResolveFlags,
this, getter_AddRefs(mProxyRequest));
}
return rv;
}
bool