зеркало из https://github.com/mozilla/pjs.git
Bug 614286 - Don't initialize the socket transport service unless we know that we're online; r=bzbarsky a=blocking-beta8+
This commit is contained in:
Родитель
8b729667ef
Коммит
d571c78f3a
|
@ -174,7 +174,7 @@ PRUint32 nsIOService::gDefaultSegmentCount = 24;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsIOService::nsIOService()
|
||||
: mOffline(PR_FALSE)
|
||||
: mOffline(PR_TRUE)
|
||||
, mOfflineForProfileChange(PR_FALSE)
|
||||
, mManageOfflineStatus(PR_TRUE)
|
||||
, mSettingOffline(PR_FALSE)
|
||||
|
@ -191,21 +191,11 @@ nsIOService::Init()
|
|||
NS_TIME_FUNCTION;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// We need to get references to these services so that we can shut them
|
||||
|
||||
// We need to get references to the DNS service so that we can shut it
|
||||
// down later. If we wait until the nsIOService is being shut down,
|
||||
// GetService will fail at that point.
|
||||
|
||||
// TODO(darin): Load the Socket and DNS services lazily.
|
||||
|
||||
mSocketTransportService = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("failed to get socket transport service");
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_TIME_FUNCTION_MARK("got SocketTransportService");
|
||||
|
||||
mDNSService = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("failed to get DNS service");
|
||||
|
@ -293,7 +283,29 @@ nsIOService::Init()
|
|||
nsIOService::~nsIOService()
|
||||
{
|
||||
gIOService = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsIOService::InitializeSocketTransportService()
|
||||
{
|
||||
NS_TIME_FUNCTION;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!mSocketTransportService) {
|
||||
mSocketTransportService = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("failed to get socket transport service");
|
||||
}
|
||||
}
|
||||
|
||||
if (mSocketTransportService) {
|
||||
rv = mSocketTransportService->Init();
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "socket transport service init failed");
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsIOService*
|
||||
nsIOService::GetInstance() {
|
||||
|
@ -742,10 +754,7 @@ nsIOService::SetOffline(PRBool offline)
|
|||
rv = mDNSService->Init();
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "DNS service init failed");
|
||||
}
|
||||
if (mSocketTransportService) {
|
||||
rv = mSocketTransportService->Init();
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "socket transport service init failed");
|
||||
}
|
||||
InitializeSocketTransportService();
|
||||
mOffline = PR_FALSE; // indicate success only AFTER we've
|
||||
// brought up the services
|
||||
|
||||
|
|
|
@ -108,6 +108,10 @@ public:
|
|||
PRBool IsOffline() { return mOffline; }
|
||||
PRBool IsLinkUp();
|
||||
|
||||
PRBool IsComingOnline() const {
|
||||
return mOffline && mSettingOffline && !mSetOfflineValue;
|
||||
}
|
||||
|
||||
private:
|
||||
// These shouldn't be called directly:
|
||||
// - construct using GetInstance
|
||||
|
@ -129,6 +133,8 @@ private:
|
|||
NS_HIDDEN_(void) GetPrefBranch(nsIPrefBranch2 **);
|
||||
NS_HIDDEN_(void) ParsePortList(nsIPrefBranch *prefBranch, const char *pref, PRBool remove);
|
||||
|
||||
nsresult InitializeSocketTransportService();
|
||||
|
||||
private:
|
||||
PRPackedBool mOffline;
|
||||
PRPackedBool mOfflineForProfileChange;
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch2.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIOService.h"
|
||||
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
|
||||
|
@ -395,6 +396,10 @@ nsSocketTransportService::Init()
|
|||
if (mShuttingDown)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
// Don't initialize inside the offline mode
|
||||
if (gIOService->IsOffline() && !gIOService->IsComingOnline())
|
||||
return NS_ERROR_OFFLINE;
|
||||
|
||||
if (!mThreadEvent) {
|
||||
mThreadEvent = PR_NewPollableEvent();
|
||||
//
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "prmon.h"
|
||||
#include "prio.h"
|
||||
#include "plstr.h"
|
||||
#include "nsIOService.h"
|
||||
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
|
||||
|
@ -382,6 +383,13 @@ nsDNSService::Init()
|
|||
if (enableIDN)
|
||||
idn = do_GetService(NS_IDNSERVICE_CONTRACTID);
|
||||
|
||||
nsDNSPrefetch::Initialize(this);
|
||||
|
||||
// Don't initialize the resolver if we're in offline mode.
|
||||
// Later on, the IO service will reinitialize us when going online.
|
||||
if (gIOService->IsOffline() && !gIOService->IsComingOnline())
|
||||
return NS_OK;
|
||||
|
||||
nsRefPtr<nsHostResolver> res;
|
||||
nsresult rv = nsHostResolver::Create(maxCacheEntries,
|
||||
maxCacheLifetime,
|
||||
|
@ -397,8 +405,6 @@ nsDNSService::Init()
|
|||
// Disable prefetching either by explicit preference or if a manual proxy is configured
|
||||
mDisablePrefetch = disablePrefetch || (proxyType == nsIProtocolProxyService::PROXYCONFIG_MANUAL);
|
||||
}
|
||||
|
||||
nsDNSPrefetch::Initialize(this);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -571,8 +577,8 @@ nsDNSService::Observe(nsISupports *subject, const char *topic, const PRUnichar *
|
|||
|
||||
if (mResolver) {
|
||||
Shutdown();
|
||||
Init();
|
||||
}
|
||||
Init();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "nsAutoLock.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
|
@ -88,6 +89,7 @@ nsHttpConnectionMgr::nsHttpConnectionMgr()
|
|||
, mNumActiveConns(0)
|
||||
, mNumIdleConns(0)
|
||||
, mTimeOfNextWakeUp(LL_MAXUINT)
|
||||
, mIsShuttingDown(PR_FALSE)
|
||||
{
|
||||
LOG(("Creating nsHttpConnectionMgr @%x\n", this));
|
||||
}
|
||||
|
@ -100,6 +102,32 @@ nsHttpConnectionMgr::~nsHttpConnectionMgr()
|
|||
nsAutoMonitor::DestroyMonitor(mMonitor);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHttpConnectionMgr::EnsureSocketThreadTargetIfOnline()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIEventTarget> sts;
|
||||
nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRBool offline = PR_TRUE;
|
||||
ioService->GetOffline(&offline);
|
||||
|
||||
if (!offline) {
|
||||
sts = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoMonitor mon(mMonitor);
|
||||
|
||||
// do nothing if already initialized or if we've shut down
|
||||
if (mSocketThreadTarget || mIsShuttingDown)
|
||||
return NS_OK;
|
||||
|
||||
mSocketThreadTarget = sts;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHttpConnectionMgr::Init(PRUint16 maxConns,
|
||||
PRUint16 maxConnsPerHost,
|
||||
|
@ -111,28 +139,21 @@ nsHttpConnectionMgr::Init(PRUint16 maxConns,
|
|||
{
|
||||
LOG(("nsHttpConnectionMgr::Init\n"));
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
{
|
||||
nsAutoMonitor mon(mMonitor);
|
||||
|
||||
nsAutoMonitor mon(mMonitor);
|
||||
mMaxConns = maxConns;
|
||||
mMaxConnsPerHost = maxConnsPerHost;
|
||||
mMaxConnsPerProxy = maxConnsPerProxy;
|
||||
mMaxPersistConnsPerHost = maxPersistConnsPerHost;
|
||||
mMaxPersistConnsPerProxy = maxPersistConnsPerProxy;
|
||||
mMaxRequestDelay = maxRequestDelay;
|
||||
mMaxPipelinedRequests = maxPipelinedRequests;
|
||||
|
||||
// do nothing if already initialized
|
||||
if (mSocketThreadTarget)
|
||||
return NS_OK;
|
||||
mIsShuttingDown = PR_FALSE;
|
||||
}
|
||||
|
||||
// no need to do any special synchronization here since there cannot be
|
||||
// any activity on the socket thread (because Shutdown is synchronous).
|
||||
mMaxConns = maxConns;
|
||||
mMaxConnsPerHost = maxConnsPerHost;
|
||||
mMaxConnsPerProxy = maxConnsPerProxy;
|
||||
mMaxPersistConnsPerHost = maxPersistConnsPerHost;
|
||||
mMaxPersistConnsPerProxy = maxPersistConnsPerProxy;
|
||||
mMaxRequestDelay = maxRequestDelay;
|
||||
mMaxPipelinedRequests = maxPipelinedRequests;
|
||||
|
||||
mSocketThreadTarget = sts;
|
||||
return rv;
|
||||
return EnsureSocketThreadTargetIfOnline();
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -151,6 +172,7 @@ nsHttpConnectionMgr::Shutdown()
|
|||
// release our reference to the STS to prevent further events
|
||||
// from being posted. this is how we indicate that we are
|
||||
// shutting down.
|
||||
mIsShuttingDown = PR_TRUE;
|
||||
mSocketThreadTarget = 0;
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -166,6 +188,12 @@ nsHttpConnectionMgr::Shutdown()
|
|||
nsresult
|
||||
nsHttpConnectionMgr::PostEvent(nsConnEventHandler handler, PRInt32 iparam, void *vparam)
|
||||
{
|
||||
// This object doesn't get reinitialized if the offline state changes, so our
|
||||
// socket thread target might be uninitialized if we were offline when this
|
||||
// object was being initialized, and we go online later on. This call takes
|
||||
// care of initializing the socket thread target if that's the case.
|
||||
EnsureSocketThreadTargetIfOnline();
|
||||
|
||||
nsAutoMonitor mon(mMonitor);
|
||||
|
||||
nsresult rv;
|
||||
|
@ -285,6 +313,12 @@ nsHttpConnectionMgr::PruneDeadConnections()
|
|||
nsresult
|
||||
nsHttpConnectionMgr::GetSocketThreadTarget(nsIEventTarget **target)
|
||||
{
|
||||
// This object doesn't get reinitialized if the offline state changes, so our
|
||||
// socket thread target might be uninitialized if we were offline when this
|
||||
// object was being initialized, and we go online later on. This call takes
|
||||
// care of initializing the socket thread target if that's the case.
|
||||
EnsureSocketThreadTargetIfOnline();
|
||||
|
||||
nsAutoMonitor mon(mMonitor);
|
||||
NS_IF_ADDREF(*target = mSocketThreadTarget);
|
||||
return NS_OK;
|
||||
|
|
|
@ -199,6 +199,8 @@ private:
|
|||
PRUint16 mMaxRequestDelay; // in seconds
|
||||
PRUint16 mMaxPipelinedRequests;
|
||||
|
||||
PRPackedBool mIsShuttingDown;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// NOTE: these members are only accessed on the socket transport thread
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -215,6 +217,7 @@ private:
|
|||
PRUint8 caps, nsHttpConnection *);
|
||||
PRBool BuildPipeline(nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **);
|
||||
nsresult ProcessNewTransaction(nsHttpTransaction *);
|
||||
nsresult EnsureSocketThreadTargetIfOnline();
|
||||
|
||||
// message handlers have this signature
|
||||
typedef void (nsHttpConnectionMgr:: *nsConnEventHandler)(PRInt32, void *);
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
function run_test() {
|
||||
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
|
||||
var linkService = Components.classes["@mozilla.org/network/network-link-service;1"]
|
||||
.getService(Components.interfaces.nsINetworkLinkService);
|
||||
|
||||
// The offline status should depends on the link status
|
||||
do_check_neq(ioService.offline, linkService.isLinkUp);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
function run_test() {
|
||||
try {
|
||||
var sts = Components.classes["@mozilla.org/network/socket-transport-service;1"]
|
||||
.getService(Components.interfaces.nsISocketTransportService);
|
||||
} catch(e) {}
|
||||
|
||||
do_check_true(!!sts);
|
||||
}
|
Загрузка…
Ссылка в новой задаче