Commit 1b080361 authored by Havoc Pennington's avatar Havoc Pennington

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

	* bus/loop.h, bus/loop.c: make the mainloop an object so we can
	have multiple ones

	* bus/*.[hc]: adapt to mainloop change
parent f216e814
2003-04-03 Havoc Pennington <hp@redhat.com>
* bus/loop.h, bus/loop.c: make the mainloop an object so we can
have multiple ones
* bus/*.[hc]: adapt to mainloop change
2003-04-03 Havoc Pennington <hp@redhat.com> 2003-04-03 Havoc Pennington <hp@redhat.com>
* bus/activation.c (load_directory): fix up memleaks * bus/activation.c (load_directory): fix up memleaks
......
...@@ -38,6 +38,7 @@ struct BusContext ...@@ -38,6 +38,7 @@ struct BusContext
int refcount; int refcount;
char *type; char *type;
char *address; char *address;
BusLoop *loop;
DBusList *servers; DBusList *servers;
BusConnections *connections; BusConnections *connections;
BusActivation *activation; BusActivation *activation;
...@@ -48,6 +49,68 @@ struct BusContext ...@@ -48,6 +49,68 @@ struct BusContext
DBusHashTable *rules_by_gid; /**< per-GID policy rules */ DBusHashTable *rules_by_gid; /**< per-GID policy rules */
}; };
static int server_data_slot = -1;
static int server_data_slot_refcount = 0;
typedef struct
{
BusContext *context;
} BusServerData;
#define BUS_SERVER_DATA(server) (dbus_server_get_data ((server), server_data_slot))
static dbus_bool_t
server_data_slot_ref (void)
{
if (server_data_slot < 0)
{
server_data_slot = dbus_server_allocate_data_slot ();
if (server_data_slot < 0)
return FALSE;
_dbus_assert (server_data_slot_refcount == 0);
}
server_data_slot_refcount += 1;
return TRUE;
}
static void
server_data_slot_unref (void)
{
_dbus_assert (server_data_slot_refcount > 0);
server_data_slot_refcount -= 1;
if (server_data_slot_refcount == 0)
{
dbus_server_free_data_slot (server_data_slot);
server_data_slot = -1;
}
}
static BusContext*
server_get_context (DBusServer *server)
{
BusContext *context;
BusServerData *bd;
if (!server_data_slot_ref ())
return NULL;
bd = BUS_SERVER_DATA (server);
if (bd == NULL)
return NULL;
context = bd->context;
server_data_slot_unref ();
return context;
}
static dbus_bool_t static dbus_bool_t
server_watch_callback (DBusWatch *watch, server_watch_callback (DBusWatch *watch,
unsigned int condition, unsigned int condition,
...@@ -62,7 +125,13 @@ static dbus_bool_t ...@@ -62,7 +125,13 @@ static dbus_bool_t
add_server_watch (DBusWatch *watch, add_server_watch (DBusWatch *watch,
void *data) void *data)
{ {
return bus_loop_add_watch (watch, server_watch_callback, data, DBusServer *server = data;
BusContext *context;
context = server_get_context (server);
return bus_loop_add_watch (context->loop,
watch, server_watch_callback, server,
NULL); NULL);
} }
...@@ -70,7 +139,13 @@ static void ...@@ -70,7 +139,13 @@ static void
remove_server_watch (DBusWatch *watch, remove_server_watch (DBusWatch *watch,
void *data) void *data)
{ {
bus_loop_remove_watch (watch, server_watch_callback, data); DBusServer *server = data;
BusContext *context;
context = server_get_context (server);
bus_loop_remove_watch (context->loop,
watch, server_watch_callback, server);
} }
...@@ -86,14 +161,26 @@ static dbus_bool_t ...@@ -86,14 +161,26 @@ static dbus_bool_t
add_server_timeout (DBusTimeout *timeout, add_server_timeout (DBusTimeout *timeout,
void *data) void *data)
{ {
return bus_loop_add_timeout (timeout, server_timeout_callback, data, NULL); DBusServer *server = data;
BusContext *context;
context = server_get_context (server);
return bus_loop_add_timeout (context->loop,
timeout, server_timeout_callback, server, NULL);
} }
static void static void
remove_server_timeout (DBusTimeout *timeout, remove_server_timeout (DBusTimeout *timeout,
void *data) void *data)
{ {
bus_loop_remove_timeout (timeout, server_timeout_callback, data); DBusServer *server = data;
BusContext *context;
context = server_get_context (server);
bus_loop_remove_timeout (context->loop,
timeout, server_timeout_callback, server);
} }
static void static void
...@@ -139,12 +226,22 @@ free_rule_list_func (void *data) ...@@ -139,12 +226,22 @@ free_rule_list_func (void *data)
dbus_free (list); dbus_free (list);
} }
static void
free_server_data (void *data)
{
BusServerData *bd = data;
dbus_free (bd);
}
static dbus_bool_t static dbus_bool_t
setup_server (BusContext *context, setup_server (BusContext *context,
DBusServer *server, DBusServer *server,
char **auth_mechanisms, char **auth_mechanisms,
DBusError *error) DBusError *error)
{ {
BusServerData *bd;
if (!dbus_server_set_auth_mechanisms (server, (const char**) auth_mechanisms)) if (!dbus_server_set_auth_mechanisms (server, (const char**) auth_mechanisms))
{ {
BUS_SET_OOM (error); BUS_SET_OOM (error);
...@@ -175,7 +272,18 @@ setup_server (BusContext *context, ...@@ -175,7 +272,18 @@ setup_server (BusContext *context,
BUS_SET_OOM (error); BUS_SET_OOM (error);
return FALSE; return FALSE;
} }
bd = dbus_new0 (BusServerData, 1);
if (!dbus_server_set_data (server,
server_data_slot,
bd, free_server_data))
{
dbus_free (bd);
return FALSE;
}
bd->context = context;
return TRUE; return TRUE;
} }
...@@ -196,8 +304,18 @@ bus_context_new (const DBusString *config_file, ...@@ -196,8 +304,18 @@ bus_context_new (const DBusString *config_file,
_DBUS_ASSERT_ERROR_IS_CLEAR (error); _DBUS_ASSERT_ERROR_IS_CLEAR (error);
if (!_dbus_string_init (&full_address)) if (!_dbus_string_init (&full_address))
return NULL; {
BUS_SET_OOM (error);
return NULL;
}
if (!server_data_slot_ref ())
{
BUS_SET_OOM (error);
_dbus_string_free (&full_address);
return NULL;
}
parser = NULL; parser = NULL;
context = NULL; context = NULL;
auth_mechanisms = NULL; auth_mechanisms = NULL;
...@@ -215,6 +333,13 @@ bus_context_new (const DBusString *config_file, ...@@ -215,6 +333,13 @@ bus_context_new (const DBusString *config_file,
context->refcount = 1; context->refcount = 1;
context->loop = bus_loop_new ();
if (context->loop == NULL)
{
BUS_SET_OOM (error);
goto failed;
}
/* Build an array of auth mechanisms */ /* Build an array of auth mechanisms */
auth_mechanisms_list = bus_config_parser_get_mechanisms (parser); auth_mechanisms_list = bus_config_parser_get_mechanisms (parser);
...@@ -401,6 +526,9 @@ bus_context_new (const DBusString *config_file, ...@@ -401,6 +526,9 @@ bus_context_new (const DBusString *config_file,
_dbus_string_free (&full_address); _dbus_string_free (&full_address);
dbus_free_string_array (auth_mechanisms); dbus_free_string_array (auth_mechanisms);
server_data_slot_unref ();
return NULL; return NULL;
} }
...@@ -501,9 +629,17 @@ bus_context_unref (BusContext *context) ...@@ -501,9 +629,17 @@ bus_context_unref (BusContext *context)
context->rules_by_gid = NULL; context->rules_by_gid = NULL;
} }
if (context->loop)
{
bus_loop_unref (context->loop);
context->loop = NULL;
}
dbus_free (context->type); dbus_free (context->type);
dbus_free (context->address); dbus_free (context->address);
dbus_free (context); dbus_free (context);
server_data_slot_unref ();
} }
} }
...@@ -532,6 +668,12 @@ bus_context_get_activation (BusContext *context) ...@@ -532,6 +668,12 @@ bus_context_get_activation (BusContext *context)
return context->activation; return context->activation;
} }
BusLoop*
bus_context_get_loop (BusContext *context)
{
return context->loop;
}
static dbus_bool_t static dbus_bool_t
list_allows_user (dbus_bool_t def, list_allows_user (dbus_bool_t def,
DBusList **list, DBusList **list,
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#include <dbus/dbus.h> #include <dbus/dbus.h>
#include <dbus/dbus-string.h> #include <dbus/dbus-string.h>
#include "loop.h"
typedef struct BusActivation BusActivation; typedef struct BusActivation BusActivation;
typedef struct BusConnections BusConnections; typedef struct BusConnections BusConnections;
typedef struct BusContext BusContext; typedef struct BusContext BusContext;
...@@ -47,6 +49,7 @@ const char* bus_context_get_type (BusContext *context) ...@@ -47,6 +49,7 @@ const char* bus_context_get_type (BusContext *context)
BusRegistry* bus_context_get_registry (BusContext *context); BusRegistry* bus_context_get_registry (BusContext *context);
BusConnections* bus_context_get_connections (BusContext *context); BusConnections* bus_context_get_connections (BusContext *context);
BusActivation* bus_context_get_activation (BusContext *context); BusActivation* bus_context_get_activation (BusContext *context);
BusLoop* bus_context_get_loop (BusContext *context);
dbus_bool_t bus_context_allow_user (BusContext *context, dbus_bool_t bus_context_allow_user (BusContext *context,
unsigned long uid); unsigned long uid);
BusPolicy* bus_context_create_connection_policy (BusContext *context, BusPolicy* bus_context_create_connection_policy (BusContext *context,
......
...@@ -89,6 +89,16 @@ connection_data_slot_unref (void) ...@@ -89,6 +89,16 @@ connection_data_slot_unref (void)
} }
} }
static BusLoop*
connection_get_loop (DBusConnection *connection)
{
BusConnectionData *d;
d = BUS_CONNECTION_DATA (connection);
return bus_context_get_loop (d->connections->context);
}
void void
bus_connection_disconnected (DBusConnection *connection) bus_connection_disconnected (DBusConnection *connection)
{ {
...@@ -195,17 +205,23 @@ connection_watch_callback (DBusWatch *watch, ...@@ -195,17 +205,23 @@ connection_watch_callback (DBusWatch *watch,
static dbus_bool_t static dbus_bool_t
add_connection_watch (DBusWatch *watch, add_connection_watch (DBusWatch *watch,
DBusConnection *connection) void *data)
{ {
return bus_loop_add_watch (watch, connection_watch_callback, connection, DBusConnection *connection = data;
return bus_loop_add_watch (connection_get_loop (connection),
watch, connection_watch_callback, connection,
NULL); NULL);
} }
static void static void
remove_connection_watch (DBusWatch *watch, remove_connection_watch (DBusWatch *watch,
DBusConnection *connection) void *data)
{ {
bus_loop_remove_watch (watch, connection_watch_callback, connection); DBusConnection *connection = data;
bus_loop_remove_watch (connection_get_loop (connection),
watch, connection_watch_callback, connection);
} }
static void static void
...@@ -226,16 +242,22 @@ connection_timeout_callback (DBusTimeout *timeout, ...@@ -226,16 +242,22 @@ connection_timeout_callback (DBusTimeout *timeout,
static dbus_bool_t static dbus_bool_t
add_connection_timeout (DBusTimeout *timeout, add_connection_timeout (DBusTimeout *timeout,
DBusConnection *connection) void *data)
{ {
return bus_loop_add_timeout (timeout, connection_timeout_callback, connection, NULL); DBusConnection *connection = data;
return bus_loop_add_timeout (connection_get_loop (connection),
timeout, connection_timeout_callback, connection, NULL);
} }
static void static void
remove_connection_timeout (DBusTimeout *timeout, remove_connection_timeout (DBusTimeout *timeout,
DBusConnection *connection) void *data)
{ {
bus_loop_remove_timeout (timeout, connection_timeout_callback, connection); DBusConnection *connection = data;
bus_loop_remove_timeout (connection_get_loop (connection),
timeout, connection_timeout_callback, connection);
} }
static dbus_bool_t static dbus_bool_t
...@@ -366,16 +388,16 @@ bus_connections_setup_connection (BusConnections *connections, ...@@ -366,16 +388,16 @@ bus_connections_setup_connection (BusConnections *connections,
d->group_ids = NULL; d->group_ids = NULL;
if (!dbus_connection_set_watch_functions (connection, if (!dbus_connection_set_watch_functions (connection,
(DBusAddWatchFunction) add_connection_watch, add_connection_watch,
(DBusRemoveWatchFunction) remove_connection_watch, remove_connection_watch,
NULL, NULL,
connection, connection,
NULL)) NULL))
goto out; goto out;
if (!dbus_connection_set_timeout_functions (connection, if (!dbus_connection_set_timeout_functions (connection,
(DBusAddTimeoutFunction) add_connection_timeout, add_connection_timeout,
(DBusRemoveTimeoutFunction) remove_connection_timeout, remove_connection_timeout,
NULL, NULL,
connection, NULL)) connection, NULL))
goto out; goto out;
...@@ -400,12 +422,7 @@ bus_connections_setup_connection (BusConnections *connections, ...@@ -400,12 +422,7 @@ bus_connections_setup_connection (BusConnections *connections,
out: out:
if (!retval) if (!retval)
{ {
if (!dbus_connection_set_data (connection,
connection_data_slot,
NULL, NULL))
_dbus_assert_not_reached ("failed to set connection data to null");
if (!dbus_connection_set_watch_functions (connection, if (!dbus_connection_set_watch_functions (connection,
NULL, NULL, NULL, NULL, NULL, NULL,
connection, connection,
...@@ -420,6 +437,11 @@ bus_connections_setup_connection (BusConnections *connections, ...@@ -420,6 +437,11 @@ bus_connections_setup_connection (BusConnections *connections,
dbus_connection_set_unix_user_function (connection, dbus_connection_set_unix_user_function (connection,
NULL, NULL, NULL); NULL, NULL, NULL);
if (!dbus_connection_set_data (connection,
connection_data_slot,
NULL, NULL))
_dbus_assert_not_reached ("failed to set connection data to null");
} }
return retval; return retval;
......
...@@ -537,8 +537,8 @@ kill_client_connection (BusContext *context, ...@@ -537,8 +537,8 @@ kill_client_connection (BusContext *context,
/* kick in the disconnect handler that unrefs the connection */ /* kick in the disconnect handler that unrefs the connection */
dbus_connection_disconnect (connection); dbus_connection_disconnect (connection);
bus_test_flush_bus (context); bus_test_run_everything (context);
_dbus_assert (bus_test_client_listed (connection)); _dbus_assert (bus_test_client_listed (connection));
/* Run disconnect handler in test.c */ /* Run disconnect handler in test.c */
...@@ -729,8 +729,8 @@ check_hello_message (BusContext *context, ...@@ -729,8 +729,8 @@ check_hello_message (BusContext *context,
dbus_message_unref (message); dbus_message_unref (message);
message = NULL; message = NULL;
bus_test_flush_bus (context); bus_test_run_everything (context);
if (!dbus_connection_get_is_connected (connection)) if (!dbus_connection_get_is_connected (connection))
{ {
...@@ -963,8 +963,8 @@ check_nonexistent_service_activation (BusContext *context, ...@@ -963,8 +963,8 @@ check_nonexistent_service_activation (BusContext *context,
dbus_message_unref (message); dbus_message_unref (message);
message = NULL; message = NULL;
bus_test_flush_bus (context); bus_test_run_everything (context);
if (!dbus_connection_get_is_connected (connection)) if (!dbus_connection_get_is_connected (connection))
{ {
...@@ -1028,6 +1028,116 @@ check_nonexistent_service_activation (BusContext *context, ...@@ -1028,6 +1028,116 @@ check_nonexistent_service_activation (BusContext *context,
return retval; return retval;
} }
#define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"
/* returns TRUE if the correct thing happens,
* but the correct thing may include OOM errors.
*/
static dbus_bool_t
check_existent_service_activation (BusContext *context,
DBusConnection *connection)
{
DBusMessage *message;
dbus_int32_t serial;
dbus_bool_t retval;
DBusError error;
dbus_error_init (&error);
message = dbus_message_new (DBUS_SERVICE_DBUS,
DBUS_MESSAGE_ACTIVATE_SERVICE);
if (message == NULL)
return TRUE;
if (!dbus_message_append_args (message,
DBUS_TYPE_STRING, EXISTENT_SERVICE_NAME,
DBUS_TYPE_UINT32, 0,
DBUS_TYPE_INVALID))
{
dbus_message_unref (message);
return TRUE;
}
if (!dbus_connection_send (connection, message, &serial))
{
dbus_message_unref (message);
return TRUE;
}
dbus_message_unref (message);
message = NULL;
bus_test_run_everything (context);
/* now wait for the message bus to hear back from the activated service */
bus_test_run_bus_loop (context);
/* and process everything again */
bus_test_run_everything (context);
if (!dbus_connection_get_is_connected (connection))
{
_dbus_verbose ("connection was disconnected\n");
return TRUE;
}
retval = FALSE;
message = dbus_connection_pop_message (connection);
if (message == NULL)
{
_dbus_warn ("Did not receive a reply to %s %d on %p\n",
DBUS_MESSAGE_ACTIVATE_SERVICE, serial, connection);
goto out;
}
_dbus_verbose ("Received %s on %p\n",
dbus_message_get_name (message), connection);
if (dbus_message_get_is_error (message))
{
if (!dbus_message_sender_is (message, DBUS_SERVICE_DBUS))
{
_dbus_warn ("Message has wrong sender %s\n",
dbus_message_get_sender (message) ?
dbus_message_get_sender (message) : "(none)");
goto out;
}
if (dbus_message_name_is (message,
DBUS_ERROR_NO_MEMORY))