/** * 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 (¬ify_user_data_slot)) return NULL; pending = dbus_new0 (DBusPendingCall, 1); if (pending == NULL) { dbus_pending_call_free_data_slot (¬ify_user_data_slot); return NULL; } timeout = _dbus_timeout_new (timeout_milliseconds, timeout_handler, pending, NULL); if (timeout == NULL) { dbus_pending_call_free_data_slot (¬ify_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 (¬ify_user_data_slot)) return NULL; pending = dbus_new0 (DBusPendingCall, 1); if (pending == NULL) { dbus_pending_call_free_data_slot (¬ify_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 (¬ify_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; }
/** * 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; }
/** * 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; }