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 */
This diff is collapsed.
......@@ -26,19 +26,29 @@
#include <dbus/dbus.h>
typedef void (* BusWatchFunction) (DBusWatch *watch,
unsigned int condition,
void *data);
typedef void (* 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,
void *data,
DBusFreeFunction free_data_func);
void bus_loop_remove_watch (DBusWatch *watch,
BusWatchFunction function,
void *data);
dbus_bool_t bus_loop_add_timeout (DBusTimeout *timeout,
BusTimeoutFunction function,
void *data,
DBusFreeFunction free_data_func);
void bus_loop_remove_timeout (DBusTimeout *timeout,
BusTimeoutFunction function,
void *data);
void bus_loop_run (void);
void bus_loop_quit (void);
dbus_bool_t bus_loop_add_watch (DBusWatch *watch,
BusWatchFunction function,
void *data,
DBusFreeFunction free_data_func);
void bus_loop_remove_watch (DBusWatch *watch,
BusWatchFunction function,
void *data);
void bus_loop_run (void);
void bus_loop_quit (void);
#endif /* BUS_LOOP_H */
......@@ -22,16 +22,41 @@
*/
#include "test.h"
#include <stdio.h>
#include <stdlib.h>
#include <dbus/dbus-string.h>
#include <dbus/dbus-sysdeps.h>
static void
die (const char *failure)
{
fprintf (stderr, "Unit test failed: %s\n", failure);
exit (1);
}
int
main (int argc, char **argv)
{
#ifdef DBUS_BUILD_TESTS
const char *dir;
DBusString test_data_dir;
if (argc > 1)
dir = argv[1];
else
dir = _dbus_getenv ("DBUS_TEST_DATA");
if (dir == NULL)
dir = "";
_dbus_string_init_const (&test_data_dir, dir);
if (!bus_dispatch_test (&test_data_dir))
die ("dispatch");
return 0;
#else /* DBUS_BUILD_TESTS */
return 0;
#endif
}
......@@ -31,7 +31,7 @@
#include <dbus/dbus.h>
#include <dbus/dbus-string.h>
dbus_bool_t bus_test_foo (const DBusString *test_data_dir);
dbus_bool_t bus_dispatch_test (const DBusString *test_data_dir);
#endif
......
......@@ -1810,31 +1810,44 @@ dbus_connection_dispatch_message (DBusConnection *connection)
*
* It is not allowed to reference a DBusWatch after it has been passed
* to remove_function.
*
* If #FALSE is returned due to lack of memory, the failure may be due
* to a #FALSE return from the new add_function. If so, the
* add_function may have been called successfully one or more times,
* but the remove_function will also have been called to remove any
* successful adds. i.e. if #FALSE is returned the net result
* should be that dbus_connection_set_watch_functions() has no effect,
* but the add_function and remove_function may have been called.
*
* @param connection the connection.
* @param add_function function to begin monitoring a new descriptor.
* @param remove_function function to stop monitoring a descriptor.
* @param data data to pass to add_function and remove_function.
* @param free_data_function function to be called to free the data.
* @returns #FALSE on failure (no memory)
*/
void
dbus_bool_t
dbus_connection_set_watch_functions (DBusConnection *connection,
DBusAddWatchFunction add_function,
DBusRemoveWatchFunction remove_function,
void *data,
DBusFreeFunction free_data_function)
{
dbus_bool_t retval;
dbus_mutex_lock (connection->mutex);
/* ref connection for slightly better reentrancy */
_dbus_connection_ref_unlocked (connection);
_dbus_watch_list_set_functions (connection->watches,
add_function, remove_function,
data, free_data_function);
retval = _dbus_watch_list_set_functions (connection->watches,
add_function, remove_function,
data, free_data_function);
dbus_mutex_unlock (connection->mutex);
/* drop our paranoid refcount */
dbus_connection_unref (connection);
return retval;
}
/**
......@@ -1855,25 +1868,30 @@ dbus_connection_set_watch_functions (DBusConnection *connection,
* @param remove_function function to remove a timeout.
* @param data data to pass to add_function and remove_function.
* @param free_data_function function to be called to free the data.
* @returns #FALSE on failure (no memory)
*/
void
dbus_bool_t
dbus_connection_set_timeout_functions (DBusConnection *connection,
DBusAddTimeoutFunction add_function,
DBusRemoveTimeoutFunction remove_function,
void *data,
DBusFreeFunction free_data_function)
{
dbus_bool_t retval;
dbus_mutex_lock (connection->mutex);
/* ref connection for slightly better reentrancy */
_dbus_connection_ref_unlocked (connection);
_dbus_timeout_list_set_functions (connection->timeouts,
add_function, remove_function,
data, free_data_function);
retval = _dbus_timeout_list_set_functions (connection->timeouts,
add_function, remove_function,
data, free_data_function);
dbus_mutex_unlock (connection->mutex);
/* drop our paranoid refcount */
dbus_connection_unref (connection);
dbus_connection_unref (connection);
return retval;
}
/**
......
......@@ -56,17 +56,15 @@ typedef enum
* can be present in current state). */
} DBusWatchFlags;
typedef void (* DBusAddWatchFunction) (DBusWatch *watch,
void *data);
typedef void (* DBusRemoveWatchFunction) (DBusWatch *watch,
void *data);
typedef void (* DBusWakeupMainFunction) (void *data);
typedef void (* DBusAddTimeoutFunction) (DBusTimeout *timeout,
void *data);
typedef void (* DBusRemoveTimeoutFunction) (DBusTimeout *timeout,
void *data);
typedef dbus_bool_t (* DBusAddWatchFunction) (DBusWatch *watch,
void *data);
typedef void (* DBusRemoveWatchFunction) (DBusWatch *watch,
void *data);
typedef void (* DBusWakeupMainFunction) (void *data);
typedef dbus_bool_t (* DBusAddTimeoutFunction) (DBusTimeout *timeout,
void *data);
typedef void (* DBusRemoveTimeoutFunction) (DBusTimeout *timeout,
void *data);
DBusConnection* dbus_connection_open (const char *address,
DBusResultCode *result);
......@@ -99,24 +97,24 @@ DBusMessage *dbus_connection_send_with_reply_and_block (DBusConnection *conn
DBusError *error);
dbus_bool_t dbus_connection_set_watch_functions (DBusConnection *connection,
DBusAddWatchFunction add_function,
DBusRemoveWatchFunction remove_function,
void *data,
DBusFreeFunction free_data_function);
dbus_bool_t dbus_connection_set_timeout_functions (DBusConnection *connection,
DBusAddTimeoutFunction add_function,
DBusRemoveTimeoutFunction remove_function,
void *data,
DBusFreeFunction free_data_function);
void dbus_connection_set_wakeup_main_function (DBusConnection *connection,
DBusWakeupMainFunction wakeup_main_function,
void *data,
DBusFreeFunction free_data_function);
void dbus_connection_handle_watch (DBusConnection *connection,
DBusWatch *watch,
unsigned int condition);
void dbus_connection_set_watch_functions (DBusConnection *connection,
DBusAddWatchFunction add_function,
DBusRemoveWatchFunction remove_function,
void *data,
DBusFreeFunction free_data_function);
void dbus_connection_set_timeout_functions (DBusConnection *connection,
DBusAddTimeoutFunction add_function,
DBusRemoveTimeoutFunction remove_function,
void *data,
DBusFreeFunction free_data_function);
void dbus_connection_set_wakeup_main_function (DBusConnection *connection,
DBusWakeupMainFunction wakeup_main_function,
void *data,
DBusFreeFunction free_data_function);
void dbus_connection_handle_watch (DBusConnection *connection,
DBusWatch *watch,
unsigned int condition);
......
......@@ -392,19 +392,20 @@ dbus_server_set_new_connection_function (DBusServer *server,
* @param remove_function function to stop monitoring a descriptor.
* @param data data to pass to add_function and remove_function.
* @param free_data_function function to be called to free the data.
* @returns #FALSE on failure (no memory)
*/
void
dbus_bool_t
dbus_server_set_watch_functions (DBusServer *server,
DBusAddWatchFunction add_function,
DBusRemoveWatchFunction remove_function,
void *data,
DBusFreeFunction free_data_function)
{
_dbus_watch_list_set_functions (server->watches,
add_function,
remove_function,
data,
free_data_function);
return _dbus_watch_list_set_functions (server->watches,
add_function,
remove_function,
data,
free_data_function);
}
/**
......@@ -419,17 +420,18 @@ dbus_server_set_watch_functions (DBusServer *server,
* @param remove_function function to remove a timeout.
* @param data data to pass to add_function and remove_function.
* @param free_data_function function to be called to free the data.
* @returns #FALSE on failure (no memory)
*/
void
dbus_bool_t
dbus_server_set_timeout_functions (DBusServer *server,
DBusAddTimeoutFunction add_function,
DBusRemoveTimeoutFunction remove_function,
void *data,
DBusFreeFunction free_data_function)
{
_dbus_timeout_list_set_functions (server->timeouts,
add_function, remove_function,
data, free_data_function);
return _dbus_timeout_list_set_functions (server->timeouts,
add_function, remove_function,
data, free_data_function);
}
/**
......
......@@ -45,31 +45,28 @@ void dbus_server_ref (DBusServer *server);
void dbus_server_unref (DBusServer *server);
void dbus_server_disconnect (DBusServer *server);
dbus_bool_t dbus_server_get_is_connected (DBusServer *server);
void dbus_server_set_new_connection_function (DBusServer *server,
DBusNewConnectionFunction function,
void *data,
DBusFreeFunction free_data_function);
dbus_bool_t dbus_server_set_watch_functions (DBusServer *server,
DBusAddWatchFunction add_function,
DBusRemoveWatchFunction remove_function,
void *data,
DBusFreeFunction free_data_function);
dbus_bool_t dbus_server_set_timeout_functions (DBusServer *server,
DBusAddTimeoutFunction add_function,
DBusRemoveTimeoutFunction remove_function,
void *data,
DBusFreeFunction free_data_function);
void dbus_server_handle_watch (DBusServer *server,
DBusWatch *watch,
unsigned int condition);
void dbus_server_set_max_connections (DBusServer *server,
int max_connections);
int dbus_server_get_max_connections (DBusServer *server);
int dbus_server_get_n_connections (DBusServer *server);
void dbus_server_set_new_connection_function (DBusServer *server,
DBusNewConnectionFunction function,
void *data,
DBusFreeFunction free_data_function);
void dbus_server_set_watch_functions (DBusServer *server,
DBusAddWatchFunction add_function,
DBusRemoveWatchFunction remove_function,
void *data,
DBusFreeFunction free_data_function);
void dbus_server_set_timeout_functions (DBusServer *server,
DBusAddTimeoutFunction add_function,
DBusRemoveTimeoutFunction remove_function,
void *data,
DBusFreeFunction free_data_function);
void dbus_server_handle_watch (DBusServer *server,
DBusWatch *watch,
unsigned int condition);
void dbus_server_set_max_connections (DBusServer *server,
int max_connections);
int dbus_server_get_max_connections (DBusServer *server);
int dbus_server_get_n_connections (DBusServer *server);
int dbus_server_allocate_data_slot (void);
void dbus_server_free_data_slot (int slot);
......
......@@ -181,15 +181,50 @@ _dbus_timeout_list_free (DBusTimeoutList *timeout_list)
* @param remove_function the remove timeout function.
* @param data the data for those functions.
* @param free_data_function the function to free the data.
* @returns #FALSE if no memory
*
*/
void
dbus_bool_t
_dbus_timeout_list_set_functions (DBusTimeoutList *timeout_list,
DBusAddTimeoutFunction add_function,
DBusRemoveTimeoutFunction remove_function,
void *data,
DBusFreeFunction free_data_function)
{
/* Add timeouts with the new function, failing on OOM */
if (add_function != NULL)
{
DBusList *link;
link = _dbus_list_get_first_link (&timeout_list->timeouts);
while (link != NULL)
{
DBusList *next = _dbus_list_get_next_link (&timeout_list->timeouts,
link);
if (!(* add_function) (link->data, data))
{
/* remove it all again and return FALSE */
DBusList *link2;
link2 = _dbus_list_get_first_link (&timeout_list->timeouts);