aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2016-02-01 09:36:30 +0100
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2017-03-14 06:28:41 +0100
commitaa3365e7a2c4de405dab8ecc27283b3a64935dcf (patch)
treea025fa368e32bb87737b0c3715a0293c95840d25
parente30f052fcd466d4a27cf03a7eddc55edbe7ef4c6 (diff)
downloadscintilla-mirror-sciteco-dev-pre-v2.0.0.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()sciteco-dev-pre-v2.0.0
* 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 25e160510..792dd3e22 100644
--- a/gtk/ScintillaGTK.cxx
+++ b/gtk/ScintillaGTK.cxx
@@ -20,6 +20,7 @@
#include <glib.h>
#include <gmodule.h>
#include <gtk/gtk.h>
+#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>
#if defined(__WIN32__) || defined(_MSC_VER)
@@ -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
@@ -2939,9 +2940,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
@@ -2949,21 +2947,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;
}
@@ -2973,7 +2962,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);
}
}