*
* @param transport the transport.
* @returns the new connection, or #NULL on failure.
- */
-DBusConnection*
-_dbus_connection_new_for_transport (DBusTransport *transport)
+*/
+static DBusConnection*
+_dbus_connection_new_for_transport_internal (DBusTransport *transport, dbus_bool_t exists)
{
DBusConnection *connection;
DBusWatchList *watch_list;
pending_replies =
_dbus_hash_table_new (DBUS_HASH_INT,
- NULL,
+ NULL,
(DBusFreeFunction)free_pending_call_on_hash_removal);
if (pending_replies == NULL)
goto error;
connection->disconnect_message_link = disconnect_link;
- CONNECTION_LOCK (connection);
-
- if (!_dbus_transport_set_connection (transport, connection))
- {
- CONNECTION_UNLOCK (connection);
+ if(!exists)
+ {
+ CONNECTION_LOCK (connection);
- goto error;
- }
+ if (!_dbus_transport_set_connection (transport, connection))
+ {
+ CONNECTION_UNLOCK (connection);
- _dbus_transport_ref (transport);
+ goto error;
+ }
- CONNECTION_UNLOCK (connection);
+ _dbus_transport_ref (transport);
+
+ CONNECTION_UNLOCK (connection);
+ }
_dbus_connection_trace_ref (connection, 0, 1, "new_for_transport");
return connection;
}
/**
+ * Creates a new connection for the given transport. A transport
+ * represents a message stream that uses some concrete mechanism, such
+ * as UNIX domain sockets. May return #NULL if insufficient
+ * memory exists to create the connection.
+ *
+ * @param transport the transport.
+ * @returns the new connection, or #NULL on failure.
+ */
+DBusConnection*
+_dbus_connection_new_for_transport (DBusTransport *transport)
+{
+ return _dbus_connection_new_for_transport_internal(transport, FALSE);
+}
+
+DBusConnection*
+_dbus_connection_new_for_used_transport (DBusTransport *transport)
+{
+ return _dbus_connection_new_for_transport_internal(transport, TRUE);
+}
+
+/**
* Increments the reference count of a DBusConnection.
* Requires that the caller already holds the connection lock.
*
dbus_message_unref (message);
}
-/* This is run without the mutex held, but after the last reference
- * to the connection has been dropped we should have no thread-related
- * problems
- */
static void
-_dbus_connection_last_unref (DBusConnection *connection)
+_dbus_connection_last_unref_internal (DBusConnection *connection, dbus_bool_t unref_transport)
{
DBusList *link;
/* You have to disconnect the connection before unref:ing it. Otherwise
* you won't get the disconnected message.
*/
- _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
+ if(unref_transport)
+ _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
_dbus_assert (connection->server_guid == NULL);
/* ---- We're going to call various application callbacks here, hope it doesn't break anything... */
_dbus_list_foreach (&connection->outgoing_messages,
free_outgoing_message,
- connection);
+ connection);
_dbus_list_clear (&connection->outgoing_messages);
_dbus_list_foreach (&connection->incoming_messages,
- (DBusForeachFunction) dbus_message_unref,
- NULL);
+ (DBusForeachFunction) dbus_message_unref,
+ NULL);
_dbus_list_clear (&connection->incoming_messages);
_dbus_counter_unref (connection->outgoing_counter);
- _dbus_transport_unref (connection->transport);
+ if(unref_transport)
+ _dbus_transport_unref (connection->transport);
if (connection->disconnect_message_link)
{
dbus_free (connection);
}
+/* This is run without the mutex held, but after the last reference
+ * to the connection has been dropped we should have no thread-related
+ * problems
+ */
+static void
+_dbus_connection_last_unref (DBusConnection *connection)
+{
+ _dbus_connection_last_unref_internal(connection, TRUE);
+}
+
/**
* Decrements the reference count of a DBusConnection, and finalizes
* it if the count reaches zero.
}
}
+void
+dbus_connection_unref_phantom (DBusConnection *connection)
+{
+ dbus_int32_t old_refcount;
+
+ _dbus_return_if_fail (connection != NULL);
+ _dbus_return_if_fail (connection->generation == _dbus_current_generation);
+
+ old_refcount = _dbus_atomic_dec (&connection->refcount);
+
+ _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1, "unref");
+
+ if (old_refcount == 1)
+ _dbus_connection_last_unref_internal(connection, FALSE);
+}
+
/*
* Note that the transport can disconnect itself (other end drops us)
* and in that case this function never runs. So this function must