diff options
author | robot-contrib <robot-contrib@yandex-team.com> | 2022-12-02 11:40:11 +0300 |
---|---|---|
committer | robot-contrib <robot-contrib@yandex-team.com> | 2022-12-02 11:40:11 +0300 |
commit | 7c06d7160fb27755c764763cb9fd1bf917d1c166 (patch) | |
tree | 39bebe3abad68108054bc13702925fc627898cfe | |
parent | b1f4ffc9c8abff3ba58dc1ec9a9f92d2f0de6806 (diff) | |
download | ydb-7c06d7160fb27755c764763cb9fd1bf917d1c166.tar.gz |
Update contrib/restricted/aws/aws-c-common to 0.8.5
10 files changed, 136 insertions, 52 deletions
diff --git a/contrib/restricted/aws/aws-c-common/CMakeLists.darwin.txt b/contrib/restricted/aws/aws-c-common/CMakeLists.darwin.txt index 36166e669d..0a6e1e1d7d 100644 --- a/contrib/restricted/aws/aws-c-common/CMakeLists.darwin.txt +++ b/contrib/restricted/aws/aws-c-common/CMakeLists.darwin.txt @@ -10,6 +10,7 @@ add_library(restricted-aws-aws-c-common) target_compile_options(restricted-aws-aws-c-common PRIVATE -DAWS_COMMON_USE_IMPORT_EXPORT + -DAWS_PTHREAD_SETNAME_TAKES_2ARGS -DCJSON_HIDE_SYMBOLS -DHAVE_SYSCONF -DAWS_AFFINITY_METHOD=AWS_AFFINITY_METHOD_NONE diff --git a/contrib/restricted/aws/aws-c-common/CMakeLists.linux-aarch64.txt b/contrib/restricted/aws/aws-c-common/CMakeLists.linux-aarch64.txt index 838fc9f72f..9235244392 100644 --- a/contrib/restricted/aws/aws-c-common/CMakeLists.linux-aarch64.txt +++ b/contrib/restricted/aws/aws-c-common/CMakeLists.linux-aarch64.txt @@ -10,6 +10,7 @@ add_library(restricted-aws-aws-c-common) target_compile_options(restricted-aws-aws-c-common PRIVATE -DAWS_COMMON_USE_IMPORT_EXPORT + -DAWS_PTHREAD_SETNAME_TAKES_2ARGS -DCJSON_HIDE_SYMBOLS -DHAVE_SYSCONF -DAWS_AFFINITY_METHOD=AWS_AFFINITY_METHOD_PTHREAD_ATTR diff --git a/contrib/restricted/aws/aws-c-common/CMakeLists.linux.txt b/contrib/restricted/aws/aws-c-common/CMakeLists.linux.txt index 6cc92733d9..e46a467dad 100644 --- a/contrib/restricted/aws/aws-c-common/CMakeLists.linux.txt +++ b/contrib/restricted/aws/aws-c-common/CMakeLists.linux.txt @@ -10,6 +10,7 @@ add_library(restricted-aws-aws-c-common) target_compile_options(restricted-aws-aws-c-common PRIVATE -DAWS_COMMON_USE_IMPORT_EXPORT + -DAWS_PTHREAD_SETNAME_TAKES_2ARGS -DCJSON_HIDE_SYMBOLS -DHAVE_SYSCONF -DAWS_AFFINITY_METHOD=AWS_AFFINITY_METHOD_PTHREAD_ATTR diff --git a/contrib/restricted/aws/aws-c-common/include/aws/common/byte_buf.h b/contrib/restricted/aws/aws-c-common/include/aws/common/byte_buf.h index e6464b4780..7df579ec4b 100644 --- a/contrib/restricted/aws/aws-c-common/include/aws/common/byte_buf.h +++ b/contrib/restricted/aws/aws-c-common/include/aws/common/byte_buf.h @@ -56,7 +56,7 @@ struct aws_byte_cursor { #define AWS_BYTE_BUF_PRI(B) ((int)(B).len < 0 ? 0 : (int)(B).len), (const char *)(B).buffer /** - * Helper Macro for inititilizing a byte cursor from a string literal + * Helper Macro for initializing a byte cursor from a string literal */ #define AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL(literal) \ { .ptr = (uint8_t *)(const char *)(literal), .len = sizeof(literal) - 1 } @@ -229,15 +229,26 @@ AWS_COMMON_API bool aws_byte_buf_eq_c_str_ignore_case(const struct aws_byte_buf *const buf, const char *const c_str); /** - * No copies, no buffer allocations. Iterates over input_str, and returns the next substring between split_on instances. + * No copies, no buffer allocations. Iterates over input_str, and returns the + * next substring between split_on instances relative to previous substr. + * Behaves similar to strtok with substr being used as state for next split. * - * Edge case rules are as follows: - * If the input is an empty string, an empty cursor will be the one entry returned. - * If the input begins with split_on, an empty cursor will be the first entry returned. - * If the input has two adjacent split_on tokens, an empty cursor will be returned. - * If the input ends with split_on, an empty cursor will be returned last. + * Returns true each time substr is set and false when there is no more splits + * (substr is set to empty in that case). + * + * Example usage. + * struct aws_byte_cursor substr = {0}; + * while (aws_byte_cursor_next_split(&input_str, ';', &substr)) { + * // ...use substr... + * } * - * It is the user's responsibility zero-initialize substr before the first call. + * Note: It is the user's responsibility zero-initialize substr before the first call. + * + * Edge case rules are as follows: + * empty input will have single empty split. ex. "" splits into "" + * if input starts with split_on then first split is empty. ex ";A" splits into "", "A" + * adjacent split tokens result in empty split. ex "A;;B" splits into "A", "", "B" + * If the input ends with split_on, last split is empty. ex. "A;" splits into "A", "" * * It is the user's responsibility to make sure the input buffer stays in memory * long enough to use the results. diff --git a/contrib/restricted/aws/aws-c-common/include/aws/common/thread.h b/contrib/restricted/aws/aws-c-common/include/aws/common/thread.h index 49e5241748..53aa6a6eef 100644 --- a/contrib/restricted/aws/aws-c-common/include/aws/common/thread.h +++ b/contrib/restricted/aws/aws-c-common/include/aws/common/thread.h @@ -5,7 +5,7 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ -#include <aws/common/common.h> +#include <aws/common/byte_buf.h> #ifndef _WIN32 # include <pthread.h> @@ -52,6 +52,13 @@ enum aws_thread_join_strategy { AWS_TJS_MANAGED, }; +/** + * Thread names should be 15 characters or less. + * Longer names will not display on Linux. + * This length does not include a null terminator. + */ +#define AWS_THREAD_NAME_RECOMMENDED_STRLEN 15 + struct aws_thread_options { size_t stack_size; /* default is -1. If you set this to anything >= 0, and the platform supports it, the thread will be pinned to @@ -67,6 +74,13 @@ struct aws_thread_options { int32_t cpu_id; enum aws_thread_join_strategy join_strategy; + + /** + * Thread name, for debugging purpose. + * The length should not exceed AWS_THREAD_NAME_RECOMMENDED_STRLEN(15) + * if you want it to display properly on all platforms. + */ + struct aws_byte_cursor name; }; #ifdef _WIN32 diff --git a/contrib/restricted/aws/aws-c-common/source/json.c b/contrib/restricted/aws/aws-c-common/source/json.c index 77e7c1d661..387f41f183 100644 --- a/contrib/restricted/aws/aws-c-common/source/json.c +++ b/contrib/restricted/aws/aws-c-common/source/json.c @@ -383,7 +383,9 @@ void aws_json_module_cleanup(void) { void aws_json_value_destroy(struct aws_json_value *value) { struct cJSON *cjson = (struct cJSON *)value; - if (!cJSON_IsInvalid(cjson)) { + /* Note: cJSON_IsInvalid returns false for NULL values, so we need explicit + check for NULL to skip delete */ + if (cjson != NULL && !cJSON_IsInvalid(cjson)) { cJSON_Delete(cjson); } } diff --git a/contrib/restricted/aws/aws-c-common/source/log_channel.c b/contrib/restricted/aws/aws-c-common/source/log_channel.c index bacc8a7e02..a7a461f9c4 100644 --- a/contrib/restricted/aws/aws-c-common/source/log_channel.c +++ b/contrib/restricted/aws/aws-c-common/source/log_channel.c @@ -127,7 +127,19 @@ static bool s_background_wait(void *context) { return impl->finished || aws_array_list_length(&impl->pending_log_lines) > 0; } -static void s_background_thread_writer(void *thread_data) { +/** + * This is where the background thread spends 99.999% of its time. + * We broke this out into its own function so that the stacktrace clearly shows + * what this thread is doing. We've had a lot of cases where users think this + * thread is deadlocked because it's stuck here. We want it to be clear + * that it's doing nothing on purpose. It's waiting for log messages... + */ +AWS_NO_INLINE +static void aws_background_logger_listen_for_messages(struct aws_log_background_channel *impl) { + aws_condition_variable_wait_pred(&impl->pending_line_signal, &impl->sync, s_background_wait, impl); +} + +static void aws_background_logger_thread(void *thread_data) { (void)thread_data; struct aws_log_channel *channel = (struct aws_log_channel *)thread_data; @@ -141,7 +153,8 @@ static void s_background_thread_writer(void *thread_data) { while (true) { aws_mutex_lock(&impl->sync); - aws_condition_variable_wait_pred(&impl->pending_line_signal, &impl->sync, s_background_wait, impl); + + aws_background_logger_listen_for_messages(impl); size_t line_count = aws_array_list_length(&impl->pending_log_lines); bool finished = impl->finished; @@ -217,9 +230,10 @@ int aws_log_channel_init_background( /* * Logging thread should need very little stack, but let's defer this to later */ - struct aws_thread_options thread_options = {.stack_size = 0}; + struct aws_thread_options thread_options = *aws_default_thread_options(); + thread_options.name = aws_byte_cursor_from_c_str("AwsLogger"); /* 15 characters is max for Linux */ - if (aws_thread_launch(&impl->background_thread, s_background_thread_writer, channel, &thread_options) == + if (aws_thread_launch(&impl->background_thread, aws_background_logger_thread, channel, &thread_options) == AWS_OP_SUCCESS) { return AWS_OP_SUCCESS; } diff --git a/contrib/restricted/aws/aws-c-common/source/posix/thread.c b/contrib/restricted/aws/aws-c-common/source/posix/thread.c index 4f742afe02..d17d859c3b 100644 --- a/contrib/restricted/aws/aws-c-common/source/posix/thread.c +++ b/contrib/restricted/aws/aws-c-common/source/posix/thread.c @@ -12,6 +12,7 @@ #include <aws/common/logging.h> #include <aws/common/private/dlloads.h> #include <aws/common/private/thread_shared.h> +#include <aws/common/string.h> #include <aws/common/thread.h> #include <dlfcn.h> @@ -66,6 +67,7 @@ struct thread_wrapper { struct thread_atexit_callback *atexit; void (*call_once)(void *); void *once_arg; + struct aws_string *name; /* * The managed thread system does lazy joins on threads once finished via their wrapper. For that to work @@ -79,6 +81,15 @@ struct thread_wrapper { static AWS_THREAD_LOCAL struct thread_wrapper *tl_wrapper = NULL; +static void s_thread_wrapper_destroy(struct thread_wrapper *wrapper) { + if (!wrapper) { + return; + } + + aws_string_destroy(wrapper->name); + aws_mem_release(wrapper->allocator, wrapper); +} + /* * thread_wrapper is platform-dependent so this function ends up being duplicated in each thread implementation */ @@ -103,12 +114,28 @@ void aws_thread_join_and_free_wrapper_list(struct aws_linked_list *wrapper_list) */ aws_thread_clean_up(&join_thread_wrapper->thread_copy); - aws_mem_release(join_thread_wrapper->allocator, join_thread_wrapper); + s_thread_wrapper_destroy(join_thread_wrapper); aws_thread_decrement_unjoined_count(); } } +/* This must be called from the thread itself. + * (only necessary for Apple, but we'll do it that way on every platform for consistency) */ +static void s_set_thread_name(pthread_t thread_id, const char *name) { +#if defined(__APPLE__) + (void)thread_id; + pthread_setname_np(name); +#elif defined(AWS_PTHREAD_SETNAME_TAKES_2ARGS) + pthread_setname_np(thread_id, name); +#elif defined(AWS_PTHREAD_SETNAME_TAKES_3ARGS) + pthread_setname_np(thread_id, name, NULL); +#else + (void)thread_id; + (void)name; +#endif +} + static void *thread_fn(void *arg) { struct thread_wrapper *wrapper_ptr = arg; @@ -117,6 +144,14 @@ static void *thread_fn(void *arg) { */ wrapper_ptr->thread_copy.thread_id = aws_thread_current_thread_id(); + /* If there's a name, set it. + * Then free the aws_string before we make copies of the wrapper struct */ + if (wrapper_ptr->name) { + s_set_thread_name(wrapper_ptr->thread_copy.thread_id, aws_string_c_str(wrapper_ptr->name)); + aws_string_destroy(wrapper_ptr->name); + wrapper_ptr->name = NULL; + } + struct thread_wrapper wrapper = *wrapper_ptr; struct aws_allocator *allocator = wrapper.allocator; tl_wrapper = &wrapper; @@ -142,7 +177,8 @@ static void *thread_fn(void *arg) { */ bool is_managed_thread = wrapper.thread_copy.detach_state == AWS_THREAD_MANAGED; if (!is_managed_thread) { - aws_mem_release(allocator, arg); + s_thread_wrapper_destroy(wrapper_ptr); + wrapper_ptr = NULL; } struct thread_atexit_callback *exit_callback_data = wrapper.atexit; @@ -213,7 +249,7 @@ int aws_thread_launch( pthread_attr_t attributes; pthread_attr_t *attributes_ptr = NULL; int attr_return = 0; - int allocation_failed = 0; + struct thread_wrapper *wrapper = NULL; bool is_managed_thread = options != NULL && options->join_strategy == AWS_TJS_MANAGED; if (is_managed_thread) { thread->detach_state = AWS_THREAD_MANAGED; @@ -259,23 +295,22 @@ int aws_thread_launch( AWS_LS_COMMON_THREAD, "id=%p: pthread_attr_setaffinity_np() failed with %d.", (void *)thread, - errno); + attr_return); goto cleanup; } } #endif /* AWS_AFFINITY_METHOD == AWS_AFFINITY_METHOD_PTHREAD_ATTR */ } - struct thread_wrapper *wrapper = - (struct thread_wrapper *)aws_mem_calloc(thread->allocator, 1, sizeof(struct thread_wrapper)); - - if (!wrapper) { - allocation_failed = 1; - goto cleanup; - } + wrapper = aws_mem_calloc(thread->allocator, 1, sizeof(struct thread_wrapper)); - if (options && options->cpu_id >= 0) { - wrapper->membind = true; + if (options) { + if (options->cpu_id >= 0) { + wrapper->membind = true; + } + if (options->name.len > 0) { + wrapper->name = aws_string_new_from_cursor(thread->allocator, &options->name); + } } wrapper->thread_copy = *thread; @@ -293,6 +328,7 @@ int aws_thread_launch( attr_return = pthread_create(&thread->thread_id, attributes_ptr, thread_fn, (void *)wrapper); if (attr_return) { + AWS_LOGF_ERROR(AWS_LS_COMMON_THREAD, "id=%p: pthread_create() failed with %d", (void *)thread, attr_return); if (is_managed_thread) { aws_thread_decrement_unjoined_count(); } @@ -313,11 +349,14 @@ int aws_thread_launch( CPU_ZERO(&cpuset); CPU_SET((uint32_t)options->cpu_id, &cpuset); - attr_return = pthread_setaffinity_np(thread->thread_id, sizeof(cpuset), &cpuset); - if (attr_return) { - AWS_LOGF_ERROR( - AWS_LS_COMMON_THREAD, "id=%p: pthread_setaffinity_np() failed with %d.", (void *)thread, errno); - goto cleanup; + /* If this fails, just warn. We can't fail anymore, the thread has already launched. */ + int setaffinity_return = pthread_setaffinity_np(thread->thread_id, sizeof(cpuset), &cpuset); + if (setaffinity_return) { + AWS_LOGF_WARN( + AWS_LS_COMMON_THREAD, + "id=%p: pthread_setaffinity_np() failed with %d. Running thread without CPU affinity.", + (void *)thread, + setaffinity_return); } } #endif /* AWS_AFFINITY_METHOD == AWS_AFFINITY_METHOD_PTHREAD */ @@ -336,22 +375,22 @@ cleanup: pthread_attr_destroy(attributes_ptr); } - if (attr_return == EINVAL) { - return aws_raise_error(AWS_ERROR_THREAD_INVALID_SETTINGS); - } - - if (attr_return == EAGAIN) { - return aws_raise_error(AWS_ERROR_THREAD_INSUFFICIENT_RESOURCE); - } - - if (attr_return == EPERM) { - return aws_raise_error(AWS_ERROR_THREAD_NO_PERMISSIONS); - } - - if (allocation_failed || attr_return == ENOMEM) { - return aws_raise_error(AWS_ERROR_OOM); + if (attr_return) { + s_thread_wrapper_destroy(wrapper); + + switch (attr_return) { + case EINVAL: + return aws_raise_error(AWS_ERROR_THREAD_INVALID_SETTINGS); + case EAGAIN: + return aws_raise_error(AWS_ERROR_THREAD_INSUFFICIENT_RESOURCE); + case EPERM: + return aws_raise_error(AWS_ERROR_THREAD_NO_PERMISSIONS); + case ENOMEM: + return aws_raise_error(AWS_ERROR_OOM); + default: + return aws_raise_error(AWS_ERROR_UNKNOWN); + } } - return AWS_OP_SUCCESS; } diff --git a/contrib/restricted/aws/aws-c-common/source/uri.c b/contrib/restricted/aws/aws-c-common/source/uri.c index f91f2921e3..0559641420 100644 --- a/contrib/restricted/aws/aws-c-common/source/uri.c +++ b/contrib/restricted/aws/aws-c-common/source/uri.c @@ -14,7 +14,6 @@ #if _MSC_VER # pragma warning(disable : 4221) /* aggregate initializer using local variable addresses */ # pragma warning(disable : 4204) /* non-constant aggregate initializer */ -# pragma warning(disable : 4996) /* sprintf */ #endif enum parser_state { @@ -143,7 +142,7 @@ int aws_uri_init_from_builder_options( if (options->port) { aws_byte_buf_append(&uri->uri_str, &port_app); char port_arr[6] = {0}; - sprintf(port_arr, "%" PRIu16, options->port); + snprintf(port_arr, sizeof(port_arr), "%" PRIu16, options->port); struct aws_byte_cursor port_csr = aws_byte_cursor_from_c_str(port_arr); aws_byte_buf_append(&uri->uri_str, &port_csr); } diff --git a/contrib/restricted/aws/aws-c-common/source/uuid.c b/contrib/restricted/aws/aws-c-common/source/uuid.c index a962abd653..f880c0d95d 100644 --- a/contrib/restricted/aws/aws-c-common/source/uuid.c +++ b/contrib/restricted/aws/aws-c-common/source/uuid.c @@ -23,7 +23,7 @@ /* disables warning non const declared initializers for Microsoft compilers */ # pragma warning(disable : 4204) # pragma warning(disable : 4706) -/* sprintf warning (we already check the bounds in this case). */ +/* sscanf warning */ # pragma warning(disable : 4996) #endif @@ -67,10 +67,12 @@ int aws_uuid_init_from_str(struct aws_uuid *uuid, const struct aws_byte_cursor * } int aws_uuid_to_str(const struct aws_uuid *uuid, struct aws_byte_buf *output) { - AWS_ERROR_PRECONDITION(output->capacity - output->len >= AWS_UUID_STR_LEN, AWS_ERROR_SHORT_BUFFER); + size_t space_remaining = output->capacity - output->len; + AWS_ERROR_PRECONDITION(space_remaining >= AWS_UUID_STR_LEN, AWS_ERROR_SHORT_BUFFER); - sprintf( + snprintf( (char *)(output->buffer + output->len), + space_remaining, UUID_FORMAT, uuid->uuid_data[0], uuid->uuid_data[1], |