[geany/geany] cb8151: GTK: Avoid possible IdleWork() calls on destructed objects

Colomban Wendling git-noreply at xxxxx
Thu May 12 13:02:15 UTC 2016


Branch:      refs/heads/master
Author:      Colomban Wendling <ban at herbesfolles.org>
Committer:   Colomban Wendling <ban at herbesfolles.org>
Date:        Thu, 12 May 2016 13:02:15 UTC
Commit:      cb8151b29b22e3248092e8d697c77423832d8992
             https://github.com/geany/geany/commit/cb8151b29b22e3248092e8d697c77423832d8992

Log Message:
-----------
GTK: Avoid possible IdleWork() calls on destructed objects

The idle callback removal clause in the ScintillaGTK destructor got
broken in the last Scintilla update [1], leading to the callback not
being removed thus possibly running after the instance destruction.
Indeed, gdk_threads_add_idle() wraps g_idle_add() with a custom user
data, thus making the g_source_remove_by_user_data() call in the
destructor incorrect, as we give it our own user data, not GDK's
wrapper one.

Fix the callback removal not to use user data matching to avoid this.

Closes #1033.

[1] https://sourceforge.net/p/scintilla/code/ci/4e5c321dda8e69104cb7b639c3107dc11dbc00f6/

X-Scintilla-Bug-URL: https://sourceforge.net/p/scintilla/bugs/1827/
X-Scintilla-Commit-ID: d889200cd9de032e278745f48b9c3108ccfa5984


Modified Paths:
--------------
    scintilla/gtk/ScintillaGTK.cxx
    scintilla/src/Editor.h

Modified: scintilla/gtk/ScintillaGTK.cxx
21 lines changed, 16 insertions(+), 5 deletions(-)
===================================================================
@@ -167,6 +167,8 @@ class ScintillaGTK : public ScintillaBase {
 #endif
 	bool repaintFullWindow;
 
+	guint styleIdleID;
+
 	// Private so ScintillaGTK objects can not be copied
 	ScintillaGTK(const ScintillaGTK &);
 	ScintillaGTK &operator=(const ScintillaGTK &);
@@ -325,6 +327,7 @@ class ScintillaGTK : public ScintillaBase {
 	static gboolean TimeOut(gpointer ptt);
 	static gboolean IdleCallback(gpointer pSci);
 	static gboolean StyleIdle(gpointer pSci);
+	virtual void IdleWork();
 	virtual void QueueIdleWork(WorkNeeded::workItems items, int upTo);
 	static void PopUpCB(GtkMenuItem *menuItem, ScintillaGTK *sciThis);
 
@@ -392,7 +395,8 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) :
 		lastWheelMouseDirection(0),
 		wheelMouseIntensity(0),
 		rgnUpdate(0),
-		repaintFullWindow(false) {
+		repaintFullWindow(false),
+		styleIdleID(0) {
 	sci = sci_;
 	wMain = GTK_WIDGET(sci);
 
@@ -424,7 +428,10 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) :
 }
 
 ScintillaGTK::~ScintillaGTK() {
-	g_source_remove_by_user_data(this);
+	if (styleIdleID) {
+		g_source_remove(styleIdleID);
+		styleIdleID = 0;
+	}
 	if (evbtn) {
 		gdk_event_free(reinterpret_cast<GdkEvent *>(evbtn));
 		evbtn = 0;
@@ -2966,12 +2973,16 @@ gboolean ScintillaGTK::StyleIdle(gpointer pSci) {
 	return FALSE;
 }
 
+void ScintillaGTK::IdleWork() {
+	Editor::IdleWork();
+	styleIdleID = 0;
+}
+
 void ScintillaGTK::QueueIdleWork(WorkNeeded::workItems items, int upTo) {
 	Editor::QueueIdleWork(items, upTo);
-	if (!workNeeded.active) {
+	if (!styleIdleID) {
 		// Only allow one style needed to be queued
-		workNeeded.active = true;
-		gdk_threads_add_idle_full(G_PRIORITY_HIGH_IDLE, StyleIdle, this, NULL);
+		styleIdleID = gdk_threads_add_idle_full(G_PRIORITY_HIGH_IDLE, StyleIdle, this, NULL);
 	}
 }
 


Modified: scintilla/src/Editor.h
4 lines changed, 1 insertions(+), 3 deletions(-)
===================================================================
@@ -46,13 +46,11 @@ class WorkNeeded {
 		workStyle=1,
 		workUpdateUI=2
 	};
-	bool active;
 	enum workItems items;
 	Position upTo;
 
-	WorkNeeded() : active(false), items(workNone), upTo(0) {}
+	WorkNeeded() : items(workNone), upTo(0) {}
 	void Reset() {
-		active = false;
 		items = workNone;
 		upTo = 0;
 	}



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Commits mailing list