/**
 * 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;
}
Beispiel #3
0
/**
 * Initializes the members of the DBusServer base class.
 * Chained up to by subclass constructors.
 *
 * @param server the server.
 * @param vtable the vtable for the subclass.
 * @param address the server's address
 * @returns #TRUE on success.
 */
dbus_bool_t
_dbus_server_init_base (DBusServer             *server,
                        const DBusServerVTable *vtable,
                        const DBusString       *address)
{
    server->vtable = vtable;

#ifdef DBUS_DISABLE_ASSERT
    _dbus_atomic_inc (&server->refcount);
#else
    {
        dbus_int32_t old_refcount = _dbus_atomic_inc (&server->refcount);

        _dbus_assert (old_refcount == 0);
    }
#endif

    server->address = NULL;
    server->watches = NULL;
    server->timeouts = NULL;
    server->published_address = FALSE;

    if (!_dbus_string_init (&server->guid_hex))
        return FALSE;

    _dbus_generate_uuid (&server->guid);

    if (!_dbus_uuid_encode (&server->guid, &server->guid_hex))
        goto failed;

    server->address = copy_address_with_guid_appended (address,
                      &server->guid_hex);
    if (server->address == NULL)
        goto failed;

    _dbus_rmutex_new_at_location (&server->mutex);
    if (server->mutex == NULL)
        goto failed;

    server->watches = _dbus_watch_list_new ();
    if (server->watches == NULL)
        goto failed;

    server->timeouts = _dbus_timeout_list_new ();
    if (server->timeouts == NULL)
        goto failed;

    _dbus_data_slot_list_init (&server->slot_list);

    _dbus_verbose ("Initialized server on address %s\n", server->address);

    return TRUE;

failed:
    _dbus_rmutex_free_at_location (&server->mutex);
    server->mutex = NULL;
    if (server->watches)
    {
        _dbus_watch_list_free (server->watches);
        server->watches = NULL;
    }
    if (server->timeouts)
    {
        _dbus_timeout_list_free (server->timeouts);
        server->timeouts = NULL;
    }
    if (server->address)
    {
        dbus_free (server->address);
        server->address = NULL;
    }
    _dbus_string_free (&server->guid_hex);

    return FALSE;
}
Beispiel #4
0
/**
 * Initializes the members of the DBusServer base class.
 * Chained up to by subclass constructors.
 *
 * @param server the server.
 * @param vtable the vtable for the subclass.
 * @param address the server's address
 * @returns #TRUE on success.
 */
dbus_bool_t
_dbus_server_init_base (DBusServer             *server,
                        const DBusServerVTable *vtable,
                        const DBusString       *address)
{
  server->vtable = vtable;
  server->refcount.value = 1;

  server->address = NULL;
  server->watches = NULL;
  server->timeouts = NULL;

  if (!_dbus_string_init (&server->guid_hex))
    return FALSE;

  _dbus_generate_uuid (&server->guid);

  if (!_dbus_uuid_encode (&server->guid, &server->guid_hex))
    goto failed;
  
  server->address = copy_address_with_guid_appended (address,
                                                     &server->guid_hex);
  if (server->address == NULL)
    goto failed;
  
  _dbus_mutex_new_at_location (&server->mutex);
  if (server->mutex == NULL)
    goto failed;
  
  server->watches = _dbus_watch_list_new ();
  if (server->watches == NULL)
    goto failed;

  server->timeouts = _dbus_timeout_list_new ();
  if (server->timeouts == NULL)
    goto failed;

  _dbus_data_slot_list_init (&server->slot_list);

  _dbus_verbose ("Initialized server on address %s\n", server->address);
  
  return TRUE;

 failed:
  _dbus_mutex_free_at_location (&server->mutex);
  server->mutex = NULL;
  if (server->watches)
    {
      _dbus_watch_list_free (server->watches);
      server->watches = NULL;
    }
  if (server->timeouts)
    {
      _dbus_timeout_list_free (server->timeouts);
      server->timeouts = NULL;
    }
  if (server->address)
    {
      dbus_free (server->address);
      server->address = NULL;
    }
  _dbus_string_free (&server->guid_hex);
  
  return FALSE;
}
dbus_bool_t
_dbus_data_slot_test (void)
{
    DBusDataSlotAllocator allocator;
    DBusDataSlotList list;
    int i;
    DBusFreeFunction old_free_func;
    void *old_data;
    DBusMutex *mutex;

    if (!_dbus_data_slot_allocator_init (&allocator))
        _dbus_assert_not_reached ("no memory for allocator");

    _dbus_data_slot_list_init (&list);

    _dbus_mutex_new_at_location (&mutex);
    if (mutex == NULL)
        _dbus_assert_not_reached ("failed to alloc mutex");

#define N_SLOTS 100

    i = 0;
    while (i < N_SLOTS)
    {
        /* we don't really want apps to rely on this ordered
         * allocation, but it simplifies things to rely on it
         * here.
         */
        dbus_int32_t tmp = -1;

        _dbus_data_slot_allocator_alloc (&allocator, &mutex, &tmp);

        if (tmp != i)
            _dbus_assert_not_reached ("did not allocate slots in numeric order\n");

        ++i;
    }

    i = 0;
    while (i < N_SLOTS)
    {
        if (!_dbus_data_slot_list_set (&allocator, &list,
                                       i,
                                       _DBUS_INT_TO_POINTER (i),
                                       test_free_slot_data_func,
                                       &old_free_func, &old_data))
            _dbus_assert_not_reached ("no memory to set data");

        _dbus_assert (old_free_func == NULL);
        _dbus_assert (old_data == NULL);

        _dbus_assert (_dbus_data_slot_list_get (&allocator, &list, i) ==
                      _DBUS_INT_TO_POINTER (i));

        ++i;
    }

    free_counter = 0;
    i = 0;
    while (i < N_SLOTS)
    {
        if (!_dbus_data_slot_list_set (&allocator, &list,
                                       i,
                                       _DBUS_INT_TO_POINTER (i),
                                       test_free_slot_data_func,
                                       &old_free_func, &old_data))
            _dbus_assert_not_reached ("no memory to set data");

        _dbus_assert (old_free_func == test_free_slot_data_func);
        _dbus_assert (_DBUS_POINTER_TO_INT (old_data) == i);

        (* old_free_func) (old_data);
        _dbus_assert (i == (free_counter - 1));

        _dbus_assert (_dbus_data_slot_list_get (&allocator, &list, i) ==
                      _DBUS_INT_TO_POINTER (i));

        ++i;
    }

    free_counter = 0;
    _dbus_data_slot_list_free (&list);

    _dbus_assert (N_SLOTS == free_counter);

    i = 0;
    while (i < N_SLOTS)
    {
        dbus_int32_t tmp = i;

        _dbus_data_slot_allocator_free (&allocator, &tmp);
        _dbus_assert (tmp == -1);
        ++i;
    }

    _dbus_mutex_free_at_location (&mutex);

    return TRUE;
}