aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2016-04-08 09:25:05 +1000
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2016-04-08 09:25:05 +1000
commit68a2a44587388528e344dc25a1a33e0e17e7e468 (patch)
tree231f119bbb4006ceaedc97923f245f53d85a9a4b
parent0604389a02a2cb5f33f5f84e460ad3d7a55f1fc4 (diff)
downloadscintilla-mirror-68a2a44587388528e344dc25a1a33e0e17e7e468.tar.gz
Scintilla Gtk: use gdk_threads_add_idle_full() instead of g_idle_add_full() and gdk_threads_add_timeout() instead of g_timeout_add()
* The g_idle/g_timeout watchers are not executed with the Gdk lock held. This causes memory corruptions and crashes when accessing the Scintilla object from the non-main-loop-thread. At least this was the case after Gdk 3.6 since Scintilla used gdk_threads_enter()/leave() for earlier versions. The timeout handlers have possibly always been broken. * The new version should work with non-deprecated APIs in all Gdk versions. * Even though this only fixes the idle handlers in Gdk >= 3.6 where gdk_threads_enter() is deprecated (the only way to provoke above situation) - and the timers of course - this patch makes the code more elegant.
-rw-r--r--gtk/ScintillaGTK.cxx21
1 files changed, 5 insertions, 16 deletions
diff --git a/gtk/ScintillaGTK.cxx b/gtk/ScintillaGTK.cxx
index ad9aa6568..80217660b 100644
--- a/gtk/ScintillaGTK.cxx
+++ b/gtk/ScintillaGTK.cxx
@@ -19,6 +19,7 @@
#include <glib.h>
#include <gmodule.h>
+#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
@@ -423,7 +424,7 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) :
}
ScintillaGTK::~ScintillaGTK() {
- g_idle_remove_by_data(this);
+ g_source_remove_by_user_data(this);
if (evbtn) {
gdk_event_free(reinterpret_cast<GdkEvent *>(evbtn));
evbtn = 0;
@@ -1077,7 +1078,7 @@ bool ScintillaGTK::FineTickerRunning(TickReason reason) {
void ScintillaGTK::FineTickerStart(TickReason reason, int millis, int /* tolerance */) {
FineTickerCancel(reason);
- timers[reason].timer = g_timeout_add(millis, TimeOut, &timers[reason]);
+ timers[reason].timer = gdk_threads_add_timeout(millis, TimeOut, &timers[reason]);
}
void ScintillaGTK::FineTickerCancel(TickReason reason) {
@@ -1093,7 +1094,7 @@ bool ScintillaGTK::SetIdle(bool on) {
if (!idler.state) {
idler.state = true;
idler.idlerID = reinterpret_cast<IdlerID>(
- g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, IdleCallback, this, NULL));
+ gdk_threads_add_idle_full(G_PRIORITY_DEFAULT_IDLE, IdleCallback, this, NULL));
}
} else {
// Stop idler, if it's running
@@ -2937,9 +2938,6 @@ gboolean ScintillaGTK::IdleCallback(gpointer pSci) {
ScintillaGTK *sciThis = static_cast<ScintillaGTK *>(pSci);
// Idler will be automatically stopped, if there is nothing
// to do while idle.
-#ifndef GDK_VERSION_3_6
- gdk_threads_enter();
-#endif
bool ret = sciThis->Idle();
if (ret == false) {
// FIXME: This will remove the idler from GTK, we don't want to
@@ -2947,21 +2945,12 @@ gboolean ScintillaGTK::IdleCallback(gpointer pSci) {
// returns false (although, it should be harmless).
sciThis->SetIdle(false);
}
-#ifndef GDK_VERSION_3_6
- gdk_threads_leave();
-#endif
return ret;
}
gboolean ScintillaGTK::StyleIdle(gpointer pSci) {
-#ifndef GDK_VERSION_3_6
- gdk_threads_enter();
-#endif
ScintillaGTK *sciThis = static_cast<ScintillaGTK *>(pSci);
sciThis->IdleWork();
-#ifndef GDK_VERSION_3_6
- gdk_threads_leave();
-#endif
// Idler will be automatically stopped
return FALSE;
}
@@ -2971,7 +2960,7 @@ void ScintillaGTK::QueueIdleWork(WorkNeeded::workItems items, int upTo) {
if (!workNeeded.active) {
// Only allow one style needed to be queued
workNeeded.active = true;
- g_idle_add_full(G_PRIORITY_HIGH_IDLE, StyleIdle, this, NULL);
+ gdk_threads_add_idle_full(G_PRIORITY_HIGH_IDLE, StyleIdle, this, NULL);
}
}