diff options
author | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2009-09-29 07:49:30 +0000 |
---|---|---|
committer | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2009-09-29 07:49:30 +0000 |
commit | a75654a326dadebacc229762eb01f5e7c65b1ccc (patch) | |
tree | 384933406e40aa0eae55368420af4b1391a568fc /src/logwindow.c | |
parent | 1ff05553158408570a7cd548fdcdf4ec7be07f5d (diff) |
made GDK locks reentrant, and made LogWindow thread-safe.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@2259 ee746299-78ed-0310-b773-934348b2243d
Diffstat (limited to 'src/logwindow.c')
-rw-r--r-- | src/logwindow.c | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/src/logwindow.c b/src/logwindow.c index 017bb37b..beab32a8 100644 --- a/src/logwindow.c +++ b/src/logwindow.c @@ -1,6 +1,6 @@ /* * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 1999-2005 Hiroyuki Yamamoto + * Copyright (C) 1999-2009 Hiroyuki Yamamoto * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,6 +41,10 @@ static LogWindow *logwindow; +#if USE_THREADS +static GThread *main_thread; +#endif + static void log_window_print_func (const gchar *str); static void log_window_message_func (const gchar *str); static void log_window_warning_func (const gchar *str); @@ -99,6 +103,13 @@ LogWindow *log_window_create(void) logwin->text = text; logwin->lines = 1; +#if USE_THREADS + logwin->aqueue = g_async_queue_new(); + + main_thread = g_thread_self(); + debug_print("main_thread = %p\n", main_thread); +#endif + logwindow = logwin; return logwin; @@ -160,7 +171,7 @@ void log_window_show(LogWindow *logwin) gtk_window_present(GTK_WINDOW(logwin->window)); } -void log_window_append(const gchar *str, LogType type) +static void log_window_append_real(const gchar *str, LogType type) { GtkTextView *text; GtkTextBuffer *buffer; @@ -172,6 +183,14 @@ void log_window_append(const gchar *str, LogType type) g_return_if_fail(logwindow != NULL); +#if USE_THREADS + if (g_thread_self() != main_thread) { + return; + } +#endif + + gdk_threads_enter(); + text = GTK_TEXT_VIEW(logwindow->text); buffer = gtk_text_view_get_buffer(text); @@ -233,6 +252,61 @@ void log_window_append(const gchar *str, LogType type) } logwindow->lines++; + + gdk_threads_leave(); +} + +void log_window_append(const gchar *str, LogType type) +{ +#if USE_THREADS + if (g_thread_self() != main_thread) { + fprintf(stderr, "log_window_append called from non-main thread (%p)\n", g_thread_self()); + log_window_append_queue(str, type); + return; + } + + log_window_flush(); +#endif + log_window_append_real(str, type); +} + +typedef struct _LogData +{ + gchar *str; + LogType type; +} LogData; + +void log_window_append_queue(const gchar *str, LogType type) +{ +#if USE_THREADS + LogData *logdata; + + logdata = g_new(LogData, 1); + logdata->str = g_strdup(str); + logdata->type = type; + + g_print("append_queue: (%d) %s\n", type, str); + g_async_queue_push(logwindow->aqueue, logdata); +#endif +} + +void log_window_flush(void) +{ +#if USE_THREADS + LogData *logdata; + + if (g_thread_self() != main_thread) { + fprintf(stderr, "log_window_flush called from non-main thread (%p)\n", g_thread_self()); + return; + } + + while ((logdata = g_async_queue_try_pop(logwindow->aqueue))) { + g_print("flush_queue: (%d) %s\n", logdata->type, logdata->str); + log_window_append_real(logdata->str, logdata->type); + g_free(logdata->str); + g_free(logdata); + } +#endif } static void log_window_print_func(const gchar *str) |