diff options
author | Alexander Smirnov <alex@ydb.tech> | 2024-10-02 11:40:21 +0000 |
---|---|---|
committer | Alexander Smirnov <alex@ydb.tech> | 2024-10-02 11:40:21 +0000 |
commit | 4a43f3fbfda5a2eee2af081bd76ae023afd481db (patch) | |
tree | ae27208d4452705b2c0ec19efdcd8132c8e8de20 /contrib | |
parent | 2a5dadb53a806ed944a3a3e1dfcaef886838360d (diff) | |
parent | 2084bac66bb1c8d3013d8ef6c61867726c4188e2 (diff) | |
download | ydb-4a43f3fbfda5a2eee2af081bd76ae023afd481db.tar.gz |
Merge branch 'rightlib' into mergelibs-241002-1139
Diffstat (limited to 'contrib')
12 files changed, 102 insertions, 228 deletions
diff --git a/contrib/libs/curl/lib/asyn-thread.c b/contrib/libs/curl/lib/asyn-thread.c index e44fe2c648..63414b6174 100644 --- a/contrib/libs/curl/lib/asyn-thread.c +++ b/contrib/libs/curl/lib/asyn-thread.c @@ -73,74 +73,23 @@ struct resdata { struct curltime start; }; -/* Doubly linked list of orphaned thread handles. */ -struct thread_list { - curl_thread_t handle; - - /* 'exiting' is set true right before an orphaned thread exits. - it should only be set by the orphaned thread from - signal_orphan_is_exiting(). */ - bool exiting; - - struct thread_list *prev, *next; -}; - -/* Orphaned threads: A global list of resolver threads that could not be - * completed in time and so they were abandoned by their parent. The list is - * culled periodically by soon-to-be exiting orphans to wait on and destroy - * those that are in the process of or have since exited, which is fast. On - * global cleanup we wait on and destroy any remaining threads, which may be - * slow but at that point we cannot defer it any longer. - */ -struct orphaned_threads { - /* Mutex to lock this. To avoid deadlock the thread-specific thread_sync_data - mutex cannot be used as an inner lock when orphaned_threads is locked. */ - curl_mutex_t mutex; - - /* List of orphaned threads. */ - struct thread_list *first, *last; - - /* Count of threads in the list that are in the process of or have exited. - (ie .exiting member of the thread_list item is set true) */ - size_t exiting_count; -}; - -static struct orphaned_threads orphaned_threads; - -/* Flags for wait_and_destroy_orphaned_threads(). - They're documented above the function definition. */ -#define WAIT_DESTROY_ALL (1<<0) -#define WAIT_DESTROY_EXITING_THREADS_ONLY (1<<1) - -static void wait_and_destroy_orphaned_threads(int flags); -static void signal_orphan_is_exiting(struct thread_list *orphan); - - /* * Curl_resolver_global_init() * Called from curl_global_init() to initialize global resolver environment. + * Does nothing here. */ int Curl_resolver_global_init(void) { - memset(&orphaned_threads, 0, sizeof(orphaned_threads)); - - if(Curl_mutex_init(&orphaned_threads.mutex)) - return CURLE_FAILED_INIT; - return CURLE_OK; } /* * Curl_resolver_global_cleanup() * Called from curl_global_cleanup() to destroy global resolver environment. + * Does nothing here. */ void Curl_resolver_global_cleanup(void) { - /* Take ownership of all orphaned resolver threads and wait for them to exit. - This is necessary because the user may choose to unload the shared library - that is/contains libcurl. */ - wait_and_destroy_orphaned_threads(WAIT_DESTROY_ALL); - Curl_mutex_destroy(&orphaned_threads.mutex); } /* @@ -220,8 +169,6 @@ struct thread_data { unsigned int poll_interval; timediff_t interval_end; struct thread_sync_data tsd; - /* 'reserved' memory must be available in case the thread is orphaned */ - void *reserved; }; static struct thread_sync_data *conn_thread_sync_data(struct Curl_easy *data) @@ -283,11 +230,7 @@ int init_thread_sync_data(struct thread_data *td, if(!tsd->mtx) goto err_exit; - if(Curl_mutex_init(tsd->mtx)) { - free(tsd->mtx); - tsd->mtx = NULL; - goto err_exit; - } + Curl_mutex_init(tsd->mtx); #ifndef CURL_DISABLE_SOCKETPAIR /* create socket pair or pipe */ @@ -346,7 +289,6 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg) { struct thread_sync_data *tsd = (struct thread_sync_data *)arg; struct thread_data *td = tsd->td; - struct thread_list *orphan = NULL; char service[12]; int rc; #ifndef CURL_DISABLE_SOCKETPAIR @@ -371,7 +313,6 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg) /* too late, gotta clean up the mess */ Curl_mutex_release(tsd->mtx); destroy_thread_sync_data(tsd); - orphan = (struct thread_list *)td->reserved; free(td); } else { @@ -389,9 +330,6 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg) Curl_mutex_release(tsd->mtx); } - if(orphan) - signal_orphan_is_exiting(orphan); - return 0; } @@ -404,7 +342,6 @@ static unsigned int CURL_STDCALL gethostbyname_thread(void *arg) { struct thread_sync_data *tsd = (struct thread_sync_data *)arg; struct thread_data *td = tsd->td; - struct thread_list *orphan = NULL; tsd->res = Curl_ipv4_resolve_r(tsd->hostname, tsd->port); @@ -419,7 +356,6 @@ static unsigned int CURL_STDCALL gethostbyname_thread(void *arg) /* too late, gotta clean up the mess */ Curl_mutex_release(tsd->mtx); destroy_thread_sync_data(tsd); - orphan = (struct thread_list *)td->reserved; free(td); } else { @@ -427,9 +363,6 @@ static unsigned int CURL_STDCALL gethostbyname_thread(void *arg) Curl_mutex_release(tsd->mtx); } - if(orphan) - signal_orphan_is_exiting(orphan); - return 0; } @@ -448,60 +381,25 @@ static void destroy_async_data(struct Curl_async *async) struct Curl_easy *data = td->tsd.data; #endif - /* We can't wait any longer for the resolver thread so if it's not done - * then it must be orphaned. - * - * 1) add thread to orphaned threads list - * 2) set thread done (this signals to thread it has been orphaned) - * - * An orphaned thread does most of its own cleanup, and any remaining - * cleanup is handled during global cleanup. + /* + * if the thread is still blocking in the resolve syscall, detach it and + * let the thread do the cleanup... */ - Curl_mutex_acquire(td->tsd.mtx); - - if(!td->tsd.done && td->thread_hnd != curl_thread_t_null) { - struct thread_list *orphan = (struct thread_list *)td->reserved; - - Curl_mutex_acquire(&orphaned_threads.mutex); - -#ifdef DEBUGBUILD - { - struct thread_list empty; - memset(&empty, 0, sizeof(empty)); - DEBUGASSERT(!memcmp(&empty, orphan, sizeof(empty))); - } -#endif - - orphan->handle = td->thread_hnd; - orphan->exiting = false; - - if(orphaned_threads.last) { - orphaned_threads.last->next = orphan; - orphan->prev = orphaned_threads.last; - } - else { - orphaned_threads.first = orphan; - orphan->prev = NULL; - } - orphaned_threads.last = orphan; - orphan->next = NULL; - - Curl_mutex_release(&orphaned_threads.mutex); - } - done = td->tsd.done; td->tsd.done = 1; - Curl_mutex_release(td->tsd.mtx); - if(done) { + if(!done) { + Curl_thread_destroy(td->thread_hnd); + } + else { if(td->thread_hnd != curl_thread_t_null) Curl_thread_join(&td->thread_hnd); destroy_thread_sync_data(&td->tsd); - free(td->reserved); - free(td); + + free(async->tdata); } #ifndef CURL_DISABLE_SOCKETPAIR /* @@ -541,11 +439,9 @@ static bool init_resolve_thread(struct Curl_easy *data, asp->status = 0; asp->dns = NULL; td->thread_hnd = curl_thread_t_null; - td->reserved = calloc(1, sizeof(struct thread_list)); - if(!td->reserved || !init_thread_sync_data(td, hostname, port, hints)) { + if(!init_thread_sync_data(td, hostname, port, hints)) { asp->tdata = NULL; - free(td->reserved); free(td); goto errno_exit; } @@ -564,7 +460,7 @@ static bool init_resolve_thread(struct Curl_easy *data, td->thread_hnd = Curl_thread_create(gethostbyname_thread, &td->tsd); #endif - if(td->thread_hnd == curl_thread_t_null) { + if(!td->thread_hnd) { /* The thread never started, so mark it as done here for proper cleanup. */ td->tsd.done = 1; err = errno; @@ -861,100 +757,4 @@ CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data, return CURLE_NOT_BUILT_IN; } -/* Helper function to wait and destroy some or all orphaned threads. - * - * WAIT_DESTROY_ALL: - * Wait and destroy all orphaned threads. This operation is not safe to specify - * in code that could run in any thread that may be orphaned (ie any resolver - * thread). Waiting on all orphaned threads may take some time. This operation - * must be specified in the call from global cleanup, and ideally nowhere else. - * - * WAIT_DESTROY_EXITING_THREADS_ONLY: - * Wait and destroy only orphaned threads that are in the process of or have - * since exited (ie those with .exiting set true). This is fast. - * - * When the calling thread owns orphaned_threads.mutex it must not call this - * function or deadlock my occur. - */ -static void wait_and_destroy_orphaned_threads(int flags) -{ - struct thread_list *thread = NULL; - - Curl_mutex_acquire(&orphaned_threads.mutex); - - if((flags & WAIT_DESTROY_EXITING_THREADS_ONLY)) { - struct thread_list *p, *next; - struct thread_list *first = NULL, *last = NULL; - - if(!orphaned_threads.exiting_count) { - Curl_mutex_release(&orphaned_threads.mutex); - return; - } - - for(p = orphaned_threads.first; p; p = next) { - next = p->next; - - if(!p->exiting) - continue; - - /* remove thread list item from orphaned_threads */ - if(p->prev) - p->prev->next = p->next; - if(p->next) - p->next->prev = p->prev; - if(orphaned_threads.first == p) - orphaned_threads.first = p->next; - if(orphaned_threads.last == p) - orphaned_threads.last = p->prev; - - /* add thread list item to new thread list */ - if(last) { - last->next = p; - p->prev = last; - } - else { - first = p; - p->prev = NULL; - } - last = p; - p->next = NULL; - } - - thread = first; - orphaned_threads.exiting_count = 0; - } - else if((flags & WAIT_DESTROY_ALL)) { - thread = orphaned_threads.first; - orphaned_threads.first = NULL; - orphaned_threads.last = NULL; - orphaned_threads.exiting_count = 0; - } - - Curl_mutex_release(&orphaned_threads.mutex); - - /* Wait and free. Must be done unlocked or there could be deadlock. */ - while(thread) { - struct thread_list *next = thread->next; - Curl_thread_join(&thread->handle); - free(thread); - thread = next; - } -} - -/* Helper function that must be called from an orphaned thread right before it - exits. */ -static void signal_orphan_is_exiting(struct thread_list *orphan) -{ - DEBUGASSERT(orphan->handle && !orphan->exiting); - - wait_and_destroy_orphaned_threads(WAIT_DESTROY_EXITING_THREADS_ONLY); - - Curl_mutex_acquire(&orphaned_threads.mutex); - - orphan->exiting = true; - orphaned_threads.exiting_count++; - - Curl_mutex_release(&orphaned_threads.mutex); -} - #endif /* CURLRES_THREADED */ diff --git a/contrib/libs/curl/lib/multi.c b/contrib/libs/curl/lib/multi.c index 8051de0628..5456113be7 100644 --- a/contrib/libs/curl/lib/multi.c +++ b/contrib/libs/curl/lib/multi.c @@ -656,10 +656,8 @@ static CURLcode multi_done(struct Curl_easy *data, /* Stop if multi_done() has already been called */ return CURLE_OK; - /* Cancel the resolver (but not dns_entry yet). We used to call - Curl_resolver_kill here but that blocks waiting for incomplete resolve - threads (eg getaddrinfo has not returned), which may take a while. */ - Curl_resolver_cancel(data); + /* Stop the resolver and free its own resources (but not dns_entry yet). */ + Curl_resolver_kill(data); /* Cleanup possible redirect junk */ Curl_safefree(data->req.newurl); diff --git a/contrib/libs/grpc/include/grpcpp/create_channel_binder.h b/contrib/libs/grpc/include/grpcpp/create_channel_binder.h index 1a2963b40e..56ae80882c 100644 --- a/contrib/libs/grpc/include/grpcpp/create_channel_binder.h +++ b/contrib/libs/grpc/include/grpcpp/create_channel_binder.h @@ -19,7 +19,7 @@ #ifdef GPR_ANDROID -#error #include <jni.h> +#include <jni.h> #include <memory> diff --git a/contrib/libs/grpc/include/grpcpp/security/binder_security_policy.h b/contrib/libs/grpc/include/grpcpp/security/binder_security_policy.h index fa14a98f79..e1c951fc66 100644 --- a/contrib/libs/grpc/include/grpcpp/security/binder_security_policy.h +++ b/contrib/libs/grpc/include/grpcpp/security/binder_security_policy.h @@ -19,7 +19,7 @@ #ifdef GPR_ANDROID -#error #include <jni.h> +#include <jni.h> #endif diff --git a/contrib/libs/grpc/src/core/ext/transport/binder/client/endpoint_binder_pool.cc b/contrib/libs/grpc/src/core/ext/transport/binder/client/endpoint_binder_pool.cc index 2b41c1db9a..5ecae2a775 100644 --- a/contrib/libs/grpc/src/core/ext/transport/binder/client/endpoint_binder_pool.cc +++ b/contrib/libs/grpc/src/core/ext/transport/binder/client/endpoint_binder_pool.cc @@ -22,7 +22,7 @@ #ifdef GPR_SUPPORT_BINDER_TRANSPORT -#error #include <jni.h> +#include <jni.h> #include "src/core/ext/transport/binder/wire_format/binder_android.h" diff --git a/contrib/libs/grpc/src/core/ext/transport/binder/client/jni_utils.h b/contrib/libs/grpc/src/core/ext/transport/binder/client/jni_utils.h index cd05b90e02..234c7be99a 100644 --- a/contrib/libs/grpc/src/core/ext/transport/binder/client/jni_utils.h +++ b/contrib/libs/grpc/src/core/ext/transport/binder/client/jni_utils.h @@ -19,7 +19,7 @@ #include <grpc/support/port_platform.h> -#error #include <jni.h> +#include <jni.h> #include <functional> #include <util/generic/string.h> diff --git a/contrib/libs/grpc/src/core/ext/transport/binder/security_policy/binder_security_policy.cc b/contrib/libs/grpc/src/core/ext/transport/binder/security_policy/binder_security_policy.cc index 5da1ec9507..a97bb6c945 100644 --- a/contrib/libs/grpc/src/core/ext/transport/binder/security_policy/binder_security_policy.cc +++ b/contrib/libs/grpc/src/core/ext/transport/binder/security_policy/binder_security_policy.cc @@ -20,7 +20,7 @@ #ifdef GPR_ANDROID -#error #include <jni.h> +#include <jni.h> #include <unistd.h> #include <grpc/support/log.h> diff --git a/contrib/libs/grpc/src/core/ext/transport/binder/server/binder_server.cc b/contrib/libs/grpc/src/core/ext/transport/binder/server/binder_server.cc index 59bbf9654a..7141aded3f 100644 --- a/contrib/libs/grpc/src/core/ext/transport/binder/server/binder_server.cc +++ b/contrib/libs/grpc/src/core/ext/transport/binder/server/binder_server.cc @@ -36,7 +36,7 @@ #ifdef GPR_SUPPORT_BINDER_TRANSPORT -#error #include <jni.h> +#include <jni.h> extern "C" { diff --git a/contrib/libs/grpc/src/core/ext/transport/binder/utils/binder_auto_utils.h b/contrib/libs/grpc/src/core/ext/transport/binder/utils/binder_auto_utils.h new file mode 100644 index 0000000000..c72f776076 --- /dev/null +++ b/contrib/libs/grpc/src/core/ext/transport/binder/utils/binder_auto_utils.h @@ -0,0 +1,76 @@ +// Copyright 2021 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_UTILS_BINDER_AUTO_UTILS_H +#define GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_UTILS_BINDER_AUTO_UTILS_H + +#include <grpc/support/port_platform.h> + +#ifdef GPR_SUPPORT_BINDER_TRANSPORT + +#include "src/core/ext/transport/binder/utils/ndk_binder.h" + +namespace grpc_binder { +namespace ndk_util { + +/// +/// Represents one strong pointer to an AIBinder object. +/// Copied from binder/ndk/include_cpp/android/binder_auto_utils.h +/// +class SpAIBinder { + public: + SpAIBinder() : mBinder(nullptr) {} + explicit SpAIBinder(AIBinder* binder) : mBinder(binder) {} + SpAIBinder(std::nullptr_t) + : SpAIBinder() {} // NOLINT(google-explicit-constructor) + SpAIBinder(const SpAIBinder& other) { *this = other; } + + ~SpAIBinder() { set(nullptr); } + SpAIBinder& operator=(const SpAIBinder& other) { + if (this == &other) { + return *this; + } + AIBinder_incStrong(other.mBinder); + set(other.mBinder); + return *this; + } + + void set(AIBinder* binder) { + AIBinder* old = *const_cast<AIBinder* volatile*>(&mBinder); + if (old != nullptr) AIBinder_decStrong(old); + if (old != *const_cast<AIBinder* volatile*>(&mBinder)) { + __assert(__FILE__, __LINE__, "Race detected."); + } + mBinder = binder; + } + + AIBinder* get() const { return mBinder; } + AIBinder** getR() { return &mBinder; } + + bool operator!=(const SpAIBinder& rhs) const { return get() != rhs.get(); } + bool operator<(const SpAIBinder& rhs) const { return get() < rhs.get(); } + bool operator<=(const SpAIBinder& rhs) const { return get() <= rhs.get(); } + bool operator==(const SpAIBinder& rhs) const { return get() == rhs.get(); } + bool operator>(const SpAIBinder& rhs) const { return get() > rhs.get(); } + bool operator>=(const SpAIBinder& rhs) const { return get() >= rhs.get(); } + + private: + AIBinder* mBinder = nullptr; +}; +} // namespace ndk_util +} // namespace grpc_binder + +#endif + +#endif // GRPC_SRC_CORE_EXT_TRANSPORT_BINDER_UTILS_BINDER_AUTO_UTILS_H diff --git a/contrib/libs/grpc/src/core/ext/transport/binder/utils/ndk_binder.h b/contrib/libs/grpc/src/core/ext/transport/binder/utils/ndk_binder.h index cabf21a7b5..1ca82c8162 100644 --- a/contrib/libs/grpc/src/core/ext/transport/binder/utils/ndk_binder.h +++ b/contrib/libs/grpc/src/core/ext/transport/binder/utils/ndk_binder.h @@ -20,7 +20,7 @@ #ifdef GPR_SUPPORT_BINDER_TRANSPORT #include <assert.h> -#error #include <jni.h> +#include <jni.h> #include <memory> diff --git a/contrib/libs/grpc/src/core/ext/transport/binder/wire_format/binder_android.h b/contrib/libs/grpc/src/core/ext/transport/binder/wire_format/binder_android.h index c1844e94f6..32c8b17354 100644 --- a/contrib/libs/grpc/src/core/ext/transport/binder/wire_format/binder_android.h +++ b/contrib/libs/grpc/src/core/ext/transport/binder/wire_format/binder_android.h @@ -19,13 +19,13 @@ #ifdef GPR_SUPPORT_BINDER_TRANSPORT -#error #include <jni.h> +#include <jni.h> #include <memory> #include "y_absl/memory/memory.h" -#error #include "src/core/ext/transport/binder/utils/binder_auto_utils.h" +#include "src/core/ext/transport/binder/utils/binder_auto_utils.h" #include "src/core/ext/transport/binder/utils/ndk_binder.h" #include "src/core/ext/transport/binder/wire_format/binder.h" #include "src/core/ext/transport/binder/wire_format/wire_reader.h" diff --git a/contrib/python/scipy/py3/ya.make b/contrib/python/scipy/py3/ya.make index 4bfa915f30..bbf87b9b5e 100644 --- a/contrib/python/scipy/py3/ya.make +++ b/contrib/python/scipy/py3/ya.make @@ -1,4 +1,4 @@ -# Generated by devtools/yamaker from nixpkgs 24.05. +# Generated by devtools/yamaker from nixpkgs 23.05. PY3_LIBRARY() |