diff options
author | Havoc Pennington <hp@redhat.com> | 2003-08-12 04:15:49 +0000 |
---|---|---|
committer | Havoc Pennington <hp@redhat.com> | 2003-08-12 04:15:49 +0000 |
commit | 1d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48 (patch) | |
tree | 26a8b3863455d26c4dc8805077a318fe8bb6d610 /dbus/dbus-connection.c | |
parent | 5c1a8e44903bd1dedc8cbefad78b0c8b61daada5 (diff) |
2003-08-12 Havoc Pennington <hp@pobox.com>
* bus/dispatch.c (bus_dispatch): make this return proper
DBusHandlerResult to avoid DBUS_ERROR_UNKNOWN_METHOD
* dbus/dbus-errors.c (dbus_set_error): use
_dbus_string_append_printf_valist
* dbus/dbus-string.c (_dbus_string_append_printf_valist)
(_dbus_string_append_printf): new
* dbus/dbus-errors.h (DBUS_ERROR_UNKNOWN_MESSAGE): change to
UNKNOWN_METHOD
* dbus/dbus-connection.c (dbus_connection_dispatch): handle
DBUS_HANDLER_RESULT_NEED_MEMORY; send default error reply if a
message is unhandled.
Diffstat (limited to 'dbus/dbus-connection.c')
-rw-r--r-- | dbus/dbus-connection.c | 103 |
1 files changed, 94 insertions, 9 deletions
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 17563f35..ba5601e3 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -36,6 +36,7 @@ #include "dbus-protocol.h" #include "dbus-dataslot.h" #include "dbus-object-registry.h" +#include "dbus-string.h" #if 0 #define CONNECTION_LOCK(connection) do { \ @@ -1942,6 +1943,8 @@ dbus_connection_borrow_message (DBusConnection *connection) DBusDispatchStatus status; _dbus_return_val_if_fail (connection != NULL, NULL); + /* can't borrow during dispatch */ + _dbus_return_val_if_fail (!connection->dispatch_acquired, NULL); /* this is called for the side effect that it queues * up any messages from the transport @@ -1977,6 +1980,8 @@ dbus_connection_return_message (DBusConnection *connection, { _dbus_return_if_fail (connection != NULL); _dbus_return_if_fail (message != NULL); + /* can't borrow during dispatch */ + _dbus_return_if_fail (!connection->dispatch_acquired); CONNECTION_LOCK (connection); @@ -2005,6 +2010,8 @@ dbus_connection_steal_borrowed_message (DBusConnection *connection, _dbus_return_if_fail (connection != NULL); _dbus_return_if_fail (message != NULL); + /* can't borrow during dispatch */ + _dbus_return_if_fail (!connection->dispatch_acquired); CONNECTION_LOCK (connection); @@ -2074,6 +2081,22 @@ _dbus_connection_pop_message_unlocked (DBusConnection *connection) return NULL; } +static void +_dbus_connection_putback_message_link_unlocked (DBusConnection *connection, + DBusList *message_link) +{ + _dbus_assert (message_link != NULL); + /* You can't borrow a message while a link is outstanding */ + _dbus_assert (connection->message_borrowed == NULL); + + _dbus_list_prepend_link (&connection->incoming_messages, + message_link); + connection->n_incoming += 1; + + _dbus_verbose ("Message %p (%s) put back into queue %p, %d incoming\n", + message_link->data, dbus_message_get_name (message_link->data), + connection, connection->n_incoming); +} /** * Returns the first-received message from the incoming message queue, @@ -2360,7 +2383,7 @@ dbus_connection_dispatch (DBusConnection *connection) CONNECTION_LOCK (connection); if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) - /* FIXME */ ; + goto out; /* Did a reply we were waiting on get filtered? */ if (reply_handler_data && result == DBUS_HANDLER_RESULT_HANDLED) @@ -2405,22 +2428,84 @@ dbus_connection_dispatch (DBusConnection *connection) message); CONNECTION_LOCK (connection); - if (result == DBUS_HANDLER_RESULT_HANDLED) + + if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED) goto out; - if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) - /* FIXME */ ; + if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL) + { + DBusMessage *reply; + DBusString str; + DBusPreallocatedSend *preallocated; + + _dbus_verbose (" sending error %s\n", + DBUS_ERROR_UNKNOWN_METHOD); + + if (!_dbus_string_init (&str)) + { + result = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto out; + } + + if (!_dbus_string_append_printf (&str, + "Method \"%s\" doesn't exist\n", + dbus_message_get_name (message))) + { + _dbus_string_free (&str); + result = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto out; + } + + reply = dbus_message_new_error (message, + DBUS_ERROR_UNKNOWN_METHOD, + _dbus_string_get_const_data (&str)); + _dbus_string_free (&str); + + if (reply == NULL) + { + result = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto out; + } + + preallocated = _dbus_connection_preallocate_send_unlocked (connection); + + if (preallocated == NULL) + { + dbus_message_unref (reply); + result = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto out; + } + + _dbus_connection_send_preallocated_unlocked (connection, preallocated, + reply, NULL); + + dbus_message_unref (reply); + + result = DBUS_HANDLER_RESULT_HANDLED; + } _dbus_verbose (" done dispatching %p (%s) on connection %p\n", message, dbus_message_get_name (message), connection); out: + if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) + { + /* Put message back, and we'll start over. + * Yes this means handlers must be idempotent if they + * don't return HANDLED; c'est la vie. + */ + _dbus_connection_putback_message_link_unlocked (connection, + message_link); + } + else + { + _dbus_list_free_link (message_link); + dbus_message_unref (message); /* don't want the message to count in max message limits + * in computing dispatch status below + */ + } + _dbus_connection_release_dispatch (connection); - - _dbus_list_free_link (message_link); - dbus_message_unref (message); /* don't want the message to count in max message limits - * in computing dispatch status - */ status = _dbus_connection_get_dispatch_status_unlocked (connection); |