diff options
author | Marco Peereboom <marco@conformal.com> | 2011-10-24 15:17:52 -0500 |
---|---|---|
committer | Marco Peereboom <marco@conformal.com> | 2011-10-24 15:17:52 -0500 |
commit | d6d4dbed7855ba747736947bad30b984a4dccb33 (patch) | |
tree | 58a292af992586817ffba87d942c885810011c15 | |
parent | f04facb5c0f762e6726658869fa745c8f25a41b9 (diff) | |
download | xombrero-d6d4dbed7855ba747736947bad30b984a4dccb33.tar.gz |
Another day another thread implementation.
The issue comes down to things like flash player are not playing nice with the gdk mutex. It does not correctly follow the enter/leave protocol. This code now detects this flaw and uses a workaround. There is no telling if this code catches all flash player locking violations but it tries its college best. Flash is such awesome quality that it often crashes on the way out. We can easily ignore that crash so whatever.
-rw-r--r-- | xxxterm.c | 95 |
1 files changed, 86 insertions, 9 deletions
diff --git a/xxxterm.c b/xxxterm.c index 26325bc..8cb9e75 100644 --- a/xxxterm.c +++ b/xxxterm.c @@ -6482,6 +6482,15 @@ color_address_bar(gpointer p) /* test to see if the user navigated away and canceled the thread */ if (t->thread != g_thread_self()) goto done; + if ((uri = get_uri(t)) == NULL) { + t->thread = NULL; + goto done; + } + if (strcmp(uri, u)) { + /* make sure we are still the same url */ + t->thread = NULL; + goto done; + } #endif white: gdk_color_parse(col_str, &color); @@ -10187,6 +10196,75 @@ usage(void) exit(0); } +GStaticRecMutex my_gdk_mtx = G_STATIC_REC_MUTEX_INIT; +volatile int mtx_depth; +int mtx_complain; + +/* + * The linux flash plugin violates the gdk locking mechanism. + * Work around the issue by using a recursive mutex with some match applied + * to see if we hit a buggy condition. + * + * The following code is painful so just don't read it. It really doesn't + * make much sense but seems to work. + */ +void +mtx_lock(void) +{ + g_static_rec_mutex_lock(&my_gdk_mtx); + mtx_depth++; + + if (mtx_depth <= 0) { + /* should not happen */ + show_oops(NULL, "negative mutex locking bug, trying to " + "correct"); + fprintf(stderr, "negative mutex locking bug, trying to " + "correct\n"); + g_static_rec_mutex_unlock_full(&my_gdk_mtx); + g_static_rec_mutex_lock(&my_gdk_mtx); + mtx_depth = 1; + return; + } + + if (mtx_depth != 1) { + /* decrease mutext depth to 1 */ + do { + g_static_rec_mutex_unlock(&my_gdk_mtx); + mtx_depth--; + } while (mtx_depth > 1); + } +} + +void +mtx_unlock(void) +{ + guint x; + + /* if mutex depth isn't 1 then something went bad */ + if (mtx_depth != 1) { + x = g_static_rec_mutex_unlock_full(&my_gdk_mtx); + if (x != 1) { + /* should not happen */ + show_oops(NULL, "mutex unlocking bug, trying to " + "correct"); + fprintf(stderr, "mutex unlocking bug, trying to " + "correct\n"); + } + mtx_depth = 0; + if (mtx_complain == 0) { + show_oops(NULL, "buggy mutex implementation detected, " + "work around implemented"); + fprintf(stderr, "buggy mutex implementation detected, " + "work around implemented"); + mtx_complain = 1; + } + return; + } + + mtx_depth--; + g_static_rec_mutex_unlock(&my_gdk_mtx); +} + int main(int argc, char *argv[]) { @@ -10207,17 +10285,14 @@ main(int argc, char *argv[]) /* prepare gtk */ #ifdef USE_THREADS g_thread_init(NULL); -#if !defined(__linux__) - /* this call hangs the flash plugin and isn't needed on linux it seems */ + gdk_threads_set_lock_functions(mtx_lock, mtx_unlock); gdk_threads_init(); -#endif gdk_threads_enter(); -#endif - gtk_init(&argc, &argv); -#ifdef USE_THREADS gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); #endif + gtk_init(&argc, &argv); + gnutls_global_init(); strlcpy(named_session, XT_SAVED_TABS_FILE, sizeof named_session); @@ -10518,13 +10593,15 @@ main(int argc, char *argv[]) gtk_main(); +#ifdef USE_THREADS + gdk_threads_leave(); + g_static_rec_mutex_unlock_full(&my_gdk_mtx); /* just in case */ +#endif + gnutls_global_deinit(); if (url_regex) regfree(&url_re); -#ifdef USE_THREADS - gdk_threads_leave(); -#endif return (0); } |