diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2016-02-01 09:36:30 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2017-03-14 06:28:41 +0100 |
commit | aa3365e7a2c4de405dab8ecc27283b3a64935dcf (patch) | |
tree | a025fa368e32bb87737b0c3715a0293c95840d25 | |
parent | e30f052fcd466d4a27cf03a7eddc55edbe7ef4c6 (diff) | |
download | scintilla-mirror-aa3365e7a2c4de405dab8ecc27283b3a64935dcf.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.cxx | 21 |
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); } } |