diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | dbus/dbus-connection.c | 58 |
2 files changed, 56 insertions, 13 deletions
@@ -1,3 +1,14 @@ +2008-02-26 John (J5) Palmieri <johnp@redhat.com> + + * correctly unref connections without guids during shutdown + * dbus/dbus-connection.c (close_connection_on_shutdown): new method + split out from shared_connections_shutdown + (shared_connections_shutdown): shutdown all shared connections + without guids + (_dbus_connection_ref_unlocked): handle OOM when prepending no guid + connections to the shared_connections_no_guid list + * Patch by Kimmo Hämäläinen <kimmo dot hamalainen at nokia dot com> + 2008-02-21 John (J5) Palmieri <johnp@redhat.com> * fix build against the latest gcc/glibc diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 66f85263..9439f63f 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -1438,6 +1438,23 @@ _dbus_connection_handle_watch (DBusWatch *watch, _DBUS_DEFINE_GLOBAL_LOCK (shared_connections); static DBusHashTable *shared_connections = NULL; +static DBusList *shared_connections_no_guid = NULL; + +static void +close_connection_on_shutdown (DBusConnection *connection) +{ + DBusMessage *message; + + dbus_connection_ref (connection); + _dbus_connection_close_possibly_shared (connection); + + /* Churn through to the Disconnected message */ + while ((message = dbus_connection_pop_message (connection))) + { + dbus_message_unref (message); + } + dbus_connection_unref (connection); +} static void shared_connections_shutdown (void *data) @@ -1450,7 +1467,6 @@ shared_connections_shutdown (void *data) while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0) { DBusConnection *connection; - DBusMessage *message; DBusHashIter iter; _dbus_hash_iter_init (shared_connections, &iter); @@ -1459,17 +1475,7 @@ shared_connections_shutdown (void *data) connection = _dbus_hash_iter_get_value (&iter); _DBUS_UNLOCK (shared_connections); - - dbus_connection_ref (connection); - _dbus_connection_close_possibly_shared (connection); - - /* Churn through to the Disconnected message */ - while ((message = dbus_connection_pop_message (connection))) - { - dbus_message_unref (message); - } - dbus_connection_unref (connection); - + close_connection_on_shutdown (connection); _DBUS_LOCK (shared_connections); /* The connection should now be dead and not in our hash ... */ @@ -1480,6 +1486,21 @@ shared_connections_shutdown (void *data) _dbus_hash_table_unref (shared_connections); shared_connections = NULL; + + if (shared_connections_no_guid != NULL) + { + DBusConnection *connection; + connection = _dbus_list_pop_first (&shared_connections_no_guid); + while (connection != NULL) + { + _DBUS_UNLOCK (shared_connections); + close_connection_on_shutdown (connection); + _DBUS_LOCK (shared_connections); + connection = _dbus_list_pop_first (&shared_connections_no_guid); + } + } + + shared_connections_no_guid = NULL; _DBUS_UNLOCK (shared_connections); } @@ -1589,7 +1610,18 @@ connection_record_shared_unlocked (DBusConnection *connection, _dbus_connection_ref_unlocked (connection); if (guid == NULL) - return TRUE; /* don't store in the hash */ + { + _DBUS_LOCK (shared_connections); + + if (!_dbus_list_prepend (&shared_connections_no_guid, connection)) + { + _DBUS_UNLOCK (shared_connections); + return FALSE; + } + + _DBUS_UNLOCK (shared_connections); + return TRUE; /* don't store in the hash */ + } /* A separate copy of the key is required in the hash table, because * we don't have a lock on the connection when we are doing a hash |