Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(851)

Unified Diff: net/ocsp/nss_ocsp.cc

Issue 3421039: Revert 60739 (still leaks on ChromiumOS!) - Reland r59972: Eagerly set the IO... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/ocsp/nss_ocsp.h ('k') | net/url_request/url_request_context.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/ocsp/nss_ocsp.cc
===================================================================
--- net/ocsp/nss_ocsp.cc (revision 60752)
+++ net/ocsp/nss_ocsp.cc (working copy)
@@ -9,19 +9,16 @@
#include <ocsp.h>
#include <nspr.h>
#include <nss.h>
-#include <pthread.h>
#include <secerr.h>
#include <string>
-#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/condition_variable.h"
#include "base/histogram.h"
-#include "base/lazy_instance.h"
-#include "base/lock.h"
#include "base/logging.h"
#include "base/message_loop.h"
+#include "base/singleton.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/thread.h"
@@ -36,93 +33,6 @@
namespace {
-// Protects |g_request_context|.
-pthread_mutex_t g_request_context_lock = PTHREAD_MUTEX_INITIALIZER;
-static URLRequestContext* g_request_context = NULL;
-
-class OCSPIOLoop : public MessageLoop::DestructionObserver {
- public:
- // MessageLoop::DestructionObserver:
- virtual void WillDestroyCurrentMessageLoop();
-
- void StartUsing() {
- AutoLock autolock(lock_);
- used_ = true;
- }
-
- bool used() const {
- AutoLock autolock(lock_);
- return used_;
- }
-
- // Called from worker thread.
- void PostTaskToIOLoop(const tracked_objects::Location& from_here, Task* task);
-
- void EnsureIOLoop();
-
- private:
- friend struct base::DefaultLazyInstanceTraits<OCSPIOLoop>;
-
- OCSPIOLoop();
- ~OCSPIOLoop();
-
- mutable Lock lock_;
- bool used_; // Protected by |lock_|.
- // This should not be modified after |used_|.
- MessageLoopForIO* io_loop_; // Protected by |lock_|.
-
- DISALLOW_COPY_AND_ASSIGN(OCSPIOLoop);
-};
-
-OCSPIOLoop::OCSPIOLoop()
- : used_(false),
- io_loop_(MessageLoopForIO::current()) {
- DCHECK(io_loop_);
- io_loop_->AddDestructionObserver(this);
-}
-
-OCSPIOLoop::~OCSPIOLoop() {
- // IO thread was already deleted before the singleton is deleted
- // in AtExitManager.
- {
- AutoLock autolock(lock_);
- DCHECK(!io_loop_);
- DCHECK(!used_);
- }
-
- pthread_mutex_lock(&g_request_context_lock);
- DCHECK(!g_request_context);
- pthread_mutex_unlock(&g_request_context_lock);
-}
-
-void OCSPIOLoop::WillDestroyCurrentMessageLoop() {
- // Prevent the worker thread from trying to access |io_loop_|.
- {
- AutoLock autolock(lock_);
- DCHECK_EQ(MessageLoopForIO::current(), io_loop_);
- io_loop_ = NULL;
- used_ = false;
- }
-
- pthread_mutex_lock(&g_request_context_lock);
- g_request_context = NULL;
- pthread_mutex_unlock(&g_request_context_lock);
-}
-
-void OCSPIOLoop::PostTaskToIOLoop(
- const tracked_objects::Location& from_here, Task* task) {
- AutoLock autolock(lock_);
- if (io_loop_)
- io_loop_->PostTask(from_here, task);
-}
-
-void OCSPIOLoop::EnsureIOLoop() {
- AutoLock autolock(lock_);
- DCHECK_EQ(MessageLoopForIO::current(), io_loop_);
-}
-
-base::LazyInstance<OCSPIOLoop> g_ocsp_io_loop(base::LINKER_INITIALIZED);
-
const int kRecvBufferSize = 4096;
// All OCSP handlers should be called in the context of
@@ -159,59 +69,98 @@
char* GetAlternateOCSPAIAInfo(CERTCertificate *cert);
-class OCSPNSSInitialization {
- private:
- friend struct base::DefaultLazyInstanceTraits<OCSPNSSInitialization>;
+class OCSPInitSingleton : public MessageLoop::DestructionObserver {
+ public:
+ // Called on IO thread.
+ virtual void WillDestroyCurrentMessageLoop() {
+ AutoLock autolock(lock_);
+ DCHECK_EQ(MessageLoopForIO::current(), io_loop_);
+ io_loop_ = NULL;
+ request_context_ = NULL;
+ };
- OCSPNSSInitialization();
- ~OCSPNSSInitialization();
+ // Called from worker thread.
+ void PostTaskToIOLoop(
+ const tracked_objects::Location& from_here, Task* task) {
+ AutoLock autolock(lock_);
+ if (io_loop_)
+ io_loop_->PostTask(from_here, task);
+ }
- SEC_HttpClientFcn client_fcn_;
+ // This is static method because it is called before NSS initialization,
+ // that is, before OCSPInitSingleton is initialized.
+ static void set_url_request_context(URLRequestContext* request_context) {
+ request_context_ = request_context;
+ }
+ static URLRequestContext* url_request_context() {
+ return request_context_;
+ }
- DISALLOW_COPY_AND_ASSIGN(OCSPNSSInitialization);
-};
+ private:
+ friend struct DefaultSingletonTraits<OCSPInitSingleton>;
-OCSPNSSInitialization::OCSPNSSInitialization() {
- // NSS calls the functions in the function table to download certificates
- // or CRLs or talk to OCSP responders over HTTP. These functions must
- // set an NSS/NSPR error code when they fail. Otherwise NSS will get the
- // residual error code from an earlier failed function call.
- client_fcn_.version = 1;
- SEC_HttpClientFcnV1Struct *ft = &client_fcn_.fcnTable.ftable1;
- ft->createSessionFcn = OCSPCreateSession;
- ft->keepAliveSessionFcn = OCSPKeepAliveSession;
- ft->freeSessionFcn = OCSPFreeSession;
- ft->createFcn = OCSPCreate;
- ft->setPostDataFcn = OCSPSetPostData;
- ft->addHeaderFcn = OCSPAddHeader;
- ft->trySendAndReceiveFcn = OCSPTrySendAndReceive;
- ft->cancelFcn = NULL;
- ft->freeFcn = OCSPFree;
- SECStatus status = SEC_RegisterDefaultHttpClient(&client_fcn_);
- if (status != SECSuccess) {
- NOTREACHED() << "Error initializing OCSP: " << PR_GetError();
+ OCSPInitSingleton()
+ : io_loop_(MessageLoopForIO::current()) {
+ DCHECK(io_loop_);
+ io_loop_->AddDestructionObserver(this);
+
+ // NSS calls the functions in the function table to download certificates
+ // or CRLs or talk to OCSP responders over HTTP. These functions must
+ // set an NSS/NSPR error code when they fail. Otherwise NSS will get the
+ // residual error code from an earlier failed function call.
+ client_fcn_.version = 1;
+ SEC_HttpClientFcnV1Struct *ft = &client_fcn_.fcnTable.ftable1;
+ ft->createSessionFcn = OCSPCreateSession;
+ ft->keepAliveSessionFcn = OCSPKeepAliveSession;
+ ft->freeSessionFcn = OCSPFreeSession;
+ ft->createFcn = OCSPCreate;
+ ft->setPostDataFcn = OCSPSetPostData;
+ ft->addHeaderFcn = OCSPAddHeader;
+ ft->trySendAndReceiveFcn = OCSPTrySendAndReceive;
+ ft->cancelFcn = NULL;
+ ft->freeFcn = OCSPFree;
+ SECStatus status = SEC_RegisterDefaultHttpClient(&client_fcn_);
+ if (status != SECSuccess) {
+ NOTREACHED() << "Error initializing OCSP: " << PR_GetError();
+ }
+
+ // Work around NSS bugs 524013 and 564334. NSS incorrectly thinks the
+ // CRLs for Network Solutions Certificate Authority have bad signatures,
+ // which causes certificates issued by that CA to be reported as revoked.
+ // By using OCSP for those certificates, which don't have AIA extensions,
+ // we can work around these bugs. See http://crbug.com/41730.
+ CERT_StringFromCertFcn old_callback = NULL;
+ status = CERT_RegisterAlternateOCSPAIAInfoCallBack(
+ GetAlternateOCSPAIAInfo, &old_callback);
+ if (status == SECSuccess) {
+ DCHECK(!old_callback);
+ } else {
+ NOTREACHED() << "Error initializing OCSP: " << PR_GetError();
+ }
}
- // Work around NSS bugs 524013 and 564334. NSS incorrectly thinks the
- // CRLs for Network Solutions Certificate Authority have bad signatures,
- // which causes certificates issued by that CA to be reported as revoked.
- // By using OCSP for those certificates, which don't have AIA extensions,
- // we can work around these bugs. See http://crbug.com/41730.
- CERT_StringFromCertFcn old_callback = NULL;
- status = CERT_RegisterAlternateOCSPAIAInfoCallBack(
- GetAlternateOCSPAIAInfo, &old_callback);
- if (status == SECSuccess) {
- DCHECK(!old_callback);
- } else {
- NOTREACHED() << "Error initializing OCSP: " << PR_GetError();
+ virtual ~OCSPInitSingleton() {
+ // IO thread was already deleted before the singleton is deleted
+ // in AtExitManager.
+ AutoLock autolock(lock_);
+ DCHECK(!io_loop_);
+ DCHECK(!request_context_);
}
-}
-OCSPNSSInitialization::~OCSPNSSInitialization() {}
+ SEC_HttpClientFcn client_fcn_;
-base::LazyInstance<OCSPNSSInitialization> g_ocsp_nss_initialization(
- base::LINKER_INITIALIZED);
+ // |lock_| protects |io_loop_|.
+ Lock lock_;
+ // I/O thread.
+ MessageLoop* io_loop_; // I/O thread
+ // URLRequestContext for OCSP handlers.
+ static URLRequestContext* request_context_;
+ DISALLOW_COPY_AND_ASSIGN(OCSPInitSingleton);
+};
+
+URLRequestContext* OCSPInitSingleton::request_context_ = NULL;
+
// Concrete class for SEC_HTTP_REQUEST_SESSION.
// Public methods except virtual methods of URLRequest::Delegate (On* methods)
// run on certificate verifier thread (worker thread).
@@ -251,7 +200,7 @@
// |io_loop_| was initialized to be NULL in constructor, and
// set only in StartURLRequest, so no need to lock |lock_| here.
DCHECK(!io_loop_);
- g_ocsp_io_loop.Get().PostTaskToIOLoop(
+ Singleton<OCSPInitSingleton>()->PostTaskToIOLoop(
FROM_HERE,
NewRunnableMethod(this, &OCSPRequestSession::StartURLRequest));
}
@@ -390,14 +339,11 @@
}
}
- // Runs on |g_ocsp_io_loop|'s IO loop.
void StartURLRequest() {
DCHECK(!request_);
- pthread_mutex_lock(&g_request_context_lock);
- URLRequestContext* url_request_context = g_request_context;
- pthread_mutex_unlock(&g_request_context_lock);
-
+ URLRequestContext* url_request_context =
+ OCSPInitSingleton::url_request_context();
if (url_request_context == NULL)
return;
@@ -530,10 +476,7 @@
SEC_HTTP_SERVER_SESSION* pSession) {
LOG(INFO) << "OCSP create session: host=" << host << " port=" << portnum;
DCHECK(!MessageLoop::current());
- pthread_mutex_lock(&g_request_context_lock);
- URLRequestContext* request_context = g_request_context;
- pthread_mutex_unlock(&g_request_context_lock);
- if (request_context == NULL) {
+ if (OCSPInitSingleton::url_request_context() == NULL) {
LOG(ERROR) << "No URLRequestContext for OCSP handler.";
// The application failed to call SetURLRequestContextForOCSP, so we
// can't create and use URLRequest. PR_NOT_IMPLEMENTED_ERROR is not an
@@ -840,40 +783,17 @@
namespace net {
-void SetMessageLoopForOCSP() {
- // Must have a MessageLoopForIO.
- DCHECK(MessageLoopForIO::current());
-
- bool used = g_ocsp_io_loop.Get().used();
-
- // Should not be called when g_ocsp_io_loop has already been used.
- DCHECK(!used);
-}
-
void EnsureOCSPInit() {
- g_ocsp_io_loop.Get().StartUsing();
- g_ocsp_nss_initialization.Get();
+ Singleton<OCSPInitSingleton>::get();
}
// This function would be called before NSS initialization.
void SetURLRequestContextForOCSP(URLRequestContext* request_context) {
- pthread_mutex_lock(&g_request_context_lock);
- if (request_context) {
- DCHECK(request_context->is_main());
- DCHECK(!g_request_context);
- } else {
- DCHECK(g_request_context);
- }
- g_request_context = request_context;
- pthread_mutex_unlock(&g_request_context_lock);
+ OCSPInitSingleton::set_url_request_context(request_context);
}
URLRequestContext* GetURLRequestContextForOCSP() {
- pthread_mutex_lock(&g_request_context_lock);
- URLRequestContext* request_context = g_request_context;
- pthread_mutex_unlock(&g_request_context_lock);
- DCHECK(request_context->is_main());
- return request_context;
+ return OCSPInitSingleton::url_request_context();
}
} // namespace net
« no previous file with comments | « net/ocsp/nss_ocsp.h ('k') | net/url_request/url_request_context.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698