Bug 1297481 - add shutdown state to protocolproxyservice
the protocol proxy service asserts that is in a clean state at dtor -
normally this happens through observe("xpcom-shutdown") but its
actually possible of other events in the xpcom run queue to
'unitialize' things before the dtor.. add a state in which fail codes
are returned instead.
MozReview-Commit-ID: XaNQEZUsRP
--- a/netwerk/base/nsProtocolProxyService.cpp
+++ b/netwerk/base/nsProtocolProxyService.cpp
@@ -423,16 +423,17 @@ nsProtocolProxyService::nsProtocolProxyS
, mHTTPSProxyPort(-1)
, mSOCKSProxyPort(-1)
, mSOCKSProxyVersion(4)
, mSOCKSProxyRemoteDNS(false)
, mProxyOverTLS(true)
, mPACMan(nullptr)
, mSessionStart(PR_Now())
, mFailedProxyTimeout(30 * 60) // 30 minute default
+ , mIsShutdown(false)
{
}
nsProtocolProxyService::~nsProtocolProxyService()
{
// These should have been cleaned up in our Observe method.
NS_ASSERTION(mHostFiltersArray.Length() == 0 && mFilters == nullptr &&
mPACMan == nullptr, "what happened to xpcom-shutdown?");
@@ -513,16 +514,17 @@ nsProtocolProxyService::ReloadNetworkPAC
NS_IMETHODIMP
nsProtocolProxyService::Observe(nsISupports *aSubject,
const char *aTopic,
const char16_t *aData)
{
if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
+ mIsShutdown = true;
// cleanup
if (mHostFiltersArray.Length() > 0) {
mHostFiltersArray.Clear();
}
if (mFilters) {
delete mFilters;
mFilters = nullptr;
}
@@ -1012,16 +1014,20 @@ nsProtocolProxyService::IsProxyDisabled(
}
return true;
}
nsresult
nsProtocolProxyService::SetupPACThread()
{
+ if (mIsShutdown) {
+ return NS_ERROR_FAILURE;
+ }
+
if (mPACMan)
return NS_OK;
mPACMan = new nsPACMan();
bool mainThreadOnly;
nsresult rv;
if (mSystemProxySettings &&
@@ -1048,17 +1054,18 @@ nsProtocolProxyService::ResetPACThread()
mPACMan = nullptr;
return SetupPACThread();
}
nsresult
nsProtocolProxyService::ConfigureFromPAC(const nsCString &spec,
bool forceReload)
{
- SetupPACThread();
+ nsresult rv = SetupPACThread();
+ NS_ENSURE_SUCCESS(rv, rv);
if (mPACMan->IsPACURI(spec) && !forceReload)
return NS_OK;
mFailedProxies.Clear();
return mPACMan->LoadPACFromURI(spec);
}
@@ -1369,16 +1376,20 @@ nsProtocolProxyService::GetFailoverForPr
NS_ADDREF(*aResult = pi->mNext);
return NS_OK;
}
nsresult
nsProtocolProxyService::InsertFilterLink(FilterLink *link, uint32_t position)
{
+ if (mIsShutdown) {
+ return NS_ERROR_FAILURE;
+ }
+
if (!mFilters) {
mFilters = link;
return NS_OK;
}
// insert into mFilters in sorted order
FilterLink *last = nullptr;
for (FilterLink *iter = mFilters; iter; iter = iter->next) {
@@ -1405,30 +1416,38 @@ nsProtocolProxyService::RegisterFilter(n
uint32_t position)
{
UnregisterFilter(filter); // remove this filter if we already have it
FilterLink *link = new FilterLink(position, filter);
if (!link) {
return NS_ERROR_OUT_OF_MEMORY;
}
- return InsertFilterLink(link, position);
+ nsresult rv = InsertFilterLink(link, position);
+ if (NS_FAILED(rv)) {
+ delete link;
+ }
+ return rv;
}
NS_IMETHODIMP
nsProtocolProxyService::RegisterChannelFilter(nsIProtocolProxyChannelFilter *channelFilter,
uint32_t position)
{
UnregisterChannelFilter(channelFilter); // remove this filter if we already have it
FilterLink *link = new FilterLink(position, channelFilter);
if (!link) {
return NS_ERROR_OUT_OF_MEMORY;
}
- return InsertFilterLink(link, position);
+ nsresult rv = InsertFilterLink(link, position);
+ if (NS_FAILED(rv)) {
+ delete link;
+ }
+ return rv;
}
nsresult
nsProtocolProxyService::RemoveFilterLink(nsISupports* givenObject)
{
FilterLink *last = nullptr;
for (FilterLink *iter = mFilters; iter; iter = iter->next) {
nsCOMPtr<nsISupports> object = do_QueryInterface(iter->filter);
@@ -1468,16 +1487,20 @@ nsProtocolProxyService::GetProxyConfigTy
{
*aProxyConfigType = mProxyConfig;
return NS_OK;
}
void
nsProtocolProxyService::LoadHostFilters(const nsACString& aFilters)
{
+ if (mIsShutdown) {
+ return;
+ }
+
// check to see the owners flag? /!?/ TODO
if (mHostFiltersArray.Length() > 0) {
mHostFiltersArray.Clear();
}
if (aFilters.IsEmpty()) {
return;
}
--- a/netwerk/base/nsProtocolProxyService.h
+++ b/netwerk/base/nsProtocolProxyService.h
@@ -395,17 +395,17 @@ protected:
nsFailedProxyTable mFailedProxies;
int32_t mFailedProxyTimeout;
private:
nsresult AsyncResolveInternal(nsIChannel *channel, uint32_t flags,
nsIProtocolProxyCallback *callback,
nsICancelable **result,
bool isSyncOK);
-
+ bool mIsShutdown;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsProtocolProxyService, NS_PROTOCOL_PROXY_SERVICE_IMPL_CID)
} // namespace net
} // namespace mozilla
#endif // !nsProtocolProxyService_h__