mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-10-31 00:12:19 +01:00 
			
		
		
		
	Merge branch '3184-socket-client-leak-with-unit-test' into 'main'
gsocketclient: Unit test for "Fix a leak of the task data on an error path" Closes #3184 See merge request GNOME/glib!4104
This commit is contained in:
		| @@ -1919,6 +1919,7 @@ try_next_connection_or_finish (GSocketClientAsyncConnectData *data, | ||||
|     } | ||||
|  | ||||
|   complete_connection_with_error (data, g_steal_pointer (&data->error_info->best_error)); | ||||
|   g_object_unref (data->task); | ||||
| } | ||||
|  | ||||
| static void | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
|  */ | ||||
|  | ||||
| #include <gio/gio.h> | ||||
| #include <gio/gnetworking.h> /* For IPV6_V6ONLY */ | ||||
|  | ||||
| static void | ||||
| on_connected (GObject      *source_object, | ||||
| @@ -173,6 +174,70 @@ test_happy_eyeballs_cancel_instant (void) | ||||
|   g_object_unref (cancel); | ||||
| } | ||||
|  | ||||
| static void | ||||
| async_result_cb (GObject      *source, | ||||
|                  GAsyncResult *res, | ||||
|                  gpointer      user_data) | ||||
| { | ||||
|   GAsyncResult **result_out = user_data; | ||||
|  | ||||
|   g_assert_null (*result_out); | ||||
|   *result_out = g_object_ref (res); | ||||
|  | ||||
|   g_main_context_wakeup (NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| test_connection_failed (void) | ||||
| { | ||||
|   GSocketClient *client = NULL; | ||||
|   GInetAddress *inet_address = NULL; | ||||
|   GSocketAddress *address = NULL; | ||||
|   GSocket *socket = NULL; | ||||
|   guint16 port; | ||||
|   GAsyncResult *async_result = NULL; | ||||
|   GSocketConnection *conn = NULL; | ||||
|   GError *local_error = NULL; | ||||
|  | ||||
|   g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/3184"); | ||||
|  | ||||
|   inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6); | ||||
|   address = g_inet_socket_address_new (inet_address, 0); | ||||
|   g_object_unref (inet_address); | ||||
|  | ||||
|   socket = g_socket_new (G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, &local_error); | ||||
|   g_assert_no_error (local_error); | ||||
|   g_socket_set_option (socket, IPPROTO_IPV6, IPV6_V6ONLY, FALSE, NULL); | ||||
|   g_socket_bind (socket, address, TRUE, &local_error); | ||||
|   g_assert_no_error (local_error); | ||||
|  | ||||
|   /* reserve a port without listening so we know that connecting to it will fail */ | ||||
|   port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address)); | ||||
|  | ||||
|   client = g_socket_client_new (); | ||||
|   /* Connect to the port we have reserved but do not listen to. Because of the slow connection | ||||
|    * caused by slow-connect-preload.c and the fact that we try to connect to both IPv4 and IPv6 | ||||
|    * we will in some way exercise the code path in try_next_connection_or_finish() that ends | ||||
|    * with a call to complete_connection_with_error(). This path previously had a memory leak. | ||||
|    * Note that the slowness is important, because without it we could bail out already in the | ||||
|    * address enumeration phase because it finishes when there are no connection attempts in | ||||
|    * progress. */ | ||||
|   g_socket_client_connect_to_host_async (client, "localhost", port, NULL, async_result_cb, &async_result); | ||||
|  | ||||
|   while (async_result == NULL) | ||||
|     g_main_context_iteration (NULL, TRUE); | ||||
|  | ||||
|   conn = g_socket_client_connect_to_uri_finish (client, async_result, &local_error); | ||||
|   g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED); | ||||
|   g_assert_null (conn); | ||||
|   g_clear_error (&local_error); | ||||
|   g_clear_object (&async_result); | ||||
|  | ||||
|   g_clear_object (&client); | ||||
|   g_clear_object (&socket); | ||||
|   g_clear_object (&address); | ||||
| } | ||||
|  | ||||
| int | ||||
| main (int argc, char *argv[]) | ||||
| { | ||||
| @@ -181,7 +246,7 @@ main (int argc, char *argv[]) | ||||
|   g_test_add_func ("/socket-client/happy-eyeballs/slow", test_happy_eyeballs); | ||||
|   g_test_add_func ("/socket-client/happy-eyeballs/cancellation/instant", test_happy_eyeballs_cancel_instant); | ||||
|   g_test_add_func ("/socket-client/happy-eyeballs/cancellation/delayed", test_happy_eyeballs_cancel_delayed); | ||||
|  | ||||
|   g_test_add_func ("/socket-client/connection-fail", test_connection_failed); | ||||
|  | ||||
|   return g_test_run (); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user