/**
 * Creates a new pending reply object.
 *
 * @param connection connection where reply will arrive
 * @param timeout_milliseconds length of timeout, -1 for default
 * @param timeout_handler timeout handler, takes pending call as data
 * @returns a new #DBusPendingCall or #NULL if no memory.
 */
DBusPendingCall*
_dbus_pending_call_new_unlocked (DBusConnection    *connection,
                                 int                timeout_milliseconds,
                                 DBusTimeoutHandler timeout_handler)
{
  DBusPendingCall *pending;
  DBusTimeout *timeout;

  _dbus_assert (timeout_milliseconds >= 0 || timeout_milliseconds == -1);
 
  if (timeout_milliseconds == -1)
    timeout_milliseconds = _DBUS_DEFAULT_TIMEOUT_VALUE;

  /* it would probably seem logical to pass in _DBUS_INT_MAX for
   * infinite timeout, but then math in
   * _dbus_connection_block_for_reply would get all overflow-prone, so
   * smack that down.
   */
  if (timeout_milliseconds > _DBUS_ONE_HOUR_IN_MILLISECONDS * 6)
    timeout_milliseconds = _DBUS_ONE_HOUR_IN_MILLISECONDS * 6;
  
  if (!dbus_pending_call_allocate_data_slot (&notify_user_data_slot))
    return NULL;
  
  pending = dbus_new0 (DBusPendingCall, 1);
  
  if (pending == NULL)
    {
      dbus_pending_call_free_data_slot (&notify_user_data_slot);
      return NULL;
    }

  timeout = _dbus_timeout_new (timeout_milliseconds,
                               timeout_handler,
			       pending, NULL);  

  if (timeout == NULL)
    {
      dbus_pending_call_free_data_slot (&notify_user_data_slot);
      dbus_free (pending);
      return NULL;
    }
  
  pending->refcount.value = 1;
  pending->connection = connection;
  _dbus_connection_ref_unlocked (pending->connection);

  pending->timeout = timeout;


  _dbus_data_slot_list_init (&pending->slot_list);
  
  return pending;
}
/**
 * Creates a new pending reply object.
 *
 * @param connection connection where reply will arrive
 * @param timeout_milliseconds length of timeout, -1 (or
 *  #DBUS_TIMEOUT_USE_DEFAULT) for default,
 *  #DBUS_TIMEOUT_INFINITE for no timeout
 * @param timeout_handler timeout handler, takes pending call as data
 * @returns a new #DBusPendingCall or #NULL if no memory.
 */
DBusPendingCall*
_dbus_pending_call_new_unlocked (DBusConnection    *connection,
                                 int                timeout_milliseconds,
                                 DBusTimeoutHandler timeout_handler)
{
  DBusPendingCall *pending;
  DBusTimeout *timeout;

  _dbus_assert (timeout_milliseconds >= 0 || timeout_milliseconds == -1);
 
  if (timeout_milliseconds == -1)
    timeout_milliseconds = _DBUS_DEFAULT_TIMEOUT_VALUE;

  if (!dbus_pending_call_allocate_data_slot (&notify_user_data_slot))
    return NULL;
  
  pending = dbus_new0 (DBusPendingCall, 1);
  
  if (pending == NULL)
    {
      dbus_pending_call_free_data_slot (&notify_user_data_slot);
      return NULL;
    }

  if (timeout_milliseconds != DBUS_TIMEOUT_INFINITE)
    {
      timeout = _dbus_timeout_new (timeout_milliseconds,
                                   timeout_handler,
                                   pending, NULL);  

      if (timeout == NULL)
        {
          dbus_pending_call_free_data_slot (&notify_user_data_slot);
          dbus_free (pending);
          return NULL;
        }

      pending->timeout = timeout;
    }
  else
    {
      pending->timeout = NULL;
    }

  _dbus_atomic_inc (&pending->refcount);
  pending->connection = connection;
  _dbus_connection_ref_unlocked (pending->connection);

  _dbus_data_slot_list_init (&pending->slot_list);

  _dbus_pending_call_trace_ref (pending, 0, 1, "new_unlocked");

  return pending;
}
BusExpireList*
bus_expire_list_new (DBusLoop      *loop,
                     int            expire_after,
                     BusExpireFunc  expire_func,
                     void          *data)
{
  BusExpireList *list;

  list = dbus_new0 (BusExpireList, 1);
  if (list == NULL)
    return NULL;

  list->expire_func = expire_func;
  list->data = data;
  list->loop = loop;
  list->expire_after = expire_after;

  list->timeout = _dbus_timeout_new (100, /* irrelevant */
                                     expire_timeout_handler,
                                     list, NULL);
  if (list->timeout == NULL)
    goto failed;

  _dbus_timeout_set_enabled (list->timeout, FALSE);

  if (!_dbus_loop_add_timeout (list->loop,
                               list->timeout,
                               call_timeout_callback, NULL, NULL))
    goto failed;

  return list;

 failed:
  if (list->timeout)
    _dbus_timeout_unref (list->timeout);

  dbus_free (list);

  return NULL;
}