EXPORT_C #endif void dbus_pending_call_unref (DBusPendingCall *pending) { dbus_bool_t last_unref; _dbus_return_if_fail (pending != NULL); /* More efficient to use the connection lock instead of atomic * int fallback if we lack atomic int decrement */ #ifdef DBUS_HAVE_ATOMIC_INT last_unref = (_dbus_atomic_dec (&pending->refcount) == 1); #else CONNECTION_LOCK (pending->connection); _dbus_assert (pending->refcount.value > 0); pending->refcount.value -= 1; last_unref = pending->refcount.value == 0; CONNECTION_UNLOCK (pending->connection); #endif if (last_unref) _dbus_pending_call_last_unref(pending); }
/** * Stores a pointer on a #DBusPendingCall, along * with an optional function to be used for freeing * the data when the data is set again, or when * the pending call is finalized. The slot number * must have been allocated with dbus_pending_call_allocate_data_slot(). * * @param pending the pending_call * @param slot the slot number * @param data the data to store * @param free_data_func finalizer function for the data * @returns #TRUE if there was enough memory to store the data */ dbus_bool_t _dbus_pending_call_set_data_unlocked (DBusPendingCall *pending, dbus_int32_t slot, void *data, DBusFreeFunction free_data_func) { DBusFreeFunction old_free_func; void *old_data; dbus_bool_t retval; retval = _dbus_data_slot_list_set (&slot_allocator, &pending->slot_list, slot, data, free_data_func, &old_free_func, &old_data); /* Drop locks to call out to app code */ CONNECTION_UNLOCK (pending->connection); if (retval) { if (old_free_func) (* old_free_func) (old_data); } CONNECTION_LOCK (pending->connection); return retval; }
/** * Sets a notification function to be called when the reply is * received or the pending call times out. * * @param pending the pending call * @param function notifier function * @param user_data data to pass to notifier function * @param free_user_data function to free the user data * @returns #FALSE if not enough memory */ dbus_bool_t dbus_pending_call_set_notify (DBusPendingCall *pending, DBusPendingCallNotifyFunction function, void *user_data, DBusFreeFunction free_user_data) { dbus_bool_t ret = FALSE; _dbus_return_val_if_fail (pending != NULL, FALSE); CONNECTION_LOCK (pending->connection); /* could invoke application code! */ if (!_dbus_pending_call_set_data_unlocked (pending, notify_user_data_slot, user_data, free_user_data)) goto out; pending->function = function; ret = TRUE; out: CONNECTION_UNLOCK (pending->connection); return ret; }
/** * Checks whether the pending call has received a reply * yet, or not. * * @param pending the pending call * @returns #TRUE if a reply has been received */ dbus_bool_t dbus_pending_call_get_completed (DBusPendingCall *pending) { dbus_bool_t completed; _dbus_return_val_if_fail (pending != NULL, FALSE); CONNECTION_LOCK (pending->connection); completed = pending->completed; CONNECTION_UNLOCK (pending->connection); return completed; }
/** * Decrements the reference count on a pending call, * freeing it if the count reaches 0. Assumes * connection lock is already held. * * @param pending the pending call object */ void _dbus_pending_call_unref_and_unlock (DBusPendingCall *pending) { dbus_int32_t old_refcount; old_refcount = _dbus_atomic_dec (&pending->refcount); _dbus_assert (old_refcount > 0); CONNECTION_UNLOCK (pending->connection); if (old_refcount == 1) _dbus_pending_call_last_unref (pending); }
/** * Decrements the reference count on a pending call, * freeing it if the count reaches 0. Assumes * connection lock is already held. * * @param pending the pending call object */ void _dbus_pending_call_unref_and_unlock (DBusPendingCall *pending) { dbus_bool_t last_unref; _dbus_assert (pending->refcount.value > 0); pending->refcount.value -= 1; last_unref = pending->refcount.value == 0; CONNECTION_UNLOCK (pending->connection); if (last_unref) _dbus_pending_call_last_unref (pending); }
/** * Retrieves data previously set with dbus_pending_call_set_data(). * The slot must still be allocated (must not have been freed). * * @param pending the pending_call * @param slot the slot to get data from * @returns the data, or #NULL if not found */ void* dbus_pending_call_get_data (DBusPendingCall *pending, dbus_int32_t slot) { void *res; _dbus_return_val_if_fail (pending != NULL, NULL); CONNECTION_LOCK (pending->connection); res = _dbus_data_slot_list_get (&slot_allocator, &pending->slot_list, slot); CONNECTION_UNLOCK (pending->connection); return res; }
/** * Stores a pointer on a #DBusPendingCall, along * with an optional function to be used for freeing * the data when the data is set again, or when * the pending call is finalized. The slot number * must have been allocated with dbus_pending_call_allocate_data_slot(). * * @param pending the pending_call * @param slot the slot number * @param data the data to store * @param free_data_func finalizer function for the data * @returns #TRUE if there was enough memory to store the data */ dbus_bool_t dbus_pending_call_set_data (DBusPendingCall *pending, dbus_int32_t slot, void *data, DBusFreeFunction free_data_func) { dbus_bool_t retval; _dbus_return_val_if_fail (pending != NULL, FALSE); _dbus_return_val_if_fail (slot >= 0, FALSE); CONNECTION_LOCK (pending->connection); retval = _dbus_pending_call_set_data_unlocked (pending, slot, data, free_data_func); CONNECTION_UNLOCK (pending->connection); return retval; }
/** * Gets the reply, or returns #NULL if none has been received * yet. Ownership of the reply message passes to the caller. This * function can only be called once per pending call, since the reply * message is tranferred to the caller. * * @param pending the pending call * @returns the reply message or #NULL. */ DBusMessage* dbus_pending_call_steal_reply (DBusPendingCall *pending) { DBusMessage *message; _dbus_return_val_if_fail (pending != NULL, NULL); _dbus_return_val_if_fail (pending->completed, NULL); _dbus_return_val_if_fail (pending->reply != NULL, NULL); CONNECTION_LOCK (pending->connection); message = pending->reply; pending->reply = NULL; CONNECTION_UNLOCK (pending->connection); return message; }
EXPORT_C #endif DBusPendingCall * dbus_pending_call_ref (DBusPendingCall *pending) { _dbus_return_val_if_fail (pending != NULL, NULL); /* The connection lock is better than the global * lock in the atomic increment fallback */ #ifdef DBUS_HAVE_ATOMIC_INT _dbus_atomic_inc (&pending->refcount); #else CONNECTION_LOCK (pending->connection); _dbus_assert (pending->refcount.value > 0); pending->refcount.value += 1; CONNECTION_UNLOCK (pending->connection); #endif return pending; }