25 #include "dbus-internals.h" 26 #include "dbus-connection-internal.h" 27 #include "dbus-message-internal.h" 28 #include "dbus-pending-call-internal.h" 29 #include "dbus-pending-call.h" 30 #include "dbus-list.h" 31 #include "dbus-threads.h" 32 #include "dbus-test.h" 53 #define CONNECTION_LOCK(connection) _dbus_connection_lock(connection) 57 #define CONNECTION_UNLOCK(connection) _dbus_connection_unlock(connection) 96 #ifdef DBUS_ENABLE_VERBOSE_MODE 97 static int enabled = -1;
99 _dbus_trace_ref (
"DBusPendingCall", pending_call, old_refcount,
100 new_refcount, why,
"DBUS_PENDING_CALL_TRACE", &enabled);
104 static dbus_int32_t notify_user_data_slot = -1;
118 int timeout_milliseconds,
124 _dbus_assert (timeout_milliseconds >= 0 || timeout_milliseconds == -1);
126 if (timeout_milliseconds == -1)
127 timeout_milliseconds = _DBUS_DEFAULT_TIMEOUT_VALUE;
166 _dbus_pending_call_trace_ref (pending, 0, 1,
"new_unlocked");
191 _dbus_verbose (
" handing message %p (%s) to pending call serial %u\n",
196 "error" :
"other type",
201 pending->
reply = message;
240 notify_user_data_slot);
242 (* pending->
function) (pending, user_data);
334 dbus_uint32_t serial)
382 dbus_uint32_t serial)
388 "Did not receive a reply. Possible causes include: " 389 "the remote application did not send a reply, " 390 "the message bus security policy blocked the reply, " 391 "the reply timeout expired, or " 392 "the network connection was broken.");
397 if (reply_link ==
NULL)
422 dbus_int32_t old_refcount;
425 _dbus_pending_call_trace_ref (pending, old_refcount, old_refcount + 1,
485 dbus_int32_t old_refcount;
489 _dbus_pending_call_trace_ref (pending, old_refcount,
490 old_refcount - 1,
"unref_and_unlock");
494 if (old_refcount == 1)
495 _dbus_pending_call_last_unref (pending);
539 slot, data, free_data_func,
540 &old_free_func, &old_data);
548 (* old_free_func) (old_data);
605 dbus_int32_t old_refcount;
607 _dbus_return_val_if_fail (pending !=
NULL,
NULL);
610 _dbus_pending_call_trace_ref (pending, old_refcount, old_refcount + 1,
625 dbus_int32_t old_refcount;
627 _dbus_return_if_fail (pending !=
NULL);
630 _dbus_pending_call_trace_ref (pending, old_refcount, old_refcount - 1,
633 if (old_refcount == 1)
634 _dbus_pending_call_last_unref(pending);
655 _dbus_return_val_if_fail (pending !=
NULL,
FALSE);
661 user_data, free_user_data))
691 _dbus_return_if_fail (pending !=
NULL);
709 _dbus_return_val_if_fail (pending !=
NULL,
FALSE);
732 _dbus_return_val_if_fail (pending !=
NULL,
NULL);
738 message = pending->
reply;
743 _dbus_message_trace_ref (message, -1, -1,
"dbus_pending_call_steal_reply");
765 _dbus_return_if_fail (pending !=
NULL);
787 _dbus_return_val_if_fail (slot_p !=
NULL,
FALSE);
807 _dbus_return_if_fail (slot_p !=
NULL);
808 _dbus_return_if_fail (*slot_p >= 0);
834 _dbus_return_val_if_fail (pending !=
NULL,
FALSE);
835 _dbus_return_val_if_fail (slot >= 0,
FALSE);
858 _dbus_return_val_if_fail (pending !=
NULL,
NULL);
An atomic integer safe to increment or decrement from multiple threads.
DBusMessage * dbus_message_ref(DBusMessage *message)
Increments the reference count of a DBusMessage.
DBusTimeout * _dbus_timeout_new(int interval, DBusTimeoutHandler handler, void *data, DBusFreeFunction free_data_function)
Creates a new DBusTimeout, enabled by default.
Internals of DBusTimeout.
#define NULL
A null pointer, defined appropriately for C or C++.
void(* DBusFreeFunction)(void *memory)
The type of a function which frees a block of memory.
void _dbus_connection_queue_synthesized_message_link(DBusConnection *connection, DBusList *link)
Adds a link + message to the incoming message queue.
DBusConnection * _dbus_pending_call_get_connection_unlocked(DBusPendingCall *pending)
Gets the connection associated with this pending call.
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
void _dbus_pending_call_finish_completion(DBusPendingCall *pending)
Call the notifier function for the pending call.
void(* DBusPendingCallNotifyFunction)(DBusPendingCall *pending, void *user_data)
Called when a pending call now has a reply available.
DBusMessage * dbus_pending_call_steal_reply(DBusPendingCall *pending)
Gets the reply, or returns NULL if none has been received yet.
dbus_bool_t _dbus_pending_call_set_data_unlocked(DBusPendingCall *pending, dbus_int32_t slot, void *data, DBusFreeFunction free_data_func)
Stores a pointer on a DBusPendingCall, along with an optional function to be used for freeing the dat...
DBusDataSlotList slot_list
Data stored by allocated integer ID.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
void * data
Data stored at this element.
Implementation details of DBusPendingCall - all fields are private.
Implementation details of DBusConnection.
#define DBUS_MESSAGE_TYPE_ERROR
Message type of an error reply message, see dbus_message_get_type()
DBusList * _dbus_list_alloc_link(void *data)
Allocates a linked list node.
#define DBUS_MESSAGE_TYPE_METHOD_RETURN
Message type of a method return message, see dbus_message_get_type()
dbus_bool_t dbus_pending_call_set_notify(DBusPendingCall *pending, DBusPendingCallNotifyFunction function, void *user_data, DBusFreeFunction free_user_data)
Sets a notification function to be called when the reply is received or the pending call times out...
dbus_bool_t dbus_pending_call_set_data(DBusPendingCall *pending, dbus_int32_t slot, void *data, DBusFreeFunction free_data_func)
Stores a pointer on a DBusPendingCall, along with an optional function to be used for freeing the dat...
dbus_bool_t _dbus_pending_call_get_completed_unlocked(DBusPendingCall *pending)
Checks whether the pending call has received a reply yet, or not.
void _dbus_connection_block_pending_call(DBusPendingCall *pending)
Blocks until a pending call times out or gets a reply.
void * dbus_pending_call_get_data(DBusPendingCall *pending, dbus_int32_t slot)
Retrieves data previously set with dbus_pending_call_set_data().
void dbus_pending_call_free_data_slot(dbus_int32_t *slot_p)
Deallocates a global ID for DBusPendingCall data slots.
Internals of DBusMessage.
unsigned int timeout_added
TRUE if we have added the timeout.
DBusConnection * connection
Connections we're associated with.
dbus_bool_t _dbus_pending_call_set_timeout_error_unlocked(DBusPendingCall *pending, DBusMessage *message, dbus_uint32_t serial)
Sets the reply message associated with the pending call to a timeout error.
dbus_bool_t dbus_pending_call_get_completed(DBusPendingCall *pending)
Checks whether the pending call has received a reply yet, or not.
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
DBusList * timeout_link
Preallocated timeout response.
dbus_bool_t _dbus_pending_call_is_timeout_added_unlocked(DBusPendingCall *pending)
Checks to see if a timeout has been added.
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
DBusTimeout * timeout
Timeout.
void dbus_pending_call_cancel(DBusPendingCall *pending)
Cancels the pending call, such that any reply or error received will just be ignored.
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
dbus_bool_t _dbus_data_slot_list_set(DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot, void *data, DBusFreeFunction free_data_func, DBusFreeFunction *old_free_func, void **old_data)
Stores a pointer in the data slot list, along with an optional function to be used for freeing the da...
void _dbus_timeout_unref(DBusTimeout *timeout)
Decrements the reference count of a DBusTimeout object and finalizes the object if the count reaches ...
#define DBUS_ERROR_NO_REPLY
No reply to a message expecting one, usually means a timeout occurred.
dbus_bool_t dbus_pending_call_allocate_data_slot(dbus_int32_t *slot_p)
Allocates an integer ID to be used for storing application-specific data on any DBusPendingCall.
DBusPendingCallNotifyFunction function
Notifier when reply arrives.
dbus_uint32_t dbus_message_get_reply_serial(DBusMessage *message)
Returns the serial that the message is a reply to or 0 if none.
DBusPendingCall * dbus_pending_call_ref(DBusPendingCall *pending)
Increments the reference count on a pending call.
dbus_uint32_t _dbus_pending_call_get_reply_serial_unlocked(DBusPendingCall *pending)
Gets the reply's serial number.
void * _dbus_data_slot_list_get(DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot)
Retrieves data previously set with _dbus_data_slot_list_set_data().
#define CONNECTION_UNLOCK(connection)
shorter and more visible way to write _dbus_connection_unlock()
#define TRUE
Expands to "1".
void _dbus_data_slot_list_init(DBusDataSlotList *list)
Initializes a slot list.
Data structure that stores the actual user data set at a given slot.
void _dbus_list_free_link(DBusList *link)
Frees a linked list node allocated with _dbus_list_alloc_link.
void dbus_pending_call_unref(DBusPendingCall *pending)
Decrements the reference count on a pending call, freeing it if the count reaches 0...
An allocator that tracks a set of slot IDs.
#define DBUS_TIMEOUT_INFINITE
An integer constant representing an infinite timeout.
void _dbus_pending_call_queue_timeout_error_unlocked(DBusPendingCall *pending, DBusConnection *connection)
If the pending call hasn't been timed out, add its timeout error reply to the connection's incoming m...
void dbus_pending_call_block(DBusPendingCall *pending)
Block until the pending call is completed.
DBusPendingCall * _dbus_pending_call_new_unlocked(DBusConnection *connection, int timeout_milliseconds, DBusTimeoutHandler timeout_handler)
Creates a new pending reply object.
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
void _dbus_pending_call_set_reply_unlocked(DBusPendingCall *pending, DBusMessage *message)
Sets the reply of a pending call with the given message, or if the message is NULL, by timing out the pending call.
unsigned int completed
TRUE if some thread has taken responsibility for completing this pending call: either the pending cal...
void _dbus_connection_remove_pending_call(DBusConnection *connection, DBusPendingCall *pending)
Removes a pending call from the connection, such that the pending reply will be ignored.
dbus_uint32_t reply_serial
Expected serial of reply.
#define FALSE
Expands to "0".
int dbus_message_get_type(DBusMessage *message)
Gets the type of a message.
#define _DBUS_LOCK_NAME(name)
Expands to name of a global lock variable.
void dbus_connection_unref(DBusConnection *connection)
Decrements the reference count of a DBusConnection, and finalizes it if the count reaches zero...
dbus_bool_t _dbus_data_slot_allocator_alloc(DBusDataSlotAllocator *allocator, dbus_int32_t *slot_id_p)
Allocates an integer ID to be used for storing data in a DBusDataSlotList.
DBusPendingCall * _dbus_pending_call_ref_unlocked(DBusPendingCall *pending)
Increments the reference count on a pending call, while the lock on its connection is already held...
DBUS_PRIVATE_EXPORT DBusConnection * _dbus_connection_ref_unlocked(DBusConnection *connection)
Increments the reference count of a DBusConnection.
#define CONNECTION_LOCK(connection)
Internals of DBusPendingCall.
DBusTimeout * _dbus_pending_call_get_timeout_unlocked(DBusPendingCall *pending)
Retrives the timeout.
void _dbus_data_slot_allocator_free(DBusDataSlotAllocator *allocator, dbus_int32_t *slot_id_p)
Deallocates an ID previously allocated with _dbus_data_slot_allocator_alloc().
DBusAtomic refcount
reference count
void dbus_message_unref(DBusMessage *message)
Decrements the reference count of a DBusMessage, freeing the message if the count reaches 0...
void _dbus_pending_call_set_reply_serial_unlocked(DBusPendingCall *pending, dbus_uint32_t serial)
Sets the reply's serial number.
void _dbus_pending_call_unref_and_unlock(DBusPendingCall *pending)
Decrements the reference count on a pending call, freeing it if the count reaches 0...
void _dbus_pending_call_start_completion_unlocked(DBusPendingCall *pending)
Sets the pending call to completed.
void _dbus_pending_call_set_timeout_added_unlocked(DBusPendingCall *pending, dbus_bool_t is_added)
Sets wether the timeout has been added.
DBusConnection * _dbus_pending_call_get_connection_and_lock(DBusPendingCall *pending)
Gets the connection associated with this pending call.
void _dbus_data_slot_list_free(DBusDataSlotList *list)
Frees the data slot list and all data slots contained in it, calling application-provided free functi...
void _dbus_list_clear(DBusList **list)
Frees all links in the list and sets the list head to NULL.
dbus_bool_t(* DBusTimeoutHandler)(void *data)
function to run when the timeout is handled
DBusMessage * reply
Reply (after we've received it)
DBusMessage * dbus_message_new_error(DBusMessage *reply_to, const char *error_name, const char *error_message)
Creates a new message that is an error reply to another message.