From a2da1c5189d53510cf44fda8650e57958d648364 Mon Sep 17 00:00:00 2001 From: "taeyoon0.lee" Date: Wed, 3 Jan 2018 16:24:00 +0900 Subject: [PATCH] Fixed crash by libcurl with open ssl in multi-threading https://curl.haxx.se/libcurl/c/threadsafe.html Change-Id: I5bd0620a2240506445a7f07d345111952d28f8fd --- build/tizen/adaptor/Makefile.am | 2 + build/tizen/adaptor/configure.ac | 1 + packaging/dali-adaptor.spec | 2 + .../resource-loader/network/file-download.cpp | 59 +++++++++++++++++++++- .../tizen/resource-loader/network/file-download.h | 19 +++++++ 5 files changed, 82 insertions(+), 1 deletion(-) diff --git a/build/tizen/adaptor/Makefile.am b/build/tizen/adaptor/Makefile.am index 4043ee9..54057ce 100644 --- a/build/tizen/adaptor/Makefile.am +++ b/build/tizen/adaptor/Makefile.am @@ -381,6 +381,7 @@ LIBDALI_ADAPTOR_LA_CXXFLAGS = \ $(LIBDRM_CFLAGS) \ $(LIBEXIF_CFLAGS) \ $(LIBCURL_CFLAGS) \ + $(LIBCRYPTO_CFLAGS) \ $(TPKP_CURL_CFLAGS) \ $(UTILX_CFLAGS) @@ -408,6 +409,7 @@ LIBDALI_ADAPTOR_LA_LIBADD = \ $(LIBDRM_LIBS) \ $(LIBEXIF_LIBS) \ $(LIBCURL_LIBS) \ + $(LIBCRYPTO_LIBS) \ $(HARFBUZZ_LIBS) \ $(TPKP_CURL_LIBS) \ $(UTILX_LIBS) \ diff --git a/build/tizen/adaptor/configure.ac b/build/tizen/adaptor/configure.ac index 4a7f614..14c137a 100644 --- a/build/tizen/adaptor/configure.ac +++ b/build/tizen/adaptor/configure.ac @@ -43,6 +43,7 @@ PKG_CHECK_MODULES(PNG, libpng) PKG_CHECK_MODULES(LIBEXIF, libexif) PKG_CHECK_MODULES(LIBDRM, libdrm) PKG_CHECK_MODULES(LIBCURL, libcurl) +PKG_CHECK_MODULES(LIBCRYPTO, libcrypto) PKG_CHECK_MODULES(HARFBUZZ, harfbuzz) PKG_CHECK_MODULES(FRIBIDI, fribidi) PKG_CHECK_MODULES(EVAS, evas) diff --git a/packaging/dali-adaptor.spec b/packaging/dali-adaptor.spec index 089ccbe..9582d9b 100644 --- a/packaging/dali-adaptor.spec +++ b/packaging/dali-adaptor.spec @@ -85,6 +85,8 @@ BuildRequires: fribidi-devel BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(capi-system-sensor) +BuildRequires: pkgconfig(libcrypto) + %if %{with wayland} ####### BUILDING FOR WAYLAND ####### diff --git a/platform-abstractions/tizen/resource-loader/network/file-download.cpp b/platform-abstractions/tizen/resource-loader/network/file-download.cpp index 80f67fa..1908597 100755 --- a/platform-abstractions/tizen/resource-loader/network/file-download.cpp +++ b/platform-abstractions/tizen/resource-loader/network/file-download.cpp @@ -20,7 +20,9 @@ // EXTERNAL INCLUDES #include +#include #include +#include #include // INTERNAL INCLUDES @@ -55,7 +57,6 @@ const long EXCLUDE_BODY = 1L; */ static Dali::TizenPlatform::Network::CurlEnvironment gCurlEnvironment; - void ConfigureCurlOptions( CURL* curlHandle, const std::string& url ) { curl_easy_setopt( curlHandle, CURLOPT_URL, url.c_str() ); @@ -212,18 +213,74 @@ bool DownloadFile( CURL* curlHandle, namespace Network { +std::mutex* CurlEnvironment::mMutexs = NULL; + CurlEnvironment::CurlEnvironment() { // Must be called before we attempt any loads. e.g. by using curl_easy_init() // and before we start any threads. curl_global_init(CURL_GLOBAL_ALL); + + // libcurl with openssl needs locking_function and thread id for threadsafe + // https://curl.haxx.se/libcurl/c/threadsafe.html + // https://www.openssl.org/docs/man1.0.2/crypto/threads.html#DESCRIPTION + // SetLockingFunction sets locking_function and get thread id by the guide. + SetLockingFunction(); } CurlEnvironment::~CurlEnvironment() { + UnsetLockingFunction(); + curl_global_cleanup(); } +// libcurl with openssl needs locking_function and thread id for threadsafe +// https://curl.haxx.se/libcurl/c/threadsafe.html +// https://www.openssl.org/docs/man1.0.2/crypto/threads.html#DESCRIPTION +void CurlEnvironment::OnOpenSSLLocking( int mode, int n, const char* file, int line ) +{ + if( mode & CRYPTO_LOCK ) + { + mMutexs[n].lock(); + } + else + { + mMutexs[n].unlock(); + } +} + +unsigned long CurlEnvironment::GetThreadId() +{ + // If dali uses c++ thread, we may replace pthread_self() to this_thread::get_id() + return static_cast< unsigned long >( pthread_self() ); +} + +void CurlEnvironment::SetLockingFunction() +{ + if( mMutexs != NULL ) + { + return; + } + + mMutexs = new std::mutex[ CRYPTO_num_locks() ]; + + CRYPTO_set_id_callback( &CurlEnvironment::GetThreadId ); + CRYPTO_set_locking_callback( &CurlEnvironment::OnOpenSSLLocking ); +} + +void CurlEnvironment::UnsetLockingFunction() +{ + if( mMutexs == NULL ) + { + return; + } + + CRYPTO_set_id_callback( NULL ); + CRYPTO_set_locking_callback( NULL ); + delete [] mMutexs; + mMutexs = NULL; +} bool DownloadRemoteFileIntoMemory( const std::string& url, Dali::Vector& dataBuffer, diff --git a/platform-abstractions/tizen/resource-loader/network/file-download.h b/platform-abstractions/tizen/resource-loader/network/file-download.h index ee3d0f5..20380a0 100644 --- a/platform-abstractions/tizen/resource-loader/network/file-download.h +++ b/platform-abstractions/tizen/resource-loader/network/file-download.h @@ -21,6 +21,7 @@ // EXTERNAL INCLUDES #include #include +#include //c++11 #include // uint8 namespace Dali @@ -50,6 +51,24 @@ public: * Destructor calls curl_global_cleanup() */ ~CurlEnvironment(); + + /** + * Locking function for libcurl with openssl + */ + static void OnOpenSSLLocking( int mode, int n, const char* file, int line ); + + /** + * Gets thread id for libcurl with openssl + */ + static unsigned long GetThreadId(); + +private: + + void SetLockingFunction(); + + void UnsetLockingFunction(); + + static std::mutex* mMutexs; }; -- 2.7.4