summaryrefslogtreecommitdiffstats
path: root/bus
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
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')
-rw-r--r--bus/bus.c5
-rw-r--r--bus/connection.c10
-rw-r--r--bus/dispatch.c7
-rw-r--r--bus/loop.c35
-rw-r--r--bus/loop.h10
-rw-r--r--bus/test.c12
-rw-r--r--bus/utils.c14
-rw-r--r--bus/utils.h1
8 files changed, 68 insertions, 26 deletions
diff --git a/bus/bus.c b/bus/bus.c
index 589dda1b..a1bc6622 100644
--- a/bus/bus.c
+++ b/bus/bus.c
@@ -39,14 +39,14 @@ struct BusContext
BusRegistry *registry;
};
-static void
+static dbus_bool_t
server_watch_callback (DBusWatch *watch,
unsigned int condition,
void *data)
{
BusContext *context = data;
- dbus_server_handle_watch (context->server, watch, condition);
+ return dbus_server_handle_watch (context->server, watch, condition);
}
static dbus_bool_t
@@ -69,6 +69,7 @@ static void
server_timeout_callback (DBusTimeout *timeout,
void *data)
{
+ /* can return FALSE on OOM but we just let it fire again later */
dbus_timeout_handle (timeout);
}
diff --git a/bus/connection.c b/bus/connection.c
index 80afc7e1..a8616683 100644
--- a/bus/connection.c
+++ b/bus/connection.c
@@ -133,20 +133,23 @@ bus_connection_disconnected (DBusConnection *connection)
dbus_connection_unref (connection);
}
-static void
+static dbus_bool_t
connection_watch_callback (DBusWatch *watch,
unsigned int condition,
void *data)
{
DBusConnection *connection = data;
+ dbus_bool_t retval;
dbus_connection_ref (connection);
- dbus_connection_handle_watch (connection, watch, condition);
+ retval = dbus_connection_handle_watch (connection, watch, condition);
bus_connection_dispatch_all_messages (connection);
dbus_connection_unref (connection);
+
+ return retval;
}
static dbus_bool_t
@@ -171,7 +174,8 @@ connection_timeout_callback (DBusTimeout *timeout,
DBusConnection *connection = data;
dbus_connection_ref (connection);
-
+
+ /* can return FALSE on OOM but we just let it fire again later */
dbus_timeout_handle (timeout);
bus_connection_dispatch_all_messages (connection);
diff --git a/bus/dispatch.c b/bus/dispatch.c
index 639b9509..b4b03d96 100644
--- a/bus/dispatch.c
+++ b/bus/dispatch.c
@@ -365,7 +365,12 @@ bus_dispatch_add_connection (DBusConnection *connection)
return FALSE;
handler = dbus_message_handler_new (bus_dispatch_message_handler, NULL, NULL);
-
+ if (handler == NULL)
+ {
+ message_handler_slot_unref ();
+ return FALSE;
+ }
+
if (!dbus_connection_add_filter (connection, handler))
{
dbus_message_handler_unref (handler);
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;
}
diff --git a/bus/loop.h b/bus/loop.h
index 72b356b2..b217a776 100644
--- a/bus/loop.h
+++ b/bus/loop.h
@@ -26,11 +26,11 @@
#include <dbus/dbus.h>
-typedef void (* BusWatchFunction) (DBusWatch *watch,
- unsigned int condition,
- void *data);
-typedef void (* BusTimeoutFunction) (DBusTimeout *timeout,
- void *data);
+typedef dbus_bool_t (* BusWatchFunction) (DBusWatch *watch,
+ unsigned int condition,
+ void *data);
+typedef void (* BusTimeoutFunction) (DBusTimeout *timeout,
+ void *data);
dbus_bool_t bus_loop_add_watch (DBusWatch *watch,
BusWatchFunction function,
diff --git a/bus/test.c b/bus/test.c
index 09e40f34..7de1d811 100644
--- a/bus/test.c
+++ b/bus/test.c
@@ -35,18 +35,21 @@
*/
static DBusList *clients = NULL;
-static void
+static dbus_bool_t
client_watch_callback (DBusWatch *watch,
unsigned int condition,
void *data)
{
DBusConnection *connection = data;
-
+ dbus_bool_t retval;
+
dbus_connection_ref (connection);
- dbus_connection_handle_watch (connection, watch, condition);
+ retval = dbus_connection_handle_watch (connection, watch, condition);
dbus_connection_unref (connection);
+
+ return retval;
}
static dbus_bool_t
@@ -71,7 +74,8 @@ client_timeout_callback (DBusTimeout *timeout,
DBusConnection *connection = data;
dbus_connection_ref (connection);
-
+
+ /* can return FALSE on OOM but we just let it fire again later */
dbus_timeout_handle (timeout);
dbus_connection_unref (connection);
diff --git a/bus/utils.c b/bus/utils.c
index 8a68d8a4..090e27f0 100644
--- a/bus/utils.c
+++ b/bus/utils.c
@@ -28,18 +28,24 @@
const char bus_no_memory_message[] = "Memory allocation failure in message bus";
-void
-bus_wait_for_memory (void)
+int
+bus_get_oom_wait (void)
{
#ifdef DBUS_BUILD_TESTS
/* make tests go fast */
- _dbus_sleep_milliseconds (10);
+ return 10;
#else
- _dbus_sleep_milliseconds (500);
+ return 500;
#endif
}
void
+bus_wait_for_memory (void)
+{
+ _dbus_sleep_milliseconds (bus_get_oom_wait ());
+}
+
+void
bus_connection_dispatch_all_messages (DBusConnection *connection)
{
while (bus_connection_dispatch_one_message (connection))
diff --git a/bus/utils.h b/bus/utils.h
index 968ece37..5b30de60 100644
--- a/bus/utils.h
+++ b/bus/utils.h
@@ -27,6 +27,7 @@
#include <dbus/dbus.h>
+int bus_get_oom_wait (void);
void bus_wait_for_memory (void);
extern const char bus_no_memory_message[];