Commit 1cdadc2f authored by Daniel Stone's avatar Daniel Stone

Hotplug: Separate D-Bus into core and hotplug API components

Break up D-Bus into two components: a D-Bus core that can be used by any
part of the server (for the moment, just the D-Bus hotplug API, and the
forthcoming HAL hotplug API), and the old D-Bus hotplug API.
parent 8bfa41e1
AM_CFLAGS = @DIX_CFLAGS@
noinst_LIBRARIES = libconfig.a
libconfig_a_SOURCES = config.c
if HAVE_DBUS
AM_CFLAGS += @DBUS_CFLAGS@
libconfig_a_SOURCES += dbus-core.c
endif
if CONFIG_DBUS_API
dbusconfigdir = $(sysconfdir)/dbus-1/system.d
dbusconfig_DATA = xorg-server.conf
noinst_LIBRARIES = libconfig.a
libconfig_a_SOURCES = config.c
libconfig_a_SOURCES += dbus.c
endif
EXTRA_DIST = xorg-server.conf
/*
* Copyright © 2006-2007 Daniel Stone
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of the copyright holders and/or authors
* not be used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission. The copyright holders
* and/or authors make no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* THE COPYRIGHT HOLDERS AND/OR AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND/OR AUTHORS BE LIABLE
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#ifdef HAVE_DBUS
#include <dbus/dbus.h>
typedef void (*config_dbus_core_connect_hook)(DBusConnection *connection,
void *data);
typedef void (*config_dbus_core_disconnect_hook)(void *data);
struct config_dbus_core_hook {
config_dbus_core_connect_hook connect;
config_dbus_core_disconnect_hook disconnect;
void *data;
struct config_dbus_core_hook *next;
};
int config_dbus_core_init(void);
void config_dbus_core_fini(void);
int config_dbus_core_add_hook(struct config_dbus_core_hook *hook);
void config_dbus_core_remove_hook(struct config_dbus_core_hook *hook);
#endif
#ifdef CONFIG_DBUS_API
int config_dbus_init(void);
void config_dbus_fini(void);
#endif
This diff is collapsed.
/*
* Copyright © 2006-2007 Daniel Stone
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of the copyright holders and/or authors
* not be used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission. The copyright holders
* and/or authors make no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* THE COPYRIGHT HOLDERS AND/OR AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND/OR AUTHORS BE LIABLE
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#define DBUS_API_SUBJECT_TO_CHANGE
#include <dbus/dbus.h>
#include <sys/select.h>
#include "config-backends.h"
#include "dix.h"
#include "os.h"
/* How often to attempt reconnecting when we get booted off the bus. */
#define RECONNECT_DELAY (10 * 1000) /* in ms */
struct dbus_core_info {
int fd;
DBusConnection *connection;
OsTimerPtr timer;
struct config_dbus_core_hook *hooks;
};
static struct dbus_core_info bus_info;
static CARD32 reconnect_timer(OsTimerPtr timer, CARD32 time, pointer arg);
static void
wakeup_handler(pointer data, int err, pointer read_mask)
{
struct dbus_core_info *info = data;
if (info->connection && FD_ISSET(info->fd, (fd_set *) read_mask))
dbus_connection_read_write_dispatch(info->connection, 0);
}
static void
block_handler(pointer data, struct timeval **tv, pointer read_mask)
{
}
/**
* Disconnect (if we haven't already been forcefully disconnected), clean up
* after ourselves, and call all registered disconnect hooks.
*/
static void
teardown(void)
{
struct config_dbus_core_hook *hook;
if (bus_info.timer) {
TimerCancel(bus_info.timer);
bus_info.timer = NULL;
}
/* We should really have pre-disconnect hooks and run them here, for
* completeness. But then it gets awkward, given that you can't
* guarantee that they'll be called ... */
if (bus_info.connection)
dbus_connection_unref(bus_info.connection);
RemoveBlockAndWakeupHandlers(block_handler, wakeup_handler, &bus_info);
RemoveGeneralSocket(bus_info.fd);
bus_info.fd = -1;
bus_info.connection = NULL;
for (hook = bus_info.hooks; hook; hook = hook->next) {
if (hook->disconnect)
hook->disconnect(hook->data);
}
}
/**
* This is a filter, which only handles the disconnected signal, which
* doesn't go to the normal message handling function. This takes
* precedence over the message handling function, so have have to be
* careful to ignore anything we don't want to deal with here.
*/
static DBusHandlerResult
message_filter(DBusConnection *connection, DBusMessage *message, void *data)
{
/* If we get disconnected, then take everything down, and attempt to
* reconnect immediately (assuming it's just a restart). The
* connection isn't valid at this point, so throw it out immediately. */
if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL,
"Disconnected")) {
DebugF("[config/dbus-core] disconnected from bus\n");
bus_info.connection = NULL;
teardown();
bus_info.timer = TimerSet(NULL, 0, 1, reconnect_timer, NULL);
return DBUS_HANDLER_RESULT_HANDLED;
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
/**
* Attempt to connect to the system bus, and set a filter to deal with
* disconnection (see message_filter above).
*
* @return 1 on success, 0 on failure.
*/
static int
connect_to_bus(void)
{
DBusError error;
struct config_dbus_core_hook *hook;
dbus_error_init(&error);
bus_info.connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
if (!bus_info.connection || dbus_error_is_set(&error)) {
DebugF("[config/dbus-core] error connecting to system bus: %s (%s)\n",
error.name, error.message);
goto err_begin;
}
/* Thankyou. Really, thankyou. */
dbus_connection_set_exit_on_disconnect(bus_info.connection, FALSE);
if (!dbus_connection_get_unix_fd(bus_info.connection, &bus_info.fd)) {
ErrorF("[config/dbus-core] couldn't get fd for system bus\n");
goto err_unref;
}
if (!dbus_connection_add_filter(bus_info.connection, message_filter,
&bus_info, NULL)) {
ErrorF("[config/dbus-core] couldn't add filter: %s (%s)\n", error.name,
error.message);
goto err_fd;
}
dbus_error_free(&error);
AddGeneralSocket(bus_info.fd);
RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, &bus_info);
for (hook = bus_info.hooks; hook; hook = hook->next) {
if (hook->connect)
hook->connect(bus_info.connection, hook->data);
}
return 1;
err_fd:
bus_info.fd = -1;
err_unref:
dbus_connection_unref(bus_info.connection);
bus_info.connection = NULL;
err_begin:
dbus_error_free(&error);
return 0;
}
static CARD32
reconnect_timer(OsTimerPtr timer, CARD32 time, pointer arg)
{
if (connect_to_bus()) {
bus_info.timer = NULL;
return 0;
}
else {
return RECONNECT_DELAY;
}
}
int
config_dbus_core_add_hook(struct config_dbus_core_hook *hook)
{
struct config_dbus_core_hook **prev;
for (prev = &bus_info.hooks; *prev; prev = &(*prev)->next)
;
*prev = hook;
/* If we're already connected, call the connect hook. */
if (bus_info.connection)
hook->connect(bus_info.connection, hook->data);
return 1;
}
void
config_dbus_core_remove_hook(struct config_dbus_core_hook *hook)
{
struct config_dbus_core_hook **prev;
for (prev = &bus_info.hooks; *prev; prev = &(*prev)->next) {
if (*prev == hook)
*prev = hook->next;
}
}
int
config_dbus_core_init(void)
{
memset(&bus_info, 0, sizeof(bus_info));
bus_info.fd = -1;
bus_info.hooks = NULL;
bus_info.connection = NULL;
bus_info.timer = TimerSet(NULL, 0, 1, reconnect_timer, NULL);
return 1;
}
void
config_dbus_core_fini(void)
{
teardown();
}
This diff is collapsed.
......@@ -519,7 +519,7 @@ AC_ARG_ENABLE(fontcache, AS_HELP_STRING([--enable-fontcache], [Build FontCa
AC_ARG_ENABLE(dbe, AS_HELP_STRING([--disable-dbe], [Build DBE extension (default: enabled)]), [DBE=$enableval], [DBE=yes])
AC_ARG_ENABLE(xf86bigfont, AS_HELP_STRING([--disable-xf86bigfont], [Build XF86 Big Font extension (default: enabled)]), [XF86BIGFONT=$enableval], [XF86BIGFONT=yes])
AC_ARG_ENABLE(dpms, AS_HELP_STRING([--disable-dpms], [Build DPMS extension (default: enabled)]), [DPMSExtension=$enableval], [DPMSExtension=yes])
AC_ARG_ENABLE(dbus, AS_HELP_STRING([--disable-dbus], [Build D-BUS support (default: auto)]), [DBUS=$enableval], [DBUS=auto])
AC_ARG_ENABLE(config-dbus, AS_HELP_STRING([--disable-config-dbus], [Build D-BUS support (default: auto)]), [CONFIG_DBUS_API=$enableval], [CONFIG_DBUS_API=auto])
AC_ARG_ENABLE(xfree86-utils, AS_HELP_STRING([--enable-xfree86-utils], [Build xfree86 DDX utilities (default: enabled)]), [XF86UTILS=$enableval], [XF86UTILS=yes])
dnl DDXes.
......@@ -619,17 +619,32 @@ dnl Core modules for most extensions, et al.
REQUIRED_MODULES="[randrproto >= 1.2] renderproto [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto [xproto >= 7.0.9] xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4.2] [kbproto >= 1.0.3]"
REQUIRED_LIBS="xfont xau fontenc $PIXMAN"
if test "x$DBUS" = xauto; then
PKG_CHECK_MODULES(DBUS, dbus-1, [DBUS=yes], [DBUS=no])
dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config
dnl API.
PKG_CHECK_MODULES(DBUS, dbus-1, [HAVE_DBUS=yes], [HAVE_DBUS=no])
if test "x$HAVE_DBUS" = xyes; then
AC_DEFINE(HAVE_DBUS, 1, [Have D-Bus support])
fi
if test "x$DBUS" = xyes; then
PKG_CHECK_MODULES(DBUS, dbus-1)
AC_DEFINE(HAVE_DBUS, 1, [Have D-BUS support])
REQUIRED_MODULES="$REQUIRED_MODULES dbus-1"
REQUIRED_LIBS="$REQUIRED_LIBS dbus-1"
AM_CONDITIONAL(HAVE_DBUS, [test "x$HAVE_DBUS" = xyes])
if test "x$CONFIG_DBUS_API" = xauto; then
CONFIG_DBUS_API="$HAVE_DBUS"
fi
if test "x$CONFIG_DBUS_API" = xyes; then
if ! test "x$HAVE_DBUS" = xyes; then
AC_MSG_ERROR([D-Bus configuration API requested, but D-Bus is not installed.])
fi
AC_DEFINE(CONFIG_DBUS_API, 1, [Use the D-Bus input configuration API])
CONFIG_LIB='$(top_builddir)/config/libconfig.a'
NEED_DBUS="yes"
fi
AM_CONDITIONAL(CONFIG_DBUS_API, [test "x$CONFIG_DBUS_API" = xyes])
if test "x$NEED_DBUS" = xyes; then
REQUIRED_LIBS="$REQUIRED_LIBS dbus-1"
fi
CONFIG_LIB='$(top_builddir)/config/libconfig.a'
AM_CONDITIONAL(DBUS, [test "x$DBUS" = xyes])
AM_CONDITIONAL(XV, [test "x$XV" = xyes])
if test "x$XV" = xyes; then
......
......@@ -310,7 +310,7 @@ main(int argc, char *argv[], char *envp[])
InitBlockAndWakeupHandlers();
/* Perform any operating system dependent initializations you'd like */
OsInit();
configInitialise();
config_init();
if(serverGeneration == 1)
{
CreateWellKnownSockets();
......@@ -482,7 +482,7 @@ main(int argc, char *argv[], char *envp[])
FreeAllResources();
#endif
configFini();
config_fini();
CloseDownDevices();
for (i = screenInfo.numScreens - 1; i >= 0; i--)
{
......
......@@ -465,9 +465,12 @@
/* Define to 1 if modules should avoid the libcwrapper */
#undef NO_LIBCWRAPPER
/* Support D-BUS */
/* Support D-Bus */
#undef HAVE_DBUS
/* Support the D-Bus hotplug API */
#undef CONFIG_DBUS_API
/* Use only built-in fonts */
#undef BUILTIN_FONTS
......
/*
* Copyright © 2006 Daniel Stone
* Copyright © 2006-2007 Daniel Stone
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
......@@ -21,10 +21,10 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef CONFIG_H
#define CONFIG_H
#ifndef HOTPLUG_H
#define HOTPLUG_H
void configInitialise(void);
void configFini(void);
void config_init(void);
void config_fini(void);
#endif /* CONFIG_H */
#endif /* HOTPLUG_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment