summaryrefslogtreecommitdiffstats
path: root/bus/loop.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-03-17 01:54:37 +0000
committerHavoc Pennington <hp@redhat.com>2003-03-17 01:54:37 +0000
commitb4a1100f4f81534e2aac0141afda750f318223d4 (patch)
tree9573e47181fc32c40f4784df0d22b2c6ee4143c4 /bus/loop.c
parent3caaa342e8db2cba690bb9e1a228ef3862e203d8 (diff)
2003-03-16 Havoc Pennington <hp@pobox.com>
* dbus/dbus-watch.c (_dbus_watch_new): handle failure to malloc the watch * dbus/dbus-server-debug-pipe.c (_dbus_transport_debug_pipe_new): add some missing dbus_set_result * bus/dispatch.c (bus_dispatch_add_connection): handle failure to alloc the DBusMessageHandler * dbus/dbus-transport.c (_dbus_transport_disconnect): don't ref the transport here, since we call this from the finalizer; it resulted in a double-finalize. * dbus/dbus-transport.c (_dbus_transport_disconnect): fix a bug where we tried to use transport->connection that was NULL, happened when transport was disconnected early on due to OOM * bus/*.c: adapt to handle OOM for watches/timeouts * dbus/dbus-transport-unix.c: port to handle OOM during watch handling * dbus/dbus-auth.c (_dbus_auth_get_unused_bytes): return a reference to unused bytes instead of a copy * dbus/dbus-server.c (dbus_server_handle_watch): return FALSE for out of memory * dbus/dbus-connection.c (dbus_connection_handle_watch): return FALSE on OOM * dbus/dbus-timeout.c (dbus_timeout_handle): return FALSE for out of memory
Diffstat (limited to 'bus/loop.c')
-rw-r--r--bus/loop.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/bus/loop.c b/bus/loop.c
index ea0ec106..93096dc5 100644
--- a/bus/loop.c
+++ b/bus/loop.c
@@ -50,6 +50,8 @@ typedef struct
Callback callback;
BusWatchFunction function;
DBusWatch *watch;
+ /* last watch handle failed due to OOM */
+ unsigned int last_iteration_oom : 1;
} WatchCallback;
typedef struct
@@ -78,6 +80,7 @@ watch_callback_new (DBusWatch *watch,
cb->watch = watch;
cb->function = function;
+ cb->last_iteration_oom = FALSE;
cb->callback.type = CALLBACK_WATCH;
cb->callback.data = data;
cb->callback.free_data_func = free_data_func;
@@ -278,11 +281,13 @@ bus_loop_iterate (dbus_bool_t block)
int n_ready;
int initial_serial;
long timeout;
-
+ dbus_bool_t oom_watch_pending;
+
retval = FALSE;
fds = NULL;
watches_for_fds = NULL;
+ oom_watch_pending = FALSE;
#if 0
_dbus_verbose (" iterate %d timeouts %d watches\n",
@@ -306,7 +311,8 @@ bus_loop_iterate (dbus_bool_t block)
{
WatchCallback *wcb = WATCH_CALLBACK (cb);
- if (dbus_watch_get_enabled (wcb->watch))
+ if (!wcb->last_iteration_oom &&
+ dbus_watch_get_enabled (wcb->watch))
++n_fds;
}
@@ -341,7 +347,15 @@ bus_loop_iterate (dbus_bool_t block)
unsigned int flags;
WatchCallback *wcb = WATCH_CALLBACK (cb);
- if (dbus_watch_get_enabled (wcb->watch))
+ if (wcb->last_iteration_oom)
+ {
+ /* we skip this one this time, but reenable it next time,
+ * and have a timeout on this iteration
+ */
+ wcb->last_iteration_oom = FALSE;
+ oom_watch_pending = TRUE;
+ }
+ else if (dbus_watch_get_enabled (wcb->watch))
{
watches_for_fds[i] = wcb;
@@ -423,7 +437,13 @@ bus_loop_iterate (dbus_bool_t block)
if (!block)
timeout = 0;
-
+
+ /* if a watch is OOM, don't wait longer than the OOM
+ * wait to re-enable it
+ */
+ if (oom_watch_pending)
+ timeout = MIN (timeout, bus_get_oom_wait ());
+
n_ready = _dbus_poll (fds, n_fds, timeout);
initial_serial = callback_list_serial;
@@ -538,9 +558,10 @@ bus_loop_iterate (dbus_bool_t block)
if (condition != 0 &&
dbus_watch_get_enabled (wcb->watch))
{
- (* wcb->function) (wcb->watch,
- condition,
- ((Callback*)wcb)->data);
+ if (!(* wcb->function) (wcb->watch,
+ condition,
+ ((Callback*)wcb)->data))
+ wcb->last_iteration_oom = TRUE;
retval = TRUE;
}