diff options
author | Havoc Pennington <hp@redhat.com> | 2003-03-15 02:19:02 +0000 |
---|---|---|
committer | Havoc Pennington <hp@redhat.com> | 2003-03-15 02:19:02 +0000 |
commit | 4c95a9782c65f88e2904c44abeb734a1b00f6353 (patch) | |
tree | d81b0c3a3497a031cb642dc5126750a36a6651ff /dbus/dbus-transport-debug.c | |
parent | f468907fb09e8198c4cce7e8f2ddeae8b5476b9e (diff) |
2003-03-14 Havoc Pennington <hp@redhat.com>
* dbus/dbus-memory.c: add a "detect buffer overwrites on free"
cheesy hack
* dbus/dbus-transport-debug.c: rework this a good bit to be
less complicated. hopefully still works.
* dbus/dbus-server-debug.c (handle_new_client): remove timeout
manually
* glib/dbus-gmain.c (timeout_handler): don't remove timeout
after running it
* dbus/dbus-message.c (dbus_message_copy): rename from
dbus_message_new_from_message, fix it up to copy
all the message fields, add test case
* bus/dispatch.c (bus_dispatch_test): add some more test code,
not quite passing yet
Diffstat (limited to 'dbus/dbus-transport-debug.c')
-rw-r--r-- | dbus/dbus-transport-debug.c | 259 |
1 files changed, 133 insertions, 126 deletions
diff --git a/dbus/dbus-transport-debug.c b/dbus/dbus-transport-debug.c index cb4b3c2c..42d1efdc 100644 --- a/dbus/dbus-transport-debug.c +++ b/dbus/dbus-transport-debug.c @@ -2,6 +2,7 @@ /* dbus-transport-debug.c In-proc debug subclass of DBusTransport * * Copyright (C) 2003 CodeFactory AB + * Copyright (C) 2003 Red Hat, Inc. * * Licensed under the Academic Free License version 1.2 * @@ -47,6 +48,13 @@ #define DEFAULT_INTERVAL 1 /** + * Hack due to lack of OOM handling in a couple places + */ +#define WAIT_FOR_MEMORY() _dbus_sleep_milliseconds (250) + +static void check_timeout (DBusTransport *transport); + +/** * Opaque object representing a debug transport. * */ @@ -59,96 +67,21 @@ struct DBusTransportDebug { DBusTransport base; /**< Parent instance */ - DBusTimeout *write_timeout; /**< Timeout for reading. */ - DBusTimeout *read_timeout; /**< Timeout for writing. */ + DBusTimeout *timeout; /**< Timeout for moving messages. */ DBusTransport *other_end; /**< The transport that this transport is connected to. */ -}; - -static void -debug_finalize (DBusTransport *transport) -{ - _dbus_transport_finalize_base (transport); - dbus_free (transport); -} - -static void -do_reading (DBusTransport *transport) -{ - DBusTransportDebug *debug_transport = (DBusTransportDebug*) transport; - - if (transport->disconnected) - return; - - /* Now dispatch the messages */ - if (dbus_connection_dispatch_message (transport->connection)) - { - debug_transport->read_timeout = - _dbus_timeout_new (DEFAULT_INTERVAL, (DBusTimeoutHandler)do_reading, - transport, NULL); - if (!_dbus_connection_add_timeout (transport->connection, - debug_transport->read_timeout)) - { - _dbus_timeout_unref (debug_transport->read_timeout); - debug_transport->read_timeout = NULL; - } - } -} + unsigned int timeout_added : 1; /**< Whether timeout has been added */ +}; -static void -check_read_timeout (DBusTransport *transport) +/* move messages in both directions */ +static dbus_bool_t +move_messages (DBusTransport *transport) { DBusTransportDebug *debug_transport = (DBusTransportDebug*) transport; - dbus_bool_t need_read_timeout; - - if (transport->connection == NULL) - return; - - _dbus_transport_ref (transport); - - need_read_timeout = dbus_connection_get_n_messages (transport->connection) > 0; if (transport->disconnected) - need_read_timeout = FALSE; - - if (need_read_timeout && - debug_transport->read_timeout == NULL) - { - debug_transport->read_timeout = - _dbus_timeout_new (DEFAULT_INTERVAL, (DBusTimeoutHandler)do_reading, - transport, NULL); - - if (debug_transport->read_timeout == NULL) - goto out; - - if (!_dbus_connection_add_timeout (transport->connection, - debug_transport->read_timeout)) - { - _dbus_timeout_unref (debug_transport->read_timeout); - debug_transport->read_timeout = NULL; - - goto out; - } - } - else if (!need_read_timeout && - debug_transport->read_timeout != NULL) - { - _dbus_connection_remove_timeout (transport->connection, - debug_transport->read_timeout); - _dbus_timeout_unref (debug_transport->read_timeout); - debug_transport->read_timeout = NULL; - } - - out: - _dbus_transport_unref (transport); -} - -static void -do_writing (DBusTransport *transport) -{ - if (transport->disconnected) - return; + return TRUE; while (!transport->disconnected && _dbus_connection_have_messages_to_send (transport->connection)) @@ -156,65 +89,106 @@ do_writing (DBusTransport *transport) DBusMessage *message, *copy; message = _dbus_connection_get_message_to_send (transport->connection); - _dbus_message_lock (message); + _dbus_assert (message != NULL); - copy = dbus_message_new_from_message (message); + copy = dbus_message_copy (message); + if (copy == NULL) + return FALSE; + + _dbus_message_lock (message); _dbus_connection_message_sent (transport->connection, message); + + _dbus_verbose (" -->transporting message %s from %s %p to %s %p\n", + dbus_message_get_name (copy), + transport->is_server ? "server" : "client", + transport->connection, + debug_transport->other_end->is_server ? "server" : "client", + debug_transport->other_end->connection); - _dbus_connection_queue_received_message (((DBusTransportDebug *)transport)->other_end->connection, + _dbus_connection_queue_received_message (debug_transport->other_end->connection, copy); dbus_message_unref (copy); } - check_read_timeout (((DBusTransportDebug *)transport)->other_end); + if (debug_transport->other_end && + !debug_transport->other_end->disconnected && + _dbus_connection_have_messages_to_send (debug_transport->other_end->connection)) + { + if (!move_messages (debug_transport->other_end)) + return FALSE; + } + + return TRUE; } static void -check_write_timeout (DBusTransport *transport) +timeout_handler (void *data) { - DBusTransportDebug *debug_transport = (DBusTransportDebug *)transport; - dbus_bool_t need_write_timeout; + DBusTransport *transport = data; - if (transport->connection == NULL) - return; + while (!move_messages (transport)) + WAIT_FOR_MEMORY (); - _dbus_transport_ref (transport); + check_timeout (transport); +} - need_write_timeout = transport->messages_need_sending; +static void +check_timeout (DBusTransport *transport) +{ + DBusTransportDebug *debug_transport = (DBusTransportDebug*) transport; - if (transport->disconnected) - need_write_timeout = FALSE; - - if (need_write_timeout && - debug_transport->write_timeout == NULL) + if (transport->connection && + transport->authenticated && + (transport->messages_need_sending || + (debug_transport->other_end && + debug_transport->other_end->messages_need_sending))) { - debug_transport->write_timeout = - _dbus_timeout_new (DEFAULT_INTERVAL, (DBusTimeoutHandler)do_writing, - transport, NULL); - - if (debug_transport->write_timeout == NULL) - goto out; - - if (!_dbus_connection_add_timeout (transport->connection, - debug_transport->write_timeout)) - { - _dbus_timeout_unref (debug_transport->write_timeout); - debug_transport->write_timeout = NULL; - } + if (!debug_transport->timeout_added) + { + /* FIXME; messages_pending is going to have to + * handle OOM somehow (probably being part of + * PreallocatedSend). See also dbus-transport-unix.c + * check_write_watch() + */ + while (!_dbus_connection_add_timeout (transport->connection, + debug_transport->timeout)) + WAIT_FOR_MEMORY (); + debug_transport->timeout_added = TRUE; + } } - else if (!need_write_timeout && - debug_transport->write_timeout != NULL) + else { - _dbus_connection_remove_timeout (transport->connection, - debug_transport->write_timeout); - _dbus_timeout_unref (debug_transport->write_timeout); - debug_transport->write_timeout = NULL; + if (debug_transport->timeout_added) + { + _dbus_connection_remove_timeout (transport->connection, + debug_transport->timeout); + debug_transport->timeout_added = FALSE; + } } +} - out: - _dbus_transport_unref (transport); +static void +debug_finalize (DBusTransport *transport) +{ + DBusTransportDebug *debug_transport = (DBusTransportDebug*) transport; + + if (debug_transport->timeout_added) + _dbus_connection_remove_timeout (transport->connection, + debug_transport->timeout); + + if (debug_transport->other_end) + { + _dbus_transport_disconnect (debug_transport->other_end); + debug_transport->other_end = NULL; + } + + _dbus_transport_finalize_base (transport); + + _dbus_timeout_unref (debug_transport->timeout); + + dbus_free (transport); } static void @@ -232,13 +206,14 @@ debug_disconnect (DBusTransport *transport) static void debug_connection_set (DBusTransport *transport) { + check_timeout (transport); } static void debug_messages_pending (DBusTransport *transport, int messages_pending) { - check_write_timeout (transport); + check_timeout (transport); } static void @@ -246,6 +221,7 @@ debug_do_iteration (DBusTransport *transport, unsigned int flags, int timeout_milliseconds) { + move_messages (transport); } static void @@ -263,6 +239,16 @@ static DBusTransportVTable debug_vtable = { debug_live_messages_changed }; +static dbus_bool_t +create_timeout_object (DBusTransportDebug *debug_transport) +{ + debug_transport->timeout = _dbus_timeout_new (DEFAULT_INTERVAL, + timeout_handler, + debug_transport, NULL); + + return debug_transport->timeout != NULL; +} + /** * Creates a new debug server transport. * @@ -288,11 +274,21 @@ _dbus_transport_debug_server_new (DBusTransport *client) return NULL; } + if (!create_timeout_object (debug_transport)) + { + _dbus_transport_finalize_base (&debug_transport->base); + dbus_free (debug_transport); + return NULL; + } + debug_transport->base.authenticated = TRUE; /* Connect the two transports */ debug_transport->other_end = client; ((DBusTransportDebug *)client)->other_end = (DBusTransport *)debug_transport; + + _dbus_verbose (" new debug server transport %p created, other end %p\n", + debug_transport, debug_transport->other_end); return (DBusTransport *)debug_transport; } @@ -335,19 +331,30 @@ _dbus_transport_debug_client_new (const char *server_name, dbus_set_result (result, DBUS_RESULT_NO_MEMORY); return NULL; } - - if (!_dbus_server_debug_accept_transport (debug_server, (DBusTransport *)debug_transport)) + + if (!create_timeout_object (debug_transport)) { _dbus_transport_finalize_base (&debug_transport->base); - - dbus_free (debug_transport); - dbus_set_result (result, DBUS_RESULT_IO_ERROR); + dbus_free (debug_transport); + dbus_set_result (result, DBUS_RESULT_NO_MEMORY); + return NULL; + } + + if (!_dbus_server_debug_accept_transport (debug_server, + (DBusTransport *)debug_transport)) + { + _dbus_timeout_unref (debug_transport->timeout); + _dbus_transport_finalize_base (&debug_transport->base); + dbus_free (debug_transport); + dbus_set_result (result, DBUS_RESULT_NO_MEMORY); return NULL; - } /* FIXME: Prolly wrong to do this. */ debug_transport->base.authenticated = TRUE; + + _dbus_verbose (" new debug client transport %p created, other end %p\n", + debug_transport, debug_transport->other_end); return (DBusTransport *)debug_transport; } |