Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package aws-c-io for openSUSE:Factory checked in at 2025-06-02 22:01:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/aws-c-io (Old) and /work/SRC/openSUSE:Factory/.aws-c-io.new.16005 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "aws-c-io" Mon Jun 2 22:01:43 2025 rev:23 rq:1281982 version:0.19.1 Changes: -------- --- /work/SRC/openSUSE:Factory/aws-c-io/aws-c-io.changes 2025-05-07 19:21:21.427434192 +0200 +++ /work/SRC/openSUSE:Factory/.aws-c-io.new.16005/aws-c-io.changes 2025-06-02 22:01:49.356361588 +0200 @@ -1,0 +2,9 @@ +Tue May 27 06:48:24 UTC 2025 - John Paul Adrian Glaubitz <adrian.glaub...@suse.com> + +- Update to version 0.19.1 + * Fix casing on Windows header files by @waahm7 in (#730) + * Acquire/Release Event Loop by @xiazhvera in (#725) + * Remove clang-3 from CI by @sbSteveK in (#731) + * Fix warnings in iOS Cross Compile CI by @waahm7 in (#733) + +------------------------------------------------------------------- Old: ---- v0.19.0.tar.gz New: ---- v0.19.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ aws-c-io.spec ++++++ --- /var/tmp/diff_new_pack.CPlGax/_old 2025-06-02 22:01:49.828381165 +0200 +++ /var/tmp/diff_new_pack.CPlGax/_new 2025-06-02 22:01:49.828381165 +0200 @@ -21,7 +21,7 @@ %define library_version 1.0.0 %define library_soversion 0unstable Name: aws-c-io -Version: 0.19.0 +Version: 0.19.1 Release: 0 Summary: I/O and TLS package AWS SDK for C License: Apache-2.0 ++++++ v0.19.0.tar.gz -> v0.19.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/.github/workflows/ci.yml new/aws-c-io-0.19.1/.github/workflows/ci.yml --- old/aws-c-io-0.19.0/.github/workflows/ci.yml 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/.github/workflows/ci.yml 2025-05-21 23:02:52.000000000 +0200 @@ -61,7 +61,6 @@ strategy: matrix: compiler: - - name: clang-3 - name: clang-6 - name: clang-8 - name: clang-9 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/.github/workflows/proof-alarm.yml new/aws-c-io-0.19.1/.github/workflows/proof-alarm.yml --- old/aws-c-io-0.19.0/.github/workflows/proof-alarm.yml 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/.github/workflows/proof-alarm.yml 2025-05-21 23:02:52.000000000 +0200 @@ -16,7 +16,7 @@ - name: Check run: | TMPFILE=$(mktemp) - echo "64a05aa7dfecba86bf4296a08b4cdf3a source/linux/epoll_event_loop.c" > $TMPFILE + echo "5109c3b2748a98621ebdc05756fdfa51 source/linux/epoll_event_loop.c" > $TMPFILE md5sum --check $TMPFILE # No further steps if successful diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/include/aws/io/event_loop.h new/aws-c-io-0.19.1/include/aws/io/event_loop.h --- old/aws-c-io-0.19.0/include/aws/io/event_loop.h 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/include/aws/io/event_loop.h 2025-05-21 23:02:52.000000000 +0200 @@ -46,7 +46,6 @@ void *user_data); int (*unsubscribe_from_io_events)(struct aws_event_loop *event_loop, struct aws_io_handle *handle); void (*free_io_event_resources)(void *user_data); - void *(*get_base_event_loop_group)(struct aws_event_loop *event_loop); bool (*is_on_callers_thread)(struct aws_event_loop *event_loop); }; @@ -176,6 +175,22 @@ void aws_event_loop_group_release(struct aws_event_loop_group *el_group); /** + * Increments the reference count on the event loop group from event loop, allowing the caller to take a reference to + * it. + * + * Returns the base event loop group of the event loop, or null if the event loop does not belong to a group. + */ +AWS_IO_API +struct aws_event_loop_group *aws_event_loop_group_acquire_from_event_loop(struct aws_event_loop *event_loop); + +/** + * Decrements the ref count of the event loop's base event loop group. When the ref count drops to zero, the event loop + * group will be destroyed. + */ +AWS_IO_API +void aws_event_loop_group_release_from_event_loop(struct aws_event_loop *event_loop); + +/** * Returns the event loop at a particular index. If the index is out of bounds, null is returned. */ AWS_IO_API diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/include/aws/io/private/event_loop_impl.h new/aws-c-io-0.19.1/include/aws/io/private/event_loop_impl.h --- old/aws-c-io-0.19.0/include/aws/io/private/event_loop_impl.h 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/include/aws/io/private/event_loop_impl.h 2025-05-21 23:02:52.000000000 +0200 @@ -25,8 +25,8 @@ size_t num_bytes_transferred); /** - * The aws_win32_OVERLAPPED struct is layout-compatible with OVERLAPPED as defined in <Windows.h>. It is used - * here to avoid pulling in a dependency on <Windows.h> which would also bring along a lot of bad macros, such + * The aws_win32_OVERLAPPED struct is layout-compatible with OVERLAPPED as defined in <windows.h>. It is used + * here to avoid pulling in a dependency on <windows.h> which would also bring along a lot of bad macros, such * as redefinitions of GetMessage and GetObject. Note that the OVERLAPPED struct layout in the Windows SDK can * never be altered without breaking binary compatibility for every existing third-party executable, so there * is no need to worry about keeping this definition in sync. @@ -75,6 +75,7 @@ uint64_t latest_tick_start; size_t current_tick_latency_sum; struct aws_atomic_var next_flush_time; + struct aws_event_loop_group *base_elg; void *impl_data; }; @@ -321,14 +322,6 @@ AWS_IO_API void aws_event_loop_free_io_event_resources(struct aws_event_loop *event_loop, struct aws_io_handle *handle); -/** - * Retrieves the aws_event_loop_group that is the parent of the aws_event_loop. This is only supported when using a - * dispatch queue event loop as they are async and their sockets need to retain a refcount on the elg to keep it alive - * and insure it has not been asyncronously destroyed before anything that needs it. - */ -AWS_IO_API -void *get_base_event_loop_group(struct aws_event_loop *event_loop); - AWS_IO_API struct aws_event_loop_group *aws_event_loop_group_new_internal( struct aws_allocator *allocator, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/include/aws/io/private/pki_utils.h new/aws-c-io-0.19.1/include/aws/io/private/pki_utils.h --- old/aws-c-io-0.19.0/include/aws/io/private/pki_utils.h 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/include/aws/io/private/pki_utils.h 2025-05-21 23:02:52.000000000 +0200 @@ -9,7 +9,7 @@ #ifdef _WIN32 /* It's ok to include external headers because this is a PRIVATE header file * (it is usually a crime to include windows.h from header file) */ -# include <Windows.h> +# include <windows.h> #endif /* _WIN32 */ #ifdef AWS_OS_APPLE diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/source/bsd/kqueue_event_loop.c new/aws-c-io-0.19.1/source/bsd/kqueue_event_loop.c --- old/aws-c-io-0.19.0/source/bsd/kqueue_event_loop.c 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/source/bsd/kqueue_event_loop.c 2025-05-21 23:02:52.000000000 +0200 @@ -49,15 +49,7 @@ void *user_data); static int s_unsubscribe_from_io_events(struct aws_event_loop *event_loop, struct aws_io_handle *handle); static void s_free_io_event_resources(void *user_data); -static void *s_get_base_event_loop_group(struct aws_event_loop *event_loop) { - (void)event_loop; - AWS_LOGF_ERROR( - AWS_LS_IO_EVENT_LOOP, - "id=%p: get_base_event_loop_group() is not supported using KQueue Event Loops", - (void *)event_loop); - aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED); - return NULL; -} + static bool s_is_event_thread(struct aws_event_loop *event_loop); static void aws_event_loop_thread(void *user_data); @@ -148,7 +140,6 @@ .subscribe_to_io_events = s_subscribe_to_io_events, .unsubscribe_from_io_events = s_unsubscribe_from_io_events, .free_io_event_resources = s_free_io_event_resources, - .get_base_event_loop_group = s_get_base_event_loop_group, .is_on_callers_thread = s_is_event_thread, }; @@ -275,6 +266,8 @@ event_loop->vtable = &s_kqueue_vtable; + event_loop->base_elg = options->parent_elg; + /* success */ return event_loop; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/source/channel.c new/aws-c-io-0.19.1/source/channel.c --- old/aws-c-io-0.19.0/source/channel.c 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/source/channel.c 2025-05-21 23:02:52.000000000 +0200 @@ -257,6 +257,10 @@ setup_args->on_setup_completed = creation_args->on_setup_completed; setup_args->user_data = creation_args->setup_user_data; + /* keep loop alive until channel is destroyed */ + channel->loop = creation_args->event_loop; + aws_event_loop_group_acquire_from_event_loop(channel->loop); + aws_task_init(&setup_args->task, s_on_channel_setup_complete, setup_args, "on_channel_setup_complete"); aws_event_loop_schedule_task_now(creation_args->event_loop, &setup_args->task); @@ -308,6 +312,8 @@ aws_channel_set_statistics_handler(channel, NULL); + aws_event_loop_group_release_from_event_loop(channel->loop); + aws_mem_release(channel->alloc, channel); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/source/darwin/dispatch_queue_event_loop.c new/aws-c-io-0.19.1/source/darwin/dispatch_queue_event_loop.c --- old/aws-c-io-0.19.0/source/darwin/dispatch_queue_event_loop.c 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/source/darwin/dispatch_queue_event_loop.c 2025-05-21 23:02:52.000000000 +0200 @@ -64,7 +64,6 @@ /* No io event resources to free */ (void)user_data; } -static void *s_get_base_event_loop_group(struct aws_event_loop *event_loop); static bool s_is_on_callers_thread(struct aws_event_loop *event_loop); static struct aws_event_loop_vtable s_vtable = { @@ -80,7 +79,6 @@ .subscribe_to_io_events = s_subscribe_to_io_events, .unsubscribe_from_io_events = s_unsubscribe_from_io_events, .free_io_event_resources = s_free_io_event_resources, - .get_base_event_loop_group = s_get_base_event_loop_group, .is_on_callers_thread = s_is_on_callers_thread, }; @@ -249,12 +247,12 @@ } loop->vtable = &s_vtable; + loop->base_elg = options->parent_elg; dispatch_loop = aws_mem_calloc(alloc, 1, sizeof(struct aws_dispatch_loop)); dispatch_loop->allocator = alloc; loop->impl_data = dispatch_loop; dispatch_loop->base_loop = loop; - dispatch_loop->base_elg = options->parent_elg; dispatch_loop->synced_data.execution_state = AWS_DLES_SUSPENDED; aws_ref_count_init(&dispatch_loop->ref_count, dispatch_loop, s_dispatch_event_loop_on_zero_ref_count); @@ -741,17 +739,6 @@ } /* - * Because dispatch queue is async we may need to acquire a refcount of the parent event loop group to prevent - * the event loop or dispatch loop from being cleaned out from underneath something that needs it. We expose the - * base elg so anything that needs to insure the event loops and dispatch loops don't get prematurely cleaned can - * hold a refcount. - */ -static void *s_get_base_event_loop_group(struct aws_event_loop *event_loop) { - struct aws_dispatch_loop *dispatch_loop = event_loop->impl_data; - return dispatch_loop->base_elg; -} - -/* * We use aws_thread_id_equal with syched_data.current_thread_id and synced_data.is_executing to determine * if operation is being executed on the same dispatch queue thread. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/source/darwin/dispatch_queue_event_loop_private.h new/aws-c-io-0.19.1/source/darwin/dispatch_queue_event_loop_private.h --- old/aws-c-io-0.19.0/source/darwin/dispatch_queue_event_loop_private.h 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/source/darwin/dispatch_queue_event_loop_private.h 2025-05-21 23:02:52.000000000 +0200 @@ -35,7 +35,6 @@ dispatch_queue_t dispatch_queue; struct aws_task_scheduler scheduler; struct aws_event_loop *base_loop; - struct aws_event_loop_group *base_elg; struct aws_ref_count ref_count; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/source/darwin/nw_socket.c new/aws-c-io-0.19.1/source/darwin/nw_socket.c --- old/aws-c-io-0.19.0/source/darwin/nw_socket.c 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/source/darwin/nw_socket.c 2025-05-21 23:02:52.000000000 +0200 @@ -412,19 +412,28 @@ return event_loop && event_loop->vtable && event_loop->impl_data; } -static void s_set_event_loop(struct aws_socket *aws_socket, struct aws_event_loop *event_loop) { +static int s_set_event_loop(struct aws_socket *aws_socket, struct aws_event_loop *event_loop) { aws_socket->event_loop = event_loop; struct nw_socket *nw_socket = aws_socket->impl; // Never re-assign an event loop AWS_FATAL_ASSERT(nw_socket->event_loop == NULL); - nw_socket->event_loop = event_loop; + // Acquire the event loop group from the event loop. The event loop group will be released when the socket is + // destroyed. + if (!aws_event_loop_group_acquire_from_event_loop(event_loop)) { + AWS_LOGF_ERROR( + AWS_LS_IO_SOCKET, + "id=%p nw_socket=%p: failed to acquire event loop group.", + (void *)aws_socket, + (void *)nw_socket); + return AWS_OP_ERR; + } + + nw_socket->event_loop = event_loop; AWS_LOGF_DEBUG( - AWS_LS_IO_SOCKET, - "id=%p nw_socket=%p: s_set_event_loop: socket acquire event loop group.", - (void *)aws_socket, - (void *)nw_socket); - aws_event_loop_group_acquire(get_base_event_loop_group(event_loop)); + AWS_LS_IO_SOCKET, "id=%p nw_socket=%p: nw_socket set event loop.", (void *)aws_socket, (void *)nw_socket); + + return AWS_OP_SUCCESS; } static void s_release_event_loop(struct nw_socket *nw_socket) { @@ -433,7 +442,7 @@ AWS_LS_IO_SOCKET, "nw_socket=%p: s_release_event_loop: socket has not event loop.", (void *)nw_socket); return; } - aws_event_loop_group_release(get_base_event_loop_group(nw_socket->event_loop)); + aws_event_loop_group_release_from_event_loop(nw_socket->event_loop); AWS_LOGF_DEBUG( AWS_LS_IO_SOCKET, "nw_socket=%p: s_release_event_loop: socket release event loop group.", (void *)nw_socket); nw_socket->event_loop = NULL; @@ -517,7 +526,7 @@ } if (g_aws_channel_max_fragment_size < KB_16) { - nw_tcp_options_set_maximum_segment_size(tcp_options, g_aws_channel_max_fragment_size); + nw_tcp_options_set_maximum_segment_size(tcp_options, (uint32_t)g_aws_channel_max_fragment_size); } } @@ -616,7 +625,7 @@ } else { char description_buffer[256]; s_get_error_description(error, description_buffer, sizeof(description_buffer)); - int crt_error_code = s_determine_socket_error(CFErrorGetCode(error)); + int crt_error_code = s_determine_socket_error((int)CFErrorGetCode(error)); AWS_LOGF_DEBUG( AWS_LS_IO_TLS, "nw_socket=%p: nw_socket SecTrustEvaluateWithError failed with crt error code: %d : %s translated from CF " @@ -1798,7 +1807,10 @@ } /* event_loop must be set prior to setup of socket parameters. */ - s_set_event_loop(socket, event_loop); + if (s_set_event_loop(socket, event_loop)) { + goto error; + } + if (s_setup_socket_params(nw_socket, &socket->options)) { goto error; } @@ -2316,6 +2328,18 @@ return aws_raise_error(AWS_IO_EVENT_LOOP_ALREADY_ASSIGNED); } + if (s_set_event_loop(socket, accept_loop)) { + AWS_LOGF_ERROR( + AWS_LS_IO_SOCKET, + "id=%p handle=%p: failed to set event loop %p, invalid event loop. It is most likely the event loop does " + "not has a parent event loop group.", + (void *)socket, + socket->io_handle.data.handle, + (void *)accept_loop); + s_unlock_socket_synced_data(nw_socket); + return aws_raise_error(AWS_IO_SOCKET_INVALID_OPTIONS); + } + aws_event_loop_connect_handle_to_io_completion_port(accept_loop, &socket->io_handle); socket->accept_result_fn = options.on_accept_result; socket->connect_accept_user_data = options.on_accept_result_user_data; @@ -2323,8 +2347,6 @@ nw_socket->on_accept_started_fn = options.on_accept_start; nw_socket->listen_accept_started_user_data = options.on_accept_start_user_data; - s_set_event_loop(socket, accept_loop); - nw_listener_set_state_changed_handler( socket->io_handle.data.handle, ^(nw_listener_state_t state, nw_error_t error) { s_handle_listener_state_changed_fn(nw_socket, state, error); @@ -2433,9 +2455,20 @@ socket->io_handle.data.handle, (void *)event_loop); - if (aws_event_loop_connect_handle_to_io_completion_port(event_loop, &socket->io_handle)) { + if (s_set_event_loop(socket, event_loop)) { + AWS_LOGF_ERROR( + AWS_LS_IO_SOCKET, + "id=%p handle=%p: assigning event loop %p failed. Invalid event loop. It is likely the event loop " + "does not has a parent event loop group.", + (void *)socket, + socket->io_handle.data.handle, + (void *)event_loop); + aws_raise_error(AWS_IO_SOCKET_INVALID_OPTIONS); + return AWS_IO_SOCKET_INVALID_OPTIONS; + } - AWS_LOGF_DEBUG( + if (aws_event_loop_connect_handle_to_io_completion_port(event_loop, &socket->io_handle)) { + AWS_LOGF_ERROR( AWS_LS_IO_SOCKET, "id=%p handle=%p: assigning event loop %p failed", (void *)socket, @@ -2444,7 +2477,6 @@ return AWS_OP_ERR; } - s_set_event_loop(socket, event_loop); nw_connection_start(socket->io_handle.data.handle); return AWS_OP_SUCCESS; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/source/event_loop.c new/aws-c-io-0.19.1/source/event_loop.c --- old/aws-c-io-0.19.0/source/event_loop.c 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/source/event_loop.c 2025-05-21 23:02:52.000000000 +0200 @@ -380,6 +380,19 @@ } } +struct aws_event_loop_group *aws_event_loop_group_acquire_from_event_loop(struct aws_event_loop *event_loop) { + if (event_loop != NULL) { + return aws_event_loop_group_acquire(event_loop->base_elg); + } + return NULL; +} + +void aws_event_loop_group_release_from_event_loop(struct aws_event_loop *event_loop) { + if (event_loop != NULL) { + aws_event_loop_group_release(event_loop->base_elg); + } +} + size_t aws_event_loop_group_get_loop_count(const struct aws_event_loop_group *el_group) { return aws_array_list_length(&el_group->event_loops); } @@ -655,11 +668,6 @@ event_loop->vtable->free_io_event_resources(handle->additional_data); } -void *get_base_event_loop_group(struct aws_event_loop *event_loop) { - AWS_ASSERT(event_loop && event_loop->vtable->get_base_event_loop_group); - return event_loop->vtable->get_base_event_loop_group(event_loop); -} - bool aws_event_loop_thread_is_callers_thread(struct aws_event_loop *event_loop) { AWS_ASSERT(event_loop->vtable && event_loop->vtable->is_on_callers_thread); return event_loop->vtable->is_on_callers_thread(event_loop); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/source/linux/epoll_event_loop.c new/aws-c-io-0.19.1/source/linux/epoll_event_loop.c --- old/aws-c-io-0.19.0/source/linux/epoll_event_loop.c 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/source/linux/epoll_event_loop.c 2025-05-21 23:02:52.000000000 +0200 @@ -68,15 +68,6 @@ void *user_data); static int s_unsubscribe_from_io_events(struct aws_event_loop *event_loop, struct aws_io_handle *handle); static void s_free_io_event_resources(void *user_data); -static void *s_get_base_event_loop_group(struct aws_event_loop *event_loop) { - (void)event_loop; - AWS_LOGF_ERROR( - AWS_LS_IO_EVENT_LOOP, - "id=%p: get_base_event_loop_group() is not supported using Epoll Event Loops", - (void *)event_loop); - aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED); - return NULL; -} static bool s_is_on_callers_thread(struct aws_event_loop *event_loop); static void aws_event_loop_thread(void *args); @@ -94,7 +85,6 @@ .subscribe_to_io_events = s_subscribe_to_io_events, .unsubscribe_from_io_events = s_unsubscribe_from_io_events, .free_io_event_resources = s_free_io_event_resources, - .get_base_event_loop_group = s_get_base_event_loop_group, .is_on_callers_thread = s_is_on_callers_thread, }; @@ -218,6 +208,7 @@ loop->impl_data = epoll_loop; loop->vtable = &s_vtable; + loop->base_elg = options->parent_elg; return loop; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/source/windows/host_resolver.c new/aws-c-io-0.19.1/source/windows/host_resolver.c --- old/aws-c-io-0.19.0/source/windows/host_resolver.c 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/source/windows/host_resolver.c 2025-05-21 23:02:52.000000000 +0200 @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0. */ -/* don't move this below the Windows.h include!!!!*/ +/* don't move this below the windows.h include!!!!*/ #include <winsock2.h> #include <ws2tcpip.h> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/source/windows/iocp/iocp_event_loop.c new/aws-c-io-0.19.1/source/windows/iocp/iocp_event_loop.c --- old/aws-c-io-0.19.0/source/windows/iocp/iocp_event_loop.c 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/source/windows/iocp/iocp_event_loop.c 2025-05-21 23:02:52.000000000 +0200 @@ -13,7 +13,7 @@ #include <aws/io/logging.h> #include <aws/io/private/event_loop_impl.h> -#include <Windows.h> +#include <windows.h> /* The next set of struct definitions are taken directly from the windows documentation. We can't include the header files directly @@ -124,15 +124,6 @@ } static int s_unsubscribe_from_io_events(struct aws_event_loop *event_loop, struct aws_io_handle *handle); static void s_free_io_event_resources(void *user_data); -static void *s_get_base_event_loop_group(struct aws_event_loop *event_loop) { - (void)event_loop; - AWS_LOGF_ERROR( - AWS_LS_IO_EVENT_LOOP, - "id=%p: get_base_event_loop_group() is not supported using IOCP Event Loops", - (void *)event_loop); - aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED); - return NULL; -} static void aws_event_loop_thread(void *user_data); void aws_overlapped_init( @@ -169,7 +160,6 @@ .subscribe_to_io_events = s_subscribe_to_io_events, .unsubscribe_from_io_events = s_unsubscribe_from_io_events, .free_io_event_resources = s_free_io_event_resources, - .get_base_event_loop_group = s_get_base_event_loop_group, .is_on_callers_thread = s_is_event_thread, }; @@ -272,6 +262,7 @@ event_loop->impl_data = impl; event_loop->vtable = &s_iocp_vtable; + event_loop->base_elg = options->parent_elg; return event_loop; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/source/windows/iocp/pipe.c new/aws-c-io-0.19.1/source/windows/iocp/pipe.c --- old/aws-c-io-0.19.0/source/windows/iocp/pipe.c 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/source/windows/iocp/pipe.c 2025-05-21 23:02:52.000000000 +0200 @@ -12,7 +12,7 @@ #include <stdbool.h> #include <stdio.h> -#include <Windows.h> +#include <windows.h> enum read_end_state { /* Pipe is open. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/source/windows/iocp/socket.c new/aws-c-io-0.19.1/source/windows/iocp/socket.c --- old/aws-c-io-0.19.0/source/windows/iocp/socket.c 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/source/windows/iocp/socket.c 2025-05-21 23:02:52.000000000 +0200 @@ -9,9 +9,9 @@ below, clang-format doesn't work (at least on my version) with the c-style comments.*/ // clang-format off -#include <WS2tcpip.h> -#include <MSWSock.h> -#include <Mstcpip.h> +#include <ws2tcpip.h> +#include <mswsock.h> +#include <mstcpip.h> // clang-format on #include <aws/io/private/socket_impl.h> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/source/windows/secure_channel_tls_handler.c new/aws-c-io-0.19.1/source/windows/secure_channel_tls_handler.c --- old/aws-c-io-0.19.0/source/windows/secure_channel_tls_handler.c 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/source/windows/secure_channel_tls_handler.c 2025-05-21 23:02:52.000000000 +0200 @@ -18,7 +18,7 @@ #include <aws/io/private/tls_channel_handler_shared.h> #include <aws/io/statistics.h> -#include <Windows.h> +#include <windows.h> #include <schannel.h> #include <security.h> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/source/windows/shared_library.c new/aws-c-io-0.19.1/source/windows/shared_library.c --- old/aws-c-io-0.19.0/source/windows/shared_library.c 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/source/windows/shared_library.c 2025-05-21 23:02:52.000000000 +0200 @@ -4,7 +4,7 @@ */ // clang-format off -#include <Windows.h> +#include <windows.h> #include <libloaderapi.h> // clang-format on diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/source/windows/windows_pki_utils.c new/aws-c-io-0.19.1/source/windows/windows_pki_utils.c --- old/aws-c-io-0.19.0/source/windows/windows_pki_utils.c 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/source/windows/windows_pki_utils.c 2025-05-21 23:02:52.000000000 +0200 @@ -10,9 +10,9 @@ #include <aws/io/logging.h> -#include <Windows.h> #include <stdio.h> #include <string.h> +#include <windows.h> #ifdef _MSC_VER # pragma warning(disable : 4221) /* aggregate initializer using local variable addresses */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/source/windows/winsock_init.c new/aws-c-io-0.19.1/source/windows/winsock_init.c --- old/aws-c-io-0.19.0/source/windows/winsock_init.c 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/source/windows/winsock_init.c 2025-05-21 23:02:52.000000000 +0200 @@ -8,9 +8,9 @@ below, clang-format doesn't work (at least on my version) with the c-style comments. */ // clang-format off -#include <WinSock2.h> -#include <WS2tcpip.h> -#include <MSWSock.h> +#include <winsock2.h> +#include <ws2tcpip.h> +#include <mswsock.h> // clang-format on #include <aws/io/logging.h> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/tests/CMakeLists.txt new/aws-c-io-0.19.1/tests/CMakeLists.txt --- old/aws-c-io-0.19.0/tests/CMakeLists.txt 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/tests/CMakeLists.txt 2025-05-21 23:02:52.000000000 +0200 @@ -116,6 +116,7 @@ add_test_case(channel_rejects_post_shutdown_tasks) add_test_case(channel_cancels_pending_tasks) add_test_case(channel_duplicate_shutdown) +add_test_case(channel_keeps_event_loop_group_alive) add_net_test_case(channel_connect_some_hosts_timeout) add_net_test_case(test_default_with_ipv6_lookup) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/tests/channel_test.c new/aws-c-io-0.19.1/tests/channel_test.c --- old/aws-c-io-0.19.0/tests/channel_test.c 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/tests/channel_test.c 2025-05-21 23:02:52.000000000 +0200 @@ -21,9 +21,10 @@ struct channel_setup_test_args { struct aws_mutex mutex; struct aws_condition_variable condition_variable; - bool setup_completed; /* protected by mutex */ - bool shutdown_completed; /* protected by mutex */ - int error_code; /* protected by mutex */ + bool setup_completed; /* protected by mutex */ + bool shutdown_completed; /* protected by mutex */ + int error_code; /* protected by mutex */ + bool event_loop_group_shutdown_completed; /* protected by mutex (not used by all tests) */ enum aws_task_status task_status; }; @@ -60,6 +61,19 @@ return AWS_OP_SUCCESS; } +static void s_event_loop_group_on_shutdown_complete(void *user_data) { + struct channel_setup_test_args *setup_test_args = user_data; + aws_mutex_lock(&setup_test_args->mutex); + setup_test_args->event_loop_group_shutdown_completed = true; + aws_condition_variable_notify_all(&setup_test_args->condition_variable); + aws_mutex_unlock(&setup_test_args->mutex); +} + +static bool s_event_loop_group_shutdown_completed_predicate(void *arg) { + struct channel_setup_test_args *setup_test_args = (struct channel_setup_test_args *)arg; + return setup_test_args->event_loop_group_shutdown_completed; +} + static int s_test_channel_setup(struct aws_allocator *allocator, void *ctx) { (void)ctx; struct aws_event_loop *event_loop = aws_event_loop_new_default(allocator, aws_high_res_clock_get_ticks); @@ -845,3 +859,74 @@ } AWS_TEST_CASE(channel_connect_some_hosts_timeout, s_test_channel_connect_some_hosts_timeout); + +/* This is a regression test. The channel didn't used to do anything to keep the event-loop alive. + * So if the event-loop-group was released before the channel, the loops would get destroyed, + * then the channel would try to schedule its own destruction task on the loop and crash. */ +static int s_test_channel_keeps_event_loop_group_alive(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + aws_io_library_init(allocator); + + struct channel_setup_test_args test_args = { + .mutex = AWS_MUTEX_INIT, + .condition_variable = AWS_CONDITION_VARIABLE_INIT, + }; + + struct aws_shutdown_callback_options event_loop_group_shutdown_options = { + .shutdown_callback_fn = s_event_loop_group_on_shutdown_complete, + .shutdown_callback_user_data = &test_args, + }; + struct aws_event_loop_group *event_loop_group = + aws_event_loop_group_new_default(allocator, 1, &event_loop_group_shutdown_options); + ASSERT_NOT_NULL(event_loop_group); + + struct aws_event_loop *event_loop = aws_event_loop_group_get_next_loop(event_loop_group); + + struct aws_channel_options channel_options = { + .on_setup_completed = s_channel_setup_test_on_setup_completed, + .setup_user_data = &test_args, + .on_shutdown_completed = s_channel_test_shutdown, + .shutdown_user_data = &test_args, + .event_loop = event_loop, + }; + + struct aws_channel *channel = NULL; + ASSERT_SUCCESS(s_channel_setup_create_and_wait(allocator, &channel_options, &test_args, &channel)); + + /* shut down channel, but don't clean it up yet */ + aws_channel_shutdown(channel, 0); + + ASSERT_SUCCESS(aws_mutex_lock(&test_args.mutex)); + ASSERT_SUCCESS(aws_condition_variable_wait_pred( + &test_args.condition_variable, &test_args.mutex, s_channel_test_shutdown_predicate, &test_args)); + ASSERT_SUCCESS(aws_mutex_unlock(&test_args.mutex)); + + /* release event loop group before channel */ + aws_event_loop_group_release(event_loop_group); + + /* wait a bit to ensure the event-loop-group doesn't shut down (because channel has a hold on it) */ + uint64_t wait_time = aws_timestamp_convert(500, AWS_TIMESTAMP_MILLIS, AWS_TIMESTAMP_NANOS, NULL); + ASSERT_SUCCESS(aws_mutex_lock(&test_args.mutex)); + ASSERT_FAILS( + aws_condition_variable_wait_for_pred( + &test_args.condition_variable, + &test_args.mutex, + wait_time, + s_event_loop_group_shutdown_completed_predicate, + &test_args), + "Channel failed to keep event loop alive"); + ASSERT_SUCCESS(aws_mutex_unlock(&test_args.mutex)); + + /* release channel for destruction */ + aws_channel_destroy(channel); + + /* event loop group should shut down now */ + ASSERT_SUCCESS(aws_mutex_lock(&test_args.mutex)); + ASSERT_SUCCESS(aws_condition_variable_wait_pred( + &test_args.condition_variable, &test_args.mutex, s_event_loop_group_shutdown_completed_predicate, &test_args)); + ASSERT_SUCCESS(aws_mutex_unlock(&test_args.mutex)); + + aws_io_library_clean_up(); + return AWS_OP_SUCCESS; +} +AWS_TEST_CASE(channel_keeps_event_loop_group_alive, s_test_channel_keeps_event_loop_group_alive) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.19.0/tests/vcc/new_destroy.c new/aws-c-io-0.19.1/tests/vcc/new_destroy.c --- old/aws-c-io-0.19.0/tests/vcc/new_destroy.c 2025-04-30 23:26:13.000000000 +0200 +++ new/aws-c-io-0.19.1/tests/vcc/new_destroy.c 2025-05-21 23:02:52.000000000 +0200 @@ -184,6 +184,7 @@ loop->impl_data = epoll_loop; loop->vtable = &s_vtable; + loop->base_elg = options->parent_elg; _(wrap(&epoll_loop->task_pre_queue.head)) _(wrap(&epoll_loop->task_pre_queue.tail))