From f587ce7845edb0eb01451368d01b5bc86b5904cd Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Sat, 15 Mar 2003 20:47:16 +0000 Subject: 2003-03-15 Havoc Pennington Make it pass the Hello handling test including all OOM codepaths. Now to do other messages... * bus/services.c (bus_service_remove_owner): fix crash when removing owner from an empty list of owners (bus_registry_ensure): don't leave service in the list of a connection's owned services if we fail to put the service in the hash table. * bus/connection.c (bus_connection_preallocate_oom_error): set error flag on the OOM error. * dbus/dbus-connection.c (_dbus_connection_new_for_transport): handle _dbus_transport_set_connection failure * dbus/dbus-transport-unix.c (_dbus_transport_new_for_fd): modify to create watches up front and simply enable/disable them as needed. (unix_connection_set): this can now fail on OOM * dbus/dbus-timeout.c, dbus/dbus-watch.c: add concept of enabling/disabling a watch or timeout. * bus/loop.c (bus_loop_iterate): don't touch disabled watches/timeouts * glib/dbus-gmain.c: adapt to enable/disable watches and timeouts --- bus/bus.c | 6 ++++-- bus/connection.c | 14 ++++++++++++-- bus/dispatch.c | 10 +++++++--- bus/loop.c | 49 ++++++++++++++++++++++++++++++++++++------------- bus/services.c | 12 ++++++++++-- bus/test.c | 6 ++++-- 6 files changed, 73 insertions(+), 24 deletions(-) (limited to 'bus') diff --git a/bus/bus.c b/bus/bus.c index b717cacc..2270f534 100644 --- a/bus/bus.c +++ b/bus/bus.c @@ -161,6 +161,7 @@ bus_context_new (const char *address, if (!dbus_server_set_watch_functions (context->server, (DBusAddWatchFunction) add_server_watch, (DBusRemoveWatchFunction) remove_server_watch, + NULL, context, NULL)) { @@ -171,6 +172,7 @@ bus_context_new (const char *address, if (!dbus_server_set_timeout_functions (context->server, (DBusAddTimeoutFunction) add_server_timeout, (DBusRemoveTimeoutFunction) remove_server_timeout, + NULL, context, NULL)) { BUS_SET_OOM (error); @@ -192,13 +194,13 @@ bus_context_shutdown (BusContext *context) return; if (!dbus_server_set_watch_functions (context->server, - NULL, NULL, + NULL, NULL, NULL, context, NULL)) _dbus_assert_not_reached ("setting watch functions to NULL failed"); if (!dbus_server_set_timeout_functions (context->server, - NULL, NULL, + NULL, NULL, NULL, context, NULL)) _dbus_assert_not_reached ("setting timeout functions to NULL failed"); diff --git a/bus/connection.c b/bus/connection.c index 1c699c6f..ee3612ae 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -107,13 +107,13 @@ bus_connection_disconnected (DBusConnection *connection) /* no more watching */ if (!dbus_connection_set_watch_functions (connection, - NULL, NULL, + NULL, NULL, NULL, connection, NULL)) _dbus_assert_not_reached ("setting watch functions to NULL failed"); if (!dbus_connection_set_timeout_functions (connection, - NULL, NULL, + NULL, NULL, NULL, connection, NULL)) _dbus_assert_not_reached ("setting timeout functions to NULL failed"); @@ -288,6 +288,7 @@ bus_connections_setup_connection (BusConnections *connections, if (!dbus_connection_set_watch_functions (connection, (DBusAddWatchFunction) add_connection_watch, (DBusRemoveWatchFunction) remove_connection_watch, + NULL, connection, NULL)) { @@ -298,6 +299,7 @@ bus_connections_setup_connection (BusConnections *connections, if (!dbus_connection_set_timeout_functions (connection, (DBusAddTimeoutFunction) add_connection_timeout, (DBusRemoveTimeoutFunction) remove_connection_timeout, + NULL, connection, NULL)) { dbus_connection_disconnect (connection); @@ -442,6 +444,8 @@ bus_connection_preallocate_oom_error (DBusConnection *connection) return FALSE; } + dbus_message_set_is_error (message, TRUE); + /* set reply serial to placeholder value just so space is already allocated * for it. */ @@ -603,6 +607,9 @@ bus_transaction_send_message (BusTransaction *transaction, BusConnectionData *d; DBusList *link; + _dbus_verbose (" trying to add message %s to transaction\n", + dbus_message_get_name (message)); + if (!dbus_connection_get_is_connected (connection)) return TRUE; /* silently ignore disconnected connections */ @@ -789,6 +796,9 @@ bus_transaction_send_error_reply (BusTransaction *transaction, _dbus_assert (error != NULL); _DBUS_ASSERT_ERROR_IS_SET (error); + + _dbus_verbose (" trying to add error %s to transaction\n", + error->name); reply = dbus_message_new_error_reply (in_reply_to, error->name, diff --git a/bus/dispatch.c b/bus/dispatch.c index ac2fb15b..d0def78f 100644 --- a/bus/dispatch.c +++ b/bus/dispatch.c @@ -514,6 +514,7 @@ check_hello_connection (BusContext *context) if (!bus_setup_debug_client (connection)) { + dbus_connection_disconnect (connection); dbus_connection_unref (connection); return TRUE; } @@ -582,9 +583,6 @@ bus_dispatch_test (const DBusString *test_data_dir) &error); if (context == NULL) _dbus_assert_not_reached ("could not alloc context"); - - check1_try_iterations (context, "create_and_hello", - check_hello_connection); foo = dbus_connection_open ("debug-pipe:name=test-server", &result); if (foo == NULL) @@ -610,8 +608,14 @@ bus_dispatch_test (const DBusString *test_data_dir) if (!check_hello_message (context, baz)) _dbus_assert_not_reached ("hello message failed"); + check1_try_iterations (context, "create_and_hello", + check_hello_connection); + + dbus_connection_disconnect (foo); dbus_connection_unref (foo); + dbus_connection_disconnect (bar); dbus_connection_unref (bar); + dbus_connection_disconnect (baz); dbus_connection_unref (baz); return TRUE; diff --git a/bus/loop.c b/bus/loop.c index 10614745..ea0ec106 100644 --- a/bus/loop.c +++ b/bus/loop.c @@ -294,9 +294,26 @@ bus_loop_iterate (dbus_bool_t block) bus_loop_quit (); goto next_iteration; } + + /* count enabled watches */ + n_fds = 0; + link = _dbus_list_get_first_link (&callbacks); + while (link != NULL) + { + DBusList *next = _dbus_list_get_next_link (&callbacks, link); + Callback *cb = link->data; + if (cb->type == CALLBACK_WATCH) + { + WatchCallback *wcb = WATCH_CALLBACK (cb); + + if (dbus_watch_get_enabled (wcb->watch)) + ++n_fds; + } - n_fds = watch_count; + link = next; + } + /* fill our array of fds and watches */ if (n_fds > 0) { fds = dbus_new0 (DBusPollFD, n_fds); @@ -323,18 +340,21 @@ bus_loop_iterate (dbus_bool_t block) { unsigned int flags; WatchCallback *wcb = WATCH_CALLBACK (cb); + + if (dbus_watch_get_enabled (wcb->watch)) + { + watches_for_fds[i] = wcb; - watches_for_fds[i] = wcb; - - flags = dbus_watch_get_flags (wcb->watch); + flags = dbus_watch_get_flags (wcb->watch); - fds[i].fd = dbus_watch_get_fd (wcb->watch); - if (flags & DBUS_WATCH_READABLE) - fds[i].events |= _DBUS_POLLIN; - if (flags & DBUS_WATCH_WRITABLE) - fds[i].events |= _DBUS_POLLOUT; + fds[i].fd = dbus_watch_get_fd (wcb->watch); + if (flags & DBUS_WATCH_READABLE) + fds[i].events |= _DBUS_POLLIN; + if (flags & DBUS_WATCH_WRITABLE) + fds[i].events |= _DBUS_POLLOUT; - ++i; + ++i; + } } link = next; @@ -359,7 +379,8 @@ bus_loop_iterate (dbus_bool_t block) DBusList *next = _dbus_list_get_next_link (&callbacks, link); Callback *cb = link->data; - if (cb->type == CALLBACK_TIMEOUT) + if (cb->type == CALLBACK_TIMEOUT && + dbus_timeout_get_enabled (TIMEOUT_CALLBACK (cb)->timeout)) { TimeoutCallback *tcb = TIMEOUT_CALLBACK (cb); unsigned long interval; @@ -427,7 +448,8 @@ bus_loop_iterate (dbus_bool_t block) if (exited) goto next_iteration; - if (cb->type == CALLBACK_TIMEOUT) + if (cb->type == CALLBACK_TIMEOUT && + dbus_timeout_get_enabled (TIMEOUT_CALLBACK (cb)->timeout)) { TimeoutCallback *tcb = TIMEOUT_CALLBACK (cb); unsigned long interval; @@ -513,7 +535,8 @@ bus_loop_iterate (dbus_bool_t block) * weird POLLFOO thing like POLLWRBAND */ - if (condition != 0) + if (condition != 0 && + dbus_watch_get_enabled (wcb->watch)) { (* wcb->function) (wcb->watch, condition, diff --git a/bus/services.c b/bus/services.c index 9508b2f7..92f6cdf4 100644 --- a/bus/services.c +++ b/bus/services.c @@ -170,6 +170,8 @@ bus_registry_ensure (BusRegistry *registry, service->name, service)) { + bus_connection_remove_owned_service (owner_if_created, + service); _dbus_list_clear (&service->owners); dbus_free (service->name); _dbus_mem_pool_dealloc (registry->service_pool, service); @@ -290,7 +292,11 @@ bus_service_remove_owner (BusService *service, return FALSE; } - if (_dbus_list_length_is_one (&service->owners)) + if (service->owners == NULL) + { + _dbus_assert_not_reached ("Tried to remove owner of a service that has no owners"); + } + else if (_dbus_list_length_is_one (&service->owners)) { /* We are the only owner - send service deleted */ if (!bus_driver_send_service_deleted (service->name, @@ -301,6 +307,7 @@ bus_service_remove_owner (BusService *service, { DBusList *link; link = _dbus_list_get_first (&service->owners); + _dbus_assert (link != NULL); link = _dbus_list_get_next_link (&service->owners, link); if (link != NULL) @@ -320,7 +327,8 @@ bus_service_remove_owner (BusService *service, if (service->owners == NULL) { /* Delete service (already sent message that it was deleted above) */ - _dbus_hash_table_remove_string (service->registry->service_hash, service->name); + _dbus_hash_table_remove_string (service->registry->service_hash, + service->name); dbus_free (service->name); _dbus_mem_pool_dealloc (service->registry->service_pool, service); diff --git a/bus/test.c b/bus/test.c index 8d8aa492..fe4cdc42 100644 --- a/bus/test.c +++ b/bus/test.c @@ -127,6 +127,7 @@ bus_setup_debug_client (DBusConnection *connection) if (!dbus_connection_set_watch_functions (connection, (DBusAddWatchFunction) add_client_watch, (DBusRemoveWatchFunction) remove_client_watch, + NULL, connection, NULL)) goto out; @@ -134,6 +135,7 @@ bus_setup_debug_client (DBusConnection *connection) if (!dbus_connection_set_timeout_functions (connection, (DBusAddTimeoutFunction) add_client_timeout, (DBusRemoveTimeoutFunction) remove_client_timeout, + NULL, connection, NULL)) goto out; @@ -148,9 +150,9 @@ bus_setup_debug_client (DBusConnection *connection) _DBUS_N_ELEMENTS (to_handle)); dbus_connection_set_watch_functions (connection, - NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL); dbus_connection_set_timeout_functions (connection, - NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL); } dbus_message_handler_unref (disconnect_handler); -- cgit