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..5c4037b07e65fbd32fccc5eb45fa3275266b7415 100644 |
--- a/net/socket/client_socket_factory.cc |
+++ b/net/socket/client_socket_factory.cc |
@@ -5,6 +5,7 @@ |
#include "net/socket/client_socket_factory.h" |
#include "base/lazy_instance.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,10 +32,24 @@ 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")); |
+ nss_thread_->Start(); |
+ } |
+ |
CertDatabase::AddObserver(this); |
} |
@@ -76,25 +91,38 @@ class DefaultClientSocketFactory : public ClientSocketFactory, |
const SSLClientSocketContext& context) { |
scoped_ptr<SSLHostInfo> shi(ssl_host_info); |
-#if defined(OS_WIN) |
+ scoped_refptr<base::SingleThreadTaskRunner> network_task_runner( |
+ base::MessageLoopProxy::current()); |
+ DCHECK(network_task_runner); |
+ |
+ scoped_refptr<base::SingleThreadTaskRunner> nss_task_runner( |
+ network_task_runner); |
+ |
+ if (g_use_dedicated_nss_thread && nss_thread_->message_loop_proxy()) |
+ nss_task_runner = nss_thread_->message_loop_proxy(); |
+ |
+#if defined(USE_OPENSSL) |
+ return new SSLClientSocketOpenSSL(transport_socket, host_and_port, |
+ ssl_config, context); |
+#elif defined(USE_NSS) |
+ return new SSLClientSocketNSS(network_task_runner, 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, |
+ return new SSLClientSocketNSS(network_task_runner, 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, |
+ return new SSLClientSocketNSS(network_task_runner, nss_task_runner, |
+ transport_socket, host_and_port, ssl_config, |
shi.release(), context); |
#else |
NOTIMPLEMENTED(); |
@@ -106,6 +134,8 @@ class DefaultClientSocketFactory : public ClientSocketFactory, |
SSLClientSocket::ClearSessionCache(); |
} |
+ private: |
+ scoped_ptr<base::Thread> nss_thread_; |
}; |
static base::LazyInstance<DefaultClientSocketFactory> |