Merge lp:~gue5t/midori/tabby-leaks into lp:midori

Proposed by gue5t gue5t
Status: Merged
Approved by: André Stösel
Approved revision: 6676
Merged at revision: 6678
Proposed branch: lp:~gue5t/midori/tabby-leaks
Merge into: lp:midori
Diff against target: 163 lines (+44/-17)
1 file modified
extensions/tabby.vala (+44/-17)
To merge this branch: bzr merge lp:~gue5t/midori/tabby-leaks
Reviewer Review Type Date Requested Status
André Stösel Approve
Review via email: mp+216810@code.launchpad.net

Commit message

Fix leaks of two references to the MidoriApp in Tabby

Description of the change

Tabby seems to assume it will never be deactivated, which is an inherently leaky philosophy. This nulls out at least the two fields that hold references to the MidoriApp when Tabby is (theoretically) deactivated.

To post a comment you must log in.
Revision history for this message
André Stösel (ivaldi) wrote :

Well, this will most likely break things if some event (which is handled by tabby) is triggered after deactivated is called. Yes, you are right, tabby assumes it is never deactivated, but if we change it, we should do it the right way.

review: Needs Fixing
Revision history for this message
gue5t gue5t (gue5t) wrote :

Tabby won't be deactivated in normal use since it's essentially part of the core, but only when the browser is shut down. When Tabby *is* deactivated, it should not hold references to the MidoriApp.

Revision history for this message
André Stösel (ivaldi) wrote :

It doesn't matter - if we do it, we should do it all right!
(There could be some race conditions which triggers some (future) event after the deactivate call and midori could segfault,... you never know ;)

Revision history for this message
gue5t gue5t (gue5t) wrote :

I guess it's fair enough that we should make sure all signals are disconnected first. I'll update the branch when I get a chance.

lp:~gue5t/midori/tabby-leaks updated
6675. By gue5t <email address hidden>

Document vfuncs in tabby and disconnect some signals on deactivation

Revision history for this message
Cris Dywan (kalikiana) wrote :

60 - public virtual void close () {
61 + public void detach () {

Is this intended?

lp:~gue5t/midori/tabby-leaks updated
6676. By gue5t <email address hidden>

Factor detach back into close to avoid extra public API change and keep code simple

Revision history for this message
André Stösel (ivaldi) wrote :

looks good (thx for the comments ;)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'extensions/tabby.vala'
2--- extensions/tabby.vala 2014-03-26 00:00:38 +0000
3+++ extensions/tabby.vala 2014-04-25 19:50:26 +0000
4@@ -16,7 +16,7 @@
5
6 /* function called from Manager object */
7 public interface IStorage : GLib.Object {
8- public abstract Katze.Array get_sessions ();
9+ public abstract Katze.Array get_saved_sessions ();
10 public abstract Base.Session get_new_session ();
11 public abstract void restore_last_sessions ();
12 public abstract void import_session (Katze.Array tabs);
13@@ -24,10 +24,15 @@
14
15 public interface ISession : GLib.Object {
16 public abstract Katze.Array get_tabs ();
17+ /* Add one tab to the database */
18 public abstract void add_item (Katze.Item item);
19+ /* Attach to a browser */
20 public abstract void attach (Midori.Browser browser);
21+ /* Attach to a browser and populate it with tabs from the database */
22 public abstract void restore (Midori.Browser browser);
23+ /* Remove all tabs from the database */
24 public abstract void remove ();
25+ /* Run when a browser is closed */
26 public abstract void close ();
27 }
28
29@@ -43,7 +48,7 @@
30 public abstract class Storage : GLib.Object, IStorage {
31 public Midori.App app { get; construct; }
32
33- public abstract Katze.Array get_sessions ();
34+ public abstract Katze.Array get_saved_sessions ();
35 public abstract Base.Session get_new_session ();
36
37 public void start_new_session () {
38@@ -52,7 +57,7 @@
39 }
40
41 public void restore_last_sessions () {
42- Katze.Array sessions = this.get_sessions ();
43+ Katze.Array sessions = this.get_saved_sessions ();
44 this.init_sessions (sessions);
45 }
46
47@@ -93,7 +98,7 @@
48 public abstract class Session : GLib.Object, ISession {
49 protected GLib.SList<double?> tab_sorting;
50
51- public Midori.Browser browser { get; protected set; }
52+ public Midori.Browser? browser { get; protected set; default = null; }
53 public SessionState state { get; protected set; default = SessionState.CLOSED; }
54
55 public abstract void add_item (Katze.Item item);
56@@ -215,12 +220,20 @@
57 }
58
59 public virtual void close () {
60- this.browser.add_tab.disconnect (this.tab_added);
61- this.browser.add_tab.disconnect (this.helper_data_changed);
62- this.browser.remove_tab.disconnect (this.tab_removed);
63- this.browser.switch_tab.disconnect (this.tab_switched);
64- this.browser.delete_event.disconnect (this.delete_event);
65- this.browser.notebook.page_reordered.disconnect (this.tab_reordered);
66+ if (this.state == SessionState.CLOSED) {
67+ assert (this.browser == null);
68+ } else {
69+ this.state = SessionState.CLOSED;
70+
71+ this.browser.add_tab.disconnect (this.tab_added);
72+ this.browser.add_tab.disconnect (this.helper_data_changed);
73+ this.browser.remove_tab.disconnect (this.tab_removed);
74+ this.browser.switch_tab.disconnect (this.tab_switched);
75+ this.browser.delete_event.disconnect (this.delete_event);
76+ this.browser.notebook.page_reordered.disconnect (this.tab_reordered);
77+
78+ this.browser = null;
79+ }
80 }
81
82 #if HAVE_GTK3
83@@ -229,7 +242,7 @@
84 protected bool delete_event (Gtk.Widget widget, Gdk.Event event) {
85 #endif
86
87- this.close();
88+ this.close ();
89 return false;
90
91 }
92@@ -481,13 +494,15 @@
93 }
94 }
95
96- public override void close() {
97+ public override void close () {
98+ /* base.close may unset this.browser, so hold onto it */
99+ Midori.Browser? my_browser = this.browser;
100 base.close ();
101
102 bool should_break = true;
103- if (!this.browser.destroy_with_parent) {
104+ if (my_browser != null && !my_browser.destroy_with_parent) {
105 foreach (Midori.Browser browser in APP.get_browsers ()) {
106- if (browser != this.browser && !browser.destroy_with_parent) {
107+ if (browser != my_browser && !browser.destroy_with_parent) {
108 should_break = false;
109 break;
110 }
111@@ -595,7 +610,7 @@
112 private class Storage : Base.Storage {
113 private Midori.Database database;
114
115- public override Katze.Array get_sessions () {
116+ public override Katze.Array get_saved_sessions () {
117 Katze.Array sessions = new Katze.Array (typeof (Session));
118
119 string sqlcmd = """
120@@ -717,7 +732,7 @@
121 }
122
123 private void browser_added (Midori.Browser browser) {
124- Base.Session session = browser.get_data<Base.Session> ("tabby-session");
125+ Base.Session? session = browser.get_data<Base.Session> ("tabby-session");
126 if (session == null) {
127 session = this.storage.get_new_session () as Base.Session;
128 browser.set_data<Base.Session> ("tabby-session", session);
129@@ -726,7 +741,7 @@
130 }
131
132 private void browser_removed (Midori.Browser browser) {
133- Base.Session session = browser.get_data<Base.Session> ("tabby-session");
134+ Base.Session? session = browser.get_data<Base.Session> ("tabby-session");
135 if (session == null) {
136 GLib.warning ("missing session");
137 } else {
138@@ -764,6 +779,17 @@
139 GLib.Idle.add (this.load_session);
140 }
141
142+ private void deactivated () {
143+ /* set_open_uris will disconnect itself if called,
144+ but it may have been called before we are deactivated */
145+ APP.add_browser.disconnect (this.set_open_uris);
146+ APP.add_browser.disconnect (this.browser_added);
147+ APP.remove_browser.disconnect (this.browser_removed);
148+ APP = null;
149+
150+ this.storage = null;
151+ }
152+
153 internal Manager () {
154 GLib.Object (name: _("Tabby"),
155 description: _("Tab and session management."),
156@@ -771,6 +797,7 @@
157 authors: "André Stösel <andre@stoesel.de>");
158
159 this.activate.connect (this.activated);
160+ this.deactivate.connect (this.deactivated);
161 }
162 }
163 }

Subscribers

People subscribed via source and target branches

to all changes: