Пример #1
0
/**
 * Stores a pointer on a DBusServer, along
 * with an optional function to be used for freeing
 * the data when the data is set again, or when
 * the server is finalized. The slot number
 * must have been allocated with dbus_server_allocate_data_slot().
 *
 * @param server the server
 * @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_server_set_data (DBusServer       *server,
                      int               slot,
                      void             *data,
                      DBusFreeFunction  free_data_func)
{
    DBusFreeFunction old_free_func;
    void *old_data;
    dbus_bool_t retval;

    _dbus_return_val_if_fail (server != NULL, FALSE);

    SERVER_LOCK (server);

    retval = _dbus_data_slot_list_set (&slot_allocator,
                                       &server->slot_list,
                                       slot, data, free_data_func,
                                       &old_free_func, &old_data);


    SERVER_UNLOCK (server);

    if (retval)
    {
        /* Do the actual free outside the server lock */
        if (old_free_func)
            (* old_free_func) (old_data);
    }

    return retval;
}
Пример #2
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_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;
}
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;
}