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
|