/** * Called to notify the D-Bus library when a previously-added watch is * ready for reading or writing, or has an exception such as a hangup. * * If this function returns #FALSE, then the file descriptor may still * be ready for reading or writing, but more memory is needed in order * to do the reading or writing. If you ignore the #FALSE return, your * application may spin in a busy loop on the file descriptor until * memory becomes available, but nothing more catastrophic should * happen. * * dbus_watch_handle() cannot be called during the * DBusAddWatchFunction, as the connection will not be ready to handle * that watch yet. * * It is not allowed to reference a DBusWatch after it has been passed * to remove_function. * * @param watch the DBusWatch object. * @param flags the poll condition using #DBusWatchFlags values * @returns #FALSE if there wasn't enough memory */ dbus_bool_t dbus_watch_handle (DBusWatch *watch, unsigned int flags) { #ifndef DBUS_DISABLE_CHECKS if (watch->fd < 0 || watch->flags == 0) { _dbus_warn_check_failed ("Watch is invalid, it should have been removed\n"); return TRUE; } #endif _dbus_return_val_if_fail (watch->fd >= 0 /* fails if watch was removed */, TRUE); _dbus_watch_sanitize_condition (watch, &flags); if (flags == 0) { _dbus_verbose ("After sanitization, watch flags on fd %d were 0\n", watch->fd); return TRUE; } else return (* watch->handler) (watch, flags, watch->handler_data); }
/** * Handles a watch by reading data, writing data, or disconnecting * the transport, as appropriate for the given condition. * * @param transport the transport. * @param watch the watch. * @param condition the current state of the watched file descriptor. * @returns #FALSE if not enough memory to fully handle the watch */ dbus_bool_t _dbus_transport_handle_watch (DBusTransport *transport, DBusWatch *watch, unsigned int condition) { dbus_bool_t retval; _dbus_assert (transport->vtable->handle_watch != NULL); if (transport->disconnected) return TRUE; if (dbus_watch_get_socket (watch) < 0) { _dbus_warn_check_failed ("Tried to handle an invalidated watch; this watch should have been removed\n"); return TRUE; } _dbus_watch_sanitize_condition (watch, &condition); _dbus_transport_ref (transport); _dbus_watch_ref (watch); retval = (* transport->vtable->handle_watch) (transport, watch, condition); _dbus_watch_unref (watch); _dbus_transport_unref (transport); return retval; }
/** * Called to notify the D-Bus library when a previously-added watch is * ready for reading or writing, or has an exception such as a hangup. * * If this function returns #FALSE, then the file descriptor may still * be ready for reading or writing, but more memory is needed in order * to do the reading or writing. If you ignore the #FALSE return, your * application may spin in a busy loop on the file descriptor until * memory becomes available, but nothing more catastrophic should * happen. * * dbus_watch_handle() cannot be called during the * DBusAddWatchFunction, as the connection will not be ready to handle * that watch yet. * * It is not allowed to reference a DBusWatch after it has been passed * to remove_function. * * @param watch the DBusWatch object. * @param flags the poll condition using #DBusWatchFlags values * @returns #FALSE if there wasn't enough memory */ dbus_bool_t dbus_watch_handle (DBusWatch *watch, unsigned int flags) { _dbus_return_val_if_fail (watch != NULL, FALSE); #ifndef DBUS_DISABLE_CHECKS if (!_dbus_pollable_is_valid (watch->fd) || watch->flags == 0) { _dbus_warn_check_failed ("Watch is invalid, it should have been removed"); return TRUE; } #endif _dbus_return_val_if_fail (_dbus_pollable_is_valid (watch->fd) /* fails if watch was removed */, TRUE); _dbus_watch_sanitize_condition (watch, &flags); if (flags == 0) { _dbus_verbose ("After sanitization, watch flags on fd %" DBUS_POLLABLE_FORMAT " were 0\n", _dbus_pollable_printable (watch->fd)); return TRUE; } else return (* watch->handler) (watch, flags, watch->handler_data); }
/** * Gets the hex-encoded UUID of the machine this function is * executed on. This UUID is guaranteed to be the same for a given * machine at least until it next reboots, though it also * makes some effort to be the same forever, it may change if the * machine is reconfigured or its hardware is modified. * * @param uuid_str string to append hex-encoded machine uuid to * @returns #FALSE if no memory */ dbus_bool_t _dbus_get_local_machine_uuid_encoded (DBusString *uuid_str) { dbus_bool_t ok; _DBUS_LOCK (machine_uuid); if (machine_uuid_initialized_generation != _dbus_current_generation) { DBusError error = DBUS_ERROR_INIT; if (!_dbus_read_local_machine_uuid (&machine_uuid, FALSE, &error)) { #ifndef DBUS_BUILD_TESTS /* For the test suite, we may not be installed so just continue silently * here. But in a production build, we want to be nice and loud about * this. */ _dbus_warn_check_failed ("D-Bus library appears to be incorrectly set up; failed to read machine uuid: %s\n" "See the manual page for dbus-uuidgen to correct this issue.\n", error.message); #endif dbus_error_free (&error); _dbus_generate_uuid (&machine_uuid); } } ok = _dbus_uuid_encode (&machine_uuid, uuid_str); _DBUS_UNLOCK (machine_uuid); return ok; }
static void addresses_shutdown_func (void *data) { int i; i = 0; while (i < N_BUS_TYPES) { if (bus_connections[i] != NULL) _dbus_warn_check_failed ("dbus_shutdown() called but connections were still live. This probably means the application did not drop all its references to bus connections.\n"); dbus_free (bus_connection_addresses[i]); bus_connection_addresses[i] = NULL; ++i; } activation_bus_type = DBUS_BUS_STARTER; }
/** * Decrements the reference count of a DBusServer. Finalizes the * server if the reference count reaches zero. * * The server must be disconnected before the refcount reaches zero. * * @param server the server. */ void dbus_server_unref (DBusServer *server) { dbus_int32_t old_refcount; /* keep this in sync with unref_unlocked */ _dbus_return_if_fail (server != NULL); old_refcount = _dbus_atomic_dec (&server->refcount); #ifndef DBUS_DISABLE_CHECKS if (_DBUS_UNLIKELY (old_refcount <= 0)) { /* undo side-effect first * please do not try to simplify the code here by using * _dbus_atomic_get(), why we don't use it is * because it issues another atomic operation even though * DBUS_DISABLE_CHECKS defined. * Bug: https://bugs.freedesktop.org/show_bug.cgi?id=68303 */ _dbus_atomic_inc (&server->refcount); _dbus_warn_check_failed (_dbus_return_if_fail_warning_format, _DBUS_FUNCTION_NAME, "old_refcount > 0", __FILE__, __LINE__); return; } #endif _dbus_server_trace_ref (server, old_refcount, old_refcount - 1, "unref"); if (old_refcount == 1) { /* lock not held! */ _dbus_assert (server->disconnected); _dbus_assert (server->vtable->finalize != NULL); (* server->vtable->finalize) (server); } }
EXPORT_C #endif dbus_bool_t dbus_server_set_timeout_functions (DBusServer *server, DBusAddTimeoutFunction add_function, DBusRemoveTimeoutFunction remove_function, DBusTimeoutToggledFunction toggled_function, void *data, DBusFreeFunction free_data_function) { dbus_bool_t result; DBusTimeoutList *timeouts; _dbus_return_val_if_fail (server != NULL, FALSE); SERVER_LOCK (server); timeouts = server->timeouts; server->timeouts = NULL; if (timeouts) { SERVER_UNLOCK (server); result = _dbus_timeout_list_set_functions (timeouts, add_function, remove_function, toggled_function, data, free_data_function); SERVER_LOCK (server); } else { _dbus_warn_check_failed ("Re-entrant call to %s\n", _DBUS_FUNCTION_NAME); result = FALSE; } server->timeouts = timeouts; SERVER_UNLOCK (server); return result; }
EXPORT_C #endif dbus_bool_t dbus_server_set_watch_functions (DBusServer *server, DBusAddWatchFunction add_function, DBusRemoveWatchFunction remove_function, DBusWatchToggledFunction toggled_function, void *data, DBusFreeFunction free_data_function) { dbus_bool_t result; DBusWatchList *watches; _dbus_return_val_if_fail (server != NULL, FALSE); SERVER_LOCK (server); watches = server->watches; server->watches = NULL; if (watches) { SERVER_UNLOCK (server); result = _dbus_watch_list_set_functions (watches, add_function, remove_function, toggled_function, data, free_data_function); SERVER_LOCK (server); } else { _dbus_warn_check_failed ("Re-entrant call to %s\n", _DBUS_FUNCTION_NAME); result = FALSE; } server->watches = watches; SERVER_UNLOCK (server); return result; }
/** * Increments the reference count of a DBusServer. * * @param server the server. * @returns the server */ DBusServer * dbus_server_ref (DBusServer *server) { dbus_int32_t old_refcount; _dbus_return_val_if_fail (server != NULL, NULL); old_refcount = _dbus_atomic_inc (&server->refcount); #ifndef DBUS_DISABLE_CHECKS if (_DBUS_UNLIKELY (old_refcount <= 0)) { _dbus_atomic_dec (&server->refcount); _dbus_warn_check_failed (_dbus_return_if_fail_warning_format, _DBUS_FUNCTION_NAME, "old_refcount > 0", __FILE__, __LINE__); return NULL; } #endif _dbus_server_trace_ref (server, old_refcount, old_refcount + 1, "ref"); return server; }
dbus_bool_t _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator, DBusMutex **mutex_loc, dbus_int32_t *slot_id_p) { dbus_int32_t slot; _dbus_mutex_lock (*mutex_loc); if (allocator->n_allocated_slots == 0) { _dbus_assert (allocator->lock_loc == NULL); allocator->lock_loc = mutex_loc; } else if (allocator->lock_loc != mutex_loc) { _dbus_warn_check_failed ("D-Bus threads were initialized after first using the D-Bus library. If your application does not directly initialize threads or use D-Bus, keep in mind that some library or plugin may have used D-Bus or initialized threads behind your back. You can often fix this problem by calling dbus_init_threads() or dbus_g_threads_init() early in your main() method, before D-Bus is used.\n"); _dbus_assert_not_reached ("exiting"); } if (*slot_id_p >= 0) { slot = *slot_id_p; _dbus_assert (slot < allocator->n_allocated_slots); _dbus_assert (allocator->allocated_slots[slot].slot_id == slot); allocator->allocated_slots[slot].refcount += 1; goto out; } _dbus_assert (*slot_id_p < 0); if (allocator->n_used_slots < allocator->n_allocated_slots) { slot = 0; while (slot < allocator->n_allocated_slots) { if (allocator->allocated_slots[slot].slot_id < 0) { allocator->allocated_slots[slot].slot_id = slot; allocator->allocated_slots[slot].refcount = 1; allocator->n_used_slots += 1; break; } ++slot; } _dbus_assert (slot < allocator->n_allocated_slots); } else { DBusAllocatedSlot *tmp; slot = -1; tmp = dbus_realloc (allocator->allocated_slots, sizeof (DBusAllocatedSlot) * (allocator->n_allocated_slots + 1)); if (tmp == NULL) goto out; allocator->allocated_slots = tmp; slot = allocator->n_allocated_slots; allocator->n_allocated_slots += 1; allocator->n_used_slots += 1; allocator->allocated_slots[slot].slot_id = slot; allocator->allocated_slots[slot].refcount = 1; } _dbus_assert (slot >= 0); _dbus_assert (slot < allocator->n_allocated_slots); _dbus_assert (*slot_id_p < 0); _dbus_assert (allocator->allocated_slots[slot].slot_id == slot); _dbus_assert (allocator->allocated_slots[slot].refcount == 1); *slot_id_p = slot; _dbus_verbose ("Allocated slot %d on allocator %p total %d slots allocated %d used\n", slot, allocator, allocator->n_allocated_slots, allocator->n_used_slots); out: _dbus_mutex_unlock (*(allocator->lock_loc)); return slot >= 0; }