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;
}
示例#4
0
/**
 * 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);
}
示例#7
0
/**
 * 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;
}
示例#8
0
/**
 * 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;
}