Merge lp:~ted/ubuntu-app-launch/lp1495871-unref-context into lp:ubuntu-app-launch/16.04

Proposed by Ted Gould
Status: Merged
Approved by: Charles Kerr
Approved revision: 215
Merged at revision: 213
Proposed branch: lp:~ted/ubuntu-app-launch/lp1495871-unref-context
Merge into: lp:ubuntu-app-launch/16.04
Prerequisite: lp:~mterry/ubuntu-app-launch/fix-ftbfs
Diff against target: 193 lines (+84/-7)
6 files modified
debian/libubuntu-app-launch2.symbols (+1/-0)
helpers-shared.c (+11/-2)
libubuntu-app-launch/ubuntu-app-launch.c (+5/-5)
libubuntu-app-launch/ubuntu-app-launch.h (+12/-0)
tools/CMakeLists.txt (+9/-0)
tools/ubuntu-app-list-pids.c (+46/-0)
To merge this branch: bzr merge lp:~ted/ubuntu-app-launch/lp1495871-unref-context
Reviewer Review Type Date Requested Status
Charles Kerr (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+279801@code.launchpad.net

This proposal supersedes a proposal from 2015-12-02.

Commit message

Ensure all pending events on the context are complete before unref'ing it.

Description of the change

So while we create a context to ensure that we can capture all the events to the CGManager connection it seems that some of those events can get stuck on the context, and they need to get processed to complete. Otherwise they hold onto references of things, and that actually results in a g_spawn getting left around because it never gets free'd. (actually of the context itself, which is a bit confusing, but eh, refcounting is fun)

Also brought in the pid tools branch because it made testing this much, much easier. You can use the ubuntu-app-list-pids tool to cause the FD to be leaked and then see it fixed with something like (assuming you've done ubuntu-app-launch firefox):

valgrind --track-fds=yes ./ubuntu-app-list-pids firefox

Which on trunk will have 6 FDs left over, but with this branch only 5. (which come from globals that we don't control)

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Charles Kerr (charlesk) wrote :

The code looks fine to me.

IIUC, the while(pending){iterate();} snippet is the main fix, while the rest of it is either sugar (eg qdata instead of data) or the pid tools branch, right?

Optional, I'd suggest extracting while(pending){iterate();} into an inline function to improve the readability a bit, eg flush_pending_events(GMainContext*). IMO this would also address thomas' comment on the readability of the /* may block */ comment

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/libubuntu-app-launch2.symbols'
2--- debian/libubuntu-app-launch2.symbols 2015-08-17 21:38:34 +0000
3+++ debian/libubuntu-app-launch2.symbols 2015-12-07 17:03:12 +0000
4@@ -3,6 +3,7 @@
5 ubuntu_app_launch_application_info@Base 0.5+15.10.20150817
6 ubuntu_app_launch_application_log_path@Base 0.4
7 ubuntu_app_launch_get_primary_pid@Base 0.4
8+ ubuntu_app_launch_get_pids@Base 0replaceme
9 ubuntu_app_launch_helper_set_exec@Base 0.5+15.10.20150604
10 ubuntu_app_launch_list_helper_instances@Base 0.4
11 ubuntu_app_launch_list_helpers@Base 0.4
12
13=== modified file 'helpers-shared.c'
14--- helpers-shared.c 2015-07-15 02:32:54 +0000
15+++ helpers-shared.c 2015-12-07 17:03:12 +0000
16@@ -145,6 +145,8 @@
17 cgroup_manager_connection_core_cb(g_dbus_connection_new_for_address_finish, res, (cgm_connection_t *)data);
18 }
19
20+G_DEFINE_QUARK(CGMANAGER_CONTEXT, cgmanager_context);
21+
22 /* Get the connection to the cgroup manager */
23 GDBusConnection *
24 cgroup_manager_connection (void)
25@@ -191,7 +193,9 @@
26 g_main_context_pop_thread_default(context);
27
28 if (!use_session_bus && connection.con != NULL) {
29- g_object_set_data(G_OBJECT(connection.con), "cgmanager-context", context);
30+ g_object_set_qdata(G_OBJECT(connection.con),
31+ cgmanager_context_quark(),
32+ context);
33 } else {
34 g_main_context_unref(context);
35 }
36@@ -213,7 +217,7 @@
37 if (cgmanager == NULL)
38 return;
39
40- GMainContext * creationcontext = g_object_get_data(G_OBJECT(cgmanager), "cgmanager-context");
41+ GMainContext * creationcontext = g_object_get_qdata(G_OBJECT(cgmanager), cgmanager_context_quark());
42 if (creationcontext == NULL) {
43 g_object_unref(cgmanager);
44 return;
45@@ -228,6 +232,11 @@
46 }
47
48 g_object_unref(cgmanager);
49+
50+ while (g_main_context_pending(creationcontext)) {
51+ g_main_context_iteration(creationcontext, TRUE /* may block */);
52+ }
53+
54 g_main_context_unref(creationcontext);
55 }
56
57
58=== modified file 'libubuntu-app-launch/ubuntu-app-launch.c'
59--- libubuntu-app-launch/ubuntu-app-launch.c 2015-12-07 17:03:12 +0000
60+++ libubuntu-app-launch/ubuntu-app-launch.c 2015-12-07 17:03:12 +0000
61@@ -38,7 +38,6 @@
62
63 static void apps_for_job (GDBusConnection * con, const gchar * name, GArray * apps, gboolean truncate_legacy);
64 static void free_helper (gpointer value);
65-static GList * pids_for_appid (const gchar * appid);
66 int kill (pid_t pid, int signal);
67 static gchar * escape_dbus_string (const gchar * input);
68
69@@ -588,7 +587,7 @@
70
71 do {
72 hash_table_size = g_hash_table_size(pidssignaled);
73- GList * pidlist = pids_for_appid(appid);
74+ GList * pidlist = ubuntu_app_launch_get_pids(appid);
75 GList * iter;
76
77 if (pidlist == NULL) {
78@@ -1506,9 +1505,10 @@
79 /* Get the PIDs for an AppID. If it's click or legacy single instance that's
80 a simple call to the helper. But if it's not, we have to make a call for
81 each instance of the app that we have running. */
82-static GList *
83-pids_for_appid (const gchar * appid)
84+GList *
85+ubuntu_app_launch_get_pids (const gchar * appid)
86 {
87+ g_return_val_if_fail(appid != NULL, NULL);
88 ual_tracepoint(pids_list_start, appid);
89
90 GDBusConnection * cgmanager = cgroup_manager_connection();
91@@ -1572,7 +1572,7 @@
92 return FALSE;
93 }
94
95- GList * pidlist = pids_for_appid(appid);
96+ GList * pidlist = ubuntu_app_launch_get_pids(appid);
97 GList * head;
98
99 for (head = pidlist; head != NULL; head = g_list_next(head)) {
100
101=== modified file 'libubuntu-app-launch/ubuntu-app-launch.h'
102--- libubuntu-app-launch/ubuntu-app-launch.h 2015-08-10 14:19:05 +0000
103+++ libubuntu-app-launch/ubuntu-app-launch.h 2015-12-07 17:03:12 +0000
104@@ -388,6 +388,18 @@
105 GPid ubuntu_app_launch_get_primary_pid (const gchar * appid);
106
107 /**
108+ * ubuntu_app_launch_get_pids:
109+ * @appid: ID of the application to look for
110+ *
111+ * Checks to see if an application is running and returns
112+ * the PIDs associated with it.
113+ *
114+ * Return Value: (transfer full) (element-type GLib.Pid): A list
115+ * of PIDs associated with @appid, empty if not running.
116+ */
117+GList * ubuntu_app_launch_get_pids (const gchar * appid);
118+
119+/**
120 * ubuntu_app_launch_pid_in_app_id:
121 * @pid: Process ID to check on
122 * @appid: ID of the application to look in
123
124=== modified file 'tools/CMakeLists.txt'
125--- tools/CMakeLists.txt 2014-09-10 15:01:22 +0000
126+++ tools/CMakeLists.txt 2015-12-07 17:03:12 +0000
127@@ -9,6 +9,15 @@
128 install(TARGETS ubuntu-app-list RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}")
129
130 ########################
131+# ubuntu-app-list-pids
132+########################
133+
134+add_executable(ubuntu-app-list-pids ubuntu-app-list-pids.c)
135+set_target_properties(ubuntu-app-list-pids PROPERTIES OUTPUT_NAME "ubuntu-app-list-pids")
136+target_link_libraries(ubuntu-app-list-pids ubuntu-launcher)
137+install(TARGETS ubuntu-app-list-pids RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}")
138+
139+########################
140 # ubuntu-app-launch
141 ########################
142
143
144=== added file 'tools/ubuntu-app-list-pids.c'
145--- tools/ubuntu-app-list-pids.c 1970-01-01 00:00:00 +0000
146+++ tools/ubuntu-app-list-pids.c 2015-12-07 17:03:12 +0000
147@@ -0,0 +1,46 @@
148+/*
149+ * Copyright © 2015 Canonical Ltd.
150+ *
151+ * This program is free software: you can redistribute it and/or modify it
152+ * under the terms of the GNU General Public License version 3, as published
153+ * by the Free Software Foundation.
154+ *
155+ * This program is distributed in the hope that it will be useful, but
156+ * WITHOUT ANY WARRANTY; without even the implied warranties of
157+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
158+ * PURPOSE. See the GNU General Public License for more details.
159+ *
160+ * You should have received a copy of the GNU General Public License along
161+ * with this program. If not, see <http://www.gnu.org/licenses/>.
162+ *
163+ * Authors:
164+ * Ted Gould <ted.gould@canonical.com>
165+ */
166+
167+#include "libubuntu-app-launch/ubuntu-app-launch.h"
168+
169+int
170+main (int argc, char * argv[])
171+{
172+ GList * pids;
173+ GList * iter;
174+
175+ if (argc != 2) {
176+ g_printerr("Usage: %s <app id>\n", argv[0]);
177+ return 1;
178+ }
179+
180+ pids = ubuntu_app_launch_get_pids(argv[1]);
181+ if (pids == NULL) {
182+ return 1;
183+ }
184+
185+ for (iter = pids; iter != NULL; iter = g_list_next(iter)) {
186+ g_print("%d\n", (GPid)GPOINTER_TO_INT(iter->data));
187+ }
188+
189+ g_list_free(pids);
190+
191+ return 0;
192+}
193+

Subscribers

People subscribed via source and target branches