From: Serge Petrenko <sergepetrenko@tarantool.org> To: alexander.turenko@tarantool.org Cc: tarantool-patches@dev.tarantool.org Subject: [Tarantool-patches] [PATCH] build: link bundled libcurl with c-ares Date: Mon, 25 Nov 2019 16:53:47 +0300 [thread overview] Message-ID: <20191125135347.5105-1-sergepetrenko@tarantool.org> (raw) libcurl has a built-in threaded resolver used for asynchronous DNS requests, however, when DNS server is slow to respond, the request still hangs tarantool until it is finished. The reason is that curl calls thread_join on the resolving thread internally upon timeout, making the calling thread hang until resolution has ended. Use c-ares as an asynchronous resolver instead to eliminate the problem. Closes #4591 --- https://github.com/tarantool/tarantool/issues/4591 https://github.com/tarantool/tarantool/tree/sp/gh-4591-link-curl-with-c-ares-full-ci .gitmodules | 3 ++ CMakeLists.txt | 6 ++++ cmake/BuildAres.cmake | 67 ++++++++++++++++++++++++++++++++++++++++ cmake/BuildLibCURL.cmake | 31 +++++++++++++++++-- third_party/c-ares | 1 + 5 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 cmake/BuildAres.cmake create mode 160000 third_party/c-ares diff --git a/.gitmodules b/.gitmodules index 76303e0c5..d45e9ce8b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -40,3 +40,6 @@ [submodule "third_party/curl"] path = third_party/curl url = https://github.com/tarantool/curl.git +[submodule "third_party/c-ares"] + path = third_party/c-ares + url = https://github.com/tarantool/c-ares.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d6c0846e..dca060857 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -339,7 +339,13 @@ endif() # Curl # option(ENABLE_BUNDLED_LIBCURL "Enable building of the bundled libcurl" ON) +option(BUNDLED_LIBCURL_USE_ARES "Build curl with bundled c-ares" + ${ENABLE_BUNDLED_LIBCURL}) if (ENABLE_BUNDLED_LIBCURL) + if(BUNDLED_LIBCURL_USE_ARES) + include(BuildAres) + ares_build() + endif() include(BuildLibCURL) curl_build() add_dependencies(build_bundled_libs bundled-libcurl) diff --git a/cmake/BuildAres.cmake b/cmake/BuildAres.cmake new file mode 100644 index 000000000..ea4cfdd9d --- /dev/null +++ b/cmake/BuildAres.cmake @@ -0,0 +1,67 @@ +# A macro to build the bundled libcares +macro(ares_build) + set(ARES_SOURCE_DIR ${PROJECT_SOURCE_DIR}/third_party/c-ares) + set(ARES_BINARY_DIR ${PROJECT_BINARY_DIR}/build/ares/work) + set(ARES_INSTALL_DIR ${PROJECT_BINARY_DIR}/build/ares/dest) + + # See BuildLibCURL.cmake for details. + set(ARES_CPPFLAGS "") + set(ARES_CFLAGS "") + set(ARES_CXXFLAGS "") + if (TARGET_OS_DARWIN AND NOT "${CMAKE_OSX_SYSROOT}" STREQUAL "") + set(ARES_CPPFLAGS "${ARES_CPPFLAGS} ${CMAKE_C_SYSROOT_FLAG} ${CMAKE_OSX_SYSROOT}") + set(ARES_CFLAGS "${ARES_CFLAGS} ${CMAKE_C_SYSROOT_FLAG} ${CMAKE_OSX_SYSROOT}") + set(ARES_CXXFLAGS "${ARES_CXXFLAGS} ${CMAKE_CXX_SYSROOT_FLAG} ${CMAKE_OSX_SYSROOT}") + endif() + + include(ExternalProject) + ExternalProject_Add( + bundled-ares-project + SOURCE_DIR ${ARES_SOURCE_DIR} + PREFIX ${ARES_INSTALL_DIR} + DOWNLOAD_DIR ${ARES_BINARY_DIR} + TMP_DIR ${ARES_BINARY_DIR}/tmp + STAMP_DIR ${ARES_BINARY_DIR}/stamp + BINARY_DIR ${ARES_BINARY_DIR} + CONFIGURE_COMMAND + cd <SOURCE_DIR> && ./buildconf && + cd <BINARY_DIR> && <SOURCE_DIR>/configure + # Pass the same toolchain as is used to build + # tarantool itself, because they can be + # incompatible. + CC=${CMAKE_C_COMPILER} + CXX=${CMAKE_CXX_COMPILER} + LD=${CMAKE_LINKER} + AR=${CMAKE_AR} + RANLIB=${CMAKE_RANLIB} + NM=${CMAKE_NM} + STRIP=${CMAKE_STRIP} + + CFLAGS=${ARES_CFLAGS} + CPPFLAGS=${ARES_CPPFLAGS} + CXXFLAGS=${ARES_CXXFLAGS} + # Pass empty LDFLAGS to discard using of + # corresponding environment variable. + # It is possible that a linker flag assumes that + # some compilation flag is set. We don't pass + # CFLAGS from environment, so we should not do it + # for LDFLAGS too. + LDFLAGS= + + --prefix=<INSTALL_DIR> + --enable-static + + BUILD_COMMAND cd <BINARY_DIR> && $(MAKE) + INSTALL_COMMAND cd <BINARY_DIR> && $(MAKE) install) + + add_library(bundled-ares STATIC IMPORTED GLOBAL) + set_target_properties(bundled-ares PROPERTIES IMPORTED_LOCATION + ${ARES_INSTALL_DIR}/lib/libcares.a) + add_dependencies(bundled-ares bundled-ares-project) + + unset(ARES_CPPFLAGS) + unset(ARES_CFLAGS) + unset(ARES_CXXFLAGS) + unset(ARES_BINARY_DIR) + unset(ARES_SOURCE_DIR) +endmacro(ares_build) diff --git a/cmake/BuildLibCURL.cmake b/cmake/BuildLibCURL.cmake index 6d40ab045..756297878 100644 --- a/cmake/BuildLibCURL.cmake +++ b/cmake/BuildLibCURL.cmake @@ -19,6 +19,21 @@ macro(curl_build) get_filename_component(FOUND_OPENSSL_ROOT_DIR ${OPENSSL_INCLUDE_DIR} DIRECTORY) set(LIBCURL_OPENSSL_OPT "--with-ssl=${FOUND_OPENSSL_ROOT_DIR}") + # Use either c-ares bundled with tarantool or + # libcurl-default threaded resolver. + if(BUNDLED_LIBCURL_USE_ARES) + set(ASYN_DNS_USED "ares") + set(ASYN_DNS_UNUSED "threaded-resolver") + set(ASYN_DNS_PATH "=${ARES_INSTALL_DIR}") + else() + set(ASYN_DNS_USED "threaded-resolver") + set(ASYN_DNS_UNUSED "ares") + set(ASYN_DNS_PATH "") + endif() + + set(ENABLED_DNS_OPT "--enable-${ASYN_DNS_USED}${ASYN_DNS_PATH}") + set(DISABLED_DNS_OPT "--disable-${ASYN_DSN_UNUSED}") + # Pass -isysroot=<SDK_PATH> option on Mac OS to a preprocessor # and a C compiler to find header files installed with an SDK. # @@ -100,17 +115,17 @@ macro(curl_build) --without-zsh-functions-dir --without-fish-functions-dir + ${ENABLED_DNS_OPT} --enable-http --enable-proxy --enable-ipv6 - --enable-threaded-resolver --enable-unix-sockets --enable-cookies --enable-http-auth --enable-mime --enable-dateparse - --disable-ares + ${DISABLED_DNS_OPT} --disable-ftp --disable-file --disable-ldap @@ -140,14 +155,26 @@ macro(curl_build) add_library(bundled-libcurl STATIC IMPORTED GLOBAL) set_target_properties(bundled-libcurl PROPERTIES IMPORTED_LOCATION ${LIBCURL_INSTALL_DIR}/lib/libcurl.a) + if (BUNDLED_LIBCURL_USE_ARES) + # Need to build ares first + add_dependencies(bundled-libcurl-project bundled-ares) + endif() add_dependencies(bundled-libcurl bundled-libcurl-project) set(CURL_INCLUDE_DIRS ${LIBCURL_INSTALL_DIR}/include) set(CURL_LIBRARIES bundled-libcurl ${LIBZ_LIBRARY}) + if (BUNDLED_LIBCURL_USE_ARES) + set(CURL_LIBRARIES ${CURL_LIBRARIES} bundled-ares) + endif() if (TARGET_OS_LINUX OR TARGET_OS_FREEBSD) set(CURL_LIBRARIES ${CURL_LIBRARIES} rt) endif() + unset(ASYN_DNS_USED) + unset(ASYN_DNS_UNUSED) + unset(ASYN_DNS_PATH) + unset(ENABLED_DNS_OPT) + unset(DISABLED_DNS_OPT) unset(LIBCURL_CPPFLAGS) unset(LIBCURL_CFLAGS) unset(FOUND_OPENSSL_ROOT_DIR) diff --git a/third_party/c-ares b/third_party/c-ares new file mode 160000 index 000000000..14e38b154 --- /dev/null +++ b/third_party/c-ares @@ -0,0 +1 @@ +Subproject commit 14e38b154c972cd41fed277e6f5c4fc8f0ed8d9f -- 2.21.0 (Apple Git-122)
next reply other threads:[~2019-11-25 13:54 UTC|newest] Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-11-25 13:53 Serge Petrenko [this message] 2019-12-18 2:33 ` Alexander Turenko 2020-01-21 12:17 ` Serge Petrenko 2020-02-08 19:28 ` Alexander Turenko
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20191125135347.5105-1-sergepetrenko@tarantool.org \ --to=sergepetrenko@tarantool.org \ --cc=alexander.turenko@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH] build: link bundled libcurl with c-ares' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox