| Index: net/socket/client_socket_factory.cc
|
| diff --git a/net/socket/client_socket_factory.cc b/net/socket/client_socket_factory.cc
|
| index 42f6d4f20cebcf90c4d82d2c1be78d6d38ed099c..ade687454a99efa329aa354f086e5ab3cc5e87c7 100644
|
| --- a/net/socket/client_socket_factory.cc
|
| +++ b/net/socket/client_socket_factory.cc
|
| @@ -5,6 +5,8 @@
|
| #include "net/socket/client_socket_factory.h"
|
|
|
| #include "base/lazy_instance.h"
|
| +#include "base/thread_task_runner_handle.h"
|
| +#include "base/threading/thread.h"
|
| #include "build/build_config.h"
|
| #include "net/base/cert_database.h"
|
| #include "net/socket/client_socket_handle.h"
|
| @@ -31,14 +33,31 @@ namespace {
|
|
|
| bool g_use_system_ssl = false;
|
|
|
| +// ChromeOS uses a hardware TPM module that may cause NSS operations to
|
| +// block for upwards of several seconds. To avoid blocking all network and
|
| +// IPC activity, run NSS SSL functions on a dedicated thread.
|
| +#if defined(OS_CHROMEOS)
|
| +bool g_use_dedicated_nss_thread = true;
|
| +#else
|
| +bool g_use_dedicated_nss_thread = false;
|
| +#endif
|
| +
|
| class DefaultClientSocketFactory : public ClientSocketFactory,
|
| public CertDatabase::Observer {
|
| public:
|
| DefaultClientSocketFactory() {
|
| + if (g_use_dedicated_nss_thread) {
|
| + nss_thread_.reset(new base::Thread("NSS SSL Thread"));
|
| + if (nss_thread_->Start())
|
| + nss_thread_task_runner_ = nss_thread_->message_loop_proxy();
|
| + }
|
| +
|
| CertDatabase::AddObserver(this);
|
| }
|
|
|
| virtual ~DefaultClientSocketFactory() {
|
| + // Note: This code never runs, as the factory is defined as a Leaky
|
| + // singleton.
|
| CertDatabase::RemoveObserver(this);
|
| }
|
|
|
| @@ -76,26 +95,43 @@ class DefaultClientSocketFactory : public ClientSocketFactory,
|
| const SSLClientSocketContext& context) {
|
| scoped_ptr<SSLHostInfo> shi(ssl_host_info);
|
|
|
| -#if defined(OS_WIN)
|
| + // nss_thread_task_runner_ may be NULL if g_use_dedicated_nss_thread is
|
| + // false or if the dedicated NSS thread failed to start. If so, cause NSS
|
| + // functions to execute on the current task runner.
|
| + //
|
| + // Note: The current task runner is obtained on each call due to unit
|
| + // tests, which may create and tear down the current thread's TaskRunner
|
| + // between each test. Because the DefaultClientSocketFactory is leaky, it
|
| + // may span multiple tests, and thus the current task runner may change
|
| + // from call to call.
|
| + scoped_refptr<base::SingleThreadTaskRunner> nss_task_runner(
|
| + nss_thread_task_runner_);
|
| + if (!nss_task_runner)
|
| + nss_task_runner = base::ThreadTaskRunnerHandle::Get();
|
| +
|
| +#if defined(USE_OPENSSL)
|
| + return new SSLClientSocketOpenSSL(transport_socket, host_and_port,
|
| + ssl_config, context);
|
| +#elif defined(USE_NSS)
|
| + return new SSLClientSocketNSS(nss_task_runner, transport_socket,
|
| + host_and_port, ssl_config, shi.release(),
|
| + context);
|
| +#elif defined(OS_WIN)
|
| if (g_use_system_ssl) {
|
| return new SSLClientSocketWin(transport_socket, host_and_port,
|
| ssl_config, context);
|
| }
|
| - return new SSLClientSocketNSS(transport_socket, host_and_port, ssl_config,
|
| - shi.release(), context);
|
| -#elif defined(USE_OPENSSL)
|
| - return new SSLClientSocketOpenSSL(transport_socket, host_and_port,
|
| - ssl_config, context);
|
| -#elif defined(USE_NSS)
|
| - return new SSLClientSocketNSS(transport_socket, host_and_port, ssl_config,
|
| - shi.release(), context);
|
| + return new SSLClientSocketNSS(nss_task_runner, transport_socket,
|
| + host_and_port, ssl_config, shi.release(),
|
| + context);
|
| #elif defined(OS_MACOSX)
|
| if (g_use_system_ssl) {
|
| return new SSLClientSocketMac(transport_socket, host_and_port,
|
| ssl_config, context);
|
| }
|
| - return new SSLClientSocketNSS(transport_socket, host_and_port, ssl_config,
|
| - shi.release(), context);
|
| + return new SSLClientSocketNSS(nss_task_runner, transport_socket,
|
| + host_and_port, ssl_config, shi.release(),
|
| + context);
|
| #else
|
| NOTIMPLEMENTED();
|
| return NULL;
|
| @@ -106,9 +142,12 @@ class DefaultClientSocketFactory : public ClientSocketFactory,
|
| SSLClientSocket::ClearSessionCache();
|
| }
|
|
|
| + private:
|
| + scoped_ptr<base::Thread> nss_thread_;
|
| + scoped_refptr<base::SingleThreadTaskRunner> nss_thread_task_runner_;
|
| };
|
|
|
| -static base::LazyInstance<DefaultClientSocketFactory>
|
| +static base::LazyInstance<DefaultClientSocketFactory>::Leaky
|
| g_default_client_socket_factory = LAZY_INSTANCE_INITIALIZER;
|
|
|
| } // namespace
|
|
|