hal: Branch 'origin' - 12 commits

Richard Hughes hughsient at kemper.freedesktop.org
Tue Oct 10 10:19:11 PDT 2006


 doc/TODO              |   35 +
 hald-runner/main.c    |    4 
 hald/Makefile.am      |    2 
 hald/debug-hald.sh    |   10 
 hald/device.c         | 1085 ++++++++++++++++++++++++++++----------------------
 hald/device.h         |   89 +---
 hald/device_info.c    |   37 -
 hald/device_store.c   |  129 -----
 hald/device_store.h   |    7 
 hald/dummy/osspec.c   |    2 
 hald/hald.c           |   99 +++-
 hald/hald.h           |    2 
 hald/hald_dbus.c      |  246 +++++------
 hald/hald_dbus.h      |    1 
 hald/hald_runner.c    |  147 ++++--
 hald/hald_runner.h    |    4 
 hald/ids.c            |    3 
 hald/linux/acpi.c     |   20 
 hald/linux/apm.c      |    6 
 hald/linux/blockdev.c |   31 -
 hald/linux/classdev.c |   52 +-
 hald/linux/coldplug.c |   39 +
 hald/linux/hotplug.c  |   21 
 hald/linux/hotplug.h  |    2 
 hald/linux/osspec.c   |    6 
 hald/linux/physdev.c  |   37 -
 hald/linux/pmu.c      |    8 
 hald/property.c       |  490 ----------------------
 hald/property.h       |  103 ----
 hald/run-hald.sh      |   10 
 hald/util.c           |   26 -
 hald/valgrind-hald.sh |   10 
 32 files changed, 1189 insertions(+), 1574 deletions(-)

New commits:
diff-tree dbffafacbf7b9143d82547b9eabe61d1a5b8fffc (from 1b5448d2f839f889da56d348990fdbcb0e6d038a)
Author: David Zeuthen <davidz at redhat.com>
Date:   Tue Oct 10 00:51:27 2006 -0400

    move property code into device object core

diff --git a/hald/Makefile.am b/hald/Makefile.am
index 5c8ba4e..1f804e1 100644
--- a/hald/Makefile.am
+++ b/hald/Makefile.am
@@ -21,7 +21,6 @@ INCLUDES = \
 #	device_info.h			device_info.c			\
 #	device_store.h			device_store.c			\
 #	logger.h			logger.c			\
-#	property.h			property.c                      \
 #	hald_dbus.h			hald_dbus.c			\
 #	hald_test.c							\
 #	hald_test_libhal.c
@@ -50,7 +49,6 @@ hald_SOURCES =                          
 	hald_dbus.h			hald_dbus.c			\
 	logger.h			logger.c			\
 	osspec.h							\
-	property.h			property.c			\
 	ids.h				ids.c			
 
 hald_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ -lm @EXPAT_LIB@ $(top_builddir)/hald/$(HALD_BACKEND)/libhald_$(HALD_BACKEND).la
diff --git a/hald/device.c b/hald/device.c
index e258f1d..15b0d8f 100644
--- a/hald/device.c
+++ b/hald/device.c
@@ -33,11 +33,318 @@
 
 #include "hald.h"
 #include "device.h"
-#include "property.h"
 #include "hald_marshal.h"
 #include "logger.h"
 #include "hald_runner.h"
 
+
+struct _HalProperty {
+	int type;
+	union {
+		char *str_value;
+		dbus_int32_t int_value;
+ 		dbus_uint64_t uint64_value;
+		dbus_bool_t bool_value;
+		double double_value;
+		GSList *strlist_value;
+	} v;
+};
+typedef struct _HalProperty HalProperty;
+
+static inline void
+hal_property_free (HalProperty *prop)
+{
+	if (prop->type == HAL_PROPERTY_TYPE_STRING) {
+		g_free (prop->v.str_value);
+	} else if (prop->type == HAL_PROPERTY_TYPE_STRLIST) {
+		GSList *i;
+		for (i = prop->v.strlist_value; i != NULL; i = g_slist_next (i)) {
+			g_free (i->data);
+		}
+		g_slist_free (prop->v.strlist_value);
+	}
+	g_free (prop);
+}
+
+static inline HalProperty *
+hal_property_new (int type)
+{
+	HalProperty *prop;
+	prop = g_new0 (HalProperty, 1);
+	prop->type = type;
+	return prop;
+}
+
+static inline int
+hal_property_get_type (HalProperty *prop)
+{
+	g_return_val_if_fail (prop != NULL, HAL_PROPERTY_TYPE_INVALID);
+	return prop->type;
+}
+
+static inline const char *
+hal_property_get_string (HalProperty *prop)
+{
+	g_return_val_if_fail (prop != NULL, NULL);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRING, NULL);
+	return prop->v.str_value;
+}
+
+static inline dbus_int32_t
+hal_property_get_int (HalProperty *prop)
+{
+	g_return_val_if_fail (prop != NULL, -1);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_INT32, -1);
+	return prop->v.int_value;
+}
+
+static inline dbus_uint64_t
+hal_property_get_uint64 (HalProperty *prop)
+{
+	g_return_val_if_fail (prop != NULL, -1);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_UINT64, -1);
+	return prop->v.uint64_value;
+}
+
+static inline dbus_bool_t
+hal_property_get_bool (HalProperty *prop)
+{
+	g_return_val_if_fail (prop != NULL, FALSE);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_BOOLEAN, FALSE);
+	return prop->v.bool_value;
+}
+
+static inline GSList *
+hal_property_get_strlist (HalProperty *prop)
+{
+	g_return_val_if_fail (prop != NULL, NULL);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, NULL);
+
+	return prop->v.strlist_value;
+}
+
+static inline char *
+hal_property_to_string (HalProperty *prop)
+{
+	g_return_val_if_fail (prop != NULL, NULL);
+
+	switch (prop->type) {
+	case HAL_PROPERTY_TYPE_STRING:
+		return g_strdup (prop->v.str_value);
+	case HAL_PROPERTY_TYPE_INT32:
+		return g_strdup_printf ("%d", prop->v.int_value);
+	case HAL_PROPERTY_TYPE_UINT64:
+		return g_strdup_printf ("%llu", (long long unsigned int) prop->v.uint64_value);
+	case HAL_PROPERTY_TYPE_BOOLEAN:
+		/* FIXME: Maybe use 1 and 0 here instead? */
+		return g_strdup (prop->v.bool_value ? "true" : "false");
+	case HAL_PROPERTY_TYPE_DOUBLE:
+		return g_strdup_printf ("%f", prop->v.double_value);
+	case HAL_PROPERTY_TYPE_STRLIST:
+	{
+		GSList *iter;
+		guint i;
+		char buf[256];
+		
+		i = 0;
+		buf[0] = '\0';
+		for (iter = hal_property_get_strlist (prop); 
+		     iter != NULL && i < sizeof(buf); 
+		     iter = g_slist_next (iter)) {
+			guint len;
+			const char *str;
+			
+			str = (const char *) iter->data;
+			len = strlen (str);
+			strncpy (buf + i, str, sizeof(buf) - i);
+			i += len;
+			
+			if (g_slist_next (iter) != NULL && i < sizeof(buf)) {
+				buf[i] = '\t';
+				i++;
+			}
+		}
+		return g_strdup (buf);
+	}
+
+	default:
+		return NULL;
+	}
+}
+
+static inline double
+hal_property_get_double (HalProperty *prop)
+{
+	g_return_val_if_fail (prop != NULL, -1.0);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_DOUBLE, -1.0);
+
+	return prop->v.double_value;
+}
+
+static inline void
+hal_property_set_string (HalProperty *prop, const char *value)
+{
+	char *endchar;
+	gboolean validated = TRUE;
+
+	g_return_if_fail (prop != NULL);
+	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_STRING ||
+			  prop->type == HAL_PROPERTY_TYPE_INVALID);
+
+	prop->type = HAL_PROPERTY_TYPE_STRING;
+	if (prop->v.str_value != NULL)
+		g_free (prop->v.str_value);
+	prop->v.str_value = g_strdup (value);
+
+	while (!g_utf8_validate (prop->v.str_value, -1,
+				 (const char **) &endchar)) {
+		validated = FALSE;
+		*endchar = '?';
+	}
+
+	if (!validated) {
+		HAL_WARNING (("Property has invalid UTF-8 string '%s'", value));
+	}
+}
+
+static inline void
+hal_property_set_int (HalProperty *prop, dbus_int32_t value)
+{
+	g_return_if_fail (prop != NULL);
+	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_INT32 ||
+			  prop->type == HAL_PROPERTY_TYPE_INVALID);
+	prop->type = HAL_PROPERTY_TYPE_INT32;
+	prop->v.int_value = value;
+}
+
+static inline void
+hal_property_set_uint64 (HalProperty *prop, dbus_uint64_t value)
+{
+	g_return_if_fail (prop != NULL);
+	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_UINT64 ||
+			  prop->type == HAL_PROPERTY_TYPE_INVALID);
+	prop->type = HAL_PROPERTY_TYPE_UINT64;
+	prop->v.uint64_value = value;
+}
+
+static inline void
+hal_property_set_bool (HalProperty *prop, dbus_bool_t value)
+{
+	g_return_if_fail (prop != NULL);
+	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_BOOLEAN ||
+			  prop->type == HAL_PROPERTY_TYPE_INVALID);
+	prop->type = HAL_PROPERTY_TYPE_BOOLEAN;
+	prop->v.bool_value = value;
+}
+
+static inline void
+hal_property_set_double (HalProperty *prop, double value)
+{
+	g_return_if_fail (prop != NULL);
+	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_DOUBLE ||
+			  prop->type == HAL_PROPERTY_TYPE_INVALID);
+	prop->type = HAL_PROPERTY_TYPE_DOUBLE;
+	prop->v.double_value = value;
+}
+
+static inline gboolean
+hal_property_strlist_append (HalProperty *prop, const char *value)
+{
+	g_return_val_if_fail (prop != NULL, FALSE);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
+
+	prop->v.strlist_value = g_slist_append (prop->v.strlist_value, g_strdup (value));
+
+	return TRUE;
+}
+
+static inline gboolean
+hal_property_strlist_prepend (HalProperty *prop, const char *value)
+{
+	g_return_val_if_fail (prop != NULL, FALSE);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
+
+	prop->v.strlist_value = g_slist_prepend (prop->v.strlist_value, g_strdup (value));
+
+	return TRUE;
+}
+
+static inline gboolean
+hal_property_strlist_remove_elem (HalProperty *prop, guint index)
+{
+	GSList *elem;
+
+	g_return_val_if_fail (prop != NULL, FALSE);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
+
+	if (prop->v.strlist_value == NULL)
+		return FALSE;
+
+	elem = g_slist_nth (prop->v.strlist_value, index);
+	if (elem == NULL)
+		return FALSE;
+
+	g_free (elem->data);
+	prop->v.strlist_value = g_slist_delete_link (prop->v.strlist_value, elem);
+	return TRUE;
+}
+
+
+static inline gboolean 
+hal_property_strlist_add (HalProperty  *prop, const char *value)
+{
+	GSList *elem;
+
+	g_return_val_if_fail (prop != NULL, FALSE);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
+
+	for (elem = prop->v.strlist_value; elem != NULL; elem = g_slist_next (elem)) {
+		if (strcmp (elem->data, value) == 0) {
+			return FALSE;
+		}
+	}
+
+	return hal_property_strlist_append (prop, value);
+}
+
+static inline gboolean 
+hal_property_strlist_remove (HalProperty *prop, const char *value)
+{
+	guint i;
+	GSList *elem;
+
+	g_return_val_if_fail (prop != NULL, FALSE);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
+
+	for (elem = prop->v.strlist_value, i = 0; elem != NULL; elem = g_slist_next (elem), i++) {
+		if (strcmp (elem->data, value) == 0) {
+			return hal_property_strlist_remove_elem (prop, i);
+		}
+	}
+
+	return FALSE;
+}
+
+static inline gboolean 
+hal_property_strlist_clear (HalProperty *prop)
+{
+	GSList *elem;
+
+	g_return_val_if_fail (prop != NULL, FALSE);
+	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
+
+	for (elem = prop->v.strlist_value; elem != NULL; elem = g_slist_next (elem)) {
+		g_free (elem->data);
+	}
+	g_slist_free (prop->v.strlist_value);
+
+	return FALSE;
+}
+
+
+
+/****************************************************************************************************************/
+
 static GObjectClass *parent_class;
 
 struct _HalDevicePrivate
diff --git a/hald/property.c b/hald/property.c
deleted file mode 100644
index 9455418..0000000
--- a/hald/property.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/***************************************************************************
- * CVSID: $Id$
- *
- * property.c : HalProperty methods
- *
- * Copyright (C) 2003 David Zeuthen, <david at fubar.dk>
- * Copyright (C) 2004 Novell, Inc.
- *
- * Licensed under the Academic Free License version 2.1
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- **************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include <string.h>
-#include <glib.h>
-
-#include "device.h"
-#include "logger.h"
-#include "property.h"
-
-struct _HalProperty {
-	int type;
-	union {
-		char *str_value;
-		dbus_int32_t int_value;
- 		dbus_uint64_t uint64_value;
-		dbus_bool_t bool_value;
-		double double_value;
-		GSList *strlist_value;
-	} v;
-};
-
-void
-hal_property_free (HalProperty *prop)
-{
-	if (prop->type == HAL_PROPERTY_TYPE_STRING) {
-		g_free (prop->v.str_value);
-	} else if (prop->type == HAL_PROPERTY_TYPE_STRLIST) {
-		GSList *i;
-		for (i = prop->v.strlist_value; i != NULL; i = g_slist_next (i)) {
-			g_free (i->data);
-		}
-		g_slist_free (prop->v.strlist_value);
-	}
-	g_free (prop);
-}
-
-HalProperty *
-hal_property_new (int type)
-{
-	HalProperty *prop;
-	prop = g_new0 (HalProperty, 1);
-	prop->type = type;
-	return prop;
-}
-
-int
-hal_property_get_type (HalProperty *prop)
-{
-	g_return_val_if_fail (prop != NULL, HAL_PROPERTY_TYPE_INVALID);
-	return prop->type;
-}
-
-const char *
-hal_property_get_string (HalProperty *prop)
-{
-	g_return_val_if_fail (prop != NULL, NULL);
-	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRING, NULL);
-	return prop->v.str_value;
-}
-
-dbus_int32_t
-hal_property_get_int (HalProperty *prop)
-{
-	g_return_val_if_fail (prop != NULL, -1);
-	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_INT32, -1);
-	return prop->v.int_value;
-}
-
-dbus_uint64_t
-hal_property_get_uint64 (HalProperty *prop)
-{
-	g_return_val_if_fail (prop != NULL, -1);
-	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_UINT64, -1);
-	return prop->v.uint64_value;
-}
-
-dbus_bool_t
-hal_property_get_bool (HalProperty *prop)
-{
-	g_return_val_if_fail (prop != NULL, FALSE);
-	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_BOOLEAN, FALSE);
-	return prop->v.bool_value;
-}
-
-char *
-hal_property_to_string (HalProperty *prop)
-{
-	g_return_val_if_fail (prop != NULL, NULL);
-
-	switch (prop->type) {
-	case HAL_PROPERTY_TYPE_STRING:
-		return g_strdup (prop->v.str_value);
-	case HAL_PROPERTY_TYPE_INT32:
-		return g_strdup_printf ("%d", prop->v.int_value);
-	case HAL_PROPERTY_TYPE_UINT64:
-		return g_strdup_printf ("%llu", (long long unsigned int) prop->v.uint64_value);
-	case HAL_PROPERTY_TYPE_BOOLEAN:
-		/* FIXME: Maybe use 1 and 0 here instead? */
-		return g_strdup (prop->v.bool_value ? "true" : "false");
-	case HAL_PROPERTY_TYPE_DOUBLE:
-		return g_strdup_printf ("%f", prop->v.double_value);
-	case HAL_PROPERTY_TYPE_STRLIST:
-	{
-		GSList *iter;
-		guint i;
-		char buf[256];
-		
-		i = 0;
-		buf[0] = '\0';
-		for (iter = hal_property_get_strlist (prop); 
-		     iter != NULL && i < sizeof(buf); 
-		     iter = g_slist_next (iter)) {
-			guint len;
-			const char *str;
-			
-			str = (const char *) iter->data;
-			len = strlen (str);
-			strncpy (buf + i, str, sizeof(buf) - i);
-			i += len;
-			
-			if (g_slist_next (iter) != NULL && i < sizeof(buf)) {
-				buf[i] = '\t';
-				i++;
-			}
-		}
-		return g_strdup (buf);
-	}
-
-	default:
-		return NULL;
-	}
-}
-
-double
-hal_property_get_double (HalProperty *prop)
-{
-	g_return_val_if_fail (prop != NULL, -1.0);
-	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_DOUBLE, -1.0);
-
-	return prop->v.double_value;
-}
-
-void
-hal_property_set_string (HalProperty *prop, const char *value)
-{
-	char *endchar;
-	gboolean validated = TRUE;
-
-	g_return_if_fail (prop != NULL);
-	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_STRING ||
-			  prop->type == HAL_PROPERTY_TYPE_INVALID);
-
-	prop->type = HAL_PROPERTY_TYPE_STRING;
-	if (prop->v.str_value != NULL)
-		g_free (prop->v.str_value);
-	prop->v.str_value = g_strdup (value);
-
-	while (!g_utf8_validate (prop->v.str_value, -1,
-				 (const char **) &endchar)) {
-		validated = FALSE;
-		*endchar = '?';
-	}
-
-	if (!validated) {
-		HAL_WARNING (("Property has invalid UTF-8 string '%s'", value));
-	}
-}
-
-void
-hal_property_set_int (HalProperty *prop, dbus_int32_t value)
-{
-	g_return_if_fail (prop != NULL);
-	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_INT32 ||
-			  prop->type == HAL_PROPERTY_TYPE_INVALID);
-	prop->type = HAL_PROPERTY_TYPE_INT32;
-	prop->v.int_value = value;
-}
-
-void
-hal_property_set_uint64 (HalProperty *prop, dbus_uint64_t value)
-{
-	g_return_if_fail (prop != NULL);
-	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_UINT64 ||
-			  prop->type == HAL_PROPERTY_TYPE_INVALID);
-	prop->type = HAL_PROPERTY_TYPE_UINT64;
-	prop->v.uint64_value = value;
-}
-
-void
-hal_property_set_bool (HalProperty *prop, dbus_bool_t value)
-{
-	g_return_if_fail (prop != NULL);
-	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_BOOLEAN ||
-			  prop->type == HAL_PROPERTY_TYPE_INVALID);
-	prop->type = HAL_PROPERTY_TYPE_BOOLEAN;
-	prop->v.bool_value = value;
-}
-
-void
-hal_property_set_double (HalProperty *prop, double value)
-{
-	g_return_if_fail (prop != NULL);
-	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_DOUBLE ||
-			  prop->type == HAL_PROPERTY_TYPE_INVALID);
-	prop->type = HAL_PROPERTY_TYPE_DOUBLE;
-	prop->v.double_value = value;
-}
-
-GSList *
-hal_property_get_strlist (HalProperty *prop)
-{
-	g_return_val_if_fail (prop != NULL, NULL);
-	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, NULL);
-
-	return prop->v.strlist_value;
-}
-
-gboolean
-hal_property_strlist_append (HalProperty *prop, const char *value)
-{
-	g_return_val_if_fail (prop != NULL, FALSE);
-	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
-
-	prop->v.strlist_value = g_slist_append (prop->v.strlist_value, g_strdup (value));
-
-	return TRUE;
-}
-
-gboolean
-hal_property_strlist_prepend (HalProperty *prop, const char *value)
-{
-	g_return_val_if_fail (prop != NULL, FALSE);
-	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
-
-	prop->v.strlist_value = g_slist_prepend (prop->v.strlist_value, g_strdup (value));
-
-	return TRUE;
-}
-
-gboolean
-hal_property_strlist_remove_elem (HalProperty *prop, guint index)
-{
-	GSList *elem;
-
-	g_return_val_if_fail (prop != NULL, FALSE);
-	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
-
-	if (prop->v.strlist_value == NULL)
-		return FALSE;
-
-	elem = g_slist_nth (prop->v.strlist_value, index);
-	if (elem == NULL)
-		return FALSE;
-
-	g_free (elem->data);
-	prop->v.strlist_value = g_slist_delete_link (prop->v.strlist_value, elem);
-	return TRUE;
-}
-
-
-gboolean 
-hal_property_strlist_add (HalProperty  *prop, const char *value)
-{
-	GSList *elem;
-
-	g_return_val_if_fail (prop != NULL, FALSE);
-	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
-
-	for (elem = prop->v.strlist_value; elem != NULL; elem = g_slist_next (elem)) {
-		if (strcmp (elem->data, value) == 0) {
-			return FALSE;
-		}
-	}
-
-	return hal_property_strlist_append (prop, value);
-}
-
-gboolean 
-hal_property_strlist_remove (HalProperty *prop, const char *value)
-{
-	guint i;
-	GSList *elem;
-
-	g_return_val_if_fail (prop != NULL, FALSE);
-	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
-
-	for (elem = prop->v.strlist_value, i = 0; elem != NULL; elem = g_slist_next (elem), i++) {
-		if (strcmp (elem->data, value) == 0) {
-			return hal_property_strlist_remove_elem (prop, i);
-		}
-	}
-
-	return FALSE;
-}
-
-gboolean 
-hal_property_strlist_clear (HalProperty *prop)
-{
-	GSList *elem;
-
-	g_return_val_if_fail (prop != NULL, FALSE);
-	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRLIST, FALSE);
-
-	for (elem = prop->v.strlist_value; elem != NULL; elem = g_slist_next (elem)) {
-		g_free (elem->data);
-	}
-	g_slist_free (prop->v.strlist_value);
-
-	return FALSE;
-}
diff --git a/hald/property.h b/hald/property.h
deleted file mode 100644
index 8a8f78e..0000000
--- a/hald/property.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/***************************************************************************
- * CVSID: $Id$
- *
- * property.c : HalProperty methods
- *
- * Copyright (C) 2003 David Zeuthen, <david at fubar.dk>
- * Copyright (C) 2004 Novell, Inc.
- *
- * Licensed under the Academic Free License version 2.1
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- **************************************************************************/
-
-#ifndef PROPERTY_H
-#define PROPERTY_H
-
-#include <dbus/dbus.h>
-
-typedef struct _HalProperty HalProperty;
-
-void          hal_property_free               (HalProperty  *prop);
-
-HalProperty *hal_property_new                 (int type);
-
-int           hal_property_get_type           (HalProperty  *prop);
-char         *hal_property_to_string          (HalProperty  *prop);
-
-const char   *hal_property_get_string         (HalProperty  *prop);
-dbus_int32_t  hal_property_get_int            (HalProperty  *prop);
-dbus_uint64_t hal_property_get_uint64         (HalProperty  *prop);
-dbus_bool_t   hal_property_get_bool           (HalProperty  *prop);
-double        hal_property_get_double         (HalProperty  *prop);
-GSList       *hal_property_get_strlist        (HalProperty  *prop);
-
-void          hal_property_set_string          (HalProperty  *prop, const char   *value);
-void          hal_property_set_int             (HalProperty  *prop, dbus_int32_t  value);
-void          hal_property_set_uint64          (HalProperty  *prop, dbus_uint64_t value);
-void          hal_property_set_bool            (HalProperty  *prop, dbus_bool_t   value);
-void          hal_property_set_double          (HalProperty  *prop, double        value);
-gboolean      hal_property_strlist_append      (HalProperty  *prop, const char   *value);
-gboolean      hal_property_strlist_prepend     (HalProperty  *prop, const char   *value);
-gboolean      hal_property_strlist_remove_elem (HalProperty  *prop, guint index);
-
-gboolean      hal_property_strlist_add        (HalProperty  *prop, const char *value);
-gboolean      hal_property_strlist_remove     (HalProperty  *prop, const char *value);
-gboolean      hal_property_strlist_clear      (HalProperty  *prop);
-
-#endif /* PROPERTY_H */
diff-tree 1b5448d2f839f889da56d348990fdbcb0e6d038a (from 826d5da730f5323d29ff6eea6f92dd5fade66c48)
Author: David Zeuthen <davidz at redhat.com>
Date:   Tue Oct 10 00:19:55 2006 -0400

    removed unneeded and fragile async matching from device store

diff --git a/hald/device_store.c b/hald/device_store.c
index 1515450..7c06aab 100644
--- a/hald/device_store.c
+++ b/hald/device_store.c
@@ -364,130 +364,3 @@ hal_device_store_match_multiple_key_valu
 
 	return matches;
 }
-
-typedef struct {
-	HalDeviceStore *store;
-	char *key;
-	char *value;
-	HalDeviceStoreAsyncCallback callback;
-	gpointer user_data;
-
-	guint prop_signal_id;
-	guint store_signal_id;
-	guint timeout_id;
-} AsyncMatchInfo;
-
-static void
-destroy_async_match_info (AsyncMatchInfo *info)
-{
-	g_object_unref (info->store);
-
-	g_free (info->key);
-	g_free (info->value);
-
-	g_signal_handler_disconnect (info->store, info->prop_signal_id);
-	g_signal_handler_disconnect (info->store, info->store_signal_id);
-	g_source_remove (info->timeout_id);
-
-	g_free (info);
-}
-
-static void
-match_device_async (HalDeviceStore *store, HalDevice *device,
-		    const char *key, gboolean removed, gboolean added,
-		    gpointer user_data)
-{
-	AsyncMatchInfo *info = (AsyncMatchInfo *) user_data;
-
-	/* Only want to do it for added or changed properties */
-	if (removed)
-		return;
-
-	/* Keys have to match */
-	if (strcmp (info->key, key) != 0)
-		return;
-
-	/* Values have to match */
-	if (strcmp (hal_device_property_get_string (device, key),
-		    info->value) != 0)
-		return;
-
-	info->callback (store, device, info->user_data);
-
-	destroy_async_match_info (info);
-}
-
-static void
-store_changed (HalDeviceStore *store, HalDevice *device,
-	       gboolean added, gpointer user_data)
-{
-	AsyncMatchInfo *info = (AsyncMatchInfo *) user_data;
-
-	if (!added)
-		return;
-
-	if (!hal_device_has_property (device, info->key))
-		return;
-
-	if (strcmp (hal_device_property_get_string (device, info->key),
-		    info->value) != 0)
-		return;
-
-	info->callback (store, device, info->user_data);
-
-	destroy_async_match_info (info);
-}
-
-static gboolean
-match_device_async_timeout (gpointer user_data)
-{
-	AsyncMatchInfo *info = (AsyncMatchInfo *) user_data;
-
-	info->callback (info->store, NULL, info->user_data);
-
-	destroy_async_match_info (info);
-
-	return FALSE;
-}
-
-void
-hal_device_store_match_key_value_string_async (HalDeviceStore *store,
-					       const char *key,
-					       const char *value,
-					       HalDeviceStoreAsyncCallback callback,
-					       gpointer user_data,
-					       int timeout)
-{
-	HalDevice *device;
-	AsyncMatchInfo *info;
-
-	/* First check to see if it's already there */
-	device = hal_device_store_match_key_value_string (store, key, value);
-
-	if (device != NULL || timeout == 0) {
-		callback (store, device, user_data);
-
-		return;
-	}
-
-	info = g_new0 (AsyncMatchInfo, 1);
-
-	info->store = g_object_ref (store);
-	info->key = g_strdup (key);
-	info->value = g_strdup (value);
-	info->callback = callback;
-	info->user_data = user_data;
-
-	info->prop_signal_id = g_signal_connect (store,
-						 "device_property_changed",
-						 G_CALLBACK (match_device_async),
-						 info);
-	info->store_signal_id = g_signal_connect (store,
-						  "store_changed",
-						  G_CALLBACK (store_changed),
-						  info);
-
-	info->timeout_id = g_timeout_add (timeout,
-					  match_device_async_timeout,
-					  info);
-}
diff --git a/hald/device_store.h b/hald/device_store.h
index 6a03ea8..0e1578a 100644
--- a/hald/device_store.h
+++ b/hald/device_store.h
@@ -109,13 +109,6 @@ GSList         *hal_device_store_match_m
 								  const char *key,
 								  const char *value);
 
-void           hal_device_store_match_key_value_string_async (HalDeviceStore *store,
-							      const char *key,
-							      const char *value,
-							      HalDeviceStoreAsyncCallback callback,
-							      gpointer user_data,
-							      int timeout);
-
 void hal_device_store_print (HalDeviceStore *store);
 
 
diff-tree 826d5da730f5323d29ff6eea6f92dd5fade66c48 (from 63a3628bc3f4af4f5cf647dd11fd47a1992491ee)
Author: David Zeuthen <davidz at redhat.com>
Date:   Tue Oct 10 00:14:41 2006 -0400

    implement missing functions after move to hash table properties

diff --git a/hald/device.c b/hald/device.c
index ad47464..e258f1d 100644
--- a/hald/device.c
+++ b/hald/device.c
@@ -175,6 +175,85 @@ hal_device_new (void)
 	return device;
 }
 
+static inline HalProperty *
+hal_device_property_find (HalDevice *device, const char *key)
+{
+	g_return_val_if_fail (device != NULL, NULL);
+	g_return_val_if_fail (key != NULL, NULL);
+
+	return g_hash_table_lookup (device->private->props, key);
+}
+
+typedef struct 
+{
+	HalDevice *target;
+	const char *source_namespace;
+	const char *target_namespace;
+	size_t source_ns_len;
+} merge_rewrite_ud_t;
+
+static void
+merge_device_rewrite_cb (HalDevice *source,
+			 const char *key,
+			 gpointer user_data)
+{
+	int type;
+	merge_rewrite_ud_t *ud;
+	HalProperty *p;
+	int target_type;
+	gchar *target_key;
+
+	ud = (merge_rewrite_ud_t *) user_data;
+
+	/* only care about properties that match source namespace */
+	if (strncmp(key, ud->source_namespace, ud->source_ns_len) != 0)
+		goto out;
+	
+	target_key = g_strdup_printf("%s%s", ud->target_namespace, key + ud->source_ns_len);
+
+	type = hal_device_property_get_type (source, key);
+
+	p = hal_device_property_find (source, key);
+
+	/* only remove target if it exists with a different type */
+	target_type = hal_device_property_get_type (ud->target, target_key);
+	if (target_type != HAL_PROPERTY_TYPE_INVALID && target_type != type) {
+		hal_device_property_remove (ud->target, target_key);
+	}
+
+	switch (type) {
+	case HAL_PROPERTY_TYPE_STRING:
+		hal_device_property_set_string (ud->target, target_key, hal_property_get_string (p));
+		break;
+		
+	case HAL_PROPERTY_TYPE_INT32:
+		hal_device_property_set_int (ud->target, target_key, hal_property_get_int (p));
+		break;
+		
+	case HAL_PROPERTY_TYPE_UINT64:
+		hal_device_property_set_uint64 (ud->target, target_key, hal_property_get_uint64 (p));
+		break;
+		
+	case HAL_PROPERTY_TYPE_BOOLEAN:
+		hal_device_property_set_bool (ud->target, target_key, hal_property_get_bool (p));
+		break;
+		
+	case HAL_PROPERTY_TYPE_DOUBLE:
+		hal_device_property_set_double (ud->target, target_key, hal_property_get_double (p));
+		break;
+
+	/* TODO: handle strlist */
+		
+	default:
+		HAL_WARNING (("Unknown property type %d", type));
+		break;
+	}
+
+	g_free (target_key);
+out:
+	;
+}
+
 /** Merge all properties from source where the key starts with 
  *  source_namespace and put them onto target replacing source_namespace
  *  with target_namespace
@@ -190,91 +269,19 @@ hal_device_merge_with_rewrite  (HalDevic
 				const char   *target_namespace,
 				const char   *source_namespace)
 {
-#if 0
-#warning FIXME
-	GSList *iter;
-	size_t source_ns_len;
-
-	source_ns_len = strlen (source_namespace);
+	merge_rewrite_ud_t ud;
 
-	/* doesn't handle info.capabilities */
+	ud.target = target;
+	ud.source_namespace = source_namespace;
+	ud.target_namespace = target_namespace;
+	ud.source_ns_len = strlen (source_namespace);
 
+	/* doesn't handle info.capabilities - TODO: should use atomic update? */
 	/* device_property_atomic_update_begin (); */
 
-	for (iter = source->private->properties; iter != NULL; iter = iter->next) {
-		HalProperty *p = iter->data;
-		int type;
-		const char *key;
-		int target_type;
-		gchar *target_key;
-
-		key = hal_property_get_key (p);
-
-		/* only care about properties that match source namespace */
-		if (strncmp(key, source_namespace, source_ns_len) != 0)
-			continue;
-
-		target_key = g_strdup_printf("%s%s", target_namespace,
-					     key+source_ns_len);
-
-		type = hal_property_get_type (p);
-
-		/* only remove target if it exists with a different type */
-		target_type = hal_device_property_get_type (target, key);
-		if (target_type != HAL_PROPERTY_TYPE_INVALID && target_type != type)
-			hal_device_property_remove (target, key);
-
-		switch (type) {
-
-		case HAL_PROPERTY_TYPE_STRING:
-			hal_device_property_set_string (
-				target, target_key,
-				hal_property_get_string (p));
-			break;
-
-		case HAL_PROPERTY_TYPE_INT32:
-			hal_device_property_set_int (
-				target, target_key,
-				hal_property_get_int (p));
-			break;
-
-		case HAL_PROPERTY_TYPE_UINT64:
-			hal_device_property_set_uint64 (
-				target, target_key,
-				hal_property_get_uint64 (p));
-			break;
-
-		case HAL_PROPERTY_TYPE_BOOLEAN:
-			hal_device_property_set_bool (
-				target, target_key,
-				hal_property_get_bool (p));
-			break;
-
-		case HAL_PROPERTY_TYPE_DOUBLE:
-			hal_device_property_set_double (
-				target, target_key,
-				hal_property_get_double (p));
-			break;
-
-		default:
-			HAL_WARNING (("Unknown property type %d", type));
-			break;
-		}
-
-		g_free (target_key);
-	}
+	hal_device_property_foreach (source, merge_device_rewrite_cb, &ud);
 
 	/* device_property_atomic_update_end (); */
-#endif
-}
-
-static inline HalProperty *
-hal_device_property_find (HalDevice *device, const char *key)
-{
-	g_return_val_if_fail (device != NULL, NULL);
-	g_return_val_if_fail (key != NULL, NULL);
-
-	return g_hash_table_lookup (device->private->props, key);
 }
 
 static inline GSList *
@@ -381,83 +388,6 @@ out:
 	return strv;	
 }
 
-
-void
-hal_device_merge (HalDevice *target, HalDevice *source)
-{
-#if 0
-#warning TODO
-	GSList *iter;
-	GSList *caps;
-
-	/* device_property_atomic_update_begin (); */
-
-	for (iter = source->private->properties; iter != NULL; iter = iter->next) {
-		HalProperty *p = iter->data;
-		int type;
-		const char *key;
-		int target_type;
-
-		key = hal_property_get_key (p);
-		type = hal_property_get_type (p);
-
-		/* handle info.capabilities in a special way */
-		if (strcmp (key, "info.capabilities") == 0)
-			continue;
-
-		/* only remove target if it exists with a different type */
-		target_type = hal_device_property_get_type (target, key);
-		if (target_type != HAL_PROPERTY_TYPE_INVALID && target_type != type)
-			hal_device_property_remove (target, key);
-
-		switch (type) {
-
-		case HAL_PROPERTY_TYPE_STRING:
-			hal_device_property_set_string (
-				target, key,
-				hal_property_get_string (p));
-			break;
-
-		case HAL_PROPERTY_TYPE_INT32:
-			hal_device_property_set_int (
-				target, key,
-				hal_property_get_int (p));
-			break;
-
-		case HAL_PROPERTY_TYPE_UINT64:
-			hal_device_property_set_uint64 (
-				target, key,
-				hal_property_get_uint64 (p));
-			break;
-
-		case HAL_PROPERTY_TYPE_BOOLEAN:
-			hal_device_property_set_bool (
-				target, key,
-				hal_property_get_bool (p));
-			break;
-
-		case HAL_PROPERTY_TYPE_DOUBLE:
-			hal_device_property_set_double (
-				target, key,
-				hal_property_get_double (p));
-			break;
-
-		default:
-			HAL_WARNING (("Unknown property type %d", type));
-			break;
-		}
-	}
-
-	/* device_property_atomic_update_end (); */
-
-	caps = hal_device_property_get_strlist (source, "info.capabilities");
-	for (iter = caps; iter != NULL; iter = iter->next) {
-		if (!hal_device_has_capability (target, iter->data))
-			hal_device_add_capability (target, iter->data);
-	}
-#endif
-}
-
 const char *
 hal_device_get_udi (HalDevice *device)
 {
@@ -946,59 +876,67 @@ hal_device_property_remove (HalDevice *d
 	return FALSE;
 }
 
-void
-hal_device_print (HalDevice *device)
+static void
+hal_device_print_foreach_cb (HalDevice *device,
+			     const char *key,
+			     gpointer user_data)
 {
-#if 0
-#warning TODO
-	GSList *iter;
+	int type;
+	HalProperty *p;
 
-        fprintf (stderr, "device udi = %s\n", hal_device_get_udi (device));
+	p = hal_device_property_find (device, key);
+	if (p == NULL) {
+		goto out;
+	}
 
-	for (iter = device->private->properties; iter != NULL; iter = iter->next) {
-		HalProperty *p = iter->data;
-                int type;
-                const char *key;
-
-                key = hal_property_get_key (p);
-                type = hal_property_get_type (p);
-
-                switch (type) {
-                case HAL_PROPERTY_TYPE_STRING:
-                        fprintf (stderr, "  %s = '%s'  (string)\n", key,
-                                hal_property_get_string (p));
-                        break;
- 
-                case HAL_PROPERTY_TYPE_INT32:
+	type = hal_property_get_type (p);
+	
+	switch (type) {
+	case HAL_PROPERTY_TYPE_STRING:
+		fprintf (stderr, "  %s = '%s'  (string)\n", key,
+			 hal_property_get_string (p));
+		break;
+		
+	case HAL_PROPERTY_TYPE_INT32:
                         fprintf (stderr, "  %s = %d  0x%x  (int)\n", key,
-                                hal_property_get_int (p),
-                                hal_property_get_int (p));
-                        break;
- 
-                case HAL_PROPERTY_TYPE_UINT64:
-                        fprintf (stderr, "  %s = %llu  0x%llx  (uint64)\n", key,
-                                (long long unsigned int) hal_property_get_uint64 (p),
-                                (long long unsigned int) hal_property_get_uint64 (p));
-                        break;
- 
-                case HAL_PROPERTY_TYPE_DOUBLE:
-                        fprintf (stderr, "  %s = %g  (double)\n", key,
-                                hal_property_get_double (p));
-                        break;
- 
-                case HAL_PROPERTY_TYPE_BOOLEAN:
-                        fprintf (stderr, "  %s = %s  (bool)\n", key,
-                                (hal_property_get_bool (p) ? "true" :
-                                 "false"));
+				 hal_property_get_int (p),
+				 hal_property_get_int (p));
                         break;
- 
-                default:
-                        HAL_WARNING (("Unknown property type %d", type));
-                        break;
-                }
-        }
+			
+	case HAL_PROPERTY_TYPE_UINT64:
+		fprintf (stderr, "  %s = %llu  0x%llx  (uint64)\n", key,
+			 (long long unsigned int) hal_property_get_uint64 (p),
+			 (long long unsigned int) hal_property_get_uint64 (p));
+		break;
+		
+	case HAL_PROPERTY_TYPE_DOUBLE:
+		fprintf (stderr, "  %s = %g  (double)\n", key,
+			 hal_property_get_double (p));
+		break;
+		
+	case HAL_PROPERTY_TYPE_BOOLEAN:
+		fprintf (stderr, "  %s = %s  (bool)\n", key,
+			 (hal_property_get_bool (p) ? "true" :
+			  "false"));
+		break;
+		
+		/* TODO: strlist */
+		
+	default:
+		HAL_WARNING (("Unknown property type %d", type));
+		break;
+	}
+
+out:
+	;
+}
+
+void
+hal_device_print (HalDevice *device)
+{
+        fprintf (stderr, "device udi = %s\n", hal_device_get_udi (device));
+	hal_device_property_foreach (device, hal_device_print_foreach_cb, NULL);
         fprintf (stderr, "\n");
-#endif
 }
 
 const char *
diff --git a/hald/device.h b/hald/device.h
index c221323..da7a0f8 100644
--- a/hald/device.h
+++ b/hald/device.h
@@ -81,18 +81,14 @@ struct _HalDeviceStrListIter {
 };
 
 
-/* Return value of FALSE means that the foreach should be short-circuited */
-typedef gboolean (*HalDevicePropertyForeachFn) (HalDevice *device,
-						const char *key,
-						gpointer user_data);
+typedef void (*HalDevicePropertyForeachFn) (HalDevice *device,
+					    const char *key,
+					    gpointer user_data);
 
 GType         hal_device_get_type            (void);
 
 HalDevice    *hal_device_new                 (void);
 
-void          hal_device_merge               (HalDevice    *target,
-					      HalDevice    *source);
-
 void          hal_device_merge_with_rewrite  (HalDevice    *target,
 					      HalDevice    *source,
 					      const char   *target_namespace,
diff --git a/hald/hald_dbus.c b/hald/hald_dbus.c
index cb8c8a0..f8901f8 100644
--- a/hald/hald_dbus.c
+++ b/hald/hald_dbus.c
@@ -674,7 +674,7 @@ out:
  * @{
  */
 
-static gboolean
+static void
 foreach_property_append (HalDevice *device, 
 			 const char *key,
 			 gpointer user_data)
@@ -836,9 +836,6 @@ foreach_property_append (HalDevice *devi
 	}
 
 	dbus_message_iter_close_container (iter, &iter_dict_entry);
-
-
-	return TRUE;
 }
 		
 	
diff --git a/hald/hald_runner.c b/hald/hald_runner.c
index 3f916b8..7940065 100644
--- a/hald/hald_runner.c
+++ b/hald/hald_runner.c
@@ -288,7 +288,7 @@ error:
   return FALSE;
 }
 
-static gboolean
+static void
 add_property_to_msg (HalDevice *device, 
 		     const char *key, 
 		     gpointer user_data)
@@ -314,8 +314,6 @@ add_property_to_msg (HalDevice *device, 
   g_free (env);
   g_free (value);
   g_free (prop_upper);
-
-  return TRUE;
 }
 
 static void
diff --git a/hald/linux/physdev.c b/hald/linux/physdev.c
index c49d0b9..75dd9a4 100644
--- a/hald/linux/physdev.c
+++ b/hald/linux/physdev.c
@@ -313,8 +313,9 @@ usb_add (const gchar *sysfs_path, HalDev
 		hal_device_property_set_string (d, "info.bus", "usb");
 
 		/* take all usb_device.* properties from parent and make them usb.* on this object */
-		if (parent != NULL)
+		if (parent != NULL) {
 			hal_device_merge_with_rewrite (d, parent, "usb.", "usb_device.");
+		}
 
 		hal_util_set_driver (d, "info.linux.driver", sysfs_path);
 
diff-tree 63a3628bc3f4af4f5cf647dd11fd47a1992491ee (from 952155ea001367144c68c3c0199b0ea82ac52997)
Author: David Zeuthen <davidz at redhat.com>
Date:   Mon Oct 9 23:33:33 2006 -0400

    use a hash table for device properties

diff --git a/hald/device.c b/hald/device.c
index 2c77cef..ad47464 100644
--- a/hald/device.c
+++ b/hald/device.c
@@ -45,7 +45,8 @@ struct _HalDevicePrivate
 	char *udi;	
 	int num_addons;
 	int num_addons_ready;
-	GSList *properties;
+
+	GHashTable *props;
 };
 
 enum {
@@ -72,14 +73,12 @@ hal_device_finalize (GObject *obj)
 	printf ("************* in finalize for udi=%s\n", device->private->udi);
 #endif
 
-
-	g_slist_foreach (device->private->properties, (GFunc) hal_property_free, NULL);
-	g_slist_free (device->private->properties);
-
 	g_free (device->private->udi);
 
 	g_free (device->private);
 
+	g_hash_table_destroy (device->private->props);
+
 	if (parent_class->finalize)
 		parent_class->finalize (obj);
 }
@@ -129,6 +128,11 @@ hal_device_init (HalDevice *device)
 				       temp_device_counter++);
 	device->private->num_addons = 0;
 	device->private->num_addons_ready = 0;
+
+	device->private->props = g_hash_table_new_full (g_str_hash, 
+							g_str_equal, 
+							g_free, 
+							(GDestroyNotify) hal_property_free);
 }
 
 GType
@@ -186,6 +190,8 @@ hal_device_merge_with_rewrite  (HalDevic
 				const char   *target_namespace,
 				const char   *source_namespace)
 {
+#if 0
+#warning FIXME
 	GSList *iter;
 	size_t source_ns_len;
 
@@ -259,29 +265,19 @@ hal_device_merge_with_rewrite  (HalDevic
 	}
 
 	/* device_property_atomic_update_end (); */
-
+#endif
 }
 
-static HalProperty *
+static inline HalProperty *
 hal_device_property_find (HalDevice *device, const char *key)
 {
-	GSList *iter;
-
 	g_return_val_if_fail (device != NULL, NULL);
 	g_return_val_if_fail (key != NULL, NULL);
 
-	for (iter = device->private->properties; iter != NULL; iter = iter->next) {
-		HalProperty *p = iter->data;
-
-		if (strcmp (hal_property_get_key (p), key) == 0) {
-			return p;
-		}
-	}
-
-	return NULL;
+	return g_hash_table_lookup (device->private->props, key);
 }
 
-static GSList *
+static inline GSList *
 hal_device_property_get_strlist (HalDevice    *device, 
 				 const char   *key)
 {
@@ -291,7 +287,6 @@ hal_device_property_get_strlist (HalDevi
 	g_return_val_if_fail (key != NULL, NULL);
 
 	prop = hal_device_property_find (device, key);
-
 	if (prop != NULL)
 		return hal_property_get_strlist (prop);
 	else
@@ -390,6 +385,8 @@ out:
 void
 hal_device_merge (HalDevice *target, HalDevice *source)
 {
+#if 0
+#warning TODO
 	GSList *iter;
 	GSList *caps;
 
@@ -458,72 +455,7 @@ hal_device_merge (HalDevice *target, Hal
 		if (!hal_device_has_capability (target, iter->data))
 			hal_device_add_capability (target, iter->data);
 	}
-}
-
-gboolean
-hal_device_matches (HalDevice *device1, HalDevice *device2,
-		    const char *namespace)
-{
-	int len;
-	GSList *iter;
-
-	len = strlen (namespace);
-
-	for (iter = device1->private->properties; iter != NULL; iter = iter->next) {
-		HalProperty *p;
-		const char *key;
-		int type;
-
-		p = (HalProperty *) iter->data;
-		key = hal_property_get_key (p);
-		type = hal_property_get_type (p);
-
-		if (strncmp (key, namespace, len) != 0)
-			continue;
-
-		if (!hal_device_has_property (device2, key))
-			return FALSE;
-
-		switch (type) {
-
-		case HAL_PROPERTY_TYPE_STRING:
-			if (strcmp (hal_property_get_string (p),
-				    hal_device_property_get_string (device2,
-								    key)) != 0)
-				return FALSE;
-			break;
-
-		case HAL_PROPERTY_TYPE_INT32:
-			if (hal_property_get_int (p) !=
-			    hal_device_property_get_int (device2, key))
-				return FALSE;
-			break;
-
-		case HAL_PROPERTY_TYPE_UINT64:
-			if (hal_property_get_uint64 (p) !=
-				hal_device_property_get_uint64 (device2, key))
-				return FALSE;
-			break;
-
-		case HAL_PROPERTY_TYPE_BOOLEAN:
-			if (hal_property_get_bool (p) !=
-			    hal_device_property_get_bool (device2, key))
-				return FALSE;
-			break;
-
-		case HAL_PROPERTY_TYPE_DOUBLE:
-			if (hal_property_get_double (p) !=
-			    hal_device_property_get_double (device2, key))
-				return FALSE;
-			break;
-
-		default:
-			HAL_WARNING (("Unknown property type %d", type));
-			break;
-		}
-	}
-
-	return TRUE;
+#endif
 }
 
 const char *
@@ -574,7 +506,7 @@ hal_device_num_properties (HalDevice *de
 {
 	g_return_val_if_fail (device != NULL, -1);
 
-	return g_slist_length (device->private->properties);
+	return g_hash_table_size (device->private->props);
 }
 
 gboolean
@@ -598,25 +530,42 @@ hal_device_property_to_string (HalDevice
 	return hal_property_to_string (prop);
 }
 
+typedef struct 
+{
+	HalDevice *device;
+	HalDevicePropertyForeachFn callback;
+	gpointer user_data;
+} hdpfe_ud_t;
+
+static void
+hdpfe (gpointer key,
+       gpointer value,
+       gpointer user_data)
+{
+	hdpfe_ud_t *c;
+	HalProperty *prop;
+
+	c = (hdpfe_ud_t *) user_data;
+	prop = (HalProperty *) value;
+
+	c->callback (c->device, (const char *) key, c->user_data);
+}
+
 void
 hal_device_property_foreach (HalDevice *device,
 			     HalDevicePropertyForeachFn callback,
 			     gpointer user_data)
 {
-	GSList *iter;
+	hdpfe_ud_t c;
 
 	g_return_if_fail (device != NULL);
 	g_return_if_fail (callback != NULL);
 
-	for (iter = device->private->properties; iter != NULL; iter = iter->next) {
-		HalProperty *p = iter->data;
-		gboolean cont;
-
-		cont = callback (device, hal_property_get_key (p), user_data);
+	c.device = device;
+	c.callback = callback;
+	c.user_data = user_data;
 
-		if (cont == FALSE)
-			return;
-	}
+	g_hash_table_foreach (device->private->props, hdpfe, &c);
 }
 
 int
@@ -803,10 +752,10 @@ hal_device_property_set_string (HalDevic
 			       key, FALSE, FALSE);
 
 	} else {
+		prop = hal_property_new (HAL_PROPERTY_TYPE_STRING);
+		hal_property_set_string (prop, value);
 
-		prop = hal_property_new_string (key, value);
-
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -838,9 +787,9 @@ hal_device_property_set_int (HalDevice *
 			       key, FALSE, FALSE);
 
 	} else {
-		prop = hal_property_new_int (key, value);
-
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		prop = hal_property_new (HAL_PROPERTY_TYPE_INT32);
+		hal_property_set_int (prop, value);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -872,9 +821,9 @@ hal_device_property_set_uint64 (HalDevic
 			       key, FALSE, FALSE);
 
 	} else {
-		prop = hal_property_new_uint64 (key, value);
-
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		prop = hal_property_new (HAL_PROPERTY_TYPE_UINT64);
+		hal_property_set_uint64 (prop, value);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -906,9 +855,9 @@ hal_device_property_set_bool (HalDevice 
 			       key, FALSE, FALSE);
 
 	} else {
-		prop = hal_property_new_bool (key, value);
-
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		prop = hal_property_new (HAL_PROPERTY_TYPE_BOOLEAN);
+		hal_property_set_bool (prop, value);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -940,9 +889,9 @@ hal_device_property_set_double (HalDevic
 			       key, FALSE, FALSE);
 
 	} else {
-		prop = hal_property_new_double (key, value);
-
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		prop = hal_property_new (HAL_PROPERTY_TYPE_DOUBLE);
+		hal_property_set_double (prop, value);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -989,26 +938,19 @@ hal_device_copy_property (HalDevice *fro
 gboolean
 hal_device_property_remove (HalDevice *device, const char *key)
 {
-	HalProperty *prop;
-
-	prop = hal_device_property_find (device, key);
-
-	if (prop == NULL)
-		return FALSE;
-
-	device->private->properties = g_slist_remove (device->private->properties, prop);
-
-	hal_property_free (prop);
-
-	g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
-		       key, TRUE, FALSE);
-
-	return TRUE;
+	if (g_hash_table_remove (device->private->props, key)) {
+		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
+			       key, TRUE, FALSE);
+		return TRUE;
+	}
+	return FALSE;
 }
 
 void
 hal_device_print (HalDevice *device)
 {
+#if 0
+#warning TODO
 	GSList *iter;
 
         fprintf (stderr, "device udi = %s\n", hal_device_get_udi (device));
@@ -1056,6 +998,7 @@ hal_device_print (HalDevice *device)
                 }
         }
         fprintf (stderr, "\n");
+#endif
 }
 
 const char *
@@ -1097,10 +1040,10 @@ hal_device_property_strlist_append (HalD
 			       key, FALSE, FALSE);
 
 	} else {
-		prop = hal_property_new_strlist (key);
+		prop = hal_property_new (HAL_PROPERTY_TYPE_STRLIST);
 		hal_property_strlist_append (prop, value);
 
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -1129,10 +1072,10 @@ hal_device_property_strlist_prepend (Hal
 			       key, FALSE, FALSE);
 
 	} else {
-		prop = hal_property_new_strlist (key);
+		prop = hal_property_new (HAL_PROPERTY_TYPE_STRLIST);
 		hal_property_strlist_prepend (prop, value);
 
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -1176,13 +1119,11 @@ hal_device_property_strlist_clear (HalDe
 	prop = hal_device_property_find (device, key);
 
 	if (prop == NULL) {
-		prop = hal_property_new_strlist (key);
-
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		prop = hal_property_new (HAL_PROPERTY_TYPE_STRLIST);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
-
 		return TRUE;
 	}
 
@@ -1223,10 +1164,10 @@ hal_device_property_strlist_add (HalDevi
 		}
 
 	} else {
-		prop = hal_property_new_strlist (key);
+		prop = hal_property_new (HAL_PROPERTY_TYPE_STRLIST);
 		hal_property_strlist_prepend (prop, value);
 
-		device->private->properties = g_slist_prepend (device->private->properties, prop);
+		g_hash_table_insert (device->private->props, g_strdup (key), prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
diff --git a/hald/device.h b/hald/device.h
index 4ba52f3..c221323 100644
--- a/hald/device.h
+++ b/hald/device.h
@@ -98,10 +98,6 @@ void          hal_device_merge_with_rewr
 					      const char   *target_namespace,
 					      const char   *source_namespace);
 
-gboolean      hal_device_matches             (HalDevice    *device1,
-					      HalDevice    *device2,
-					      const char   *namespace);
-
 const char   *hal_device_get_udi             (HalDevice    *device);
 void          hal_device_set_udi             (HalDevice    *device,
 					      const char   *udi);
diff --git a/hald/property.c b/hald/property.c
index 5f89e78..9455418 100644
--- a/hald/property.c
+++ b/hald/property.c
@@ -36,8 +36,6 @@
 #include "property.h"
 
 struct _HalProperty {
-	char *key;
-
 	int type;
 	union {
 		char *str_value;
@@ -52,8 +50,6 @@ struct _HalProperty {
 void
 hal_property_free (HalProperty *prop)
 {
-	g_free (prop->key);
-
 	if (prop->type == HAL_PROPERTY_TYPE_STRING) {
 		g_free (prop->v.str_value);
 	} else if (prop->type == HAL_PROPERTY_TYPE_STRLIST) {
@@ -63,114 +59,22 @@ hal_property_free (HalProperty *prop)
 		}
 		g_slist_free (prop->v.strlist_value);
 	}
-
 	g_free (prop);
 }
 
-static inline HalProperty *
-hal_property_new (void)
-{
-	HalProperty *prop;
-	prop = g_new0 (HalProperty, 1); 
-	return prop;
-}
-
-HalProperty *
-hal_property_new_string (const char *key, const char *value)
-{
-	HalProperty *prop;
-	char *endchar;
-	gboolean validated = TRUE;
-
-	prop = hal_property_new ();
-
-	prop->type = HAL_PROPERTY_TYPE_STRING;
-	prop->key = g_strdup (key);
-	prop->v.str_value = g_strdup (value != NULL ? value : "");
-
-	while (!g_utf8_validate (prop->v.str_value, -1,
-				 (const char **) &endchar)) {
-		validated = FALSE;
-		*endchar = '?';
-	}
-
-	if (!validated) {
-		HAL_WARNING (("Key '%s' has invalid UTF-8 string '%s'",
-			      key, prop->v.str_value));
-	}
-
-	return prop;
-}
-
 HalProperty *
-hal_property_new_int (const char *key, dbus_int32_t value)
+hal_property_new (int type)
 {
 	HalProperty *prop;
-
-	prop = hal_property_new ();
-
-	prop->type = HAL_PROPERTY_TYPE_INT32;
-	prop->key = g_strdup (key);
-	prop->v.int_value = value;
-
+	prop = g_new0 (HalProperty, 1);
+	prop->type = type;
 	return prop;
 }
 
-HalProperty *
-hal_property_new_uint64 (const char *key, dbus_uint64_t value)
-{
-	HalProperty *prop;
-
-	prop = hal_property_new ();
-
-	prop->type = HAL_PROPERTY_TYPE_UINT64;
-	prop->key = g_strdup (key);
-	prop->v.uint64_value = value;
-
-	return prop;
-}
-
-HalProperty *
-hal_property_new_bool (const char *key, dbus_bool_t value)
-{
-	HalProperty *prop;
-
-	prop = hal_property_new ();
-
-	prop->type = HAL_PROPERTY_TYPE_BOOLEAN;
-	prop->key = g_strdup (key);
-	prop->v.bool_value = value;
-
-	return prop;
-}
-
-HalProperty *
-hal_property_new_double (const char *key, double value)
-{
-	HalProperty *prop;
-
-	prop = hal_property_new ();
-
-	prop->type = HAL_PROPERTY_TYPE_DOUBLE;
-	prop->key = g_strdup (key);
-	prop->v.double_value = value;
-
-	return prop;
-}
-
-const char *
-hal_property_get_key (HalProperty *prop)
-{
-	g_return_val_if_fail (prop != NULL, NULL);
-
-	return prop->key;
-}
-
 int
 hal_property_get_type (HalProperty *prop)
 {
 	g_return_val_if_fail (prop != NULL, HAL_PROPERTY_TYPE_INVALID);
-
 	return prop->type;
 }
 
@@ -179,7 +83,6 @@ hal_property_get_string (HalProperty *pr
 {
 	g_return_val_if_fail (prop != NULL, NULL);
 	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_STRING, NULL);
-
 	return prop->v.str_value;
 }
 
@@ -188,7 +91,6 @@ hal_property_get_int (HalProperty *prop)
 {
 	g_return_val_if_fail (prop != NULL, -1);
 	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_INT32, -1);
-
 	return prop->v.int_value;
 }
 
@@ -197,7 +99,6 @@ hal_property_get_uint64 (HalProperty *pr
 {
 	g_return_val_if_fail (prop != NULL, -1);
 	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_UINT64, -1);
-
 	return prop->v.uint64_value;
 }
 
@@ -206,7 +107,6 @@ hal_property_get_bool (HalProperty *prop
 {
 	g_return_val_if_fail (prop != NULL, FALSE);
 	g_return_val_if_fail (prop->type == HAL_PROPERTY_TYPE_BOOLEAN, FALSE);
-
 	return prop->v.bool_value;
 }
 
@@ -290,8 +190,7 @@ hal_property_set_string (HalProperty *pr
 	}
 
 	if (!validated) {
-		HAL_WARNING (("Key '%s' has invalid UTF-8 string '%s'",
-			      prop->key, value));
+		HAL_WARNING (("Property has invalid UTF-8 string '%s'", value));
 	}
 }
 
@@ -301,7 +200,6 @@ hal_property_set_int (HalProperty *prop,
 	g_return_if_fail (prop != NULL);
 	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_INT32 ||
 			  prop->type == HAL_PROPERTY_TYPE_INVALID);
-
 	prop->type = HAL_PROPERTY_TYPE_INT32;
 	prop->v.int_value = value;
 }
@@ -312,7 +210,6 @@ hal_property_set_uint64 (HalProperty *pr
 	g_return_if_fail (prop != NULL);
 	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_UINT64 ||
 			  prop->type == HAL_PROPERTY_TYPE_INVALID);
-
 	prop->type = HAL_PROPERTY_TYPE_UINT64;
 	prop->v.uint64_value = value;
 }
@@ -323,7 +220,6 @@ hal_property_set_bool (HalProperty *prop
 	g_return_if_fail (prop != NULL);
 	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_BOOLEAN ||
 			  prop->type == HAL_PROPERTY_TYPE_INVALID);
-
 	prop->type = HAL_PROPERTY_TYPE_BOOLEAN;
 	prop->v.bool_value = value;
 }
@@ -334,25 +230,10 @@ hal_property_set_double (HalProperty *pr
 	g_return_if_fail (prop != NULL);
 	g_return_if_fail (prop->type == HAL_PROPERTY_TYPE_DOUBLE ||
 			  prop->type == HAL_PROPERTY_TYPE_INVALID);
-
 	prop->type = HAL_PROPERTY_TYPE_DOUBLE;
 	prop->v.double_value = value;
 }
 
-HalProperty *
-hal_property_new_strlist (const char *key)
-{
-	HalProperty *prop;
-
-	prop = hal_property_new ();
-
-	prop->type = HAL_PROPERTY_TYPE_STRLIST;
-	prop->key = g_strdup (key);
-	prop->v.strlist_value = NULL;
-
-	return prop;
-}
-
 GSList *
 hal_property_get_strlist (HalProperty *prop)
 {
diff --git a/hald/property.h b/hald/property.h
index 07d9597..8a8f78e 100644
--- a/hald/property.h
+++ b/hald/property.h
@@ -33,19 +33,8 @@ typedef struct _HalProperty HalProperty;
 
 void          hal_property_free               (HalProperty  *prop);
 
-HalProperty *hal_property_new_string          (const char   *key,
-					       const char   *value);
-HalProperty *hal_property_new_int             (const char   *key,
-					       dbus_int32_t  value);
-HalProperty *hal_property_new_uint64          (const char   *key,
-					       dbus_uint64_t value);
-HalProperty *hal_property_new_bool            (const char   *key,
-					       dbus_bool_t   value);
-HalProperty *hal_property_new_double          (const char   *key,
-					       double        value);
-HalProperty *hal_property_new_strlist         (const char   *key);
+HalProperty *hal_property_new                 (int type);
 
-const char   *hal_property_get_key            (HalProperty  *prop);
 int           hal_property_get_type           (HalProperty  *prop);
 char         *hal_property_to_string          (HalProperty  *prop);
 
@@ -56,28 +45,17 @@ dbus_bool_t   hal_property_get_bool     
 double        hal_property_get_double         (HalProperty  *prop);
 GSList       *hal_property_get_strlist        (HalProperty  *prop);
 
-void          hal_property_set_string         (HalProperty  *prop,
-					       const char   *value);
-void          hal_property_set_int            (HalProperty  *prop,
-					       dbus_int32_t  value);
-void          hal_property_set_uint64         (HalProperty  *prop,
-					       dbus_uint64_t value);
-void          hal_property_set_bool           (HalProperty  *prop,
-					       dbus_bool_t   value);
-void          hal_property_set_double         (HalProperty  *prop,
-					       double        value);
-gboolean      hal_property_strlist_append     (HalProperty  *prop,
-					       const char   *value);
-gboolean      hal_property_strlist_prepend    (HalProperty  *prop,
-					       const char   *value);
-gboolean      hal_property_strlist_remove_elem (HalProperty  *prop,
-					        guint index);
-
-gboolean      hal_property_strlist_add        (HalProperty  *prop,
-					       const char *value);
-gboolean      hal_property_strlist_remove     (HalProperty  *prop,
-					       const char *value);
-gboolean      hal_property_strlist_clear      (HalProperty  *prop);
+void          hal_property_set_string          (HalProperty  *prop, const char   *value);
+void          hal_property_set_int             (HalProperty  *prop, dbus_int32_t  value);
+void          hal_property_set_uint64          (HalProperty  *prop, dbus_uint64_t value);
+void          hal_property_set_bool            (HalProperty  *prop, dbus_bool_t   value);
+void          hal_property_set_double          (HalProperty  *prop, double        value);
+gboolean      hal_property_strlist_append      (HalProperty  *prop, const char   *value);
+gboolean      hal_property_strlist_prepend     (HalProperty  *prop, const char   *value);
+gboolean      hal_property_strlist_remove_elem (HalProperty  *prop, guint index);
 
+gboolean      hal_property_strlist_add        (HalProperty  *prop, const char *value);
+gboolean      hal_property_strlist_remove     (HalProperty  *prop, const char *value);
+gboolean      hal_property_strlist_clear      (HalProperty  *prop);
 
 #endif /* PROPERTY_H */
diff-tree 952155ea001367144c68c3c0199b0ea82ac52997 (from 5daaab35fb0917cdfc6f8a480e214ab76f564b56)
Author: David Zeuthen <davidz at redhat.com>
Date:   Mon Oct 9 23:29:21 2006 -0400

    fix crasher in GetProperty() method

diff --git a/hald/hald_dbus.c b/hald/hald_dbus.c
index 8f30e2f..cb8c8a0 100644
--- a/hald/hald_dbus.c
+++ b/hald/hald_dbus.c
@@ -1210,7 +1210,7 @@ device_get_property (DBusConnection * co
 		     hal_device_property_strlist_iter_next (&striter)) {
 			const char *v;
 			v = hal_device_property_strlist_iter_get_value (&striter);
-			dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_STRING, v);
+			dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_STRING, &v);
 		}
 
 		dbus_message_iter_close_container (&iter, &iter_array);
diff-tree 5daaab35fb0917cdfc6f8a480e214ab76f564b56 (from 5742b5dbee411fb2df32053791dfc6ec0383bc94)
Author: David Zeuthen <davidz at redhat.com>
Date:   Mon Oct 9 20:32:58 2006 -0400

    switch device_info.c to use strlist iterator

diff --git a/hald/device.c b/hald/device.c
index 97005e1..2c77cef 100644
--- a/hald/device.c
+++ b/hald/device.c
@@ -349,8 +349,11 @@ gboolean
 hal_device_property_strlist_iter_is_valid (HalDeviceStrListIter *iter)
 {
 	g_return_val_if_fail (iter != NULL, FALSE);
-	g_return_val_if_fail (iter->i != NULL, FALSE);
-	return TRUE;
+	if (iter->i == NULL) {
+		return FALSE;
+	} else {
+		return TRUE;
+	}
 }
 
 char **
diff --git a/hald/device_info.c b/hald/device_info.c
index 1ccaa45..78ba7cf 100644
--- a/hald/device_info.c
+++ b/hald/device_info.c
@@ -579,12 +579,12 @@ handle_match (ParsingContext * pc, const
 			}
 		} else if (hal_device_property_get_type (d, prop_to_check) == HAL_PROPERTY_TYPE_STRLIST && 
 			   needle != NULL) {
-			guint i;
-			guint num_elems;
+			HalDeviceStrListIter iter;
 
-			num_elems = hal_device_property_get_strlist_length (d, prop_to_check);
-			for (i = 0; i < num_elems; i++) {
-				const char *str = hal_device_property_get_strlist_elem (d, prop_to_check, i);
+			for (hal_device_property_strlist_iter_init (d, prop_to_check, &iter);
+			     hal_device_property_strlist_iter_is_valid (&iter);
+			     hal_device_property_strlist_iter_next (&iter)) {
+				const char *str = hal_device_property_strlist_iter_get_value (&iter);
 				if (strcmp (str, needle) == 0) {
 					contains = TRUE;
 					break;
@@ -617,12 +617,12 @@ handle_match (ParsingContext * pc, const
 			}
 		} else if (hal_device_property_get_type (d, prop_to_check) == HAL_PROPERTY_TYPE_STRLIST && 
 			   needle != NULL) {
-			guint i;
-			guint num_elems;
-			
-			num_elems = hal_device_property_get_strlist_length (d, prop_to_check);
-			for (i = 0; i < num_elems; i++) {
-				const char *str = hal_device_property_get_strlist_elem (d, prop_to_check, i);
+			HalDeviceStrListIter iter;
+
+			for (hal_device_property_strlist_iter_init (d, prop_to_check, &iter);
+			     hal_device_property_strlist_iter_is_valid (&iter);
+			     hal_device_property_strlist_iter_next (&iter)) {
+				const char *str = hal_device_property_strlist_iter_get_value (&iter);
 				if (g_ascii_strcasecmp (str, needle) == 0) {
 					contains_ncase = TRUE;
 					break;
diff-tree 5742b5dbee411fb2df32053791dfc6ec0383bc94 (from 1f777cb8d4a4300c7762eeb6150789ba0dec9e44)
Author: David Zeuthen <davidz at redhat.com>
Date:   Mon Oct 9 20:23:07 2006 -0400

    use an iterator to iterate over strlist instead of using GSList

diff --git a/hald/device.c b/hald/device.c
index b10dc84..97005e1 100644
--- a/hald/device.c
+++ b/hald/device.c
@@ -262,6 +262,128 @@ hal_device_merge_with_rewrite  (HalDevic
 
 }
 
+static HalProperty *
+hal_device_property_find (HalDevice *device, const char *key)
+{
+	GSList *iter;
+
+	g_return_val_if_fail (device != NULL, NULL);
+	g_return_val_if_fail (key != NULL, NULL);
+
+	for (iter = device->private->properties; iter != NULL; iter = iter->next) {
+		HalProperty *p = iter->data;
+
+		if (strcmp (hal_property_get_key (p), key) == 0) {
+			return p;
+		}
+	}
+
+	return NULL;
+}
+
+static GSList *
+hal_device_property_get_strlist (HalDevice    *device, 
+				 const char   *key)
+{
+	HalProperty *prop;
+
+	g_return_val_if_fail (device != NULL, NULL);
+	g_return_val_if_fail (key != NULL, NULL);
+
+	prop = hal_device_property_find (device, key);
+
+	if (prop != NULL)
+		return hal_property_get_strlist (prop);
+	else
+		return NULL;
+}
+
+guint
+hal_device_property_get_strlist_length (HalDevice    *device,
+					const char   *key)
+{
+	GSList *i;
+
+	i = hal_device_property_get_strlist (device, key);
+	if (i != NULL)
+		return g_slist_length (i);
+	else
+		return 0;
+}
+
+void
+hal_device_property_strlist_iter_init (HalDevice    *device,
+				       const char   *key,
+				       HalDeviceStrListIter *iter)
+{
+	HalProperty *prop;
+
+	g_return_if_fail (device != NULL);
+	g_return_if_fail (key != NULL);
+
+	prop = hal_device_property_find (device, key);
+
+	if (prop != NULL)
+		iter->i = hal_property_get_strlist (prop);
+	else
+		iter->i = NULL;
+}
+
+const char *
+hal_device_property_strlist_iter_get_value (HalDeviceStrListIter *iter)
+{
+	g_return_val_if_fail (iter != NULL, NULL);
+	g_return_val_if_fail (iter->i != NULL, NULL);
+	return iter->i->data;
+}
+
+void
+hal_device_property_strlist_iter_next (HalDeviceStrListIter *iter)
+{
+	g_return_if_fail (iter != NULL);
+	g_return_if_fail (iter->i != NULL);
+	iter->i = g_slist_next (iter->i);
+}
+
+gboolean
+hal_device_property_strlist_iter_is_valid (HalDeviceStrListIter *iter)
+{
+	g_return_val_if_fail (iter != NULL, FALSE);
+	g_return_val_if_fail (iter->i != NULL, FALSE);
+	return TRUE;
+}
+
+char **
+hal_device_property_dup_strlist_as_strv (HalDevice    *device,
+					 const char   *key)
+{
+	guint j;
+	guint len;
+	gchar **strv;
+	GSList *i;
+
+	strv = NULL;
+
+	i = hal_device_property_get_strlist (device, key);
+	if (i == NULL)
+		goto out;
+
+	len = g_slist_length (i);
+	if (len == 0)
+		goto out;
+
+	strv = g_new (char *, len + 1);
+
+	for (j = 0; i != NULL; i = g_slist_next (i), j++) {
+		strv[j] = g_strdup ((const gchar *) i->data);
+	}
+	strv[j] = NULL;
+
+out:
+	return strv;	
+}
+
+
 void
 hal_device_merge (HalDevice *target, HalDevice *source)
 {
@@ -452,25 +574,6 @@ hal_device_num_properties (HalDevice *de
 	return g_slist_length (device->private->properties);
 }
 
-static HalProperty *
-hal_device_property_find (HalDevice *device, const char *key)
-{
-	GSList *iter;
-
-	g_return_val_if_fail (device != NULL, NULL);
-	g_return_val_if_fail (key != NULL, NULL);
-
-	for (iter = device->private->properties; iter != NULL; iter = iter->next) {
-		HalProperty *p = iter->data;
-
-		if (strcmp (hal_property_get_key (p), key) == 0) {
-			return p;
-		}
-	}
-
-	return NULL;
-}
-
 gboolean
 hal_device_has_property (HalDevice *device, const char *key)
 {
@@ -952,23 +1055,6 @@ hal_device_print (HalDevice *device)
         fprintf (stderr, "\n");
 }
 
-GSList *
-hal_device_property_get_strlist (HalDevice    *device, 
-				 const char   *key)
-{
-	HalProperty *prop;
-
-	g_return_val_if_fail (device != NULL, NULL);
-	g_return_val_if_fail (key != NULL, NULL);
-
-	prop = hal_device_property_find (device, key);
-
-	if (prop != NULL)
-		return hal_property_get_strlist (prop);
-	else
-		return NULL;
-}
-
 const char *
 hal_device_property_get_strlist_elem (HalDevice    *device,
 				      const char   *key,
diff --git a/hald/device.h b/hald/device.h
index b30109c..4ba52f3 100644
--- a/hald/device.h
+++ b/hald/device.h
@@ -74,6 +74,13 @@ struct _HalDeviceClass {
 #define HAL_PROPERTY_TYPE_STRLIST     ((int) (DBUS_TYPE_STRING<<8)+('l'))
 
 
+/* private; do not access; might change in the future */
+typedef struct _HalDeviceStrListIter      HalDeviceStrListIter;
+struct _HalDeviceStrListIter {
+	GSList *i;
+};
+
+
 /* Return value of FALSE means that the foreach should be short-circuited */
 typedef gboolean (*HalDevicePropertyForeachFn) (HalDevice *device,
 						const char *key,
@@ -132,11 +139,20 @@ dbus_bool_t   hal_device_property_get_bo
 					      const char   *key);
 double        hal_device_property_get_double (HalDevice    *device,
 					      const char   *key);
-GSList       *hal_device_property_get_strlist (HalDevice    *device,
-					       const char   *key);
 const char   *hal_device_property_get_strlist_elem (HalDevice    *device,
 						    const char   *key,
 						    guint index);
+guint         hal_device_property_get_strlist_length (HalDevice    *device,
+						      const char   *key);
+char        **hal_device_property_dup_strlist_as_strv (HalDevice    *device,
+						       const char   *key);
+
+void          hal_device_property_strlist_iter_init (HalDevice    *device,
+						     const char   *key,
+						     HalDeviceStrListIter *iter);
+const char   *hal_device_property_strlist_iter_get_value (HalDeviceStrListIter *iter);
+void          hal_device_property_strlist_iter_next (HalDeviceStrListIter *iter);
+gboolean      hal_device_property_strlist_iter_is_valid (HalDeviceStrListIter *iter);
 
 
 
diff --git a/hald/device_info.c b/hald/device_info.c
index 6f2a153..1ccaa45 100644
--- a/hald/device_info.c
+++ b/hald/device_info.c
@@ -579,12 +579,12 @@ handle_match (ParsingContext * pc, const
 			}
 		} else if (hal_device_property_get_type (d, prop_to_check) == HAL_PROPERTY_TYPE_STRLIST && 
 			   needle != NULL) {
-			GSList *i;
-			GSList *value;
+			guint i;
+			guint num_elems;
 
-			value = hal_device_property_get_strlist (d, prop_to_check);
-			for (i = value; i != NULL; i = g_slist_next (i)) {
-				const char *str = i->data;
+			num_elems = hal_device_property_get_strlist_length (d, prop_to_check);
+			for (i = 0; i < num_elems; i++) {
+				const char *str = hal_device_property_get_strlist_elem (d, prop_to_check, i);
 				if (strcmp (str, needle) == 0) {
 					contains = TRUE;
 					break;
@@ -617,12 +617,12 @@ handle_match (ParsingContext * pc, const
 			}
 		} else if (hal_device_property_get_type (d, prop_to_check) == HAL_PROPERTY_TYPE_STRLIST && 
 			   needle != NULL) {
-			GSList *i;
-			GSList *value;
-
-			value = hal_device_property_get_strlist (d, prop_to_check);
-			for (i = value; i != NULL; i = g_slist_next (i)) {
-				const char *str = i->data;
+			guint i;
+			guint num_elems;
+			
+			num_elems = hal_device_property_get_strlist_length (d, prop_to_check);
+			for (i = 0; i < num_elems; i++) {
+				const char *str = hal_device_property_get_strlist_elem (d, prop_to_check, i);
 				if (g_ascii_strcasecmp (str, needle) == 0) {
 					contains_ncase = TRUE;
 					break;
diff --git a/hald/hald.c b/hald/hald.c
index 48b35f4..71e73bd 100644
--- a/hald/hald.c
+++ b/hald/hald.c
@@ -101,26 +101,25 @@ gdl_store_changed (HalDeviceStore *store
 		   gboolean is_added, gpointer user_data)
 {
 	if (is_added) {
-		GSList *addons;
+		HalDeviceStrListIter iter;
 
 		HAL_INFO (("Added device to GDL; udi=%s", hal_device_get_udi(device)));
 
-		if ((addons = hal_device_property_get_strlist (device, "info.addons")) != NULL) {
-			GSList *i;
-
-			for (i = addons; i != NULL; i = g_slist_next (i)) {
-				const gchar *command_line;
-				gchar *extra_env[2] = {"HALD_ACTION=addon", NULL};
-
-				command_line = (const gchar *) i->data;
-				if (hald_runner_start(device, command_line, extra_env, addon_terminated, NULL, NULL)) {
-					HAL_INFO (("Started addon %s for udi %s", 
-						   command_line, hal_device_get_udi(device)));
-					hal_device_inc_num_addons (device);
-				} else {
-					HAL_ERROR (("Cannot start addon %s for udi %s", 
-						    command_line, hal_device_get_udi(device)));
-				}
+		for (hal_device_property_strlist_iter_init (device, "info.addons", &iter);
+		     hal_device_property_strlist_iter_is_valid (&iter);
+		     hal_device_property_strlist_iter_next (&iter)) {
+			const gchar *command_line;
+			gchar *extra_env[2] = {"HALD_ACTION=addon", NULL};
+			
+			command_line = hal_device_property_strlist_iter_get_value (&iter);
+
+			if (hald_runner_start(device, command_line, extra_env, addon_terminated, NULL, NULL)) {
+				HAL_INFO (("Started addon %s for udi %s", 
+					   command_line, hal_device_get_udi(device)));
+				hal_device_inc_num_addons (device);
+			} else {
+				HAL_ERROR (("Cannot start addon %s for udi %s", 
+					    command_line, hal_device_get_udi(device)));
 			}
 		}
 	} else {
diff --git a/hald/hald_dbus.c b/hald/hald_dbus.c
index f864e63..8f30e2f 100644
--- a/hald/hald_dbus.c
+++ b/hald/hald_dbus.c
@@ -798,7 +798,7 @@ foreach_property_append (HalDevice *devi
 	case HAL_PROPERTY_TYPE_STRLIST:
 	{
 		DBusMessageIter iter_var, iter_array;
-		GSList *iter;
+		HalDeviceStrListIter iter;
 
 		dbus_message_iter_open_container (&iter_dict_entry,
 						  DBUS_TYPE_VARIANT,
@@ -811,10 +811,11 @@ foreach_property_append (HalDevice *devi
 						  DBUS_TYPE_STRING_AS_STRING,
 						  &iter_array);
 
-		for (iter = hal_device_property_get_strlist (device, key); iter != NULL; iter = iter->next) {
-				     
+		for (hal_device_property_strlist_iter_init (device, key, &iter);
+		     hal_device_property_strlist_iter_is_valid (&iter);
+		     hal_device_property_strlist_iter_next (&iter)) {
 			const char *v;
-			v = (const char *) iter->data;
+			v = hal_device_property_strlist_iter_get_value (&iter);
 
 			dbus_message_iter_append_basic (&iter_array, 
 							DBUS_TYPE_STRING,
@@ -1196,7 +1197,7 @@ device_get_property (DBusConnection * co
 	}
 	case HAL_PROPERTY_TYPE_STRLIST:
 	{
-		GSList *l;
+		HalDeviceStrListIter striter;
 		DBusMessageIter iter_array;
 
 		dbus_message_iter_open_container (&iter, 
@@ -1204,8 +1205,12 @@ device_get_property (DBusConnection * co
 						  DBUS_TYPE_STRING_AS_STRING,
 						  &iter_array);
 
-		for (l = hal_device_property_get_strlist (d, key); l != NULL; l = g_slist_next (l)) {
-			dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_STRING, &(l->data));
+		for (hal_device_property_strlist_iter_init (d, key, &striter);
+		     hal_device_property_strlist_iter_is_valid (&striter);
+		     hal_device_property_strlist_iter_next (&striter)) {
+			const char *v;
+			v = hal_device_property_strlist_iter_get_value (&striter);
+			dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_STRING, v);
 		}
 
 		dbus_message_iter_close_container (&iter, &iter_array);
@@ -1742,7 +1747,7 @@ device_query_capability (DBusConnection 
 {
 	dbus_bool_t rc;
 	const char *udi;
-	GSList *caps;
+	HalDeviceStrListIter striter;
 	char *capability;
 	HalDevice *d;
 	DBusMessage *reply;
@@ -1775,15 +1780,12 @@ device_query_capability (DBusConnection 
 		DIE (("No memory"));
 
 	rc = FALSE;
-	caps = hal_device_property_get_strlist (d, "info.capabilities");
-	if (caps != NULL) {
-		GSList *iter;
-
-		for (iter = caps; iter != NULL; iter=g_slist_next(iter)) {
-			if (strcmp (iter->data, capability) == 0) {
-				rc = TRUE;
-				break;
-			}
+	for (hal_device_property_strlist_iter_init (d, "info.capabilities", &striter);
+	     hal_device_property_strlist_iter_is_valid (&striter);
+	     hal_device_property_strlist_iter_next (&striter)) {
+		if (strcmp (hal_device_property_strlist_iter_get_value (&striter), capability) == 0) {
+			rc = TRUE;
+			break;
 		}
 	}
 
@@ -3464,49 +3466,45 @@ do_introspect (DBusConnection  *connecti
 				       "    </method>\n"
 
 				       "  </interface>\n");
+			HalDeviceStrListIter if_iter;
 
-			GSList *interfaces;
-			GSList *i;
+			for (hal_device_property_strlist_iter_init (d, "info.interfaces", &if_iter);
+			     hal_device_property_strlist_iter_is_valid (&if_iter);
+			     hal_device_property_strlist_iter_next (&if_iter)) {
+				const char *ifname;
+				char *method_name_prop;
+				char *method_sign_prop;
+				char *method_argn_prop;
+				GSList *i;
+				HalDeviceStrListIter name_iter;
+				HalDeviceStrListIter sign_iter;
+				HalDeviceStrListIter argn_iter;
 
-			interfaces = hal_device_property_get_strlist (d, "info.interfaces");
-			for (i = interfaces; i != NULL; i = g_slist_next (i)) {
-				const char *ifname = (const char *) i->data;
-				char *method_names_prop;
-				char *method_signatures_prop;
-				char *method_argnames_prop;
-				GSList *method_names;
-				GSList *method_signatures;
-				GSList *method_argnames;
-				GSList *j;
-				GSList *k;
-				GSList *l;
+				ifname = hal_device_property_strlist_iter_get_value (&if_iter);
 
 				g_string_append_printf (xml, "  <interface name=\"%s\">\n", ifname);
 
-				method_names_prop = g_strdup_printf ("%s.method_names", ifname);
-				method_signatures_prop = g_strdup_printf ("%s.method_signatures", ifname);
-				method_argnames_prop = g_strdup_printf ("%s.method_argnames", ifname);
-
-				method_names = hal_device_property_get_strlist (d, method_names_prop);
-				method_signatures = hal_device_property_get_strlist (d, method_signatures_prop);
-				method_argnames = hal_device_property_get_strlist (d, method_argnames_prop);
+				method_name_prop = g_strdup_printf ("%s.method_names", ifname);
+				method_sign_prop = g_strdup_printf ("%s.method_signatures", ifname);
+				method_argn_prop = g_strdup_printf ("%s.method_argnames", ifname);
 
 				/* consult local list */
-				if (method_names == NULL) {
-					GSList *i;
-
-					for (i = helper_interface_handlers; i != NULL; i = g_slist_next (i)) {
-						HelperInterfaceHandler *hih = i->data;
-						if (strcmp (hih->udi, path) == 0) {
-							xml = g_string_append (xml, hih->introspection_xml);
-						}
+				for (i = helper_interface_handlers; i != NULL; i = g_slist_next (i)) {
+					HelperInterfaceHandler *hih = i->data;
+					if (strcmp (hih->udi, path) == 0) {
+						xml = g_string_append (xml, hih->introspection_xml);
 					}
-					
 				}
-
-				for (j = method_names, k = method_signatures, l = method_argnames;
-				     j != NULL && k != NULL && l != NULL;
-				     j = g_slist_next (j), k = g_slist_next (k), l = g_slist_next (l)) {
+				
+				for (hal_device_property_strlist_iter_init (d, method_name_prop, &name_iter),
+					     hal_device_property_strlist_iter_init (d, method_sign_prop, &sign_iter),
+					     hal_device_property_strlist_iter_init (d, method_argn_prop, &argn_iter);
+				     hal_device_property_strlist_iter_is_valid (&name_iter) &&
+					     hal_device_property_strlist_iter_is_valid (&sign_iter) &&
+					     hal_device_property_strlist_iter_is_valid (&argn_iter);
+				     hal_device_property_strlist_iter_next (&name_iter),
+					     hal_device_property_strlist_iter_next (&sign_iter),
+					     hal_device_property_strlist_iter_next (&argn_iter)) {
 					const char *name;
 					const char *sig;
 					const char *argnames;
@@ -3514,9 +3512,9 @@ do_introspect (DBusConnection  *connecti
 					unsigned int n;
 					unsigned int m;
 
-					name = j->data;
-					sig = k->data;
-					argnames = l->data;
+					name     = hal_device_property_strlist_iter_get_value (&name_iter);
+					sig      = hal_device_property_strlist_iter_get_value (&sign_iter);
+					argnames = hal_device_property_strlist_iter_get_value (&argn_iter);
 
 					args = g_strsplit (argnames, " ", 0);
 
@@ -3558,9 +3556,9 @@ do_introspect (DBusConnection  *connecti
 
 				xml = g_string_append (xml, "  </interface>\n");
 
-				g_free (method_names_prop);
-				g_free (method_signatures_prop);
-				g_free (method_argnames_prop);
+				g_free (method_name_prop);
+				g_free (method_sign_prop);
+				g_free (method_argn_prop);
 			}		
 
 	}
@@ -3848,23 +3846,26 @@ hald_dbus_filter_handle_methods (DBusCon
 		} 
 
 		if (d != NULL && interface != NULL && method != NULL && signature != NULL) {
-			GSList *interfaces;
-			GSList *i;
-
-			interfaces = hal_device_property_get_strlist (d, "info.interfaces");
-			for (i = interfaces; i != NULL; i = g_slist_next (i)) {
-				const char *ifname = (const char *) i->data;
+			HalDeviceStrListIter if_iter;
+			
+			for (hal_device_property_strlist_iter_init (d, "info.interfaces", &if_iter);
+			     hal_device_property_strlist_iter_is_valid (&if_iter);
+			     hal_device_property_strlist_iter_next (&if_iter)) {
+				const char *ifname = hal_device_property_strlist_iter_get_value (&if_iter);
 
 				if (strcmp (ifname, interface) == 0) {
 					guint num;
-					GSList *method_names;
+					HalDeviceStrListIter name_iter;
 					char *s;
 
 					s = g_strdup_printf ("%s.method_names", interface);
-					method_names = hal_device_property_get_strlist (d, s);
+					hal_device_property_strlist_iter_init (d, s, &name_iter);
 					g_free (s);
-					for (i = method_names, num = 0; i != NULL; i = g_slist_next (i), num++) {
-						const char *methodname = (const char *) i->data;
+					for (num = 0; 
+					     hal_device_property_strlist_iter_is_valid (&name_iter);
+					     hal_device_property_strlist_iter_next (&name_iter), num++) {
+						const char *methodname;
+						methodname = hal_device_property_strlist_iter_get_value (&name_iter);
 						if (strcmp (methodname, method) == 0) {
 							const char *execpath;
 							const char *sig;
diff --git a/hald/util.c b/hald/util.c
index 8cac0f1..405cc23 100644
--- a/hald/util.c
+++ b/hald/util.c
@@ -841,7 +841,7 @@ callout_do_next (Callout *c)
 
 static void
 hal_callout_device (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2, 
-		    GSList *programs, gchar **extra_env)
+		    char **programs, gchar **extra_env)
 {
 	Callout *c;
 
@@ -850,7 +850,7 @@ hal_callout_device (HalDevice *d, HalCal
 	c->callback = callback;
 	c->userdata1 = userdata1;
 	c->userdata2 = userdata2;
-	c->programs = hal_util_dup_strv_from_g_slist (programs);
+	c->programs = programs;
 	c->extra_env = g_strdupv (extra_env);
 	c->next_program = 0;
 
@@ -860,14 +860,16 @@ hal_callout_device (HalDevice *d, HalCal
 void
 hal_util_callout_device_add (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2)
 {
-	GSList *programs;
+	char **programs;
 	gchar *extra_env[2] = {"HALD_ACTION=add", NULL};
 
-	if ((programs = hal_device_property_get_strlist (d, "info.callouts.add")) == NULL) {
+	programs = hal_device_property_dup_strlist_as_strv (d, "info.callouts.add");
+	if (programs == NULL) {
 		callback (d, userdata1, userdata2);
 		goto out;
 	}	
 
+
 	HAL_INFO (("Add callouts for udi=%s", hal_device_get_udi (d)));
 
 	hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env);
@@ -878,10 +880,11 @@ out:
 void
 hal_util_callout_device_remove (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2)
 {
-	GSList *programs;
+	char **programs;
 	gchar *extra_env[2] = {"HALD_ACTION=remove", NULL};
 
-	if ((programs = hal_device_property_get_strlist (d, "info.callouts.remove")) == NULL) {
+	programs = hal_device_property_dup_strlist_as_strv (d, "info.callouts.remove");
+	if (programs == NULL) {
 		callback (d, userdata1, userdata2);
 		goto out;
 	}	
@@ -896,10 +899,11 @@ out:
 void
 hal_util_callout_device_preprobe (HalDevice *d, HalCalloutsDone callback, gpointer userdata1, gpointer userdata2)
 {
-	GSList *programs;
+	char **programs;
 	gchar *extra_env[2] = {"HALD_ACTION=preprobe", NULL};
 
-	if ((programs = hal_device_property_get_strlist (d, "info.callouts.preprobe")) == NULL) {
+	programs = hal_device_property_dup_strlist_as_strv (d, "info.callouts.preprobe");
+	if (programs == NULL) {
 		callback (d, userdata1, userdata2);
 		goto out;
 	}	
diff-tree 1f777cb8d4a4300c7762eeb6150789ba0dec9e44 (from 6ae9274c007edfbec8ac101f42a0e8f2a4424bc2)
Author: David Zeuthen <davidz at redhat.com>
Date:   Mon Oct 9 18:49:43 2006 -0400

    make HalProperty private to HalDevice implementation (makes it easier to nuke)

diff --git a/hald/device.c b/hald/device.c
index cfd0f8f..b10dc84 100644
--- a/hald/device.c
+++ b/hald/device.c
@@ -33,6 +33,7 @@
 
 #include "hald.h"
 #include "device.h"
+#include "property.h"
 #include "hald_marshal.h"
 #include "logger.h"
 #include "hald_runner.h"
@@ -443,15 +444,6 @@ hal_device_has_capability (HalDevice *de
 	return matched;
 }
 
-gboolean
-hal_device_has_property (HalDevice *device, const char *key)
-{
-	g_return_val_if_fail (device != NULL, FALSE);
-	g_return_val_if_fail (key != NULL, FALSE);
-
-	return hal_device_property_find (device, key) != NULL;
-}
-
 int
 hal_device_num_properties (HalDevice *device)
 {
@@ -460,7 +452,7 @@ hal_device_num_properties (HalDevice *de
 	return g_slist_length (device->private->properties);
 }
 
-HalProperty *
+static HalProperty *
 hal_device_property_find (HalDevice *device, const char *key)
 {
 	GSList *iter;
@@ -471,13 +463,23 @@ hal_device_property_find (HalDevice *dev
 	for (iter = device->private->properties; iter != NULL; iter = iter->next) {
 		HalProperty *p = iter->data;
 
-		if (strcmp (hal_property_get_key (p), key) == 0)
+		if (strcmp (hal_property_get_key (p), key) == 0) {
 			return p;
+		}
 	}
 
 	return NULL;
 }
 
+gboolean
+hal_device_has_property (HalDevice *device, const char *key)
+{
+	g_return_val_if_fail (device != NULL, FALSE);
+	g_return_val_if_fail (key != NULL, FALSE);
+	
+	return hal_device_property_find (device, key) != NULL;
+}
+
 char *
 hal_device_property_to_string (HalDevice *device, const char *key)
 {
@@ -504,7 +506,7 @@ hal_device_property_foreach (HalDevice *
 		HalProperty *p = iter->data;
 		gboolean cont;
 
-		cont = callback (device, p, user_data);
+		cont = callback (device, hal_property_get_key (p), user_data);
 
 		if (cont == FALSE)
 			return;
diff --git a/hald/device.h b/hald/device.h
index 247e143..b30109c 100644
--- a/hald/device.h
+++ b/hald/device.h
@@ -30,8 +30,6 @@
 #include <glib-object.h>
 #include <dbus/dbus.h>
 
-#include "property.h"
-
 struct _HalDevicePrivate;
 typedef struct _HalDevicePrivate HalDevicePrivate;
 
@@ -67,9 +65,18 @@ struct _HalDeviceClass {
 #define HAL_IS_DEVICE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
                                      HAL_TYPE_DEVICE))
 
+#define HAL_PROPERTY_TYPE_INVALID     DBUS_TYPE_INVALID
+#define HAL_PROPERTY_TYPE_INT32       DBUS_TYPE_INT32
+#define HAL_PROPERTY_TYPE_UINT64      DBUS_TYPE_UINT64
+#define HAL_PROPERTY_TYPE_DOUBLE      DBUS_TYPE_DOUBLE
+#define HAL_PROPERTY_TYPE_BOOLEAN     DBUS_TYPE_BOOLEAN
+#define HAL_PROPERTY_TYPE_STRING      DBUS_TYPE_STRING
+#define HAL_PROPERTY_TYPE_STRLIST     ((int) (DBUS_TYPE_STRING<<8)+('l'))
+
+
 /* Return value of FALSE means that the foreach should be short-circuited */
 typedef gboolean (*HalDevicePropertyForeachFn) (HalDevice *device,
-						HalProperty *property,
+						const char *key,
 						gpointer user_data);
 
 GType         hal_device_get_type            (void);
@@ -99,8 +106,7 @@ gboolean      hal_device_has_capability 
 
 gboolean      hal_device_has_property        (HalDevice    *device,
 					      const char   *key);
-HalProperty  *hal_device_property_find       (HalDevice    *device,
-					      const char   *key);
+
 int           hal_device_num_properties      (HalDevice    *device);
 char *        hal_device_property_to_string  (HalDevice    *device,
 					      const char   *key);
diff --git a/hald/hald_dbus.c b/hald/hald_dbus.c
index 834ee06..f864e63 100644
--- a/hald/hald_dbus.c
+++ b/hald/hald_dbus.c
@@ -675,12 +675,12 @@ out:
  */
 
 static gboolean
-foreach_property_append (HalDevice *device, HalProperty *p,
+foreach_property_append (HalDevice *device, 
+			 const char *key,
 			 gpointer user_data)
 {
 	DBusMessageIter *iter;
 	DBusMessageIter iter_dict_entry;
-	const char *key;
 	int type;
 
 	iter = (DBusMessageIter *)user_data;
@@ -690,8 +690,7 @@ foreach_property_append (HalDevice *devi
 					  NULL,
 					  &iter_dict_entry);
 
-	key = hal_property_get_key (p);
-	type = hal_property_get_type (p);
+	type = hal_device_property_get_type (device, key);
 
 	dbus_message_iter_append_basic (&iter_dict_entry, DBUS_TYPE_STRING, &key);
 
@@ -701,7 +700,7 @@ foreach_property_append (HalDevice *devi
 		DBusMessageIter iter_var;
 		const char *v;
 
-		v = hal_property_get_string (p);
+		v = hal_device_property_get_string (device, key);
 
 		dbus_message_iter_open_container (&iter_dict_entry,
 						  DBUS_TYPE_VARIANT,
@@ -721,7 +720,7 @@ foreach_property_append (HalDevice *devi
 		DBusMessageIter iter_var;
 		dbus_int32_t v;
 
-		v = hal_property_get_int (p);
+		v = hal_device_property_get_int (device, key);
 
 		dbus_message_iter_open_container (&iter_dict_entry,
 						  DBUS_TYPE_VARIANT,
@@ -741,7 +740,7 @@ foreach_property_append (HalDevice *devi
 		DBusMessageIter iter_var;
 		dbus_uint64_t v;
 
-		v = hal_property_get_uint64 (p);
+		v = hal_device_property_get_uint64 (device, key);
 
 		dbus_message_iter_open_container (&iter_dict_entry,
 						  DBUS_TYPE_VARIANT,
@@ -761,7 +760,7 @@ foreach_property_append (HalDevice *devi
 		DBusMessageIter iter_var;
 		double v;
 
-		v = hal_property_get_double (p);
+		v = hal_device_property_get_double (device, key);
 
 		dbus_message_iter_open_container (&iter_dict_entry,
 						  DBUS_TYPE_VARIANT,
@@ -781,7 +780,7 @@ foreach_property_append (HalDevice *devi
 		DBusMessageIter iter_var;
 		dbus_bool_t v;
 
-		v = hal_property_get_bool (p);
+		v = hal_device_property_get_bool (device, key);
 
 		dbus_message_iter_open_container (&iter_dict_entry,
 						  DBUS_TYPE_VARIANT,
@@ -812,7 +811,7 @@ foreach_property_append (HalDevice *devi
 						  DBUS_TYPE_STRING_AS_STRING,
 						  &iter_array);
 
-		for (iter = hal_property_get_strlist (p); iter != NULL; iter = iter->next) {
+		for (iter = hal_device_property_get_strlist (device, key); iter != NULL; iter = iter->next) {
 				     
 			const char *v;
 			v = (const char *) iter->data;
@@ -1125,11 +1124,10 @@ device_get_property (DBusConnection * co
 	const char *udi;
 	char *key;
 	int type;
-	HalProperty *p;
 
 	udi = dbus_message_get_path (message);
 
-	HAL_TRACE (("entering, udi=%s", udi));
+     	HAL_TRACE (("entering, udi=%s", udi));
 
 	d = hal_device_store_find (hald_get_gdl (), udi);
 	if (d == NULL)
@@ -1148,8 +1146,7 @@ device_get_property (DBusConnection * co
 		return DBUS_HANDLER_RESULT_HANDLED;
 	}
 
-	p = hal_device_property_find (d, key);
-	if (p == NULL) {
+	if (!hal_device_has_property (d, key)) {
 		raise_no_such_property (connection, message, udi, key);
 		return DBUS_HANDLER_RESULT_HANDLED;
 	}
@@ -1160,40 +1157,40 @@ device_get_property (DBusConnection * co
 
 	dbus_message_iter_init_append (reply, &iter);
 
-	type = hal_property_get_type (p);
+	type = hal_device_property_get_type (d, key);
 	switch (type) {
 	case HAL_PROPERTY_TYPE_STRING:
 	{
 		const char *s;
-		s = hal_property_get_string (p);
+		s = hal_device_property_get_string (d, key);
 		dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &s);
 		break;
 	}
 	case HAL_PROPERTY_TYPE_INT32:
 	{
 		dbus_int32_t i;
-		i = hal_property_get_int (p);
+		i = hal_device_property_get_int (d, key);
 		dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &i);
 		break;
 	}
 	case HAL_PROPERTY_TYPE_UINT64:
 	{
 		dbus_uint64_t ul;
-		ul = hal_property_get_uint64 (p);
+		ul = hal_device_property_get_uint64 (d, key);
 		dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT64, &ul);
 		break;
 	}
 	case HAL_PROPERTY_TYPE_DOUBLE:
 	{
-		double d;
-		d = hal_property_get_double (p);
-		dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &d);
+		double vd;
+		vd = hal_device_property_get_double (d, key);
+		dbus_message_iter_append_basic (&iter, DBUS_TYPE_DOUBLE, &vd);
 		break;
 	}
 	case HAL_PROPERTY_TYPE_BOOLEAN:
 	{
 		dbus_bool_t b;
-		b = hal_property_get_bool (p);
+		b = hal_device_property_get_bool (d, key);
 		dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &b);
 		break;
 	}
@@ -1207,7 +1204,7 @@ device_get_property (DBusConnection * co
 						  DBUS_TYPE_STRING_AS_STRING,
 						  &iter_array);
 
-		for (l = hal_property_get_strlist (p); l != NULL; l = g_slist_next (l)) {
+		for (l = hal_device_property_get_strlist (d, key); l != NULL; l = g_slist_next (l)) {
 			dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_STRING, &(l->data));
 		}
 
@@ -1252,7 +1249,6 @@ device_get_property_type (DBusConnection
 	HalDevice *d;
 	const char *udi;
 	char *key;
-	HalProperty *p;
 	dbus_int32_t i;
 
 	udi = dbus_message_get_path (message);
@@ -1276,8 +1272,7 @@ device_get_property_type (DBusConnection
 		return DBUS_HANDLER_RESULT_HANDLED;
 	}
 
-	p = hal_device_property_find (d, key);
-	if (p == NULL) {
+	if (!hal_device_has_property (d, key)) {
 		raise_no_such_property (connection, message, udi, key);
 		return DBUS_HANDLER_RESULT_HANDLED;
 	}
@@ -1286,7 +1281,7 @@ device_get_property_type (DBusConnection
 	if (reply == NULL)
 		DIE (("No memory"));
 
-	i = hal_property_get_type (p);
+	i = hal_device_property_get_type (d, key);
 	dbus_message_iter_init_append (reply, &iter);
 	dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &i);
 
diff --git a/hald/hald_runner.c b/hald/hald_runner.c
index b605424..3f916b8 100644
--- a/hald/hald_runner.c
+++ b/hald/hald_runner.c
@@ -289,15 +289,16 @@ error:
 }
 
 static gboolean
-add_property_to_msg (HalDevice *device, HalProperty *property, 
-                                     gpointer user_data)
+add_property_to_msg (HalDevice *device, 
+		     const char *key, 
+		     gpointer user_data)
 {
   char *prop_upper, *value;
   char *c;
   gchar *env;
   DBusMessageIter *iter = (DBusMessageIter *)user_data;
   
-  prop_upper = g_ascii_strup (hal_property_get_key (property), -1);
+  prop_upper = g_ascii_strup (key, -1);
  
   /* periods aren't valid in the environment, so replace them with
    * underscores. */
@@ -306,7 +307,7 @@ add_property_to_msg (HalDevice *device, 
       *c = '_';
   }
 
-  value = hal_property_to_string (property);
+  value = hal_device_property_to_string (device, key);
   env = g_strdup_printf ("HAL_PROP_%s=%s", prop_upper, value);
   dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &env);
 
diff --git a/hald/property.c b/hald/property.c
index 9a1adaa..5f89e78 100644
--- a/hald/property.c
+++ b/hald/property.c
@@ -31,6 +31,7 @@
 #include <string.h>
 #include <glib.h>
 
+#include "device.h"
 #include "logger.h"
 #include "property.h"
 
diff --git a/hald/property.h b/hald/property.h
index 32f21df..07d9597 100644
--- a/hald/property.h
+++ b/hald/property.h
@@ -31,14 +31,6 @@
 
 typedef struct _HalProperty HalProperty;
 
-#define HAL_PROPERTY_TYPE_INVALID         DBUS_TYPE_INVALID
-#define HAL_PROPERTY_TYPE_INT32       DBUS_TYPE_INT32
-#define HAL_PROPERTY_TYPE_UINT64      DBUS_TYPE_UINT64
-#define HAL_PROPERTY_TYPE_DOUBLE      DBUS_TYPE_DOUBLE
-#define HAL_PROPERTY_TYPE_BOOLEAN     DBUS_TYPE_BOOLEAN
-#define HAL_PROPERTY_TYPE_STRING      DBUS_TYPE_STRING
-#define HAL_PROPERTY_TYPE_STRLIST     ((int) (DBUS_TYPE_STRING<<8)+('l'))
-
 void          hal_property_free               (HalProperty  *prop);
 
 HalProperty *hal_property_new_string          (const char   *key,
diff-tree 6ae9274c007edfbec8ac101f42a0e8f2a4424bc2 (from 54192c66659d5c531f74b9859052db06a58b8eaf)
Author: David Zeuthen <davidz at redhat.com>
Date:   Mon Oct 9 17:47:39 2006 -0400

    clean up HalDevice and HalProperty a bit

diff --git a/hald/device.c b/hald/device.c
index 223d431..cfd0f8f 100644
--- a/hald/device.c
+++ b/hald/device.c
@@ -50,8 +50,6 @@ struct _HalDevicePrivate
 enum {
 	PROPERTY_CHANGED,
 	CAPABILITY_ADDED,
-	CALLOUTS_FINISHED,
-	CANCELLED,
 	LAST_SIGNAL
 };
 
@@ -117,26 +115,6 @@ hal_device_class_init (HalDeviceClass *k
 			      hald_marshal_VOID__STRING,
 			      G_TYPE_NONE, 1,
 			      G_TYPE_STRING);
-
-	signals[CALLOUTS_FINISHED] =
-		g_signal_new ("callouts_finished",
-			      G_TYPE_FROM_CLASS (klass),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (HalDeviceClass,
-					       callouts_finished),
-			      NULL, NULL,
-			      hald_marshal_VOID__VOID,
-			      G_TYPE_NONE, 0);
-
-	signals[CANCELLED] =
-		g_signal_new ("cancelled",
-			      G_TYPE_FROM_CLASS (klass),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (HalDeviceClass,
-					       cancelled),
-			      NULL, NULL,
-			      hald_marshal_VOID__VOID,
-			      G_TYPE_NONE, 0);
 }
 
 static void
@@ -920,22 +898,6 @@ hal_device_property_remove (HalDevice *d
 	return TRUE;
 }
 
-gboolean
-hal_device_property_set_attribute (HalDevice *device,
-				   const char *key,
-				   enum PropertyAttribute attr,
-				   gboolean val)
-{
-	HalProperty *prop;
-
-	prop = hal_device_property_find (device, key);
-
-	if (prop == NULL)
-		return FALSE;
-
-	return TRUE;
-}
-
 void
 hal_device_print (HalDevice *device)
 {
@@ -988,110 +950,6 @@ hal_device_print (HalDevice *device)
         fprintf (stderr, "\n");
 }
 
-
-typedef struct {
-	char *key;
-	HalDevice *device;
-	HalDeviceAsyncCallback callback;
-	gpointer user_data;
-
-	guint prop_signal_id;
-	guint timeout_id;
-} AsyncMatchInfo;
-
-static void
-destroy_async_match_info (AsyncMatchInfo *ai)
-{
-	g_free (ai->key);
-	g_signal_handler_disconnect (ai->device, ai->prop_signal_id);
-	g_source_remove (ai->timeout_id);
-	g_object_unref (ai->device);
-	g_free (ai);
-}
-
-static void
-prop_changed_cb (HalDevice *device, const char *key,
-		 gboolean removed, gboolean added, gpointer user_data)
-{
-	AsyncMatchInfo *ai = user_data;
-
-	if (strcmp (key, ai->key) != 0)
-		return;
-
-	/* the property is no longer there */
-	if (removed)
-		goto cleanup;
-
-
-	ai->callback (ai->device, ai->user_data, TRUE);
-
-cleanup:
-	destroy_async_match_info (ai);
-}
-
-
-static gboolean
-async_wait_timeout (gpointer user_data)
-{
-	AsyncMatchInfo *ai = (AsyncMatchInfo *) user_data;
-
-	ai->callback (ai->device, ai->user_data, FALSE);
-
-	destroy_async_match_info (ai);
-
-	return FALSE;
-}
-
-void
-hal_device_async_wait_property (HalDevice    *device,
-				const char   *key,
-				HalDeviceAsyncCallback callback,
-				gpointer     user_data,
-				int          timeout)
-{
-	HalProperty *prop;
-	AsyncMatchInfo *ai;
-
-	/* check if property already exists */
-	prop = hal_device_property_find (device, key);
-
-	if (prop != NULL || timeout==0) {
-		callback (device, user_data, prop != NULL);
-		return;
-	}
-
-	ai = g_new0 (AsyncMatchInfo, 1);
-
-	ai->device = g_object_ref (device);
-	ai->key = g_strdup (key);
-	ai->callback = callback;
-	ai->user_data = user_data;
-
-	ai->prop_signal_id = g_signal_connect (device, "property_changed",
-					       G_CALLBACK (prop_changed_cb),
-					       ai);
-
-	ai->timeout_id = g_timeout_add (timeout, async_wait_timeout, ai);
-}
-
-void
-hal_device_callouts_finished (HalDevice *device)
-{
-	g_signal_emit (device, signals[CALLOUTS_FINISHED], 0);
-}
-
-/** Used when giving up on a device, e.g. if no device file appeared
- */
-void
-hal_device_cancel (HalDevice *device)
-{
-	HAL_INFO (("udi=%s", device->private->udi));
-	g_signal_emit (device, signals[CANCELLED], 0);
-}
-
-
-
-
 GSList *
 hal_device_property_get_strlist (HalDevice    *device, 
 				 const char   *key)
diff --git a/hald/device.h b/hald/device.h
index 6ffe494..247e143 100644
--- a/hald/device.h
+++ b/hald/device.h
@@ -55,10 +55,6 @@ struct _HalDeviceClass {
 
 	void (*capability_added) (HalDevice *device,
 				  const char *capability);
-
-	void (*callouts_finished) (HalDevice *device);
-
-	void (*cancelled) (HalDevice *device);
 };
 
 #define HAL_TYPE_DEVICE             (hal_device_get_type ())
@@ -71,10 +67,6 @@ struct _HalDeviceClass {
 #define HAL_IS_DEVICE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), \
                                      HAL_TYPE_DEVICE))
 
-typedef void     (*HalDeviceAsyncCallback) (HalDevice *device,
-					    gpointer user_data,
-					    gboolean prop_exists);
-
 /* Return value of FALSE means that the foreach should be short-circuited */
 typedef gboolean (*HalDevicePropertyForeachFn) (HalDevice *device,
 						HalProperty *property,
@@ -180,29 +172,14 @@ gboolean      hal_device_property_strlis
 gboolean      hal_device_property_remove     (HalDevice    *device,
 					      const char   *key);
 
+
+void          hal_device_print               (HalDevice    *device);
+
 gboolean      hal_device_copy_property       (HalDevice *from_device, 
 					      const char *from,
 					      HalDevice *to_device,
 					      const char *to);
 
-
-void          hal_device_print               (HalDevice    *device);
-
-void          hal_device_async_wait_property (HalDevice    *device,
-					      const char   *key,
-					      HalDeviceAsyncCallback callback,
-					      gpointer      user_data,
-					      int           timeout);
-
-void          hal_device_callouts_finished    (HalDevice    *device);
-
-void          hal_device_cancel               (HalDevice    *device);
-
-gboolean      hal_device_property_set_attribute (HalDevice *device,
-						 const char *key,
-						 enum PropertyAttribute attr,
-						 gboolean persistence);
-
 void          hal_device_inc_num_addons (HalDevice *device);
 
 gboolean      hal_device_inc_num_ready_addons (HalDevice *device);
diff --git a/hald/linux/coldplug.c b/hald/linux/coldplug.c
index 3693cda..d220f4a 100644
--- a/hald/linux/coldplug.c
+++ b/hald/linux/coldplug.c
@@ -227,6 +227,7 @@ static HotplugEvent
 	struct stat statbuf;
 	gboolean from_pool = FALSE;
 
+	/* TODO: FIXME: this is experimental code */
 	if (pool == NULL) {
 		pool = g_new0 (HotplugEvent, pool_size);
 		pool_next_free = 0;
diff --git a/hald/linux/osspec.c b/hald/linux/osspec.c
index def76ff..ee3d2b2 100644
--- a/hald/linux/osspec.c
+++ b/hald/linux/osspec.c
@@ -448,7 +448,7 @@ set_suspend_hibernate_keys (HalDevice *d
 	ssize_t read;
 	size_t len;
 	char *poweroptions;
-	char *pmtype;
+	const char *pmtype;
 	FILE *fp;
 
 	can_suspend = FALSE;
@@ -474,7 +474,7 @@ set_suspend_hibernate_keys (HalDevice *d
 		can_hibernate = TRUE;
 	free (poweroptions);
 
-	pmtype = hal_device_property_get_string(d, "power_management.type");
+	pmtype = hal_device_property_get_string (d, "power_management.type");
 	if (pmtype != NULL && strcmp(pmtype, "pmu") == 0) {
 		/* We got our own helper for suspend PMU machines */
 		can_suspend = TRUE;
diff --git a/hald/property.c b/hald/property.c
index 8a4955d..9a1adaa 100644
--- a/hald/property.c
+++ b/hald/property.c
@@ -37,8 +37,6 @@
 struct _HalProperty {
 	char *key;
 
-	void *foo;
-
 	int type;
 	union {
 		char *str_value;
@@ -48,9 +46,6 @@ struct _HalProperty {
 		double double_value;
 		GSList *strlist_value;
 	} v;
-	gboolean readonly;
-	gboolean persistence;
-	gboolean callout;
 };
 
 void
@@ -343,44 +338,6 @@ hal_property_set_double (HalProperty *pr
 	prop->v.double_value = value;
 }
 
-void
-hal_property_set_attribute (HalProperty *prop,
-			    enum PropertyAttribute attr,
-			    gboolean val)
-{
-	g_return_if_fail (prop != NULL);
-
-	switch (attr) {
-	case READONLY:
-		prop->readonly = val;
-		break;
-	case PERSISTENCE:
-		prop->persistence = val;
-		break;
-	case CALLOUT:
-		prop->callout = val;
-		break;
-	}
-}
-
-gboolean
-hal_property_get_attribute (HalProperty *prop,
-			    enum PropertyAttribute attr)
-{
-	g_return_val_if_fail (prop != NULL, -1);
-
-	switch (attr) {
-	case READONLY:
-		return prop->readonly;
-	case PERSISTENCE:
-		return prop->persistence;
-	case CALLOUT:
-		return prop->callout;
-	default:
-		return -1;
-	}
-}
-
 HalProperty *
 hal_property_new_strlist (const char *key)
 {
diff --git a/hald/property.h b/hald/property.h
index b5afa25..32f21df 100644
--- a/hald/property.h
+++ b/hald/property.h
@@ -39,12 +39,6 @@ typedef struct _HalProperty HalProperty;
 #define HAL_PROPERTY_TYPE_STRING      DBUS_TYPE_STRING
 #define HAL_PROPERTY_TYPE_STRLIST     ((int) (DBUS_TYPE_STRING<<8)+('l'))
 
-enum PropertyAttribute {
-	READONLY,
-	PERSISTENCE,
-	CALLOUT
-};
-
 void          hal_property_free               (HalProperty  *prop);
 
 HalProperty *hal_property_new_string          (const char   *key,
@@ -94,10 +88,4 @@ gboolean      hal_property_strlist_remov
 gboolean      hal_property_strlist_clear      (HalProperty  *prop);
 
 
-void          hal_property_set_attribute      (HalProperty *prop,
-					       enum PropertyAttribute attr,
-					       gboolean val);
-gboolean      hal_property_get_attribute      (HalProperty *prop,
-					       enum PropertyAttribute attr);
-
 #endif /* PROPERTY_H */
diff-tree 54192c66659d5c531f74b9859052db06a58b8eaf (from bd9e32febb881700d76fb3524c86ee469463a946)
Author: David Zeuthen <davidz at redhat.com>
Date:   Mon Oct 9 03:15:27 2006 -0400

    some memory optimization work
    
    There's an interesting behavior on startup. On my machine we allocate
    around 300 HotplugEvent objects (each of 3604 bytes) on startup and
    put them on the queue. When we're done processing an event it's freed.
    This leads to interesting memory fragmentation problems. Some
    experimental code I've just put in allocates the first 1000 in a fixed
    array. Seems to save 200-300kb writable memory.
    
    Also move some bits of HalDevice into HalDevicePrivate. Fix up the
    rest of the code not to rely on the ->udi member as it's now only
    available through the existing hal_device_get_uid() method.

diff --git a/hald-runner/main.c b/hald-runner/main.c
index fbb7a63..18565bf 100644
--- a/hald-runner/main.c
+++ b/hald-runner/main.c
@@ -180,6 +180,10 @@ filter(DBusConnection *con, DBusMessage 
 	} else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "Kill")) {
 		handle_kill(con, msg);
 		return DBUS_HANDLER_RESULT_HANDLED;
+	} else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "Shutdown")) {
+		run_kill_all ();
+		exit (0);
+		return DBUS_HANDLER_RESULT_HANDLED;
 	} else if (dbus_message_is_method_call(msg, "org.freedesktop.HalRunner", "KillAll")) {
 		run_kill_all();
 		/* alwasy successfull */
diff --git a/hald/debug-hald.sh b/hald/debug-hald.sh
index c2aab4b..acc91aa 100755
--- a/hald/debug-hald.sh
+++ b/hald/debug-hald.sh
@@ -3,8 +3,12 @@
 export HALD_RUNNER_PATH=`pwd`/linux:`pwd`/linux/probing:`pwd`/linux/addons:`pwd`/.:`pwd`/../tools:`pwd`/../tools/linux
 export PATH=`pwd`/../hald-runner:$PATH
 
-rm -rf .local-fdi
-make -C ../fdi install DESTDIR=`pwd`/.local-fdi prefix=/
+if [ "$1" = "--skip-fdi-install" ] ; then
+    shift
+else
+    rm -rf .local-fdi
+    make -C ../fdi install DESTDIR=`pwd`/.local-fdi prefix=/
+fi
 export HAL_FDI_SOURCE_PREPROBE=.local-fdi/share/hal/fdi/preprobe
 export HAL_FDI_SOURCE_INFORMATION=.local-fdi/share/hal/fdi/information
 export HAL_FDI_SOURCE_POLICY=.local-fdi/share/hal/fdi/policy
@@ -12,5 +16,5 @@ export HAL_FDI_SOURCE_POLICY=.local-fdi/
 echo ========================================
 echo Just type \'run\' to start debugging hald
 echo ========================================
-gdb run --args ./hald --daemon=no --verbose=yes
+gdb run --args ./hald --daemon=no --verbose=yes $@
 
diff --git a/hald/device.c b/hald/device.c
index f54401f..223d431 100644
--- a/hald/device.c
+++ b/hald/device.c
@@ -39,6 +39,14 @@
 
 static GObjectClass *parent_class;
 
+struct _HalDevicePrivate
+{
+	char *udi;	
+	int num_addons;
+	int num_addons_ready;
+	GSList *properties;
+};
+
 enum {
 	PROPERTY_CHANGED,
 	CAPABILITY_ADDED,
@@ -62,17 +70,19 @@ hal_device_finalize (GObject *obj)
 
 #ifdef HALD_MEMLEAK_DBG
 	dbg_hal_device_object_delta--;
-	printf ("************* in finalize for udi=%s\n", device->udi);
+	printf ("************* in finalize for udi=%s\n", device->private->udi);
 #endif
 
 
-	g_slist_foreach (device->properties, (GFunc) hal_property_free, NULL);
+	g_slist_foreach (device->private->properties, (GFunc) hal_property_free, NULL);
+	g_slist_free (device->private->properties);
 
-	g_free (device->udi);
+	g_free (device->private->udi);
+
+	g_free (device->private);
 
 	if (parent_class->finalize)
 		parent_class->finalize (obj);
-
 }
 
 static void
@@ -134,10 +144,12 @@ hal_device_init (HalDevice *device)
 {
 	static int temp_device_counter = 0;
 
-	device->udi = g_strdup_printf ("/org/freedesktop/Hal/devices/temp/%d",
+	device->private = g_new0 (HalDevicePrivate, 1);
+
+	device->private->udi = g_strdup_printf ("/org/freedesktop/Hal/devices/temp/%d",
 				       temp_device_counter++);
-	device->num_addons = 0;
-	device->num_addons_ready = 0;
+	device->private->num_addons = 0;
+	device->private->num_addons_ready = 0;
 }
 
 GType
@@ -204,7 +216,7 @@ hal_device_merge_with_rewrite  (HalDevic
 
 	/* device_property_atomic_update_begin (); */
 
-	for (iter = source->properties; iter != NULL; iter = iter->next) {
+	for (iter = source->private->properties; iter != NULL; iter = iter->next) {
 		HalProperty *p = iter->data;
 		int type;
 		const char *key;
@@ -279,7 +291,7 @@ hal_device_merge (HalDevice *target, Hal
 
 	/* device_property_atomic_update_begin (); */
 
-	for (iter = source->properties; iter != NULL; iter = iter->next) {
+	for (iter = source->private->properties; iter != NULL; iter = iter->next) {
 		HalProperty *p = iter->data;
 		int type;
 		const char *key;
@@ -353,7 +365,7 @@ hal_device_matches (HalDevice *device1, 
 
 	len = strlen (namespace);
 
-	for (iter = device1->properties; iter != NULL; iter = iter->next) {
+	for (iter = device1->private->properties; iter != NULL; iter = iter->next) {
 		HalProperty *p;
 		const char *key;
 		int type;
@@ -413,15 +425,15 @@ hal_device_matches (HalDevice *device1, 
 const char *
 hal_device_get_udi (HalDevice *device)
 {
-	return device->udi;
+	return device->private->udi;
 }
 
 void
 hal_device_set_udi (HalDevice *device, const char *udi)
 {
-	if (device->udi != NULL)
-		g_free (device->udi);
-	device->udi = g_strdup (udi);
+	if (device->private->udi != NULL)
+		g_free (device->private->udi);
+	device->private->udi = g_strdup (udi);
 }
 
 void
@@ -467,7 +479,7 @@ hal_device_num_properties (HalDevice *de
 {
 	g_return_val_if_fail (device != NULL, -1);
 
-	return g_slist_length (device->properties);
+	return g_slist_length (device->private->properties);
 }
 
 HalProperty *
@@ -478,7 +490,7 @@ hal_device_property_find (HalDevice *dev
 	g_return_val_if_fail (device != NULL, NULL);
 	g_return_val_if_fail (key != NULL, NULL);
 
-	for (iter = device->properties; iter != NULL; iter = iter->next) {
+	for (iter = device->private->properties; iter != NULL; iter = iter->next) {
 		HalProperty *p = iter->data;
 
 		if (strcmp (hal_property_get_key (p), key) == 0)
@@ -510,7 +522,7 @@ hal_device_property_foreach (HalDevice *
 	g_return_if_fail (device != NULL);
 	g_return_if_fail (callback != NULL);
 
-	for (iter = device->properties; iter != NULL; iter = iter->next) {
+	for (iter = device->private->properties; iter != NULL; iter = iter->next) {
 		HalProperty *p = iter->data;
 		gboolean cont;
 
@@ -708,7 +720,7 @@ hal_device_property_set_string (HalDevic
 
 		prop = hal_property_new_string (key, value);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -742,7 +754,7 @@ hal_device_property_set_int (HalDevice *
 	} else {
 		prop = hal_property_new_int (key, value);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -776,7 +788,7 @@ hal_device_property_set_uint64 (HalDevic
 	} else {
 		prop = hal_property_new_uint64 (key, value);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -810,7 +822,7 @@ hal_device_property_set_bool (HalDevice 
 	} else {
 		prop = hal_property_new_bool (key, value);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -844,7 +856,7 @@ hal_device_property_set_double (HalDevic
 	} else {
 		prop = hal_property_new_double (key, value);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -898,7 +910,7 @@ hal_device_property_remove (HalDevice *d
 	if (prop == NULL)
 		return FALSE;
 
-	device->properties = g_slist_remove (device->properties, prop);
+	device->private->properties = g_slist_remove (device->private->properties, prop);
 
 	hal_property_free (prop);
 
@@ -931,7 +943,7 @@ hal_device_print (HalDevice *device)
 
         fprintf (stderr, "device udi = %s\n", hal_device_get_udi (device));
 
-	for (iter = device->properties; iter != NULL; iter = iter->next) {
+	for (iter = device->private->properties; iter != NULL; iter = iter->next) {
 		HalProperty *p = iter->data;
                 int type;
                 const char *key;
@@ -1073,7 +1085,7 @@ hal_device_callouts_finished (HalDevice 
 void
 hal_device_cancel (HalDevice *device)
 {
-	HAL_INFO (("udi=%s", device->udi));
+	HAL_INFO (("udi=%s", device->private->udi));
 	g_signal_emit (device, signals[CANCELLED], 0);
 }
 
@@ -1139,7 +1151,7 @@ hal_device_property_strlist_append (HalD
 		prop = hal_property_new_strlist (key);
 		hal_property_strlist_append (prop, value);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -1171,7 +1183,7 @@ hal_device_property_strlist_prepend (Hal
 		prop = hal_property_new_strlist (key);
 		hal_property_strlist_prepend (prop, value);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -1217,7 +1229,7 @@ hal_device_property_strlist_clear (HalDe
 	if (prop == NULL) {
 		prop = hal_property_new_strlist (key);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -1265,7 +1277,7 @@ hal_device_property_strlist_add (HalDevi
 		prop = hal_property_new_strlist (key);
 		hal_property_strlist_prepend (prop, value);
 
-		device->properties = g_slist_prepend (device->properties, prop);
+		device->private->properties = g_slist_prepend (device->private->properties, prop);
 
 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
 			       key, FALSE, TRUE);
@@ -1323,7 +1335,7 @@ hal_device_property_strlist_is_empty (Ha
 void
 hal_device_inc_num_addons (HalDevice *device)
 {
-	device->num_addons++;
+	device->private->num_addons++;
 }
 
 gboolean
@@ -1331,18 +1343,18 @@ hal_device_inc_num_ready_addons (HalDevi
 {
 	if (hal_device_are_all_addons_ready (device)) {
 		HAL_ERROR (("In hal_device_inc_num_ready_addons for udi=%s but all addons are already ready!", 
-			    device->udi));
+			    device->private->udi));
 		return FALSE;
 	}
 
-	device->num_addons_ready++;
+	device->private->num_addons_ready++;
 	return TRUE;
 }
 
 gboolean
 hal_device_are_all_addons_ready (HalDevice *device)
 {
-	if (device->num_addons_ready == device->num_addons) {
+	if (device->private->num_addons_ready == device->private->num_addons) {
 		return TRUE;
 	} else {
 		return FALSE;
diff --git a/hald/device.h b/hald/device.h
index a9531ba..6ffe494 100644
--- a/hald/device.h
+++ b/hald/device.h
@@ -32,18 +32,16 @@
 
 #include "property.h"
 
+struct _HalDevicePrivate;
+typedef struct _HalDevicePrivate HalDevicePrivate;
+
+
 typedef struct _HalDevice      HalDevice;
 typedef struct _HalDeviceClass HalDeviceClass;
 
 struct _HalDevice {
 	GObject parent;
-
-	char *udi;
-	
-	GSList *properties;
-
-	int num_addons;
-	int num_addons_ready;
+	HalDevicePrivate *private;
 };
 
 struct _HalDeviceClass {
@@ -84,7 +82,7 @@ typedef gboolean (*HalDevicePropertyFore
 
 GType         hal_device_get_type            (void);
 
-HalDevice   *hal_device_new                  (void);
+HalDevice    *hal_device_new                 (void);
 
 void          hal_device_merge               (HalDevice    *target,
 					      HalDevice    *source);
diff --git a/hald/device_info.c b/hald/device_info.c
index cf42935..6f2a153 100644
--- a/hald/device_info.c
+++ b/hald/device_info.c
@@ -345,10 +345,10 @@ handle_match (ParsingContext * pc, const
 
 	/* Resolve key paths like 'someudi/foo/bar/baz:prop.name' '@prop.here.is.an.udi:with.prop.name' */
 	if (!resolve_udiprop_path (key,
-				   pc->device->udi,
+				   hal_device_get_udi (pc->device),
 				   udi_to_check, sizeof (udi_to_check),
 				   prop_to_check, sizeof (prop_to_check))) {
-		HAL_ERROR (("Could not resolve keypath '%s' on udi '%s'", key, pc->device->udi));
+		HAL_ERROR (("Could not resolve keypath '%s' on udi '%s'", key, hal_device_get_udi (pc->device)));
 		return FALSE;
 	}
 
@@ -537,7 +537,7 @@ handle_match (ParsingContext * pc, const
 		if (strcmp (attr[3], "false") == 0)
 			should_be_absolute_path = FALSE;
 
-		/*HAL_INFO (("d->udi='%s', prop_to_check='%s'", d->udi, prop_to_check));*/
+		/*HAL_INFO (("hal_device_get_udi (d)='%s', prop_to_check='%s'", hal_device_get_udi (d), prop_to_check));*/
 
 		if (hal_device_property_get_type (d, prop_to_check) != HAL_PROPERTY_TYPE_STRING)
 			return FALSE;
@@ -1074,7 +1074,7 @@ start (ParsingContext * pc, const char *
 static void 
 spawned_device_callouts_add_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
 {
-	HAL_INFO (("Add callouts completed udi=%s", d->udi));
+	HAL_INFO (("Add callouts completed udi=%s", hal_device_get_udi (d)));
 
 	/* Move from temporary to global device store */
 	hal_device_store_remove (hald_get_tdl (), d);
@@ -1165,10 +1165,11 @@ end (ParsingContext * pc, const char *el
 			 * '@prop.here.is.an.udi:with.prop.name'
 			 */
 			if (!resolve_udiprop_path (pc->cdata_buf,
-						   pc->device->udi,
+						   hal_device_get_udi (pc->device),
 						   udi_to_merge_from, sizeof (udi_to_merge_from),
 						   prop_to_merge, sizeof (prop_to_merge))) {
-				HAL_ERROR (("Could not resolve keypath '%s' on udi '%s'", pc->cdata_buf, pc->device->udi));
+				HAL_ERROR (("Could not resolve keypath '%s' on udi '%s'", pc->cdata_buf, 
+					    hal_device_get_udi (pc->device)));
 			} else {
 				HalDevice *d;
 
@@ -1286,12 +1287,12 @@ end (ParsingContext * pc, const char *el
 
 		if (spawned == NULL) {
 			HAL_INFO (("Spawning new device object '%s' caused by <spawn> on udi '%s'", 
-				   pc->merge_key, pc->device->udi));
+				   pc->merge_key, hal_device_get_udi (pc->device)));
 
 			spawned = hal_device_new ();
 			hal_device_property_set_string (spawned, "info.bus", "unknown");
 			hal_device_property_set_string (spawned, "info.udi", pc->merge_key);
-			hal_device_property_set_string (spawned, "info.parent", pc->device->udi);
+			hal_device_property_set_string (spawned, "info.parent", hal_device_get_udi (pc->device));
 			hal_device_set_udi (spawned, pc->merge_key);
 			
 			hal_device_store_add (hald_get_tdl (), spawned);
diff --git a/hald/device_store.c b/hald/device_store.c
index d11cf6e..1515450 100644
--- a/hald/device_store.c
+++ b/hald/device_store.c
@@ -174,7 +174,7 @@ hal_device_store_add (HalDeviceStore *st
 {
 	const char buf[] = "/org/freedesktop/Hal/devices/";
 
-	if (strncmp(device->udi, buf, sizeof (buf) - 1) != 0) {
+	if (strncmp(hal_device_get_udi (device), buf, sizeof (buf) - 1) != 0) {
 		
 		HAL_ERROR(("Can't add HalDevice with incorrect UDI. Valid "
 			   "UDI must start with '/org/freedesktop/Hal/devices/'"));
diff --git a/hald/dummy/osspec.c b/hald/dummy/osspec.c
index 74165ec..4d010f7 100644
--- a/hald/dummy/osspec.c
+++ b/hald/dummy/osspec.c
@@ -45,7 +45,7 @@ osspec_init (void)
 static void 
 computer_callouts_add_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
 {
-	HAL_INFO (("Add callouts completed udi=%s", d->udi));
+	HAL_INFO (("Add callouts completed udi=%s", hal_device_get_udi (d)));
 
 	/* Move from temporary to global device store */
 	hal_device_store_remove (hald_get_tdl (), d);
diff --git a/hald/hald.c b/hald/hald.c
index cb5c6c7..48b35f4 100644
--- a/hald/hald.c
+++ b/hald/hald.c
@@ -79,7 +79,7 @@ addon_terminated (HalDevice *device, gui
 		  gint return_code, gchar **error,
 		  gpointer data1, gpointer data2)
 {
-	HAL_INFO (("in addon_terminated for udi=%s", device->udi));
+	HAL_INFO (("in addon_terminated for udi=%s", hal_device_get_udi (device)));
 
 	/* TODO: log to syslog - addons shouldn't just terminate, this is a bug with the addon */
 
@@ -371,6 +371,10 @@ main (int argc, char *argv[])
 
 	openlog ("hald", LOG_PID, LOG_DAEMON);
 
+#ifdef HALD_MEMLEAK_DBG
+	g_mem_set_vtable (glib_mem_profiler_table);
+#endif
+
 	g_type_init ();
 
 	if (getenv ("HALD_VERBOSE"))
@@ -473,6 +477,7 @@ main (int argc, char *argv[])
 	/*master_slave_setup ();
 	  sleep (100000000);*/
 
+
 	loop = g_main_loop_new (NULL, FALSE);
 
 	HAL_INFO ((PACKAGE_STRING));
@@ -543,7 +548,6 @@ main (int argc, char *argv[])
 		HAL_INFO (("Will not daemonize"));
 	}
 
-
 	/* we need to do stuff when we are expected to terminate, thus
 	 * this involves looking for SIGTERM; UNIX signal handlers are
 	 * evil though, so set up a pipe to transmit the signal.
@@ -569,6 +573,7 @@ main (int argc, char *argv[])
 	/* set up the local dbus server */
 	if (!hald_dbus_local_server_init ())
 		return 1;
+
 	/* Start the runner helper daemon */
 	if (!hald_runner_start_runner ()) {
 		return 1;
@@ -595,12 +600,21 @@ extern int dbg_hal_device_object_delta;
 
 /* useful for valgrinding; see below */
 static gboolean
+my_shutdown2 (gpointer data)
+{
+	g_mem_profile ();
+	sleep (10000);
+	/*exit (1);*/
+	return FALSE;
+}
+
+static gboolean
 my_shutdown (gpointer data)
 {
 	HalDeviceStore *gdl;
 	
-	printf ("Num devices in TDL: %d\n", g_slist_length ((hald_get_tdl ())->devices));
-	printf ("Num devices in GDL: %d\n", g_slist_length ((hald_get_gdl ())->devices));
+	HAL_INFO (("Num devices in TDL: %d", g_slist_length ((hald_get_tdl ())->devices)));
+	HAL_INFO (("Num devices in GDL: %d", g_slist_length ((hald_get_gdl ())->devices)));
 	
 	gdl = hald_get_gdl ();
 next:
@@ -609,10 +623,19 @@ next:
 		hal_device_store_remove (gdl, d);
 		g_object_unref (d);
 		goto next;
-	}
-	
-	printf ("hal_device_object_delta = %d (should be zero)\n", dbg_hal_device_object_delta);
-	exit (1);
+	}	
+
+	HAL_INFO (("hal_device_object_delta = %d (should be zero)", dbg_hal_device_object_delta));
+
+	hald_dbus_local_server_shutdown ();
+	hald_runner_stop_runner ();
+
+	HAL_INFO (("Shutting down in five seconds"));
+	g_timeout_add (5 * 1000,
+		       my_shutdown2,
+		       NULL);
+
+	return FALSE;
 }
 #endif
 
diff --git a/hald/hald.h b/hald/hald.h
index b810947..cb86cd7 100644
--- a/hald/hald.h
+++ b/hald/hald.h
@@ -56,7 +56,7 @@ extern dbus_bool_t hald_is_shutting_down
  *
  * Use hald/valgrind-hald.sh for this
  */
-/*#define HALD_MEMLEAK_DBG 60*/
+/*#define HALD_MEMLEAK_DBG 10*/
 
 /**
  *  @}
diff --git a/hald/hald_dbus.c b/hald/hald_dbus.c
index 7a51bfb..834ee06 100644
--- a/hald/hald_dbus.c
+++ b/hald/hald_dbus.c
@@ -342,7 +342,7 @@ foreach_device_match_get_udi_tdl (HalDev
 	const char *dev_value;
 
 	/* skip devices in the TDL that hasn't got a real UDI yet */
-	if (strncmp (device->udi, "/org/freedesktop/Hal/devices/temp",
+	if (strncmp (hal_device_get_udi (device), "/org/freedesktop/Hal/devices/temp",
 		     sizeof ("/org/freedesktop/Hal/devices/temp")) == 0)
 		return TRUE;
 
@@ -444,9 +444,11 @@ foreach_device_by_capability (HalDeviceS
 	DeviceCapabilityInfo *info = (DeviceCapabilityInfo *) user_data;
 
 	if (hal_device_has_capability (device, info->capability)) {
+		const char *udi;
+		udi = hal_device_get_udi (device);
 		dbus_message_iter_append_basic (info->iter,
 						DBUS_TYPE_STRING,
-						&(device->udi));
+						&udi);
 	}
 
 	return TRUE;
@@ -2125,7 +2127,7 @@ device_send_signal_property_modified (Ha
 
 /*
     HAL_INFO(("Entering, udi=%s, key=%s, in_gdl=%s, removed=%s added=%s",
-              device->udi, key, 
+              hal_device_get_udi (device), key, 
               in_gdl ? "true" : "false",
               removed ? "true" : "false",
               added ? "true" : "false"));
@@ -2629,7 +2631,7 @@ manager_new_device (DBusConnection * con
 static void 
 manager_remove_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
 {
-	HAL_INFO (("Remove callouts completed udi=%s", d->udi));
+	HAL_INFO (("Remove callouts completed udi=%s", hal_device_get_udi (d)));
 
 	if (!hal_device_store_remove (hald_get_gdl (), d)) {
 		HAL_WARNING (("Error removing device"));
@@ -2708,7 +2710,7 @@ manager_remove (DBusConnection * connect
 static void
 manager_commit_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
 {
-	HAL_INFO (("Add callouts completed udi=%s", d->udi));
+	HAL_INFO (("Add callouts completed udi=%s", hal_device_get_udi (d)));
 }
 
 /*
@@ -2902,7 +2904,7 @@ device_is_executing_method (HalDevice *d
 
 	ret = FALSE;
 
-	if (g_hash_table_lookup_extended (udi_to_method_queue, d->udi, &origkey, (gpointer) &queue)) {
+	if (g_hash_table_lookup_extended (udi_to_method_queue, hal_device_get_udi (d), &origkey, (gpointer) &queue)) {
 
 		if (queue != NULL) {
 			MethodInvocation *mi;
@@ -3013,7 +3015,7 @@ hald_exec_method_cb (HalDevice *d, guint
 	gchar *exp_name = NULL;
 	gchar *exp_detail = NULL;
 
-	hald_exec_method_process_queue (d->udi);
+	hald_exec_method_process_queue (hal_device_get_udi (d));
 
 	message = (DBusMessage *) data1;
 	conn = (DBusConnection *) data2;
@@ -3218,7 +3220,7 @@ hald_exec_method (HalDevice *d, DBusConn
 	}
 
 	mi = g_new0 (MethodInvocation, 1);
-	mi->udi = g_strdup (d->udi);
+	mi->udi = g_strdup (hal_device_get_udi (d));
 	mi->execpath = g_strdup (execpath);
 	mi->extra_env = g_strdupv (extra_env);
 	mi->mstdin = g_strdup (stdin_str->str);
@@ -3943,11 +3945,11 @@ local_server_message_handler (DBusConnec
 			      DBusMessage *message, 
 			      void *user_data)
 {
-	/*HAL_INFO (("local_server_message_handler: destination=%s obj_path=%s interface=%s method=%s", 
+	HAL_INFO (("local_server_message_handler: destination=%s obj_path=%s interface=%s method=%s", 
 		   dbus_message_get_destination (message), 
 		   dbus_message_get_path (message), 
 		   dbus_message_get_interface (message),
-		   dbus_message_get_member (message)));*/
+		   dbus_message_get_member (message)));
 
 	if (dbus_message_is_method_call (message, "org.freedesktop.DBus", "AddMatch")) {
 		DBusMessage *reply;
@@ -3965,7 +3967,9 @@ local_server_message_handler (DBusConnec
 		GSList *i;
 		GSList *j;
 		
-		HAL_INFO (("Client to local_server was disconnected"));
+		HAL_INFO (("************************"));
+		HAL_INFO (("Client to local_server was disconnected for %x", connection));
+		HAL_INFO (("************************"));
 
 		for (i = helper_interface_handlers; i != NULL; i = j) {
 			HelperInterfaceHandler *hih = i->data;
@@ -3993,7 +3997,9 @@ local_server_message_handler (DBusConnec
 		}
 		dbus_message_unref (copy);
 	} else {
-		return hald_dbus_filter_handle_methods (connection, message, user_data, TRUE);
+		DBusHandlerResult ret;
+		ret = hald_dbus_filter_handle_methods (connection, message, user_data, TRUE);
+		return ret;
 	}
 
 	return DBUS_HANDLER_RESULT_HANDLED;
@@ -4002,7 +4008,9 @@ local_server_message_handler (DBusConnec
 static void
 local_server_unregister_handler (DBusConnection *connection, void *user_data)
 {
-	HAL_INFO (("unregistered"));
+	HAL_INFO (("***************************"));
+	HAL_INFO (("********* unregistered %x", connection));
+	HAL_INFO (("***************************"));
 }
 
 static void
@@ -4014,8 +4022,9 @@ local_server_handle_connection (DBusServ
 					&local_server_message_handler, 
 					NULL, NULL, NULL, NULL};
 
-	HAL_INFO (("%d: Got a connection", getpid ()));
-	HAL_INFO (("dbus_connection_get_is_connected = %d", dbus_connection_get_is_connected (new_connection)));
+	HAL_INFO (("***************************"));
+	HAL_INFO (("********* got a connection %x", new_connection));
+	HAL_INFO (("***************************"));
 
 	/*dbus_connection_add_filter (new_connection, server_filter_function, NULL, NULL);*/
 
@@ -4029,14 +4038,12 @@ local_server_handle_connection (DBusServ
 
 
 static DBusServer *local_server = NULL;
+static char *local_server_address = NULL;
 
 char *
 hald_dbus_local_server_addr (void)
 {
-	if (local_server == NULL)
-		return NULL;
-
-	return dbus_server_get_address (local_server);
+	return local_server_address;
 }
 
 gboolean
@@ -4055,7 +4062,8 @@ hald_dbus_local_server_init (void)
 		HAL_ERROR (("Cannot create D-BUS server"));
 		goto out;
 	}
-	HAL_INFO (("local server is listening at %s", dbus_server_get_address (local_server)));
+	local_server_address = dbus_server_get_address (local_server);
+	HAL_INFO (("local server is listening at %s", local_server_address));
 	dbus_server_setup_with_g_main (local_server, NULL);
 	dbus_server_set_new_connection_function (local_server, local_server_handle_connection, NULL, NULL);	
 
@@ -4065,6 +4073,19 @@ out:
 	return ret;
 }
 
+void
+hald_dbus_local_server_shutdown (void)
+{
+	if (local_server != NULL) {
+		HAL_INFO (("Shutting down local server"));
+		dbus_server_disconnect (local_server);
+		dbus_server_unref (local_server);
+		local_server = NULL;
+		dbus_free (local_server_address);
+		local_server_address = NULL;
+	}
+}
+
 gboolean
 hald_dbus_init (void)
 {
diff --git a/hald/hald_dbus.h b/hald/hald_dbus.h
index d81cb47..439f451 100644
--- a/hald/hald_dbus.h
+++ b/hald/hald_dbus.h
@@ -90,6 +90,7 @@ void device_property_atomic_update_end  
 gboolean hald_dbus_init (void);
 
 gboolean hald_dbus_local_server_init (void);
+void hald_dbus_local_server_shutdown (void);
 
 DBusHandlerResult hald_dbus_filter_function (DBusConnection * connection, DBusMessage * message, void *user_data);
 
diff --git a/hald/hald_runner.c b/hald/hald_runner.c
index db76103..b605424 100644
--- a/hald/hald_runner.c
+++ b/hald/hald_runner.c
@@ -33,6 +33,10 @@
 #include <glib.h>
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib-lowlevel.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <signal.h>
 
 #include "hald.h"
 #include "util.h"
@@ -61,7 +65,7 @@ typedef struct
 } RunningProcess;
 
 /* mapping from PID to RunningProcess */
-static GHashTable *running_processes;
+static GHashTable *running_processes = NULL;
 
 static gboolean
 rprd_foreach (gpointer key,
@@ -72,7 +76,7 @@ rprd_foreach (gpointer key,
 	RunningProcess *rp = value;
 	HalDevice *device = user_data;
 
-	if (rp->device == device) {
+	if (device == NULL || rp->device == device) {
 		remove = TRUE;
 		g_free (rp);
 	}
@@ -83,7 +87,9 @@ rprd_foreach (gpointer key,
 static void
 running_processes_remove_device (HalDevice *device)
 {
-	g_hash_table_foreach_remove (running_processes, rprd_foreach, device);
+	if (running_processes != NULL) {
+		g_hash_table_foreach_remove (running_processes, rprd_foreach, device);
+	}
 }
 
 void
@@ -99,11 +105,11 @@ runner_server_message_handler (DBusConne
 			       void *user_data)
 {
 
-	/*HAL_INFO (("runner_server_message_handler: destination=%s obj_path=%s interface=%s method=%s", 
+	HAL_INFO (("runner_server_message_handler: destination=%s obj_path=%s interface=%s method=%s", 
 		   dbus_message_get_destination (message), 
 		   dbus_message_get_path (message), 
 		   dbus_message_get_interface (message),
-		   dbus_message_get_member (message)));*/
+		   dbus_message_get_member (message)));
 	if (dbus_message_is_signal (message, 
 				    "org.freedesktop.HalRunner", 
 				    "StartedProcessExited")) {
@@ -118,22 +124,33 @@ runner_server_message_handler (DBusConne
 
 			pid = (GPid) dpid;
 
-			/*HAL_INFO (("Previously started process with pid %d exited", pid));*/
-			rp = g_hash_table_lookup (running_processes, (gpointer) pid);
-			if (rp != NULL) {
-				rp->cb (rp->device, 0, 0, NULL, rp->data1, rp->data2);
-				g_hash_table_remove (running_processes, (gpointer) pid);
-				g_free (rp);
+			if (running_processes != NULL) {
+				/*HAL_INFO (("Previously started process with pid %d exited", pid));*/
+				rp = g_hash_table_lookup (running_processes, (gpointer) pid);
+				if (rp != NULL) {
+					rp->cb (rp->device, 0, 0, NULL, rp->data1, rp->data2);
+					g_hash_table_remove (running_processes, (gpointer) pid);
+					g_free (rp);
+				}
 			}
 		}
+	} else if (dbus_message_is_signal (message, 
+					   DBUS_INTERFACE_LOCAL, 
+					   "Disconnected") &&
+		   strcmp (dbus_message_get_path (message), DBUS_PATH_LOCAL) == 0) {
+		HAL_INFO (("runner process disconnected"));
+		dbus_connection_unref (connection);
 	}
+
 	return DBUS_HANDLER_RESULT_HANDLED;
 }
 
 static void
 runner_server_unregister_handler (DBusConnection *connection, void *user_data)
 {
-	HAL_INFO (("unregistered"));
+	HAL_INFO (("========================================"));
+	HAL_INFO (("runner_server_unregister_handler"));
+	HAL_INFO (("========================================"));
 }
 
 
@@ -152,6 +169,8 @@ handle_connection(DBusServer *server,
 		dbus_connection_ref (new_connection);
 		dbus_connection_setup_with_g_main (new_connection, NULL);
 
+		HAL_INFO (("runner connection is %p", new_connection));
+
 		dbus_connection_register_fallback (new_connection, 
 						   "/org/freedesktop",
 						   &vtable,
@@ -162,40 +181,79 @@ handle_connection(DBusServer *server,
 	}
 }
 
+static GPid runner_pid;
+static DBusServer *runner_server = NULL;
+static guint runner_watch;
+
+
 static void
-runner_died(GPid pid, gint status, gpointer data) {
-  g_spawn_close_pid (pid);
-  DIE (("Runner died"));
+runner_died(GPid pid, gint status, gpointer data)
+{
+	g_spawn_close_pid (pid);
+	DIE (("Runner died"));
+}
+
+void
+hald_runner_stop_runner (void)
+{
+	if (runner_server != NULL) {
+		DBusMessage *msg;
+
+		/* Don't care about running processes anymore */
+		g_hash_table_foreach_remove (running_processes, rprd_foreach, NULL);
+		g_hash_table_destroy (running_processes);
+		running_processes = NULL;
+
+		HAL_INFO (("Killing runner with pid %d", runner_pid));
+
+		g_source_remove (runner_watch);
+		g_spawn_close_pid (runner_pid);
+
+		msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
+						   "/org/freedesktop/HalRunner",
+						   "org.freedesktop.HalRunner",
+						   "Shutdown");
+		if (msg == NULL) 
+			DIE(("No memory"));
+		dbus_connection_send (runner_connection, msg, NULL);
+		dbus_message_unref(msg);
+
+		dbus_server_disconnect (runner_server);
+		dbus_server_unref (runner_server);
+		runner_server = NULL;
+
+	}
 }
 
 gboolean
 hald_runner_start_runner(void)
 {
-  DBusServer *server = NULL;
   DBusError err;
   GError *error = NULL;
-  GPid pid;
   char *argv[] = { NULL, NULL};
   char *env[] =  { NULL, NULL, NULL, NULL};
   const char *hald_runner_path;
+  char *server_address;
 
   running_processes = g_hash_table_new (g_direct_hash, g_direct_equal);
 
   dbus_error_init(&err);
-  server = dbus_server_listen(DBUS_SERVER_ADDRESS, &err);
-  if (server == NULL) {
+  runner_server = dbus_server_listen(DBUS_SERVER_ADDRESS, &err);
+  if (runner_server == NULL) {
     HAL_ERROR (("Cannot create D-BUS server for the runner"));
     goto error;
   }
 
-  dbus_server_setup_with_g_main(server, NULL);
-  dbus_server_set_new_connection_function(server, handle_connection, 
+  dbus_server_setup_with_g_main(runner_server, NULL);
+  dbus_server_set_new_connection_function(runner_server, handle_connection, 
                                           NULL, NULL);
 
 
   argv[0] = "hald-runner";
+  server_address = dbus_server_get_address(runner_server);
   env[0] = g_strdup_printf("HALD_RUNNER_DBUS_ADDRESS=%s",
-             dbus_server_get_address(server));
+			   server_address);
+  dbus_free (server_address);
   hald_runner_path = g_getenv("HALD_RUNNER_PATH");
   if (hald_runner_path != NULL) {
 	  env[1] = g_strdup_printf ("PATH=%s:" PACKAGE_LIBEXEC_DIR ":" PACKAGE_SCRIPT_DIR ":" PACKAGE_BIN_DIR, hald_runner_path);
@@ -207,7 +265,7 @@ hald_runner_start_runner(void)
   
   
   if (!g_spawn_async(NULL, argv, env, G_SPAWN_DO_NOT_REAP_CHILD|G_SPAWN_SEARCH_PATH, 
-        NULL, NULL, &pid, &error)) {
+        NULL, NULL, &runner_pid, &error)) {
     HAL_ERROR (("Could not spawn runner : '%s'", error->message));
     g_error_free (error);
     goto error;
@@ -215,18 +273,18 @@ hald_runner_start_runner(void)
   g_free(env[0]);
   g_free(env[1]);
 
-  HAL_INFO (("Runner has pid %d", pid));
+  HAL_INFO (("Runner has pid %d", runner_pid));
 
-  g_child_watch_add(pid, runner_died, NULL);
+  runner_watch = g_child_watch_add(runner_pid, runner_died, NULL);
   while (runner_connection == NULL) {
     /* Wait for the runner */
-    g_main_context_iteration(NULL, TRUE);
+    g_main_context_iteration (NULL, TRUE);
   }
   return TRUE;
 
 error:
-  if (server != NULL)
-    dbus_server_unref(server);
+  if (runner_server != NULL)
+    dbus_server_unref(runner_server);
   return FALSE;
 }
 
@@ -389,7 +447,7 @@ hald_runner_start (HalDevice *device, co
 	if (dbus_message_get_args (reply, &err,
 				   DBUS_TYPE_INT64, &pid_from_runner,
 				   DBUS_TYPE_INVALID)) {
-		if (cb != NULL) {
+		if (cb != NULL && running_processes != NULL) {
 			RunningProcess *rp;
 			rp = g_new0 (RunningProcess, 1);
 			rp->pid = (GPid) pid_from_runner;
@@ -454,8 +512,11 @@ call_notify(DBusPendingCall *pending, vo
   g_object_unref (hb->d);
 
   dbus_message_unref(m);
-  g_array_free(error, FALSE);
+  g_array_free(error, TRUE);
 
+  g_free (hb);
+
+  dbus_pending_call_unref (pending);
   return;
 malformed:
   /* Send a Fail callback on malformed messages */
@@ -465,7 +526,11 @@ malformed:
   g_object_unref (hb->d);
 
   dbus_message_unref(m);
-  g_array_free(error, FALSE);
+  g_array_free(error, TRUE);
+
+  g_free (hb);
+
+  dbus_pending_call_unref (pending);
 }
 
 /* Run a helper program using the commandline, with input as infomation on
@@ -481,6 +546,7 @@ hald_runner_run_method(HalDevice *device
   DBusMessageIter iter;
   DBusPendingCall *call;
   HelperData *hd = NULL;
+
   msg = dbus_message_new_method_call("org.freedesktop.HalRunner",
                              "/org/freedesktop/HalRunner",
                              "org.freedesktop.HalRunner",
@@ -500,7 +566,7 @@ hald_runner_run_method(HalDevice *device
                                               msg, &call, INT_MAX))
     DIE (("No memory"));
 
-  hd = malloc(sizeof(HelperData));
+  hd = g_new0 (HelperData, 1);
   hd->d = device;
   hd->cb = cb;
   hd->data1 = data1;
@@ -508,12 +574,12 @@ hald_runner_run_method(HalDevice *device
 
   g_object_ref (device);
 
-  dbus_pending_call_set_notify(call, call_notify, hd, free);
+  dbus_pending_call_set_notify(call, call_notify, hd, NULL);
   dbus_message_unref(msg);
   return;
 error:
   dbus_message_unref(msg);
-  free(hd);
+  g_free(hd);
   cb(device, HALD_RUN_FAILED, 0, NULL, data1, data2);
 }
 
diff --git a/hald/hald_runner.h b/hald/hald_runner.h
index ca05573..0fc2425 100644
--- a/hald/hald_runner.h
+++ b/hald/hald_runner.h
@@ -49,6 +49,10 @@ typedef void (*HalRunTerminatedCB) (HalD
 gboolean
 hald_runner_start_runner(void);
 
+/* Stop the runner daemon */
+void
+hald_runner_stop_runner(void);
+
 /* Start a helper, returns true on a successfull start. 
  * cb will be called on abnormal or premature termination
  * only 
diff --git a/hald/ids.c b/hald/ids.c
index 6c10f52..5d2fe62 100644
--- a/hald/ids.c
+++ b/hald/ids.c
@@ -545,7 +545,6 @@ ids_init (void)
 	usb_ids_load (HWDATA_DIR "/usb.ids");
 }
 
-
 /* This, somewhat incomplete, list is from this sources:
  * http://www.plasma-online.de/english/identify/serial/pnp_id_pnp.html 
  * http://www-pc.uni-regensburg.de/hardware/TECHNIK/PCI_PNP/pnpid.txt
@@ -555,7 +554,7 @@ ids_init (void)
 struct pnp_id {
 	char *id;
    	char *desc;
-} static pnp_ids_list[] = {
+} static  pnp_ids_list[] = {
 	/* Crystal Semiconductor devices */
 	{"CSC0000", "Crystal Semiconductor CS423x sound -- SB/WSS/OPL3 emulation"},
 	{"CSC0001", "Crystal Semiconductor CS423x sound -- joystick"},
diff --git a/hald/linux/acpi.c b/hald/linux/acpi.c
index eae5c51..040cb33 100644
--- a/hald/linux/acpi.c
+++ b/hald/linux/acpi.c
@@ -211,11 +211,13 @@ battery_refresh_poll (HalDevice *d)
 	hal_device_property_set_int (d, "battery.charge_level.last_full", normalised_lastfull);
 	hal_device_property_set_int (d, "battery.charge_level.rate", normalised_rate);
 
-	remaining_time = util_compute_time_remaining (d->udi, normalised_rate, normalised_current, normalised_lastfull,
-				hal_device_property_get_bool (d, "battery.rechargeable.is_discharging"),
-				hal_device_property_get_bool (d, "battery.rechargeable.is_charging"),
-				hal_device_property_get_bool (d, "battery.remaining_time.calculate_per_time"));
-	remaining_percentage = util_compute_percentage_charge (d->udi, normalised_current, normalised_lastfull);
+	remaining_time = util_compute_time_remaining (
+		hal_device_get_udi (d), 
+		normalised_rate, normalised_current, normalised_lastfull,
+		hal_device_property_get_bool (d, "battery.rechargeable.is_discharging"),
+		hal_device_property_get_bool (d, "battery.rechargeable.is_charging"),
+		hal_device_property_get_bool (d, "battery.remaining_time.calculate_per_time"));
+	remaining_percentage = util_compute_percentage_charge (hal_device_get_udi (d), normalised_current, normalised_lastfull);
 	/*
 	 * Only set keys if no error (signified with negative return value)
 	 * Scrict checking is needed to ensure that the values presented by HAL
@@ -1065,7 +1067,7 @@ acpi_generic_add (const gchar *acpi_path
 	hal_device_property_set_string (d, "linux.acpi_path", acpi_path);
 	hal_device_property_set_int (d, "linux.acpi_type", handler->acpi_type);
 	if (parent != NULL)
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	else
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	if (handler->refresh == NULL || !handler->refresh (d, handler)) {
@@ -1211,7 +1213,7 @@ acpi_callouts_add_done (HalDevice *d, gp
 {
 	void *end_token = (void *) userdata1;
 
-	HAL_INFO (("Add callouts completed udi=%s", d->udi));
+	HAL_INFO (("Add callouts completed udi=%s", hal_device_get_udi (d)));
 
 	/* Move from temporary to global device store */
 	hal_device_store_remove (hald_get_tdl (), d);
@@ -1225,7 +1227,7 @@ acpi_callouts_remove_done (HalDevice *d,
 {
 	void *end_token = (void *) userdata1;
 
-	HAL_INFO (("Remove callouts completed udi=%s", d->udi));
+	HAL_INFO (("Remove callouts completed udi=%s", hal_device_get_udi (d)));
 
 	if (!hal_device_store_remove (hald_get_gdl (), d)) {
 		HAL_WARNING (("Error removing device"));
@@ -1331,7 +1333,7 @@ acpi_rescan_device (HalDevice *d)
 		}
 	}
 
-	HAL_WARNING (("Didn't find a rescan handler for udi %s", d->udi));
+	HAL_WARNING (("Didn't find a rescan handler for udi %s", hal_device_get_udi (d)));
 	return TRUE;
 }
 
diff --git a/hald/linux/apm.c b/hald/linux/apm.c
index a11148f..ae5873a 100644
--- a/hald/linux/apm.c
+++ b/hald/linux/apm.c
@@ -229,7 +229,7 @@ battery_refresh (HalDevice *d, APMDevHan
 		hal_device_property_set_bool (d, "battery.rechargeable.is_discharging", is_discharging);
 
 		/* set the percentage charge, easy. */
-		remaining_percentage = util_compute_percentage_charge (d->udi, i.battery_percentage, 100);
+		remaining_percentage = util_compute_percentage_charge (hal_device_get_udi (d), i.battery_percentage, 100);
 	
 		/* Only set keys if no error (signified with negative return value) */
 		if (remaining_percentage > 0)
@@ -328,7 +328,7 @@ apm_generic_add (const gchar *apm_path, 
 	hal_device_property_set_string (d, "linux.apm_path", apm_path);
 	hal_device_property_set_int (d, "linux.apm_type", handler->apm_type);
 	if (parent != NULL)
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	else
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	if (handler->refresh == NULL || !handler->refresh (d, handler)) {
@@ -500,7 +500,7 @@ apm_rescan_device (HalDevice *d)
 		}
 	}
 
-	HAL_WARNING (("Didn't find a rescan handler for udi %s", d->udi));
+	HAL_WARNING (("Didn't find a rescan handler for udi %s", hal_device_get_udi (d)));
 
 out:
 	return ret;
diff --git a/hald/linux/blockdev.c b/hald/linux/blockdev.c
index 0510065..b3f9b11 100644
--- a/hald/linux/blockdev.c
+++ b/hald/linux/blockdev.c
@@ -122,7 +122,7 @@ blockdev_callouts_add_done (HalDevice *d
 {
 	void *end_token = (void *) userdata1;
 
-	HAL_INFO (("Add callouts completed udi=%s", d->udi));
+	HAL_INFO (("Add callouts completed udi=%s", hal_device_get_udi (d)));
 
 	/* Move from temporary to global device store */
 	hal_device_store_remove (hald_get_tdl (), d);
@@ -136,7 +136,7 @@ blockdev_callouts_remove_done (HalDevice
 {
 	void *end_token = (void *) userdata1;
 
-	HAL_INFO (("Remove callouts completed udi=%s", d->udi));
+	HAL_INFO (("Remove callouts completed udi=%s", hal_device_get_udi (d)));
 
 	if (!hal_device_store_remove (hald_get_gdl (), d)) {
 		HAL_WARNING (("Error removing device"));
@@ -247,7 +247,7 @@ blockdev_refresh_mount_state (HalDevice 
 		 * lost... it is merely delayed...
 		 */
 		if (device_is_executing_method (dev, "org.freedesktop.Hal.Device.Volume", "Unmount")) {
-			HAL_INFO (("/proc/mounts tells that %s is unmounted - waiting for Unmount() to complete to change mount state", dev->udi));
+			HAL_INFO (("/proc/mounts tells that %s is unmounted - waiting for Unmount() to complete to change mount state", hal_device_get_udi (dev)));
 		} else {
 			char *mount_point;
 
@@ -697,8 +697,8 @@ hotplug_event_begin_add_blockdev (const 
 							HAL_INFO ((" slave_volume_stordev_udi='%s'!", slave_volume_stordev_udi));
 							parent = hal_device_store_find (hald_get_gdl (), slave_volume_stordev_udi);
 							if (parent != NULL) {
-								HAL_INFO ((" parent='%s'!", parent->udi));
-								hal_device_property_set_string (d, "volume.crypto_luks.clear.backing_volume", slave_volume->udi);
+								HAL_INFO ((" parent='%s'!", hal_device_get_udi (parent)));
+								hal_device_property_set_string (d, "volume.crypto_luks.clear.backing_volume", hal_device_get_udi (slave_volume));
 								is_device_mapper = TRUE;
 							}
 						}
@@ -725,7 +725,7 @@ hotplug_event_begin_add_blockdev (const 
 
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", parent->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	hal_device_property_set_int (d, "linux.hotplug_type", HOTPLUG_EVENT_SYSFS_BLOCK);
 
 	hal_device_property_set_string (d, "block.device", device_file);
@@ -755,7 +755,7 @@ hotplug_event_begin_add_blockdev (const 
 		hal_device_property_set_string (d, "info.vendor", "");
 		hal_device_property_set_string (d, "info.product", "PC Floppy Drive");
 		hal_device_property_set_string (d, "storage.drive_type", "floppy");
-		hal_device_property_set_string (d, "storage.physical_device", parent->udi);
+		hal_device_property_set_string (d, "storage.physical_device", hal_device_get_udi (parent));
 		hal_device_property_set_bool (d, "storage.removable", TRUE);
 		hal_device_property_set_bool (d, "storage.removable.media_available", FALSE);
 		hal_device_property_set_bool (d, "storage.hotpluggable", FALSE);
@@ -820,7 +820,7 @@ hotplug_event_begin_add_blockdev (const 
 		/* walk up the device chain to find the physical device, 
 		 * start with our parent. On the way, optionally pick up
 		 * the scsi if it exists */
-		udi_it = parent->udi;
+		udi_it = hal_device_get_udi (parent);
 		while (udi_it != NULL) {
 			HalDevice *d_it;
 
@@ -1034,7 +1034,7 @@ hotplug_event_begin_add_blockdev (const 
 		 * VOLUMES
 		 *
 		 ************************/
-		hal_device_property_set_string (d, "block.storage_device", parent->udi);
+		hal_device_property_set_string (d, "block.storage_device", hal_device_get_udi (parent));
 
 		/* defaults */
 		hal_device_property_set_string (d, "storage.model", "");
@@ -1140,7 +1140,7 @@ force_unmount_cb (HalDevice *d, guint32 
 {
 	void *end_token = (void *) data1;
 
-	HAL_INFO (("force_unmount_cb for udi='%s', exit_type=%d, return_code=%d", d->udi, exit_type, return_code));
+	HAL_INFO (("force_unmount_cb for udi='%s', exit_type=%d, return_code=%d", hal_device_get_udi (d), exit_type, return_code));
 
 	if (exit_type == HALD_RUN_SUCCESS && error != NULL && 
 	    error[0] != NULL && error[1] != NULL) {
@@ -1175,7 +1175,7 @@ force_unmount (HalDevice *d, void *end_t
 		extra_env[0] = "HAL_METHOD_INVOKED_BY_UID=0";
 		extra_env[1] = NULL;
 		
-		HAL_INFO (("force_unmount for udi='%s'", d->udi));
+		HAL_INFO (("force_unmount for udi='%s'", hal_device_get_udi (d)));
 		syslog (LOG_NOTICE, "forcibly attempting to lazy unmount %s as enclosing drive was disconnected", device_file);
 		
 		unmount_stdin = "lazy\n";
@@ -1235,7 +1235,7 @@ hotplug_event_begin_remove_blockdev (con
 		if (fakevolume != NULL) {
 			HotplugEvent *hotplug_event;
 			HAL_INFO (("Storage device with a fakevolume is going away; "
-				   "synthesizing hotplug rem for fakevolume %s", fakevolume->udi));
+				   "synthesizing hotplug rem for fakevolume %s", hal_device_get_udi (fakevolume)));
 			hotplug_event = blockdev_generate_remove_hotplug_event (fakevolume);
 			if (hotplug_event != NULL) {
 				/* push synthesized event at front of queue and repost this event... this is such that
@@ -1295,7 +1295,8 @@ block_rescan_storage_done (HalDevice *d,
 		if (fakevolume != NULL) {
 			/* generate hotplug event to remove the fakevolume */
 			HotplugEvent *hotplug_event;
-			HAL_INFO (("Media removal detected; synthesizing hotplug rem for fakevolume %s", fakevolume->udi));
+			HAL_INFO (("Media removal detected; synthesizing hotplug rem for fakevolume %s", 
+				   hal_device_get_udi (fakevolume)));
 			hotplug_event = blockdev_generate_remove_hotplug_event (fakevolume);
 			if (hotplug_event != NULL) {
 				hotplug_event_enqueue (hotplug_event);
@@ -1315,11 +1316,11 @@ blockdev_rescan_device (HalDevice *d)
 
 	ret = FALSE;
 
-	HAL_INFO (("Entering, udi=%s", d->udi));
+	HAL_INFO (("Entering, udi=%s", hal_device_get_udi (d)));
 
 	/* This only makes sense on storage devices */
 	if (hal_device_property_get_bool (d, "block.is_volume")) {
-		HAL_INFO (("No action on volumes", d->udi));
+		HAL_INFO (("No action on volumes", hal_device_get_udi (d)));
 		goto out;
 	}
 
diff --git a/hald/linux/classdev.c b/hald/linux/classdev.c
index 5e61ce9..dfbb338 100644
--- a/hald/linux/classdev.c
+++ b/hald/linux/classdev.c
@@ -67,8 +67,8 @@ input_add (const gchar *sysfs_path, cons
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 	if (physdev != NULL) {
-		hal_device_property_set_string (d, "input.physical_device", physdev->udi);
-		hal_device_property_set_string (d, "info.parent", physdev->udi);
+		hal_device_property_set_string (d, "input.physical_device", hal_device_get_udi (physdev));
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -122,12 +122,12 @@ bluetooth_add (const gchar *sysfs_path, 
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 
 	hal_device_property_set_string (d, "info.category", "bluetooth_hci");
 	hal_device_add_capability (d, "bluetooth_hci");
 
-	hal_device_property_set_string (d, "bluetooth_hci.physical_device", physdev->udi);
+	hal_device_property_set_string (d, "bluetooth_hci.physical_device", hal_device_get_udi (physdev));
 	hal_util_set_string_from_file (d, "bluetooth_hci.interface_name", sysfs_path, "name");
 
 	hal_device_property_set_string (d, "info.product", "Bluetooth Host Controller Interface");
@@ -166,12 +166,12 @@ net_add (const gchar *sysfs_path, const 
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 
 	hal_device_property_set_string (d, "info.category", "net");
 	hal_device_add_capability (d, "net");
 
-	hal_device_property_set_string (d, "net.physical_device", physdev->udi);
+	hal_device_property_set_string (d, "net.physical_device", hal_device_get_udi (physdev));
 
 	ifname = hal_util_get_last_element (sysfs_path);
 	hal_device_property_set_string (d, "net.interface", ifname);
@@ -290,7 +290,7 @@ scsi_generic_add (const gchar *sysfs_pat
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 	hal_device_property_set_string (d, "info.category", "scsi_generic");
 	hal_device_add_capability (d, "scsi_generic");
 	hal_device_property_set_string (d, "info.product", "SCSI Generic Interface");
@@ -332,7 +332,7 @@ scsi_host_add (const gchar *sysfs_path, 
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path_in_devices);
 	
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 
 	hal_device_property_set_string (d, "info.category", "scsi_host");
 	hal_device_add_capability (d, "scsi_host");
@@ -381,7 +381,7 @@ usbclass_add (const gchar *sysfs_path, c
 		d = hal_device_new ();
 		hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 		hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path_in_devices);
-		hal_device_property_set_string (d, "info.parent", physdev->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 
 		hal_device_property_set_string (d, "info.category", "hiddev");
 		hal_device_add_capability (d, "hiddev");
@@ -394,7 +394,7 @@ usbclass_add (const gchar *sysfs_path, c
 		d = hal_device_new ();
 		hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 		hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path_in_devices);
-		hal_device_property_set_string (d, "info.parent", physdev->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 
 		hal_device_property_set_string (d, "info.category", "printer");
 		hal_device_add_capability (d, "printer");
@@ -402,7 +402,7 @@ usbclass_add (const gchar *sysfs_path, c
 		hal_device_property_set_string (d, "info.product", "Printer");
 		hal_device_property_set_string (d, "printer.device", device_file);
 
-		hal_device_property_set_string (d, "printer.physical_device", physdev->udi);
+		hal_device_property_set_string (d, "printer.physical_device", hal_device_get_udi (physdev));
 	}
 
 out:
@@ -460,7 +460,7 @@ usbraw_add (const gchar *sysfs_path, con
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 	hal_device_property_set_string (d, "info.category", "usbraw");
 	hal_device_add_capability (d, "usbraw");
 	hal_device_property_set_string (d, "info.product", "USB Raw Device Access");
@@ -498,7 +498,7 @@ video4linux_add (const gchar *sysfs_path
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 	hal_device_property_set_string (d, "info.category", "video4linux");
 	hal_device_add_capability (d, "video4linux");
 	hal_device_property_set_string (d, "info.product", "Video Device");
@@ -536,7 +536,7 @@ dvb_add (const gchar *sysfs_path, const 
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 	hal_device_property_set_string (d, "info.category", "dvb");
 	hal_device_add_capability (d, "dvb");
 	hal_device_property_set_string (d, "info.product", "DVB Device");
@@ -618,8 +618,8 @@ sound_add (const gchar *sysfs_path, cons
 			hal_device_property_set_string (d, "info.category", "alsa");
 			hal_device_add_capability (d, "alsa");
 			hal_device_property_set_string (d, "alsa.device_file", device_file);
-			hal_device_property_set_string (d, "info.parent", physdev->udi);
-			hal_device_property_set_string (d, "alsa.physical_device", physdev->udi);
+			hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
+			hal_device_property_set_string (d, "alsa.physical_device", hal_device_get_udi (physdev));
 			hal_device_property_set_int (d, "alsa.card", cardnum);
 			hal_device_property_set_string (d, "alsa.type", "control");
 	
@@ -635,8 +635,8 @@ sound_add (const gchar *sysfs_path, cons
 			hal_device_property_set_string (d, "info.category", "alsa");
 			hal_device_add_capability (d, "alsa");
 			hal_device_property_set_string (d, "alsa.device_file", device_file);
-			hal_device_property_set_string (d, "info.parent", physdev->udi);
-			hal_device_property_set_string (d, "alsa.physical_device", physdev->udi);
+			hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
+			hal_device_property_set_string (d, "alsa.physical_device", hal_device_get_udi (physdev));
 			hal_device_property_set_int (d, "alsa.card", cardnum);
 			hal_device_property_set_int (d, "alsa.device", devicenum);
 	
@@ -708,8 +708,8 @@ sound_add (const gchar *sysfs_path, cons
 			hal_device_property_set_string (d, "info.category", "oss");
 			hal_device_add_capability (d, "oss");
 			hal_device_property_set_string (d, "oss.device_file", device_file);
-			hal_device_property_set_string (d, "info.parent", physdev->udi);
-			hal_device_property_set_string (d, "oss.physical_device", physdev->udi);
+			hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
+			hal_device_property_set_string (d, "oss.physical_device", hal_device_get_udi (physdev));
 			hal_device_property_set_int (d, "oss.card", cardnum);
 	
 			snprintf (aprocdir, sizeof (aprocdir), "%s/asound/card%d", get_hal_proc_path (), cardnum);
@@ -843,10 +843,10 @@ serial_add (const gchar *sysfs_path, con
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 	hal_device_property_set_string (d, "info.category", "serial");
 	hal_device_add_capability (d, "serial");
-	hal_device_property_set_string (d, "serial.physical_device", physdev->udi);
+	hal_device_property_set_string (d, "serial.physical_device", hal_device_get_udi (physdev));
 	hal_device_property_set_string (d, "serial.device", device_file);
 
 	last_elem = hal_util_get_last_element(sysfs_path);
@@ -932,7 +932,7 @@ tape_add (const gchar *sysfs_path, const
 
 	d = hal_device_new ();
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 	hal_device_property_set_string (d, "info.category", "tape");
 	hal_device_add_capability (d, "tape");
 	hal_device_add_capability (physdev, "tape");
@@ -987,7 +987,7 @@ mmc_host_add (const gchar *sysfs_path, c
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path_in_devices);
 
-	hal_device_property_set_string (d, "info.parent", physdev->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (physdev));
 
 	hal_device_property_set_string (d, "info.category", "mmc_host");
 	hal_device_add_capability (d, "mmc_host");
@@ -1205,7 +1205,7 @@ classdev_callouts_add_done (HalDevice *d
 {
 	void *end_token = (void *) userdata1;
 
-	HAL_INFO (("Add callouts completed udi=%s", d->udi));
+	HAL_INFO (("Add callouts completed udi=%s", hal_device_get_udi (d)));
 
 	/* Move from temporary to global device store */
 	hal_device_store_remove (hald_get_tdl (), d);
@@ -1219,7 +1219,7 @@ classdev_callouts_remove_done (HalDevice
 {
 	void *end_token = (void *) userdata1;
 
-	HAL_INFO (("Remove callouts completed udi=%s", d->udi));
+	HAL_INFO (("Remove callouts completed udi=%s", hal_device_get_udi (d)));
 
 	if (!hal_device_store_remove (hald_get_gdl (), d)) {
 		HAL_WARNING (("Error removing device"));
diff --git a/hald/linux/coldplug.c b/hald/linux/coldplug.c
index 2ce29f6..3693cda 100644
--- a/hald/linux/coldplug.c
+++ b/hald/linux/coldplug.c
@@ -198,9 +198,26 @@ hal_util_init_sysfs_to_udev_map (void)
 error:
 	g_free(udevinfo_stdout);
 	g_hash_table_destroy (sysfs_to_udev_map);
+	sysfs_to_udev_map = NULL;
 	return FALSE;
 }
 
+static HotplugEvent *pool = NULL;
+static int pool_next_free = 0;
+static int pool_num_freed = 0;
+static int pool_size = 1000;
+
+static void 
+pool_free (gpointer data)
+{
+	HAL_INFO (("pool_num_freed = %d (of %d)", pool_num_freed, pool_next_free));
+	pool_num_freed++;
+	if (pool_num_freed == pool_next_free) {
+		HAL_INFO (("Freeing whole pool"));
+		g_free (pool);
+	}
+}
+
 static HotplugEvent
 *coldplug_get_hotplug_event(const gchar *sysfs_path, const gchar *subsystem, HotplugEventType type)
 {
@@ -208,15 +225,29 @@ static HotplugEvent
 	const char *pos;
 	gchar path[HAL_PATH_MAX];
 	struct stat statbuf;
+	gboolean from_pool = FALSE;
 
-	hotplug_event = g_new0 (HotplugEvent, 1);
-	if (hotplug_event == NULL)
-		return NULL;
+	if (pool == NULL) {
+		pool = g_new0 (HotplugEvent, pool_size);
+		pool_next_free = 0;
+		pool_num_freed = 0;
+	}
+
+	if (pool_next_free >= pool_size) {
+		hotplug_event = g_new0 (HotplugEvent, 1);
+	} else {
+		from_pool = TRUE;
+		hotplug_event = pool + pool_next_free++;
+		hotplug_event->free_function = pool_free;
+	}
 
 	/* lookup if udev has something stored in its database */
 	hotplug_event_udev = (HotplugEvent *) g_hash_table_lookup (sysfs_to_udev_map, sysfs_path);
 	if (hotplug_event_udev != NULL) {
 		memcpy(hotplug_event, hotplug_event_udev, sizeof(HotplugEvent));
+		if (from_pool) {
+			hotplug_event->free_function = pool_free;
+		}
 		HAL_INFO (("new event (dev node from udev) '%s' '%s'", hotplug_event->sysfs.sysfs_path, hotplug_event->sysfs.device_file));
 	} else {
 		/* device is not in udev database */
@@ -462,6 +493,7 @@ static void queue_events(void)
 
 		g_free (sysfs_dev->path);
 		g_free (sysfs_dev->subsystem);
+		g_free (sysfs_dev);
 	}
 
 	g_slist_free (device_list);
diff --git a/hald/linux/hotplug.c b/hald/linux/hotplug.c
index 5187c97..ab6618f 100644
--- a/hald/linux/hotplug.c
+++ b/hald/linux/hotplug.c
@@ -62,7 +62,12 @@ hotplug_event_end (void *end_token)
 	HotplugEvent *hotplug_event = (HotplugEvent *) end_token;
 
 	hotplug_events_in_progress = g_slist_remove (hotplug_events_in_progress, hotplug_event);
-	g_free (hotplug_event);
+
+	if (hotplug_event->free_function != NULL) {
+		hotplug_event->free_function (hotplug_event);
+	} else {
+		g_free (hotplug_event);
+	}
 	hotplug_event_process_queue ();
 }
 
@@ -438,7 +443,7 @@ hotplug_rescan_device (HalDevice *d)
 		break;
 
 	default:
-		HAL_INFO (("Unknown hotplug type for udi=%s", d->udi));
+		HAL_INFO (("Unknown hotplug type for udi=%s", hal_device_get_udi (d)));
 		ret = FALSE;
 		break;
 	}
@@ -454,7 +459,7 @@ hotplug_reprobe_generate_remove_events (
 	HotplugEvent *e;
 
 	/* first remove childs */
-	childs = hal_device_store_match_multiple_key_value_string (hald_get_gdl (), "info.parent", d->udi);
+	childs = hal_device_store_match_multiple_key_value_string (hald_get_gdl (), "info.parent", hal_device_get_udi (d));
 	for (i = childs; i != NULL; i = g_slist_next (i)) {
 		HalDevice *child;
 
@@ -463,7 +468,7 @@ hotplug_reprobe_generate_remove_events (
 	}
 
 	/* then remove self */
-	HAL_INFO (("Generate remove event for udi %s", d->udi));
+	HAL_INFO (("Generate remove event for udi %s", hal_device_get_udi (d)));
 	switch (hal_device_property_get_int (d, "linux.hotplug_type")) {
 	case HOTPLUG_EVENT_SYSFS_BUS:
 		e = physdev_generate_remove_hotplug_event (d);
@@ -491,7 +496,7 @@ hotplug_reprobe_generate_remove_events (
 
 	default:
 		e = NULL;
-		HAL_INFO (("Unknown hotplug type for udi=%s", d->udi));
+		HAL_INFO (("Unknown hotplug type for udi=%s", hal_device_get_udi (d)));
 		break;
 	}
 
@@ -508,7 +513,7 @@ hotplug_reprobe_generate_add_events (Hal
 	HotplugEvent *e;
 
 	/* first add self */
-	HAL_INFO (("Generate add event for udi %s", d->udi));
+	HAL_INFO (("Generate add event for udi %s", hal_device_get_udi (d)));
 	switch (hal_device_property_get_int (d, "linux.hotplug_type")) {
 	case HOTPLUG_EVENT_SYSFS_BUS:
 		e = physdev_generate_add_hotplug_event (d);
@@ -536,7 +541,7 @@ hotplug_reprobe_generate_add_events (Hal
 
 	default:
 		e = NULL;
-		HAL_INFO (("Unknown hotplug type for udi=%s", d->udi));
+		HAL_INFO (("Unknown hotplug type for udi=%s", hal_device_get_udi (d)));
 		break;
 	}
 
@@ -545,7 +550,7 @@ hotplug_reprobe_generate_add_events (Hal
 	}
 
 	/* then add childs */
-	childs = hal_device_store_match_multiple_key_value_string (hald_get_gdl (), "info.parent", d->udi);
+	childs = hal_device_store_match_multiple_key_value_string (hald_get_gdl (), "info.parent", hal_device_get_udi (d));
 	for (i = childs; i != NULL; i = g_slist_next (i)) {
 		HalDevice *child;
 
diff --git a/hald/linux/hotplug.h b/hald/linux/hotplug.h
index d93d620..3619617 100644
--- a/hald/linux/hotplug.h
+++ b/hald/linux/hotplug.h
@@ -56,6 +56,8 @@ typedef struct
 	HotplugActionType action;				/* Whether the event is add or remove */
 	HotplugEventType type;					/* Type of event */
 
+	void (*free_function) (gpointer data);
+
 	union {
 		struct {
 			char subsystem[HAL_NAME_MAX];		/* Kernel subsystem the device belongs to */
diff --git a/hald/linux/osspec.c b/hald/linux/osspec.c
index bcfe115..def76ff 100644
--- a/hald/linux/osspec.c
+++ b/hald/linux/osspec.c
@@ -325,7 +325,7 @@ osspec_init (void)
 static void 
 computer_callouts_add_done (HalDevice *d, gpointer userdata1, gpointer userdata2)
 {
-	HAL_INFO (("Add callouts completed udi=%s", d->udi));
+	HAL_INFO (("Add callouts completed udi=%s", hal_device_get_udi (d)));
 
 	/* Move from temporary to global device store */
 	hal_device_store_remove (hald_get_tdl (), d);
diff --git a/hald/linux/physdev.c b/hald/linux/physdev.c
index 0c92a3e..c49d0b9 100644
--- a/hald/linux/physdev.c
+++ b/hald/linux/physdev.c
@@ -61,7 +61,7 @@ pci_add (const gchar *sysfs_path, HalDev
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "pci");
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -225,7 +225,7 @@ usb_add (const gchar *sysfs_path, HalDev
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	}
 
 	/* only USB interfaces got a : in the bus_id */
@@ -376,7 +376,7 @@ ide_add (const gchar *sysfs_path, HalDev
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "ide");
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -427,7 +427,7 @@ pnp_add (const gchar *sysfs_path, HalDev
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "pnp");
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -483,7 +483,7 @@ platform_add (const gchar *sysfs_path, H
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "platform");
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -528,7 +528,7 @@ serio_add (const gchar *sysfs_path, HalD
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "serio");
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -576,7 +576,7 @@ pcmcia_add (const gchar *sysfs_path, Hal
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "pcmcia");
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -656,7 +656,7 @@ scsi_add (const gchar *sysfs_path, HalDe
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "scsi");
-	hal_device_property_set_string (d, "info.parent", parent->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 
 	bus_id = hal_util_get_last_element (sysfs_path);
 	sscanf (bus_id, "%d:%d:%d:%d", &host_num, &bus_num, &target_num, &lun_num);
@@ -750,7 +750,7 @@ mmc_add (const gchar *sysfs_path, HalDev
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "mmc");
-	hal_device_property_set_string (d, "info.parent", parent->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 
 	hal_util_set_driver (d, "info.linux.driver", sysfs_path);
 
@@ -826,7 +826,7 @@ xen_add (const gchar *sysfs_path, HalDev
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "xen");
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -899,7 +899,7 @@ ieee1394_add (const gchar *sysfs_path, H
 	hal_device_property_set_string (d, "linux.sysfs_path", sysfs_path);
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "ieee1394");
-	hal_device_property_set_string (d, "info.parent", parent->udi);
+	hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 
 	hal_util_set_driver (d, "info.linux.driver", sysfs_path);
 
@@ -1038,7 +1038,7 @@ ccw_add (const gchar *sysfs_path, HalDev
 					sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "ccw");
 	if (parent != NULL)
-                hal_device_property_set_string (d, "info.parent", parent->udi);
+                hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
         else
                 hal_device_property_set_string
 		  (d, "info.parent",
@@ -1210,7 +1210,7 @@ ccwgroup_add (const gchar *sysfs_path, H
 					sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "ccwgroup");
 	if (parent != NULL)
-                hal_device_property_set_string (d, "info.parent", parent->udi);
+                hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
         else
                 hal_device_property_set_string
 		  (d, "info.parent",
@@ -1277,7 +1277,7 @@ iucv_add (const gchar *sysfs_path, HalDe
 					sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "iucv");
 	if (parent != NULL)
-                hal_device_property_set_string (d, "info.parent", parent->udi);
+                hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
         else
                 hal_device_property_set_string
 		  (d, "info.parent",
@@ -1323,7 +1323,7 @@ pseudo_add (const gchar *sysfs_path, Hal
 	hal_device_property_set_string (d, "linux.sysfs_path_device", sysfs_path);
 	hal_device_property_set_string (d, "info.bus", "pseudo");
 	if (parent != NULL) {
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	} else {
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	}
@@ -1505,7 +1505,7 @@ physdev_callouts_add_done (HalDevice *d,
 {
 	void *end_token = (void *) userdata1;
 
-	HAL_INFO (("Add callouts completed udi=%s", d->udi));
+	HAL_INFO (("Add callouts completed udi=%s", hal_device_get_udi (d)));
 
 	/* Move from temporary to global device store */
 	hal_device_store_remove (hald_get_tdl (), d);
@@ -1519,7 +1519,7 @@ physdev_callouts_remove_done (HalDevice 
 {
 	void *end_token = (void *) userdata1;
 
-	HAL_INFO (("Remove callouts completed udi=%s", d->udi));
+	HAL_INFO (("Remove callouts completed udi=%s", hal_device_get_udi (d)));
 
 	if (!hal_device_store_remove (hald_get_gdl (), d)) {
 		HAL_WARNING (("Error removing device"));
diff --git a/hald/linux/pmu.c b/hald/linux/pmu.c
index b43d5f0..3a174f0 100644
--- a/hald/linux/pmu.c
+++ b/hald/linux/pmu.c
@@ -131,14 +131,14 @@ battery_refresh (HalDevice *d, PMUDevHan
 
 		/* TODO: could read some pmu file? */
 		remaining_time = util_compute_time_remaining (
-					d->udi,
+					hal_device_get_udi (d),
 					hal_device_property_get_int (d, "battery.charge_level.rate"),
 					current,
 					last_full,
 					hal_device_property_get_bool (d, "battery.rechargeable.is_discharging"),
 					hal_device_property_get_bool (d, "battery.rechargeable.is_charging"),
 					hal_device_property_get_bool (d, "battery.remaining_time.calculate_per_time"));
-		remaining_percentage = util_compute_percentage_charge (d->udi, current, last_full);
+		remaining_percentage = util_compute_percentage_charge (hal_device_get_udi (d), current, last_full);
 		/*
 		 * Only set keys if no error (signified with negative return value)
 		 * Scrict checking is needed to ensure that the values presented by HAL
@@ -400,7 +400,7 @@ pmu_generic_add (const gchar *pmu_path, 
 	hal_device_property_set_string (d, "linux.pmu_path", pmu_path);
 	hal_device_property_set_int (d, "linux.pmu_type", handler->pmu_type);
 	if (parent != NULL)
-		hal_device_property_set_string (d, "info.parent", parent->udi);
+		hal_device_property_set_string (d, "info.parent", hal_device_get_udi (parent));
 	else
 		hal_device_property_set_string (d, "info.parent", "/org/freedesktop/Hal/devices/computer");
 	if (handler->refresh == NULL || !handler->refresh (d, handler)) {
@@ -580,7 +580,7 @@ pmu_rescan_device (HalDevice *d)
 		}
 	}
 
-	HAL_WARNING (("Didn't find a rescan handler for udi %s", d->udi));
+	HAL_WARNING (("Didn't find a rescan handler for udi %s", hal_device_get_udi (d)));
 
 out:
 	return ret;
diff --git a/hald/property.c b/hald/property.c
index 2caeb2b..8a4955d 100644
--- a/hald/property.c
+++ b/hald/property.c
@@ -37,6 +37,8 @@
 struct _HalProperty {
 	char *key;
 
+	void *foo;
+
 	int type;
 	union {
 		char *str_value;
@@ -54,7 +56,6 @@ struct _HalProperty {
 void
 hal_property_free (HalProperty *prop)
 {
-
 	g_free (prop->key);
 
 	if (prop->type == HAL_PROPERTY_TYPE_STRING) {
@@ -70,6 +71,14 @@ hal_property_free (HalProperty *prop)
 	g_free (prop);
 }
 
+static inline HalProperty *
+hal_property_new (void)
+{
+	HalProperty *prop;
+	prop = g_new0 (HalProperty, 1); 
+	return prop;
+}
+
 HalProperty *
 hal_property_new_string (const char *key, const char *value)
 {
@@ -77,7 +86,7 @@ hal_property_new_string (const char *key
 	char *endchar;
 	gboolean validated = TRUE;
 
-	prop = g_new0 (HalProperty, 1);
+	prop = hal_property_new ();
 
 	prop->type = HAL_PROPERTY_TYPE_STRING;
 	prop->key = g_strdup (key);
@@ -102,7 +111,7 @@ hal_property_new_int (const char *key, d
 {
 	HalProperty *prop;
 
-	prop = g_new0 (HalProperty, 1);
+	prop = hal_property_new ();
 
 	prop->type = HAL_PROPERTY_TYPE_INT32;
 	prop->key = g_strdup (key);
@@ -116,7 +125,7 @@ hal_property_new_uint64 (const char *key
 {
 	HalProperty *prop;
 
-	prop = g_new0 (HalProperty, 1);
+	prop = hal_property_new ();
 
 	prop->type = HAL_PROPERTY_TYPE_UINT64;
 	prop->key = g_strdup (key);
@@ -130,7 +139,7 @@ hal_property_new_bool (const char *key, 
 {
 	HalProperty *prop;
 
-	prop = g_new0 (HalProperty, 1);
+	prop = hal_property_new ();
 
 	prop->type = HAL_PROPERTY_TYPE_BOOLEAN;
 	prop->key = g_strdup (key);
@@ -144,7 +153,7 @@ hal_property_new_double (const char *key
 {
 	HalProperty *prop;
 
-	prop = g_new0 (HalProperty, 1);
+	prop = hal_property_new ();
 
 	prop->type = HAL_PROPERTY_TYPE_DOUBLE;
 	prop->key = g_strdup (key);
@@ -377,7 +386,7 @@ hal_property_new_strlist (const char *ke
 {
 	HalProperty *prop;
 
-	prop = g_new0 (HalProperty, 1);
+	prop = hal_property_new ();
 
 	prop->type = HAL_PROPERTY_TYPE_STRLIST;
 	prop->key = g_strdup (key);
diff --git a/hald/util.c b/hald/util.c
index 225142b..8cac0f1 100644
--- a/hald/util.c
+++ b/hald/util.c
@@ -868,7 +868,7 @@ hal_util_callout_device_add (HalDevice *
 		goto out;
 	}	
 
-	HAL_INFO (("Add callouts for udi=%s", d->udi));
+	HAL_INFO (("Add callouts for udi=%s", hal_device_get_udi (d)));
 
 	hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env);
 out:
@@ -886,7 +886,7 @@ hal_util_callout_device_remove (HalDevic
 		goto out;
 	}	
 
-	HAL_INFO (("Remove callouts for udi=%s", d->udi));
+	HAL_INFO (("Remove callouts for udi=%s", hal_device_get_udi (d)));
 
 	hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env);
 out:
@@ -904,7 +904,7 @@ hal_util_callout_device_preprobe (HalDev
 		goto out;
 	}	
 
-	HAL_INFO (("Preprobe callouts for udi=%s", d->udi));
+	HAL_INFO (("Preprobe callouts for udi=%s", hal_device_get_udi (d)));
 
 	hal_callout_device (d, callback, userdata1, userdata2, programs, extra_env);
 out:
diff --git a/hald/valgrind-hald.sh b/hald/valgrind-hald.sh
index 11f95c3..d9f3fec 100755
--- a/hald/valgrind-hald.sh
+++ b/hald/valgrind-hald.sh
@@ -3,10 +3,14 @@
 export HALD_RUNNER_PATH=`pwd`/linux:`pwd`/linux/probing:`pwd`/linux/addons:`pwd`/.:`pwd`/../tools:`pwd`/../tools/linux
 export PATH=`pwd`/../hald-runner:$PATH
 
-rm -rf .local-fdi
-make -C ../fdi install DESTDIR=`pwd`/.local-fdi prefix=/
+if [ "$1" = "--skip-fdi-install" ] ; then
+    shift
+else
+    rm -rf .local-fdi
+    make -C ../fdi install DESTDIR=`pwd`/.local-fdi prefix=/
+fi
 export HAL_FDI_SOURCE_PREPROBE=.local-fdi/share/hal/fdi/preprobe
 export HAL_FDI_SOURCE_INFORMATION=.local-fdi/share/hal/fdi/information
 export HAL_FDI_SOURCE_POLICY=.local-fdi/share/hal/fdi/policy
 
-valgrind --num-callers=20 --show-reachable=yes --leak-check=yes --tool=memcheck ./hald --daemon=no --verbose=yes
+valgrind --num-callers=20 --show-reachable=yes --leak-check=yes --tool=memcheck ./hald --daemon=no --verbose=yes $@
diff-tree bd9e32febb881700d76fb3524c86ee469463a946 (from 0fe19dec4668a0d8288941d56a351d7dc1c895b7)
Author: David Zeuthen <davidz at redhat.com>
Date:   Sun Oct 8 18:49:16 2006 -0400

    make it easier to measure startup time
    
    Add an option to exit the daemon after probing. The magical invocation is
    
     # time ./run-hald.sh --skip-fdi-install --exit-after-probing > /dev/null 2>&1
    
    running from the hald/ directory (need one normal run to install the
    fdi files). On my Macbook Pro I get these figures
    
     real    0m2.084s
     user    0m0.564s
     sys     0m0.576s

diff --git a/hald/hald.c b/hald/hald.c
index 02ae7a0..cb5c6c7 100644
--- a/hald/hald.c
+++ b/hald/hald.c
@@ -212,13 +212,15 @@ usage ()
 	fprintf (stderr, "\n" "usage : hald [--daemon=yes|no] [--verbose=yes|no] [--help]\n");
 	fprintf (stderr,
 		 "\n"
-		 "        --daemon=yes|no      Become a daemon\n"
-		 "        --verbose=yes|no     Print out debug (overrides HALD_VERBOSE)\n"
- 		 "        --use-syslog         Print out debug messages to syslog instead of stderr.\n"
-		 "                             Use this option to get debug messages if HAL runs as\n"
-		 "                             daemon.\n"
-		 "        --help               Show this information and exit\n"
-		 "        --version            Output version information and exit"
+		 "        --daemon=yes|no       Become a daemon\n"
+		 "        --verbose=yes|no      Print out debug (overrides HALD_VERBOSE)\n"
+ 		 "        --use-syslog          Print out debug messages to syslog instead of\n"
+		 "                              stderr. Use this option to get debug messages\n"
+		 "                              if hald runs as a daemon.\n"
+		 "        --help                Show this information and exit\n"
+		 "        --version             Output version information and exit\n"
+		 "        --exit-after-probing  Exit when probing is complete. Useful only\n"
+		 "                              when profiling hald.\n"
 		 "\n"
 		 "The HAL daemon detects devices present in the system and provides the\n"
 		 "org.freedesktop.Hal service through the system-wide message bus provided\n"
@@ -234,6 +236,7 @@ static dbus_bool_t opt_become_daemon = T
 /** If #TRUE, we will spew out debug */
 dbus_bool_t hald_is_verbose = FALSE;
 dbus_bool_t hald_use_syslog = FALSE;
+dbus_bool_t hald_debug_exit_after_probing = FALSE;
 
 static int sigterm_unix_signal_pipe_fds[2];
 static GIOChannel *sigterm_iochn;
@@ -399,6 +402,7 @@ main (int argc, char *argv[])
 		int option_index = 0;
 		const char *opt;
 		static struct option long_options[] = {
+			{"exit-after-probing", 0, NULL, 0},
 			{"daemon", 1, NULL, 0},
 			{"verbose", 1, NULL, 0},
 			{"use-syslog", 0, NULL, 0},
@@ -422,6 +426,8 @@ main (int argc, char *argv[])
 			} else if (strcmp (opt, "version") == 0) {
 				fprintf (stderr, "HAL package version: " PACKAGE_VERSION "\n");
 				return 0;
+			} else if (strcmp (opt, "exit-after-probing") == 0) {
+				hald_debug_exit_after_probing = TRUE;
 			} else if (strcmp (opt, "daemon") == 0) {
 				if (strcmp ("yes", optarg) == 0) {
 					opt_become_daemon = TRUE;
@@ -618,6 +624,13 @@ osspec_probe_done (void)
 
 	HAL_INFO (("Device probing completed"));
 
+	if (hald_debug_exit_after_probing) {
+		HAL_INFO (("Exiting on user request (--exit-after-probing)"));
+		hald_runner_kill_all();
+		exit (0);
+	}
+
+
 	if (!hald_dbus_init ()) {
 		hald_runner_kill_all();
 		exit (1);
diff --git a/hald/run-hald.sh b/hald/run-hald.sh
index d8e6cb3..0ae1f6b 100755
--- a/hald/run-hald.sh
+++ b/hald/run-hald.sh
@@ -3,13 +3,17 @@
 export HALD_RUNNER_PATH=`pwd`/linux:`pwd`/linux/probing:`pwd`/linux/addons:`pwd`/.:`pwd`/../tools:`pwd`/../tools/linux
 export PATH=`pwd`/../hald-runner:$PATH
 
-rm -rf .local-fdi
-make -C ../fdi install DESTDIR=`pwd`/.local-fdi prefix=/
+if [ "$1" = "--skip-fdi-install" ] ; then
+    shift
+else
+    rm -rf .local-fdi
+    make -C ../fdi install DESTDIR=`pwd`/.local-fdi prefix=/
+fi
 export HAL_FDI_SOURCE_PREPROBE=.local-fdi/share/hal/fdi/preprobe
 export HAL_FDI_SOURCE_INFORMATION=.local-fdi/share/hal/fdi/information
 export HAL_FDI_SOURCE_POLICY=.local-fdi/share/hal/fdi/policy
 
-./hald --daemon=no --verbose=yes
+./hald --daemon=no --verbose=yes $@
 #./hald --daemon=no
 
 
diff-tree 0fe19dec4668a0d8288941d56a351d7dc1c895b7 (from 51b841cd59a73fc093535ddd9e512d3036ebbbc4)
Author: David Zeuthen <davidz at redhat.com>
Date:   Sun Oct 8 14:32:27 2006 -0400

    add some thoughts about optimization work needed

diff --git a/doc/TODO b/doc/TODO
index 94be6c4..921afab 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -99,12 +99,37 @@ Other items
    require reworking the 'fakevolume' code as we'd be adding more
    than one fakevolume
 
-Items that might be interesting or maybe not:
----------------------------------------------
+Optimization
+------------
 
- - Port hal daemon core to use dbus-glib bindings? I'm not convinced this
-   will buy us much, the core code is already done, debugged and working
-   plus dbus-glib bindings only support one interface per proxy...
+ - Don't load, parse all fdi files 4 times for every device object
+   added. It's wasteful to parse the same file over and over agin
+   - load, parse fdi file into "rule object", see
+     http://lists.freedesktop.org/archives/hal/2006-July/005672.html
+   - load all rule objects at startup into cache
+   - evict all cache items after startup
+   - expire cache items after timeout / LRU scheme
+
+ - Don't load pci.ids, usb.ids into memory (pci.ids 426333 bytes, usb.ids
+   is 153540 bytes) at startup (even without parsing it); it costs
+   580K right now. It's wasteful to parse the same file over and over again.
+   - load, parse file into efficient lookup tree
+   - free tree when no longer used?
+
+ - Device Store lookup cleanups
+
+ - Device Object property cleanups
+
+ - Port hal daemon core to use dbus glib bindings
+   - One proxy per hal device object
+   - hal device object is an GObject
+   - wants to export multiple D-Bus interfaces for a single GObject
+   - for some interfaces... need/want to handle all messages on myself
+     (for forwarding to addons)
+   - ie. need to partipate in Introspection() on "DBusGProxy" stuff
+
+ - Linux: Optionally drop sysfs coldplug code
+   - for starting up before udev and piggy tailing on udev's coldplug code
 
 External projects:
 ------------------


More information about the hal-commit mailing list