static DBusMessageFilter *
_dbus_message_filter_ref (DBusMessageFilter *filter)
{
- _dbus_assert (filter->refcount.value > 0);
+#ifdef DBUS_DISABLE_ASSERT
_dbus_atomic_inc (&filter->refcount);
+#else
+ dbus_int32_t old_value;
+
+ old_value = _dbus_atomic_inc (&filter->refcount);
+ _dbus_assert (old_value > 0);
+#endif
return filter;
}
static void
_dbus_message_filter_unref (DBusMessageFilter *filter)
{
- _dbus_assert (filter->refcount.value > 0);
+ dbus_int32_t old_value;
+
+ old_value = _dbus_atomic_dec (&filter->refcount);
+ _dbus_assert (old_value > 0);
- if (_dbus_atomic_dec (&filter->refcount) == 1)
+ if (old_value == 1)
{
if (filter->free_user_data_function)
(* filter->free_user_data_function) (filter->user_data);
* @param message the message that was sent.
*/
void
-_dbus_connection_message_sent (DBusConnection *connection,
- DBusMessage *message)
+_dbus_connection_message_sent_unlocked (DBusConnection *connection,
+ DBusMessage *message)
{
DBusList *link;
if (_dbus_modify_sigpipe)
_dbus_disable_sigpipe ();
-
- connection->refcount.value = 1;
+
+ /* initialized to 0: use atomic op to avoid mixing atomic and non-atomic */
+ _dbus_atomic_inc (&connection->refcount);
connection->transport = transport;
connection->watches = watch_list;
connection->timeouts = timeout_list;
void
_dbus_connection_close_if_only_one_ref (DBusConnection *connection)
{
- dbus_int32_t tmp_refcount;
+ dbus_int32_t refcount;
CONNECTION_LOCK (connection);
- /* We increment and then decrement the refcount, because there is no
- * _dbus_atomic_get (mirroring the fact that there's no InterlockedGet
- * on Windows). */
- _dbus_atomic_inc (&connection->refcount);
- tmp_refcount = _dbus_atomic_dec (&connection->refcount);
-
- /* The caller should have one ref, and this function temporarily took
- * one more, which is reflected in this count even though we already
- * released it (relying on the caller's ref) due to _dbus_atomic_dec
- * semantics */
- _dbus_assert (tmp_refcount >= 2);
+ refcount = _dbus_atomic_get (&connection->refcount);
+ /* The caller should have at least one ref */
+ _dbus_assert (refcount >= 1);
- if (tmp_refcount == 2)
+ if (refcount == 1)
_dbus_connection_close_possibly_shared_and_unlock (connection);
else
CONNECTION_UNLOCK (connection);
DBusList *link;
_dbus_verbose ("Finalizing connection %p\n", connection);
-
- _dbus_assert (connection->refcount.value == 0);
-
+
+ _dbus_assert (_dbus_atomic_get (&connection->refcount) == 0);
+
/* You have to disconnect the connection before unref:ing it. Otherwise
* you won't get the disconnected message.
*/
while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
{
- _dbus_connection_message_sent (connection, link->data);
+ _dbus_connection_message_sent_unlocked (connection, link->data);
}
}
}
if (preallocated == NULL)
{
+ /* It's OK that this is finalized, because it hasn't been seen by
+ * anything that could attach user callbacks */
dbus_message_unref (reply);
result = DBUS_HANDLER_RESULT_NEED_MEMORY;
_dbus_verbose ("no memory for error send in dispatch\n");
if (filter == NULL)
return FALSE;
- filter->refcount.value = 1;
-
+ _dbus_atomic_inc (&filter->refcount);
+
CONNECTION_LOCK (connection);
if (!_dbus_list_append (&connection->filter_list,