Commit 3bea9353 authored by Havoc Pennington's avatar Havoc Pennington

2003-03-13 Havoc Pennington <hp@redhat.com>

	* dbus/dbus-timeout.c (_dbus_timeout_list_set_functions): handle
	out of memory

	* dbus/dbus-watch.c (_dbus_watch_list_set_functions): handle out
	of memory

	* dbus/dbus-connection.h: Make AddWatchFunction and
	AddTimeoutFunction return a bool so they can fail on out-of-memory

	* bus/bus.c (bus_context_new): set up timeout handlers

	* bus/connection.c (bus_connections_setup_connection): set up
	timeout handlers

	* glib/dbus-gmain.c: adapt to the fact that set_functions stuff
	can fail

	* bus/bus.c (bus_context_new): adapt to changes

	* bus/connection.c: adapt to changes

	* test/watch.c: adapt to DBusWatch changes

	* bus/dispatch.c (bus_dispatch_test): started adding this but
	didn't finish
parent 81c30364
2003-03-13 Havoc Pennington <hp@redhat.com>
* dbus/dbus-timeout.c (_dbus_timeout_list_set_functions): handle
out of memory
* dbus/dbus-watch.c (_dbus_watch_list_set_functions): handle out
of memory
* dbus/dbus-connection.h: Make AddWatchFunction and
AddTimeoutFunction return a bool so they can fail on out-of-memory
* bus/bus.c (bus_context_new): set up timeout handlers
* bus/connection.c (bus_connections_setup_connection): set up
timeout handlers
* glib/dbus-gmain.c: adapt to the fact that set_functions stuff
can fail
* bus/bus.c (bus_context_new): adapt to changes
* bus/connection.c: adapt to changes
* test/watch.c: adapt to DBusWatch changes
* bus/dispatch.c (bus_dispatch_test): started adding this but
didn't finish
2003-03-14 Anders Carlsson <andersca@codefactory.se>
* bus/dispatch.c (send_service_nonexistent_error): Fix typo.
......
......@@ -60,7 +60,7 @@ noinst_PROGRAMS=$(TESTS)
bus_test_SOURCES= \
test-main.c
bus_test_LDADD= $(top_builddir)/dbus/libdbus-convenience.la libdbus-daemon.la
bus_test_LDADD= $(top_builddir)/dbus/libdbus-1.la libdbus-daemon.la
## mop up the gcov files
clean-local:
......
......@@ -49,12 +49,12 @@ server_watch_callback (DBusWatch *watch,
dbus_server_handle_watch (context->server, watch, condition);
}
static void
static dbus_bool_t
add_server_watch (DBusWatch *watch,
BusContext *context)
{
bus_loop_add_watch (watch, server_watch_callback, context,
NULL);
return bus_loop_add_watch (watch, server_watch_callback, context,
NULL);
}
static void
......@@ -64,6 +64,27 @@ remove_server_watch (DBusWatch *watch,
bus_loop_remove_watch (watch, server_watch_callback, context);
}
static void
server_timeout_callback (DBusTimeout *timeout,
void *data)
{
dbus_timeout_handle (timeout);
}
static dbus_bool_t
add_server_timeout (DBusTimeout *timeout,
BusContext *context)
{
return bus_loop_add_timeout (timeout, server_timeout_callback, context, NULL);
}
static void
remove_server_timeout (DBusTimeout *timeout,
BusContext *context)
{
bus_loop_remove_timeout (timeout, server_timeout_callback, context);
}
static void
new_connection_callback (DBusServer *server,
DBusConnection *new_connection,
......@@ -136,11 +157,24 @@ bus_context_new (const char *address,
new_connection_callback,
context, NULL);
dbus_server_set_watch_functions (context->server,
(DBusAddWatchFunction) add_server_watch,
(DBusRemoveWatchFunction) remove_server_watch,
context,
NULL);
if (!dbus_server_set_watch_functions (context->server,
(DBusAddWatchFunction) add_server_watch,
(DBusRemoveWatchFunction) remove_server_watch,
context,
NULL))
{
BUS_SET_OOM (error);
goto failed;
}
if (!dbus_server_set_timeout_functions (context->server,
(DBusAddTimeoutFunction) add_server_timeout,
(DBusRemoveTimeoutFunction) remove_server_timeout,
context, NULL))
{
BUS_SET_OOM (error);
goto failed;
}
return context;
......@@ -152,6 +186,22 @@ bus_context_new (const char *address,
void
bus_context_shutdown (BusContext *context)
{
if (context->server == NULL ||
!dbus_server_get_is_connected (context->server))
return;
if (!dbus_server_set_watch_functions (context->server,
NULL, NULL,
context,
NULL))
_dbus_assert_not_reached ("setting watch functions to NULL failed");
if (!dbus_server_set_timeout_functions (context->server,
NULL, NULL,
context,
NULL))
_dbus_assert_not_reached ("setting timeout functions to NULL failed");
dbus_server_disconnect (context->server);
}
......@@ -170,6 +220,8 @@ bus_context_unref (BusContext *context)
if (context->refcount == 0)
{
bus_context_shutdown (context);
if (context->registry)
bus_registry_unref (context->registry);
if (context->connections)
......
......@@ -108,11 +108,18 @@ bus_connection_disconnected (DBusConnection *connection)
bus_dispatch_remove_connection (connection);
/* no more watching */
dbus_connection_set_watch_functions (connection,
NULL, NULL,
connection,
NULL);
if (!dbus_connection_set_watch_functions (connection,
NULL, NULL,
connection,
NULL))
_dbus_assert_not_reached ("setting watch functions to NULL failed");
if (!dbus_connection_set_timeout_functions (connection,
NULL, NULL,
connection,
NULL))
_dbus_assert_not_reached ("setting timeout functions to NULL failed");
bus_connection_remove_transactions (connection);
_dbus_list_remove (&d->connections->list, connection);
......@@ -140,12 +147,12 @@ connection_watch_callback (DBusWatch *watch,
dbus_connection_unref (connection);
}
static void
static dbus_bool_t
add_connection_watch (DBusWatch *watch,
DBusConnection *connection)
{
bus_loop_add_watch (watch, connection_watch_callback, connection,
NULL);
return bus_loop_add_watch (watch, connection_watch_callback, connection,
NULL);
}
static void
......@@ -155,6 +162,27 @@ remove_connection_watch (DBusWatch *watch,
bus_loop_remove_watch (watch, connection_watch_callback, connection);
}
static void
connection_timeout_callback (DBusTimeout *timeout,
void *data)
{
dbus_timeout_handle (timeout);
}
static dbus_bool_t
add_connection_timeout (DBusTimeout *timeout,
DBusConnection *connection)
{
return bus_loop_add_timeout (timeout, connection_timeout_callback, connection, NULL);
}
static void
remove_connection_timeout (DBusTimeout *timeout,
DBusConnection *connection)
{
bus_loop_remove_timeout (timeout, connection_timeout_callback, connection);
}
static void
free_connection_data (void *data)
{
......@@ -249,18 +277,35 @@ bus_connections_setup_connection (BusConnections *connections,
dbus_connection_disconnect (connection);
return FALSE;
}
dbus_connection_ref (connection);
dbus_connection_set_watch_functions (connection,
(DBusAddWatchFunction) add_connection_watch,
(DBusRemoveWatchFunction) remove_connection_watch,
connection,
NULL);
if (!dbus_connection_set_watch_functions (connection,
(DBusAddWatchFunction) add_connection_watch,
(DBusRemoveWatchFunction) remove_connection_watch,
connection,
NULL))
{
dbus_connection_disconnect (connection);
return FALSE;
}
if (!dbus_connection_set_timeout_functions (connection,
(DBusAddTimeoutFunction) add_connection_timeout,
(DBusRemoveTimeoutFunction) remove_connection_timeout,
connection, NULL))
{
dbus_connection_disconnect (connection);
return FALSE;
}
/* Setup the connection with the dispatcher */
if (!bus_dispatch_add_connection (connection))
return FALSE;
{
dbus_connection_disconnect (connection);
return FALSE;
}
dbus_connection_ref (connection);
return TRUE;
}
......
......@@ -27,6 +27,7 @@
#include "services.h"
#include "utils.h"
#include "bus.h"
#include "test.h"
#include <dbus/dbus-internals.h>
#include <string.h>
......@@ -142,11 +143,9 @@ send_service_nonexistent_error (BusTransaction *transaction,
return TRUE;
}
static DBusHandlerResult
bus_dispatch_message_handler (DBusMessageHandler *handler,
DBusConnection *connection,
DBusMessage *message,
void *user_data)
static void
bus_dispatch (DBusConnection *connection,
DBusMessage *message)
{
const char *sender, *service_name, *message_name;
DBusError error;
......@@ -313,6 +312,15 @@ bus_dispatch_message_handler (DBusMessageHandler *handler,
}
dbus_connection_unref (connection);
}
static DBusHandlerResult
bus_dispatch_message_handler (DBusMessageHandler *handler,
DBusConnection *connection,
DBusMessage *message,
void *user_data)
{
bus_dispatch (connection, message);
return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
}
......@@ -361,3 +369,70 @@ bus_dispatch_remove_connection (DBusConnection *connection)
NULL, NULL);
}
#ifdef DBUS_BUILD_TESTS
static void
run_test_bus (BusContext *context)
{
}
static dbus_bool_t
check_hello_message (BusContext *context,
DBusConnection *connection)
{
DBusMessage *message;
dbus_int32_t serial;
message = dbus_message_new (DBUS_SERVICE_DBUS,
DBUS_MESSAGE_HELLO);
if (message == NULL)
_dbus_assert_not_reached ("no memory");
if (!dbus_connection_send (connection, message, &serial))
_dbus_assert_not_reached ("no memory");
return TRUE;
}
dbus_bool_t
bus_dispatch_test (const DBusString *test_data_dir)
{
BusContext *context;
DBusError error;
const char *activation_dirs[] = { NULL, NULL };
DBusConnection *foo;
DBusConnection *bar;
DBusConnection *baz;
DBusResultCode result;
return TRUE; /* FIXME */
dbus_error_init (&error);
context = bus_context_new ("debug:name=test-server",
activation_dirs,
&error);
if (context == NULL)
_dbus_assert_not_reached ("could not alloc context");
foo = dbus_connection_open ("debug:name=test-server", &result);
if (foo == NULL)
_dbus_assert_not_reached ("could not alloc connection");
bar = dbus_connection_open ("debug:name=test-server", &result);
if (bar == NULL)
_dbus_assert_not_reached ("could not alloc connection");
baz = dbus_connection_open ("debug:name=test-server", &result);
if (baz == NULL)
_dbus_assert_not_reached ("could not alloc connection");
return TRUE;
}
#endif /* DBUS_BUILD_TESTS */
......@@ -26,20 +26,46 @@
#include <dbus/dbus-list.h>
#include <dbus/dbus-sysdeps.h>
static DBusList *watches = NULL;
static int watch_list_serial = 0;
static DBusList *callbacks = NULL;
static int callback_list_serial = 0;
static int watch_count = 0;
static int timeout_count = 0;
static dbus_bool_t exited = FALSE;
typedef enum
{
CALLBACK_WATCH,
CALLBACK_TIMEOUT
} CallbackType;
typedef struct
{
DBusWatch *watch;
BusWatchFunction function;
CallbackType type;
void *data;
DBusFreeFunction free_data_func;
} Callback;
typedef struct
{
Callback callback;
BusWatchFunction function;
DBusWatch *watch;
} WatchCallback;
dbus_bool_t
bus_loop_add_watch (DBusWatch *watch,
typedef struct
{
Callback callback;
DBusTimeout *timeout;
BusTimeoutFunction function;
unsigned long last_tv_sec;
unsigned long last_tv_usec;
} TimeoutCallback;
#define WATCH_CALLBACK(callback) ((WatchCallback*)callback)
#define TIMEOUT_CALLBACK(callback) ((TimeoutCallback*)callback)
static WatchCallback*
watch_callback_new (DBusWatch *watch,
BusWatchFunction function,
void *data,
DBusFreeFunction free_data_func)
......@@ -48,20 +74,108 @@ bus_loop_add_watch (DBusWatch *watch,
cb = dbus_new (WatchCallback, 1);
if (cb == NULL)
return FALSE;
return NULL;
cb->watch = watch;
cb->function = function;
cb->data = data;
cb->free_data_func = free_data_func;
cb->callback.type = CALLBACK_WATCH;
cb->callback.data = data;
cb->callback.free_data_func = free_data_func;
return cb;
}
if (!_dbus_list_append (&watches, cb))
static TimeoutCallback*
timeout_callback_new (DBusTimeout *timeout,
BusTimeoutFunction function,
void *data,
DBusFreeFunction free_data_func)
{
TimeoutCallback *cb;
cb = dbus_new (TimeoutCallback, 1);
if (cb == NULL)
return NULL;
cb->timeout = timeout;
cb->function = function;
_dbus_get_current_time (&cb->last_tv_sec,
&cb->last_tv_usec);
cb->callback.type = CALLBACK_TIMEOUT;
cb->callback.data = data;
cb->callback.free_data_func = free_data_func;
return cb;
}
static void
callback_free (Callback *cb)
{
if (cb->free_data_func)
(* cb->free_data_func) (cb->data);
dbus_free (cb);
}
static dbus_bool_t
add_callback (Callback *cb)
{
if (!_dbus_list_append (&callbacks, cb))
return FALSE;
callback_list_serial += 1;
switch (cb->type)
{
dbus_free (cb);
return FALSE;
case CALLBACK_WATCH:
watch_count += 1;
break;
case CALLBACK_TIMEOUT:
timeout_count += 1;
break;
}
return TRUE;
}
static void
remove_callback (DBusList *link)
{
Callback *cb = link->data;
switch (cb->type)
{
case CALLBACK_WATCH:
watch_count -= 1;
break;
case CALLBACK_TIMEOUT:
timeout_count -= 1;
break;
}
callback_free (cb);
_dbus_list_remove_link (&callbacks, link);
callback_list_serial += 1;
}
dbus_bool_t
bus_loop_add_watch (DBusWatch *watch,
BusWatchFunction function,
void *data,
DBusFreeFunction free_data_func)
{
WatchCallback *wcb;
wcb = watch_callback_new (watch, function, data, free_data_func);
if (wcb == NULL)
return FALSE;
watch_list_serial += 1;
if (!add_callback ((Callback*) wcb))
{
wcb->callback.free_data_func = NULL; /* don't want to have this side effect */
callback_free ((Callback*) wcb);
return FALSE;
}
return TRUE;
}
......@@ -73,23 +187,18 @@ bus_loop_remove_watch (DBusWatch *watch,
{
DBusList *link;
link = _dbus_list_get_first_link (&watches);
link = _dbus_list_get_first_link (&callbacks);
while (link != NULL)
{
DBusList *next = _dbus_list_get_next_link (&watches, link);
WatchCallback *cb = link->data;
DBusList *next = _dbus_list_get_next_link (&callbacks, link);
Callback *this = link->data;
if (cb->watch == watch &&
cb->function == function &&
cb->data == data)
if (this->type == CALLBACK_WATCH &&
WATCH_CALLBACK (this)->watch == watch &&
this->data == data &&
WATCH_CALLBACK (this)->function == function)
{
_dbus_list_remove_link (&watches, link);
watch_list_serial += 1;
if (cb->free_data_func)
(* cb->free_data_func) (cb->data);
dbus_free (cb);
remove_callback (link);
return;
}
......@@ -101,6 +210,58 @@ bus_loop_remove_watch (DBusWatch *watch,
watch, function, data);
}
dbus_bool_t
bus_loop_add_timeout (DBusTimeout *timeout,
BusTimeoutFunction function,
void *data,
DBusFreeFunction free_data_func)
{
TimeoutCallback *tcb;
tcb = timeout_callback_new (timeout, function, data, free_data_func);
if (tcb == NULL)
return FALSE;
if (!add_callback ((Callback*) tcb))
{
tcb->callback.free_data_func = NULL; /* don't want to have this side effect */
callback_free ((Callback*) tcb);
return FALSE;
}
return TRUE;
}
void
bus_loop_remove_timeout (DBusTimeout *timeout,
BusTimeoutFunction function,
void *data)
{
DBusList *link;
link = _dbus_list_get_first_link (&callbacks);
while (link != NULL)
{
DBusList *next = _dbus_list_get_next_link (&callbacks, link);
Callback *this = link->data;
if (this->type == CALLBACK_TIMEOUT &&
TIMEOUT_CALLBACK (this)->timeout == timeout &&
this->data == data &&
TIMEOUT_CALLBACK (this)->function == function)
{
remove_callback (link);
return;
}
link = next;
}
_dbus_warn ("could not find timeout %p function %p data %p to remove\n",
timeout, function, data);
}
void
bus_loop_run (void)
{
......@@ -113,59 +274,187 @@ bus_loop_run (void)
DBusList *link;
int n_ready;
int initial_serial;
long timeout;
fds = NULL;
watches_for_fds = NULL;
n_fds = _dbus_list_get_length (&watches);
if (n_fds == 0)
if (callbacks == NULL)
{
bus_loop_quit ();
goto next_iteration;
}
fds = dbus_new0 (DBusPollFD, n_fds);
while (fds == NULL)
n_fds = watch_count;
if (n_fds > 0)
{
bus_wait_for_memory ();
fds = dbus_new0 (DBusPollFD, n_fds);
while (fds == NULL)
{
bus_wait_for_memory ();
fds = dbus_new0 (DBusPollFD, n_fds);
}
watches_for_fds = dbus_new (WatchCallback*, n_fds);
while (watches_for_fds == NULL)
{
bus_wait_for_memory ();
watches_for_fds = dbus_new (WatchCallback*, n_fds);
}