Merge lp:~ted/indicator-session/removing-me into lp:indicator-session/0.1
- removing-me
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~ted/indicator-session/removing-me |
Merge into: | lp:indicator-session/0.1 |
Diff against target: |
192 lines (+60/-81) 1 file modified
src/session-service.c (+60/-81) |
To merge this branch: | bzr merge lp:~ted/indicator-session/removing-me |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
David Barth | Approve | ||
Review via email: mp+20474@code.launchpad.net |
Commit message
Description of the change
Ted Gould (ted) wrote : | # |
David Barth (dbarth) wrote : | # |
Hmm, it feels you should avoid going into the loop if the user_count is wrong, to avoid some pathological cases. I'd prefer to cut processing as soon as possible, and check for the guest account explicitly.
Ted Gould (ted) wrote : | # |
On Tue, 2010-03-02 at 20:31 +0000, David Barth wrote:
> Hmm, it feels you should avoid going into the loop if the
> user_count is wrong, to avoid some pathological cases. I'd
> prefer to cut processing as soon as possible, and check for
> the guest account explicitly.
To find the guest account we're going to have to look through the
entries until we find it, which is the same thing as when we find the
guest account we discover the issue, and break. I'm not sure that it'd
be any faster to do in another loop.
David Barth (dbarth) wrote : | # |
Ok, this is a dynamic account... But that loop means that it's going to be very costly on system connected to directories with thousands of entries.
I think you should exploit that fact that a guest account is a system one, ie with an ID below LAST_SYSTEM_UID. That's in /etc/adduser.conf.
Not sure if that changes a lot, but as 'guest' is already hardcoded, either hardcoding to < 999, or sourcing the conf file to get the environment variable.
Ted Gould (ted) wrote : | # |
On Tue, 2010-03-02 at 23:12 +0000, David Barth wrote:
> Ok, this is a dynamic account... But that loop means that
> it's going to be very costly on system connected to directories
> with thousands of entries.
>
> I think you should exploit that fact that a guest account is
> a system one, ie with an ID below LAST_SYSTEM_UID. That's in
> /etc/adduser.conf.
>
> Not sure if that changes a lot, but as 'guest' is already
> hardcoded, either hardcoding to < 999, or sourcing the conf
> file to get the environment variable.
But, we're getting all the names from GDM. I don't think that we can
request a subset of that list. I think the only way we could do it is
to specially request information on the guest account from ConsoleKit
and avoid GDM all together.
The other option would be to not show if the guest is logged in when
we're in "overflow mode."
I guess my feeling is that we're talking about thousands of string
comparisons. Which, on a modern processor is calculated in ms...
But, if you want, we can go with option A. I think it'd be the best,
just talk to ConsoleKit directly about the guest account.
David Barth (dbarth) wrote : | # |
The issue is network access with a directory, not so much the number of entries. Enumerating accounts may be extremely slow. But I think it's more of gdm's role here, and so the cache should already be populated anyway.
Go ahead with the patch.
Preview Diff
1 | === modified file 'src/session-service.c' |
2 | --- src/session-service.c 2010-02-23 22:55:45 +0000 |
3 | +++ src/session-service.c 2010-03-02 20:05:22 +0000 |
4 | @@ -68,9 +68,6 @@ |
5 | static DbusmenuMenuitem *lock_menuitem = NULL; |
6 | static DbusmenuMenuitem *switch_menuitem = NULL; |
7 | |
8 | -static gint count; |
9 | -static GList *users; |
10 | - |
11 | static DbusmenuMenuitem * root_menuitem = NULL; |
12 | static GMainLoop * mainloop = NULL; |
13 | static DBusGProxy * up_main_proxy = NULL; |
14 | @@ -415,6 +412,7 @@ |
15 | UsersServiceDbus *service) |
16 | { |
17 | DbusmenuMenuitem *mi = NULL; |
18 | + DbusmenuMenuitem * guest_mi = NULL; |
19 | GList *u; |
20 | UserData *user; |
21 | gboolean can_activate; |
22 | @@ -444,12 +442,12 @@ |
23 | |
24 | if (check_guest_session ()) |
25 | { |
26 | - mi = dbusmenu_menuitem_new (); |
27 | - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, USER_ITEM_TYPE); |
28 | - dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, _("Guest Session")); |
29 | - dbusmenu_menuitem_property_set_bool (mi, USER_ITEM_PROP_LOGGED_IN, FALSE); |
30 | - dbusmenu_menuitem_child_append (root, mi); |
31 | - g_signal_connect (G_OBJECT (mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_guest_session), NULL); |
32 | + guest_mi = dbusmenu_menuitem_new (); |
33 | + dbusmenu_menuitem_property_set (guest_mi, DBUSMENU_MENUITEM_PROP_TYPE, USER_ITEM_TYPE); |
34 | + dbusmenu_menuitem_property_set (guest_mi, USER_ITEM_PROP_NAME, _("Guest Session")); |
35 | + dbusmenu_menuitem_property_set_bool (guest_mi, USER_ITEM_PROP_LOGGED_IN, FALSE); |
36 | + dbusmenu_menuitem_child_append (root, guest_mi); |
37 | + g_signal_connect (G_OBJECT (guest_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_guest_session), NULL); |
38 | } |
39 | |
40 | if (check_new_session ()) |
41 | @@ -472,39 +470,49 @@ |
42 | } |
43 | } |
44 | |
45 | - if (count > MINIMUM_USERS && count < MAXIMUM_USERS) |
46 | - { |
47 | - if (users != NULL) |
48 | - { |
49 | - GList *l = NULL; |
50 | - |
51 | - for (l = users; l != NULL; l = l->next) |
52 | - { |
53 | - users = g_list_delete_link (users, l); |
54 | - } |
55 | - |
56 | - users = NULL; |
57 | - } |
58 | - |
59 | - users = users_service_dbus_get_user_list (service); |
60 | - |
61 | - users = g_list_sort (users, (GCompareFunc)compare_users_by_username); |
62 | - |
63 | - for (u = users; u != NULL; u = g_list_next (u)) |
64 | - { |
65 | - user = u->data; |
66 | - |
67 | - user->service = service; |
68 | - |
69 | - mi = dbusmenu_menuitem_new (); |
70 | - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, USER_ITEM_TYPE); |
71 | - dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, user->real_name); |
72 | - dbusmenu_menuitem_property_set_bool (mi, USER_ITEM_PROP_LOGGED_IN, user->sessions != NULL); |
73 | - dbusmenu_menuitem_child_append (root, mi); |
74 | - g_signal_connect (G_OBJECT (mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_user_session), user); |
75 | - } |
76 | - } |
77 | - } |
78 | + GList * users = NULL; |
79 | + users = users_service_dbus_get_user_list (service); |
80 | + guint user_count = g_list_length(users); |
81 | + |
82 | + if (user_count > MINIMUM_USERS && user_count < MAXIMUM_USERS) { |
83 | + users = g_list_sort (users, (GCompareFunc)compare_users_by_username); |
84 | + } |
85 | + |
86 | + for (u = users; u != NULL; u = g_list_next (u)) { |
87 | + user = u->data; |
88 | + user->service = service; |
89 | + |
90 | + if (user->uid == getuid()) { |
91 | + /* Hide me from the list */ |
92 | + continue; |
93 | + } |
94 | + |
95 | + if (g_strcmp0(user->user_name, "guest") == 0) { |
96 | + /* Check to see if the guest has sessions and so therefore should |
97 | + get a check mark. */ |
98 | + if (user->sessions != NULL) { |
99 | + dbusmenu_menuitem_property_set_bool (guest_mi, USER_ITEM_PROP_LOGGED_IN, TRUE); |
100 | + } |
101 | + /* If we're showing user accounts, keep going through the list */ |
102 | + if (user_count > MINIMUM_USERS && user_count < MAXIMUM_USERS) { |
103 | + continue; |
104 | + } |
105 | + /* If not, we can stop here */ |
106 | + break; |
107 | + } |
108 | + |
109 | + if (user_count > MINIMUM_USERS && user_count < MAXIMUM_USERS) { |
110 | + mi = dbusmenu_menuitem_new (); |
111 | + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, USER_ITEM_TYPE); |
112 | + dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, user->real_name); |
113 | + dbusmenu_menuitem_property_set_bool (mi, USER_ITEM_PROP_LOGGED_IN, user->sessions != NULL); |
114 | + dbusmenu_menuitem_child_append (root, mi); |
115 | + g_signal_connect (G_OBJECT (mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (activate_user_session), user); |
116 | + } |
117 | + } |
118 | + |
119 | + g_list_free(users); |
120 | + } |
121 | |
122 | DbusmenuMenuitem * separator = dbusmenu_menuitem_new(); |
123 | dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); |
124 | @@ -562,42 +570,13 @@ |
125 | /* Signal called when a user is added. It updates the count and |
126 | rebuilds the menu */ |
127 | static void |
128 | -user_added (UsersServiceDbus *service, |
129 | - UserData *user, |
130 | - gpointer user_data) |
131 | -{ |
132 | - DbusmenuMenuitem *root = (DbusmenuMenuitem *)user_data; |
133 | - |
134 | - count++; |
135 | - |
136 | - rebuild_items (root, service); |
137 | -} |
138 | - |
139 | -/* Signal called when a user is deleted. It updates the count and |
140 | - rebuilds the menu */ |
141 | -static void |
142 | -user_removed (UsersServiceDbus *service, |
143 | - UserData *user, |
144 | - gpointer user_data) |
145 | -{ |
146 | - DbusmenuMenuitem *root = (DbusmenuMenuitem *)user_data; |
147 | - |
148 | - count--; |
149 | - |
150 | - rebuild_items (root, service); |
151 | -} |
152 | - |
153 | -/* Wrapper around rebuild_items that is used on the first call |
154 | - so that we can initialize the count variable. */ |
155 | -static void |
156 | -create_items (DbusmenuMenuitem *root, |
157 | - UsersServiceDbus *service) |
158 | -{ |
159 | - g_return_if_fail (IS_USERS_SERVICE_DBUS (service)); |
160 | - |
161 | - count = users_service_dbus_get_user_count (service); |
162 | - |
163 | - rebuild_items (root, service); |
164 | +user_change (UsersServiceDbus *service, |
165 | + UserData *user, |
166 | + gpointer user_data) |
167 | +{ |
168 | + DbusmenuMenuitem *root = (DbusmenuMenuitem *)user_data; |
169 | + rebuild_items (root, service); |
170 | + return; |
171 | } |
172 | |
173 | /* When the service interface starts to shutdown, we |
174 | @@ -638,15 +617,15 @@ |
175 | |
176 | dbus_interface = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL); |
177 | |
178 | - create_items (root_menuitem, dbus_interface); |
179 | + rebuild_items (root_menuitem, dbus_interface); |
180 | |
181 | g_signal_connect (G_OBJECT (dbus_interface), |
182 | "user-added", |
183 | - G_CALLBACK (user_added), |
184 | + G_CALLBACK (user_change), |
185 | root_menuitem); |
186 | g_signal_connect (G_OBJECT (dbus_interface), |
187 | "user-removed", |
188 | - G_CALLBACK (user_removed), |
189 | + G_CALLBACK (user_change), |
190 | root_menuitem); |
191 | |
192 | setup_up(); |
This branch started with just wanting to ensure that there isn't a menu
item for the currently logged in user. But, then there's more.
Ended up restructuring the code slightly so that we could also detect to
see if the guest user is logged in. This involved making count and
users variables not global which allowed for simplifying the callbacks
for user added and removed.