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) |
wtc
2012/05/30 22:54:29
It may be a good idea to do this on more platforms
Ryan Sleevi
2012/05/30 23:20:10
I agree, but as a possible merge candidate, I want
wtc
2012/05/31 01:23:42
If you plan to merge this CL to the Chrome 20 bran
Ryan Sleevi
2012/05/31 01:31:14
Agreed, that's the goal :)
|
+bool g_use_dedicated_nss_thread = true; |
+#else |
+bool g_use_dedicated_nss_thread = false; |
+#endif |
Ryan Sleevi
2012/05/30 02:11:33
Design context: I debated very heavily on where th
wtc
2012/05/30 22:54:29
I agree with the design decision of creating the N
|
+ |
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()) |
wtc
2012/05/30 22:54:29
If g_use_dedicated_nss_thread is true, nss_thread_
Ryan Sleevi
2012/05/30 23:20:10
If the thread fails to start, it'll be NULL. With
|
+ nss_task_runner = nss_thread_->message_loop_proxy(); |
Ryan Sleevi
2012/05/30 02:14:33
Further design context:
Note that I'm not checkin
wtc
2012/05/30 22:54:29
I agree with the design decision of moving all NSS
|
+ |
+#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> |