diff options
author | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-22 18:42:12 +0000 |
---|---|---|
committer | thestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-22 18:42:12 +0000 |
commit | 500bdbe6de1a8dd68d84ef6a3fde61be705029b2 (patch) | |
tree | dd32694203a3fdc0f229e9972329be7a0340e195 | |
parent | 817e1dd8ae6ed6be46c408a7c7ee579888f55e67 (diff) | |
download | chromium_src-500bdbe6de1a8dd68d84ef6a3fde61be705029b2.zip chromium_src-500bdbe6de1a8dd68d84ef6a3fde61be705029b2.tar.gz chromium_src-500bdbe6de1a8dd68d84ef6a3fde61be705029b2.tar.bz2 |
Linux: Dynamically load libgnutls.so in the cloud printing CUPS code.
BUG=46954
TEST=chrome binary built on Hardy no longer explictily depend on libgnutls.so.13.
Review URL: http://codereview.chromium.org/2823018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50487 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/chrome.gyp | 1 | ||||
-rw-r--r-- | chrome/service/cloud_print/print_system.h | 2 | ||||
-rw-r--r-- | chrome/service/cloud_print/print_system_cups.cc | 80 |
3 files changed, 57 insertions, 26 deletions
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index a486c7d..f55067f 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -1131,7 +1131,6 @@ 'libraries': [ '-lcups', '-lgcrypt', - '-lgnutls', ], }, 'defines': [ diff --git a/chrome/service/cloud_print/print_system.h b/chrome/service/cloud_print/print_system.h index 23f6f41..b7d0ce5 100644 --- a/chrome/service/cloud_print/print_system.h +++ b/chrome/service/cloud_print/print_system.h @@ -12,7 +12,6 @@ #include "base/file_path.h" #include "base/ref_counted.h" #include "base/values.h" -#include "googleurl/src/gurl.h" // This is the interface for platform-specific code for cloud print namespace cloud_print { @@ -169,4 +168,3 @@ typedef PrintSystem::PrinterWatcher::Delegate PrinterWatcherDelegate; } // namespace cloud_print #endif // CHROME_SERVICE_CLOUD_PRINT_PRINT_SYSTEM_H_ - diff --git a/chrome/service/cloud_print/print_system_cups.cc b/chrome/service/cloud_print/print_system_cups.cc index 2f32a5a..b624f40 100644 --- a/chrome/service/cloud_print/print_system_cups.cc +++ b/chrome/service/cloud_print/print_system_cups.cc @@ -5,56 +5,92 @@ #include "chrome/service/cloud_print/print_system.h" #include <cups/cups.h> -#include <list> -#include <map> - -#include <gnutls/gnutls.h> -#include <gcrypt.h> +#include <dlfcn.h> #include <errno.h> +#include <gcrypt.h> #include <pthread.h> -#include "base/json/json_reader.h" +#include <list> +#include <map> + #include "base/file_path.h" #include "base/file_util.h" -#include "base/logging.h" +#include "base/json/json_reader.h" #include "base/lock.h" +#include "base/logging.h" #include "base/message_loop.h" #include "base/rand_util.h" #include "base/string_util.h" #include "base/task.h" #include "base/utf_string_conversions.h" +#include "googleurl/src/gurl.h" -namespace cloud_print { - -static const char kCUPSPrinterInfoOpt[] = "printer-info"; -static const char kCUPSPrinterStateOpt[] = "printer-state"; -static const wchar_t kCUPSPrintServerURL[] = L"print_server_url"; - -// Default port for IPP print servers. -static const int kDefaultIPPServerPort = 631; +namespace { // Init GCrypt library (needed for CUPS) using pthreads. // I've hit a bug in CUPS library, when it crashed with: "ath.c:184: // _gcry_ath_mutex_lock: Assertion `*lock == ((ath_mutex_t) 0)' failed." // It happened whe multiple threads tried printing simultaneously. -// Google search for 'gnutls thread safety' provided with following solution. +// Google search for 'gnutls thread safety' provided with following solution +// where we initialize gcrypt by initializing gnutls. +// +// Initially, we linked with -lgnutls and simply called gnutls_global_init(), +// but this did not work well since we build one binary on Ubuntu Hardy and +// expect it to run on many Linux distros. (See http://crbug.com/46954) +// So instead we use dlopen() and dlsym() to dynamically load and call +// gnutls_global_init(). GCRY_THREAD_OPTION_PTHREAD_IMPL; +bool init_gnutls() { + const char* kGnuTlsFile = "libgnutls.so"; + void* gnutls_lib = dlopen(kGnuTlsFile, RTLD_NOW); + if (!gnutls_lib) { + LOG(ERROR) << "Cannot load " << kGnuTlsFile; + return false; + } + const char* kGnuTlsInitFuncName = "gnutls_global_init"; + int (*pgnutls_global_init)(void) = reinterpret_cast<int(*)()>( + dlsym(gnutls_lib, kGnuTlsInitFuncName)); + if (!pgnutls_global_init) { + LOG(ERROR) << "Could not find " << kGnuTlsInitFuncName + << " in " << kGnuTlsFile; + return false; + } + return ((*pgnutls_global_init)() == 0); +} + void init_gcrypt() { + // The gnutls_global_init() man page warns it's not thread safe. Locking this + // entire function just to be on the safe side. + static Lock init_gcrypt_lock; + AutoLock init_gcrypt_autolock(init_gcrypt_lock); static bool gcrypt_initialized = false; if (!gcrypt_initialized) { gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); - gnutls_global_init(); - gcrypt_initialized = true; + gcrypt_initialized = init_gnutls(); + if (!gcrypt_initialized) { + LOG(ERROR) << "Gcrypt initialization failed"; + } } } +} // namespace + +namespace cloud_print { + +static const char kCUPSPrinterInfoOpt[] = "printer-info"; +static const char kCUPSPrinterStateOpt[] = "printer-state"; +static const wchar_t kCUPSPrintServerURL[] = L"print_server_url"; + +// Default port for IPP print servers. +static const int kDefaultIPPServerPort = 631; + // Helper wrapper around http_t structure, with connection and cleanup // functionality. class HttpConnectionCUPS { public: - explicit HttpConnectionCUPS(const GURL& print_server_url) : http_(NULL) { + explicit HttpConnectionCUPS(const GURL& print_server_url) : http_(NULL) { // If we have an empty url, use default print server. if (print_server_url.is_empty()) return; @@ -67,7 +103,7 @@ class HttpConnectionCUPS { HTTP_ENCRYPT_NEVER); if (http_ == NULL) { LOG(ERROR) << "CP_CUPS: Failed connecting to print server: " << - print_server_url; + print_server_url; } } @@ -462,7 +498,7 @@ FilePath PrintSystemCUPS::GetPPD(const char* name) { // cupsGetPPD returns a filename stored in a static buffer in CUPS. // Protect this code with lock. static Lock ppd_lock; - ppd_lock.Acquire(); + AutoLock ppd_autolock(ppd_lock); FilePath ppd_path; const char* ppd_file_path = NULL; if (print_server_url_.is_empty()) { // Use default (local) print server. @@ -473,7 +509,6 @@ FilePath PrintSystemCUPS::GetPPD(const char* name) { } if (ppd_file_path) ppd_path = FilePath(ppd_file_path); - ppd_lock.Release(); return ppd_path; } @@ -500,4 +535,3 @@ int PrintSystemCUPS::GetJobs(cups_job_t** jobs, const char* name, } } // namespace cloud_print - |