summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-transport-unix.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-03-15 20:47:16 +0000
committerHavoc Pennington <hp@redhat.com>2003-03-15 20:47:16 +0000
commitf587ce7845edb0eb01451368d01b5bc86b5904cd (patch)
treef3a549cd61df701882d818b5fc452b1438097f5b /dbus/dbus-transport-unix.c
parentf05f87a825ab8ed5273674a7f65521ffc526f0d2 (diff)
2003-03-15 Havoc Pennington <hp@pobox.com>
Make it pass the Hello handling test including all OOM codepaths. Now to do other messages... * bus/services.c (bus_service_remove_owner): fix crash when removing owner from an empty list of owners (bus_registry_ensure): don't leave service in the list of a connection's owned services if we fail to put the service in the hash table. * bus/connection.c (bus_connection_preallocate_oom_error): set error flag on the OOM error. * dbus/dbus-connection.c (_dbus_connection_new_for_transport): handle _dbus_transport_set_connection failure * dbus/dbus-transport-unix.c (_dbus_transport_new_for_fd): modify to create watches up front and simply enable/disable them as needed. (unix_connection_set): this can now fail on OOM * dbus/dbus-timeout.c, dbus/dbus-watch.c: add concept of enabling/disabling a watch or timeout. * bus/loop.c (bus_loop_iterate): don't touch disabled watches/timeouts * glib/dbus-gmain.c: adapt to enable/disable watches and timeouts
Diffstat (limited to 'dbus/dbus-transport-unix.c')
-rw-r--r--dbus/dbus-transport-unix.c166
1 files changed, 59 insertions, 107 deletions
diff --git a/dbus/dbus-transport-unix.c b/dbus/dbus-transport-unix.c
index 3c5fe848..23ab7c54 100644
--- a/dbus/dbus-transport-unix.c
+++ b/dbus/dbus-transport-unix.c
@@ -117,6 +117,12 @@ check_write_watch (DBusTransport *transport)
if (transport->connection == NULL)
return;
+
+ if (transport->disconnected)
+ {
+ _dbus_assert (unix_transport->write_watch == NULL);
+ return;
+ }
_dbus_transport_ref (transport);
@@ -126,51 +132,10 @@ check_write_watch (DBusTransport *transport)
need_write_watch = transport->send_credentials_pending ||
_dbus_auth_do_work (transport->auth) == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND;
- if (transport->disconnected)
- need_write_watch = FALSE;
-
- if (need_write_watch &&
- unix_transport->write_watch == NULL)
- {
- unix_transport->write_watch =
- _dbus_watch_new (unix_transport->fd,
- DBUS_WATCH_WRITABLE);
-
- /* FIXME this is total crack. The proper fix is probably to
- * allocate the write watch on transport creation, keep it
- * allocated. But that doesn't solve needing memory to add the
- * watch. messages_pending is going to have to handle OOM
- * somehow (probably being part of PreallocatedSend)
- */
- if (unix_transport->write_watch == NULL)
- goto out;
+ _dbus_connection_toggle_watch (transport->connection,
+ unix_transport->write_watch,
+ need_write_watch);
- if (!_dbus_connection_add_watch (transport->connection,
- unix_transport->write_watch))
- {
- _dbus_watch_invalidate (unix_transport->write_watch);
- _dbus_watch_unref (unix_transport->write_watch);
- unix_transport->write_watch = NULL;
- }
- }
- else if (!need_write_watch &&
- unix_transport->write_watch != NULL)
- {
- _dbus_connection_remove_watch (transport->connection,
- unix_transport->write_watch);
- _dbus_watch_invalidate (unix_transport->write_watch);
- _dbus_watch_unref (unix_transport->write_watch);
- unix_transport->write_watch = NULL;
- }
- else
- {
-#if 0
- _dbus_verbose ("Write watch is unchanged from %p on fd %d\n",
- unix_transport->write_watch, unix_transport->fd);
-#endif
- }
-
- out:
_dbus_transport_unref (transport);
}
@@ -182,6 +147,12 @@ check_read_watch (DBusTransport *transport)
if (transport->connection == NULL)
return;
+
+ if (transport->disconnected)
+ {
+ _dbus_assert (unix_transport->read_watch == NULL);
+ return;
+ }
_dbus_transport_ref (transport);
@@ -192,57 +163,10 @@ check_read_watch (DBusTransport *transport)
need_read_watch = transport->receive_credentials_pending ||
_dbus_auth_do_work (transport->auth) == DBUS_AUTH_STATE_WAITING_FOR_INPUT;
-#if 0
- _dbus_verbose ("need_read_watch = %d authenticated = %d\n",
- need_read_watch, _dbus_transport_get_is_authenticated (transport));
-#endif
-
- if (transport->disconnected)
- need_read_watch = FALSE;
-
- if (need_read_watch &&
- unix_transport->read_watch == NULL)
- {
- _dbus_verbose ("Adding read watch to unix fd %d\n",
- unix_transport->fd);
-
- unix_transport->read_watch =
- _dbus_watch_new (unix_transport->fd,
- DBUS_WATCH_READABLE);
+ _dbus_connection_toggle_watch (transport->connection,
+ unix_transport->read_watch,
+ need_read_watch);
- /* we can maybe add it some other time, just silently bomb */
- if (unix_transport->read_watch == NULL)
- goto out;
-
- if (!_dbus_connection_add_watch (transport->connection,
- unix_transport->read_watch))
- {
- _dbus_watch_invalidate (unix_transport->read_watch);
- _dbus_watch_unref (unix_transport->read_watch);
- unix_transport->read_watch = NULL;
- }
- }
- else if (!need_read_watch &&
- unix_transport->read_watch != NULL)
- {
- _dbus_verbose ("Removing read watch from unix fd %d\n",
- unix_transport->fd);
-
- _dbus_connection_remove_watch (transport->connection,
- unix_transport->read_watch);
- _dbus_watch_invalidate (unix_transport->read_watch);
- _dbus_watch_unref (unix_transport->read_watch);
- unix_transport->read_watch = NULL;
- }
- else
- {
-#if 0
- _dbus_verbose ("Read watch is unchanged from %p on fd %d\n",
- unix_transport->read_watch, unix_transport->fd);
-#endif
- }
-
- out:
_dbus_transport_unref (transport);
}
@@ -908,11 +832,27 @@ unix_disconnect (DBusTransport *transport)
unix_transport->fd = -1;
}
-static void
+static dbus_bool_t
unix_connection_set (DBusTransport *transport)
{
+ DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
+
+ if (!_dbus_connection_add_watch (transport->connection,
+ unix_transport->write_watch))
+ return FALSE;
+
+ if (!_dbus_connection_add_watch (transport->connection,
+ unix_transport->read_watch))
+ {
+ _dbus_connection_remove_watch (transport->connection,
+ unix_transport->write_watch);
+ return FALSE;
+ }
+
check_read_watch (transport);
check_write_watch (transport);
+
+ return TRUE;
}
static void
@@ -1120,19 +1060,24 @@ _dbus_transport_new_for_fd (int fd,
if (!_dbus_string_init (&unix_transport->encoded_message,
_DBUS_INT_MAX))
- {
- dbus_free (unix_transport);
- return NULL;
- }
+ goto failed_0;
+
+ unix_transport->write_watch = _dbus_watch_new (fd,
+ DBUS_WATCH_WRITABLE,
+ FALSE);
+ if (unix_transport->write_watch == NULL)
+ goto failed_1;
+
+ unix_transport->read_watch = _dbus_watch_new (fd,
+ DBUS_WATCH_READABLE,
+ FALSE);
+ if (unix_transport->read_watch == NULL)
+ goto failed_2;
if (!_dbus_transport_init_base (&unix_transport->base,
&unix_vtable,
server))
- {
- _dbus_string_free (&unix_transport->encoded_message);
- dbus_free (unix_transport);
- return NULL;
- }
+ goto failed_3;
unix_transport->fd = fd;
unix_transport->message_bytes_written = 0;
@@ -1140,11 +1085,18 @@ _dbus_transport_new_for_fd (int fd,
/* These values should probably be tunable or something. */
unix_transport->max_bytes_read_per_iteration = 2048;
unix_transport->max_bytes_written_per_iteration = 2048;
-
- check_read_watch ((DBusTransport*) unix_transport);
- check_write_watch ((DBusTransport*) unix_transport);
return (DBusTransport*) unix_transport;
+
+ failed_3:
+ _dbus_watch_unref (unix_transport->read_watch);
+ failed_2:
+ _dbus_watch_unref (unix_transport->write_watch);
+ failed_1:
+ _dbus_string_free (&unix_transport->encoded_message);
+ failed_0:
+ dbus_free (unix_transport);
+ return NULL;
}
/**