Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package aws-c-event-stream for openSUSE:Factory checked in at 2026-01-09 17:04:49 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/aws-c-event-stream (Old) and /work/SRC/openSUSE:Factory/.aws-c-event-stream.new.1928 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "aws-c-event-stream" Fri Jan 9 17:04:49 2026 rev:10 rq:1326346 version:0.5.9 Changes: -------- --- /work/SRC/openSUSE:Factory/aws-c-event-stream/aws-c-event-stream.changes 2025-09-19 16:10:52.453979738 +0200 +++ /work/SRC/openSUSE:Factory/.aws-c-event-stream.new.1928/aws-c-event-stream.changes 2026-01-09 17:07:00.104728861 +0100 @@ -1,0 +2,8 @@ +Mon Jan 5 09:05:21 UTC 2026 - John Paul Adrian Glaubitz <[email protected]> + +- Update to version 0.5.9 + * Fix bind failure by @sfod in (#138) +- from version 0.5.8 + * Wait for RPC server listener setup by @sfod in (#136) + +------------------------------------------------------------------- Old: ---- v0.5.7.tar.gz New: ---- v0.5.9.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ aws-c-event-stream.spec ++++++ --- /var/tmp/diff_new_pack.qOWxW2/_old 2026-01-09 17:07:01.188773795 +0100 +++ /var/tmp/diff_new_pack.qOWxW2/_new 2026-01-09 17:07:01.192773961 +0100 @@ -21,7 +21,7 @@ %define library_version 1.0.0 %define library_soversion 1 Name: aws-c-event-stream -Version: 0.5.7 +Version: 0.5.9 Release: 0 Summary: C99 implementation of the vnd.amazon.eventstream content-type License: Apache-2.0 ++++++ v0.5.7.tar.gz -> v0.5.9.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-event-stream-0.5.7/source/event_stream_rpc_server.c new/aws-c-event-stream-0.5.9/source/event_stream_rpc_server.c --- old/aws-c-event-stream-0.5.7/source/event_stream_rpc_server.c 2025-09-10 20:45:50.000000000 +0200 +++ new/aws-c-event-stream-0.5.9/source/event_stream_rpc_server.c 2025-12-11 18:20:00.000000000 +0100 @@ -13,11 +13,14 @@ * permissions and limitations under the License. */ +#include "aws/io/future.h" + #include <aws/event-stream/event_stream_channel_handler.h> #include <aws/event-stream/event_stream_rpc_server.h> #include <aws/event-stream/private/event_stream_rpc_priv.h> #include <aws/common/atomics.h> +#include <aws/common/clock.h> #include <aws/common/hash_table.h> #include <aws/io/channel.h> @@ -48,6 +51,7 @@ bool enable_read_backpressure; bool initialized; void *user_data; + struct aws_future_void *setup_future; }; struct aws_event_stream_rpc_server_connection { @@ -256,6 +260,29 @@ } } +static void s_on_server_listener_setup(struct aws_server_bootstrap *bootstrap, int error_code, void *user_data) { + (void)bootstrap; + struct aws_event_stream_rpc_server_listener *server = user_data; + AWS_LOGF_DEBUG( + AWS_LS_EVENT_STREAM_RPC_SERVER, + "id=%p: listener setup completed with error %s", + (void *)server, + aws_error_debug_str(error_code)); + + /* Ensure that setup_future will be alive during aws_future_void_set_* call even if a waiter thread releases + * setup_future immediately after aws_future_void_wait returns result. Otherwise, aws_future_void_set_* might + * use already freed memory. */ + aws_future_void_acquire(server->setup_future); + + if (error_code) { + aws_future_void_set_error(server->setup_future, error_code); + } else { + aws_future_void_set_result(server->setup_future); + } + + aws_future_void_release(server->setup_future); +} + /* incoming from a socket on this listener. */ static void s_on_accept_channel_setup( struct aws_server_bootstrap *bootstrap, @@ -361,36 +388,31 @@ static void s_on_server_listener_destroy(struct aws_server_bootstrap *bootstrap, void *user_data) { (void)bootstrap; - struct aws_event_stream_rpc_server_listener *listener = user_data; + struct aws_event_stream_rpc_server_listener *server = user_data; - AWS_LOGF_INFO(AWS_LS_EVENT_STREAM_RPC_SERVER, "id=%p: destroying server", (void *)listener); + AWS_LOGF_INFO(AWS_LS_EVENT_STREAM_RPC_SERVER, "id=%p: destroying server", (void *)server); /* server bootstrap invokes this callback regardless of if the listener was successfully created, so * just check that we successfully set it up before freeing anything. When that's fixed in aws-c-io, this * code will still be correct, so just leave it here for now. */ - if (listener->initialized) { - if (listener->on_destroy_callback) { - listener->on_destroy_callback(listener, listener->user_data); - } - aws_mem_release(listener->allocator, listener); + /* Call a user-provided destruction callback only if the server initialization was successful. If initialization + * failed, the calling side got NULL from aws_event_stream_rpc_server_new_listener and doesn't expect anything to + * be called from the event stream server's internals. */ + if (server->initialized && server->on_destroy_callback) { + server->on_destroy_callback(server, server->user_data); } + + aws_mem_release(server->allocator, server); } struct aws_event_stream_rpc_server_listener *aws_event_stream_rpc_server_new_listener( struct aws_allocator *allocator, struct aws_event_stream_rpc_server_listener_options *options) { + struct aws_event_stream_rpc_server_listener *result = NULL; struct aws_event_stream_rpc_server_listener *server = aws_mem_calloc(allocator, 1, sizeof(struct aws_event_stream_rpc_server_listener)); - if (!server) { - AWS_LOGF_ERROR( - AWS_LS_EVENT_STREAM_RPC_SERVER, - "static: failed to allocate new server with error %s", - aws_error_debug_str(aws_last_error())); - return NULL; - } - AWS_LOGF_DEBUG(AWS_LS_EVENT_STREAM_RPC_SERVER, "static: new server is %p", (void *)server); aws_atomic_init_int(&server->ref_count, 1); @@ -401,6 +423,7 @@ .enable_read_back_pressure = false, .host_name = options->host_name, .port = options->port, + .setup_callback = s_on_server_listener_setup, .incoming_callback = s_on_accept_channel_setup, .shutdown_callback = s_on_accept_channel_shutdown, .destroy_callback = s_on_server_listener_destroy, @@ -413,27 +436,48 @@ server->on_new_connection = options->on_new_connection; server->on_connection_shutdown = options->on_connection_shutdown; server->user_data = options->user_data; + server->setup_future = aws_future_void_new(allocator); + struct aws_future_void *setup_future = server->setup_future; - server->listener = aws_server_bootstrap_new_socket_listener(&bootstrap_options); - - if (!server->listener) { + struct aws_socket *listener = aws_server_bootstrap_new_socket_listener(&bootstrap_options); + if (!listener) { AWS_LOGF_ERROR( AWS_LS_EVENT_STREAM_RPC_SERVER, "static: failed to allocate new socket listener with error %s", aws_error_debug_str(aws_last_error())); - goto error; + goto done; } - server->initialized = true; - return server; + /* With all the possible event loop hiccups, 60 seconds is still more than enough for completing binding and + * listening, successfully or not. */ + uint64_t timeout_sec = 60; + /* Handle async nw_socket (Apple Network framework socket) case when the actual work (i.e. binding and listening) is + * happening asynchronously in the dispatch queue event loop. In case of a failure, the server destruction can be + * already in progress in the event loop thread. + * For POSIX sockets the error handling is happening in a synchronous manner. + */ + aws_future_void_wait(setup_future, timeout_sec * AWS_TIMESTAMP_NANOS); + int listen_error = aws_future_void_get_error(setup_future); -error: - if (server->listener) { - aws_server_bootstrap_destroy_socket_listener(options->bootstrap, server->listener); + if (listen_error) { + AWS_LOGF_ERROR( + AWS_LS_EVENT_STREAM_RPC_SERVER, + "static: failed to setup new socket listener with error %s", + aws_error_debug_str(listen_error)); + aws_raise_error(listen_error); + goto done; } - aws_mem_release(server->allocator, server); - return NULL; + /* At this point a listening socket is successfully initialized, so we complete the server initialization. */ + server->listener = listener; + server->initialized = true; + result = server; + +done: + /* Even if aws_server_bootstrap_new_socket_listener fails, the bootstrap_options.destroy_callback will still + * be fired. So, to avoid a race condition we delegate server's destruction to that callback. */ + aws_future_void_release(setup_future); + return result; } uint32_t aws_event_stream_rpc_server_listener_get_bound_port( @@ -456,14 +500,6 @@ current_count + 1); } -static void s_destroy_server(struct aws_event_stream_rpc_server_listener *server) { - if (server) { - AWS_LOGF_INFO(AWS_LS_EVENT_STREAM_RPC_SERVER, "id=%p: destroying server", (void *)server); - /* the memory for this is cleaned up in the listener shutdown complete callback. */ - aws_server_bootstrap_destroy_socket_listener(server->bootstrap, server->listener); - } -} - void aws_event_stream_rpc_server_listener_release(struct aws_event_stream_rpc_server_listener *server) { if (!server) { return; @@ -474,7 +510,9 @@ AWS_LS_EVENT_STREAM_RPC_SERVER, "id=%p: server released, new ref count is %zu.", (void *)server, ref_count - 1); if (ref_count == 1) { - s_destroy_server(server); + AWS_LOGF_INFO(AWS_LS_EVENT_STREAM_RPC_SERVER, "id=%p: ref count reached 0, destroying server", (void *)server); + /* the memory for this is cleaned up in the listener shutdown complete callback. */ + aws_server_bootstrap_destroy_socket_listener(server->bootstrap, server->listener); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-event-stream-0.5.7/tests/CMakeLists.txt new/aws-c-event-stream-0.5.9/tests/CMakeLists.txt --- old/aws-c-event-stream-0.5.7/tests/CMakeLists.txt 2025-09-10 20:45:50.000000000 +0200 +++ new/aws-c-event-stream-0.5.9/tests/CMakeLists.txt 2025-12-11 18:20:00.000000000 +0100 @@ -47,6 +47,7 @@ add_net_test_case(test_event_stream_rpc_server_connection_stream_id_ahead) add_net_test_case(test_event_stream_rpc_server_connection_continuation_reused_stream_id_fails) add_net_test_case(test_event_stream_rpc_server_connection_continuation_max_stream_id_reached) +add_test_case(test_event_stream_rpc_server_bind_failure) add_net_test_case(test_event_stream_rpc_client_connection_setup_and_teardown) add_net_test_case(test_event_stream_rpc_client_connection_connect) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-event-stream-0.5.7/tests/event_stream_rpc_server_connection_test.c new/aws-c-event-stream-0.5.9/tests/event_stream_rpc_server_connection_test.c --- old/aws-c-event-stream-0.5.7/tests/event_stream_rpc_server_connection_test.c 2025-09-10 20:45:50.000000000 +0200 +++ new/aws-c-event-stream-0.5.9/tests/event_stream_rpc_server_connection_test.c 2025-12-11 18:20:00.000000000 +0100 @@ -30,6 +30,7 @@ struct aws_mutex shutdown_lock; struct aws_condition_variable shutdown_cvar; bool shutdown_completed; + uint16_t server_listener_port; }; static struct test_data s_test_data; @@ -165,6 +166,7 @@ ASSERT_TRUE(error_code == AWS_IO_SOCKET_ADDRESS_IN_USE || error_code == AWS_ERROR_NO_PERMISSION); } } + test_data->server_listener_port = test_port; test_data->allocator = allocator; @@ -1900,3 +1902,36 @@ s_test_event_stream_rpc_server_connection_continuation_max_stream_id_reached, s_fixture_shutdown, &s_test_data) + +static int s_test_event_stream_rpc_server_bind_failure(struct aws_allocator *allocator, void *ctx) { + struct test_data *test_data = ctx; + + struct aws_socket_options socket_options = { + .domain = AWS_SOCKET_IPV4, + .type = AWS_SOCKET_STREAM, + }; + + struct aws_event_stream_rpc_server_listener_options listener_options = { + .socket_options = &socket_options, + .host_name = "127.0.0.1", + .port = test_data->server_listener_port, + .bootstrap = test_data->server_bootstrap, + }; + + struct aws_event_stream_rpc_server_listener *listener = + aws_event_stream_rpc_server_new_listener(allocator, &listener_options); + ASSERT_NULL(listener); + int error_code = aws_last_error(); + ASSERT_TRUE(error_code == AWS_IO_SOCKET_ADDRESS_IN_USE); + + aws_event_stream_rpc_server_connection_close(test_data->connection, AWS_ERROR_SUCCESS); + + return AWS_OP_SUCCESS; +} + +AWS_TEST_CASE_FIXTURE( + test_event_stream_rpc_server_bind_failure, + s_fixture_setup, + s_test_event_stream_rpc_server_bind_failure, + s_fixture_shutdown, + &s_test_data)
