aboutsummaryrefslogtreecommitdiff
blob: 6fdd6faf11ff18bb28e2e8f8dee7b90ea437314d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
From 0c584a62e3393b0a92c297b422c819b2d7ccde17 Mon Sep 17 00:00:00 2001
From: Danny Kukawka <danny.kukawka@web.de>
Date: Mon, 25 Aug 2008 12:54:08 +0200
Subject: [PATCH 16/48] fixed Lock() handling

Fixed Lock() handling.

The current code store the lock information for a lock owner into a
hash-table with these info: key=service_name of the lock owner and
as value the device which was locked. Unfortunately this don't work
if a service request more than one lock, because the old one get
overwritten in the hash table. Use instead of the device a GSList
with devices. This should solve

If the lock owner dies, remove the locks of the old_service_name and
not of the new_service_name (otherwise the locks get never released).
---
 hald/hald_dbus.c |   67 +++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 51 insertions(+), 16 deletions(-)

diff --git a/hald/hald_dbus.c b/hald/hald_dbus.c
index 6889275..51dd7ae 100644
--- a/hald/hald_dbus.c
+++ b/hald/hald_dbus.c
@@ -2580,6 +2580,51 @@ device_release_global_interface_lock (DBusConnection *connection, DBusMessage *m
 
 static GHashTable *services_with_locks = NULL;
 
+static void
+services_with_locks_add_lock (const char* lock_owner, HalDevice *device) {
+
+	GSList *devices;
+
+	devices = g_hash_table_lookup (services_with_locks, lock_owner);
+
+        devices = g_slist_prepend (devices, device);
+
+	g_hash_table_insert (services_with_locks, strdup(lock_owner), devices);
+}
+
+static void 
+services_with_locks_remove_lock (const char* lock_owner, HalDevice *device) {
+	
+	GSList *devices;
+
+	devices = g_hash_table_lookup (services_with_locks, lock_owner);
+
+	devices = g_slist_remove (devices, device);
+
+	g_hash_table_insert (services_with_locks, strdup(lock_owner), devices);
+}
+
+static void 
+services_with_locks_remove_lockowner (const char* lock_owner) {
+	
+	GSList *devices;
+
+	devices = g_hash_table_lookup (services_with_locks, lock_owner);
+
+        if (devices != NULL) {
+		GSList *iter;
+
+		for (iter = devices; iter != NULL; iter = iter->next) {
+			HalDevice *d = iter->data;
+			hal_device_property_remove (d, "info.locked");
+			hal_device_property_remove (d, "info.locked.reason");
+			hal_device_property_remove (d, "info.locked.dbus_name");
+		}
+	}
+	g_hash_table_remove (services_with_locks, lock_owner);		
+}
+
+
 /**  
  *  device_lock:
  *  @connection:         D-BUS connection
@@ -2655,8 +2700,7 @@ device_lock (DBusConnection * connection,
 					       g_object_unref);
 	}
 
-	g_hash_table_insert (services_with_locks, g_strdup (sender),
-			     g_object_ref (d));
+	services_with_locks_add_lock (sender, d);
 
 	if (!dbus_connection_send (connection, reply, NULL))
 		DIE (("No memory"));
@@ -2741,9 +2785,9 @@ device_unlock (DBusConnection *connection,
 		return DBUS_HANDLER_RESULT_HANDLED;
 	}
 
-	if (g_hash_table_lookup (services_with_locks, sender))
-		g_hash_table_remove (services_with_locks, sender);
-	else {
+	if (g_hash_table_lookup (services_with_locks, sender)) {
+		services_with_locks_remove_lock (sender, d);
+	} else {
 		HAL_WARNING (("Service '%s' was not in the list of services "
 			      "with locks!", sender));
 	}
@@ -5181,7 +5225,6 @@ hald_dbus_filter_function (DBusConnection * connection,
 		char *name;
 		char *old_service_name;
 		char *new_service_name;
-		HalDevice *d;
 
 		if (!dbus_message_get_args (message, NULL,
 					    DBUS_TYPE_STRING, &name,
@@ -5196,16 +5239,8 @@ hald_dbus_filter_function (DBusConnection * connection,
 
 		ci_tracker_name_owner_changed (ci_tracker, name, old_service_name, new_service_name);
 
-		if (services_with_locks != NULL) {
-			d = g_hash_table_lookup (services_with_locks, new_service_name);
-			if (d != NULL) {
-				hal_device_property_remove (d, "info.locked");
-				hal_device_property_remove (d, "info.locked.reason");
-				hal_device_property_remove (d, "info.locked.dbus_name");
-				
-				g_hash_table_remove (services_with_locks, new_service_name);
-			}
-		}
+		if (services_with_locks != NULL)
+			services_with_locks_remove_lockowner(old_service_name);
 
                 if (strlen (old_service_name) > 0)
                         hal_device_client_disconnected (old_service_name);
-- 
1.6.1.2