diff options
author | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2009-10-16 07:41:01 +0000 |
---|---|---|
committer | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2009-10-16 07:41:01 +0000 |
commit | 7633da4efcb1ce694f02759838bd10e6366c7846 (patch) | |
tree | 7dda20ac0c44625fa542b464b1936a515ebd2088 | |
parent | eb03d22324fbf818eae312e82ffe8e2b63fda8ae (diff) |
made codeconv module thread-safe. update search window using timer.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@2284 ee746299-78ed-0310-b773-934348b2243d
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | libsylph/codeconv.c | 114 | ||||
-rw-r--r-- | src/query_search.c | 47 |
3 files changed, 140 insertions, 26 deletions
@@ -1,3 +1,8 @@ +2009-10-16 + + * libsylph/codeconv.c: made codeconv module thread-safe. + * src/query_search.c: update search window using timer. + 2009-10-13 * src/plugin.[ch] diff --git a/libsylph/codeconv.c b/libsylph/codeconv.c index 36dd264c..a71af5a0 100644 --- a/libsylph/codeconv.c +++ b/libsylph/codeconv.c @@ -770,13 +770,28 @@ static gchar *conv_jistoutf8(const gchar *inbuf, gint *error) return utf8str; } +#if USE_THREADS +#define S_LOCK_DEFINE_STATIC(name) G_LOCK_DEFINE_STATIC(name) +#define S_LOCK(name) G_LOCK(name) +#define S_UNLOCK(name) G_UNLOCK(name) +#else +#define S_LOCK_DEFINE_STATIC(name) +#define S_LOCK(name) +#define S_UNLOCK(name) +#endif + static gchar *conv_sjistoutf8(const gchar *inbuf, gint *error) { static iconv_t cd = (iconv_t)-1; static gboolean iconv_ok = TRUE; + S_LOCK_DEFINE_STATIC(cd); + gchar *ret; + + S_LOCK(cd); if (cd == (iconv_t)-1) { if (!iconv_ok) { + S_UNLOCK(cd); if (error) *error = -1; return g_strdup(inbuf); @@ -789,6 +804,7 @@ static gchar *conv_sjistoutf8(const gchar *inbuf, gint *error) g_warning("conv_sjistoutf8(): %s\n", g_strerror(errno)); iconv_ok = FALSE; + S_UNLOCK(cd); if (error) *error = -1; return g_strdup(inbuf); @@ -796,16 +812,23 @@ static gchar *conv_sjistoutf8(const gchar *inbuf, gint *error) } } - return conv_iconv_strdup_with_cd(inbuf, cd, error); + ret = conv_iconv_strdup_with_cd(inbuf, cd, error); + S_UNLOCK(cd); + return ret; } static gchar *conv_euctoutf8(const gchar *inbuf, gint *error) { static iconv_t cd = (iconv_t)-1; static gboolean iconv_ok = TRUE; + S_LOCK_DEFINE_STATIC(cd); + gchar *ret; + + S_LOCK(cd); if (cd == (iconv_t)-1) { if (!iconv_ok) { + S_UNLOCK(cd); if (error) *error = -1; return g_strdup(inbuf); @@ -818,6 +841,7 @@ static gchar *conv_euctoutf8(const gchar *inbuf, gint *error) g_warning("conv_euctoutf8(): %s\n", g_strerror(errno)); iconv_ok = FALSE; + S_UNLOCK(cd); if (error) *error = -1; return g_strdup(inbuf); @@ -825,7 +849,9 @@ static gchar *conv_euctoutf8(const gchar *inbuf, gint *error) } } - return conv_iconv_strdup_with_cd(inbuf, cd, error); + ret = conv_iconv_strdup_with_cd(inbuf, cd, error); + S_UNLOCK(cd); + return ret; } static gchar *conv_anytoutf8(const gchar *inbuf, gint *error) @@ -854,9 +880,14 @@ static gchar *conv_utf8tosjis(const gchar *inbuf, gint *error) { static iconv_t cd = (iconv_t)-1; static gboolean iconv_ok = TRUE; + S_LOCK_DEFINE_STATIC(cd); + gchar *ret; + + S_LOCK(cd); if (cd == (iconv_t)-1) { if (!iconv_ok) { + S_UNLOCK(cd); if (error) *error = -1; return g_strdup(inbuf); @@ -869,6 +900,7 @@ static gchar *conv_utf8tosjis(const gchar *inbuf, gint *error) g_warning("conv_utf8tosjis(): %s\n", g_strerror(errno)); iconv_ok = FALSE; + S_UNLOCK(cd); if (error) *error = -1; return g_strdup(inbuf); @@ -878,16 +910,23 @@ static gchar *conv_utf8tosjis(const gchar *inbuf, gint *error) if (isutf8bom(inbuf)) inbuf += 3; - return conv_iconv_strdup_with_cd(inbuf, cd, error); + ret = conv_iconv_strdup_with_cd(inbuf, cd, error); + S_UNLOCK(cd); + return ret; } static gchar *conv_utf8toeuc(const gchar *inbuf, gint *error) { static iconv_t cd = (iconv_t)-1; static gboolean iconv_ok = TRUE; + S_LOCK_DEFINE_STATIC(cd); + gchar *ret; + + S_LOCK(cd); if (cd == (iconv_t)-1) { if (!iconv_ok) { + S_UNLOCK(cd); if (error) *error = -1; return g_strdup(inbuf); @@ -900,6 +939,7 @@ static gchar *conv_utf8toeuc(const gchar *inbuf, gint *error) g_warning("conv_utf8toeuc(): %s\n", g_strerror(errno)); iconv_ok = FALSE; + S_UNLOCK(cd); if (error) *error = -1; return g_strdup(inbuf); @@ -909,7 +949,9 @@ static gchar *conv_utf8toeuc(const gchar *inbuf, gint *error) if (isutf8bom(inbuf)) inbuf += 3; - return conv_iconv_strdup_with_cd(inbuf, cd, error); + ret = conv_iconv_strdup_with_cd(inbuf, cd, error); + S_UNLOCK(cd); + return ret; } static gchar *conv_utf8tojis(const gchar *inbuf, gint *error) @@ -1829,9 +1871,14 @@ static GHashTable *conv_get_charset_to_str_table(void) { static GHashTable *table; gint i; + S_LOCK_DEFINE_STATIC(table); + + S_LOCK(table); - if (table) + if (table) { + S_UNLOCK(table); return table; + } table = g_hash_table_new(NULL, g_direct_equal); @@ -1844,16 +1891,23 @@ static GHashTable *conv_get_charset_to_str_table(void) } } + S_UNLOCK(table); return table; } static GHashTable *conv_get_charset_from_str_table(void) { static GHashTable *table; + S_LOCK_DEFINE_STATIC(table); + gint i; - if (table) + S_LOCK(table); + + if (table) { + S_UNLOCK(table); return table; + } table = g_hash_table_new(str_case_hash, str_case_equal); @@ -1862,6 +1916,7 @@ static GHashTable *conv_get_charset_from_str_table(void) GUINT_TO_POINTER(charsets[i].charset)); } + S_UNLOCK(table); return table; } @@ -1891,29 +1946,38 @@ CharSet conv_get_locale_charset(void) #ifndef G_OS_WIN32 gint i; #endif + S_LOCK_DEFINE_STATIC(cur_charset); - if (cur_charset != -1) + S_LOCK(cur_charset); + + if (cur_charset != -1) { + S_UNLOCK(cur_charset); return cur_charset; + } cur_locale = conv_get_current_locale(); if (!cur_locale) { cur_charset = C_US_ASCII; + S_UNLOCK(cur_charset); return cur_charset; } if (strcasestr(cur_locale, "UTF-8") || strcasestr(cur_locale, "utf8")) { cur_charset = C_UTF_8; + S_UNLOCK(cur_charset); return cur_charset; } if ((p = strcasestr(cur_locale, "@euro")) && p[5] == '\0') { cur_charset = C_ISO_8859_15; + S_UNLOCK(cur_charset); return cur_charset; } #ifdef G_OS_WIN32 cur_charset = conv_get_charset_from_str(conv_get_locale_charset_str()); + S_UNLOCK(cur_charset); return cur_charset; #else for (i = 0; i < sizeof(locale_table) / sizeof(locale_table[0]); i++) { @@ -1924,6 +1988,7 @@ CharSet conv_get_locale_charset(void) if (!g_ascii_strncasecmp(cur_locale, locale_table[i].locale, strlen(locale_table[i].locale))) { cur_charset = locale_table[i].charset; + S_UNLOCK(cur_charset); return cur_charset; } else if ((p = strchr(locale_table[i].locale, '_')) && !strchr(p + 1, '.')) { @@ -1931,12 +1996,14 @@ CharSet conv_get_locale_charset(void) !g_ascii_strncasecmp(cur_locale, locale_table[i].locale, 2)) { cur_charset = locale_table[i].charset; + S_UNLOCK(cur_charset); return cur_charset; } } } cur_charset = C_AUTO; + S_UNLOCK(cur_charset); return cur_charset; #endif } @@ -1944,6 +2011,9 @@ CharSet conv_get_locale_charset(void) const gchar *conv_get_locale_charset_str(void) { static const gchar *codeset = NULL; + S_LOCK_DEFINE_STATIC(codeset); + + S_LOCK(codeset); if (!codeset) { #ifdef G_OS_WIN32 @@ -1956,7 +2026,13 @@ const gchar *conv_get_locale_charset_str(void) #endif } - return codeset ? codeset : CS_INTERNAL; + if (codeset) { + S_UNLOCK(codeset); + return codeset; + } + + S_UNLOCK(codeset); + return CS_INTERNAL; } CharSet conv_get_internal_charset(void) @@ -1975,18 +2051,25 @@ CharSet conv_get_outgoing_charset(void) const gchar *cur_locale; const gchar *p; gint i; + S_LOCK_DEFINE_STATIC(out_charset); - if (out_charset != -1) + S_LOCK(out_charset); + + if (out_charset != -1) { + S_UNLOCK(out_charset); return out_charset; + } cur_locale = conv_get_current_locale(); if (!cur_locale) { out_charset = C_AUTO; + S_UNLOCK(out_charset); return out_charset; } if ((p = strcasestr(cur_locale, "@euro")) && p[5] == '\0') { out_charset = C_ISO_8859_15; + S_UNLOCK(out_charset); return out_charset; } @@ -2008,6 +2091,7 @@ CharSet conv_get_outgoing_charset(void) } } + S_UNLOCK(out_charset); return out_charset; } @@ -2051,6 +2135,9 @@ gboolean conv_is_multibyte_encoding(CharSet encoding) const gchar *conv_get_current_locale(void) { static const gchar *cur_locale; + S_LOCK_DEFINE_STATIC(cur_locale); + + S_LOCK(cur_locale); if (!cur_locale) { #ifdef G_OS_WIN32 @@ -2071,6 +2158,7 @@ const gchar *conv_get_current_locale(void) cur_locale ? cur_locale : "(none)"); } + S_UNLOCK(cur_locale); return cur_locale; } @@ -2078,9 +2166,14 @@ gboolean conv_is_ja_locale(void) { static gint is_ja_locale = -1; const gchar *cur_locale; + S_LOCK_DEFINE_STATIC(is_ja_locale); - if (is_ja_locale != -1) + S_LOCK(is_ja_locale); + + if (is_ja_locale != -1) { + S_UNLOCK(is_ja_locale); return is_ja_locale != 0; + } is_ja_locale = 0; cur_locale = conv_get_current_locale(); @@ -2089,6 +2182,7 @@ gboolean conv_is_ja_locale(void) is_ja_locale = 1; } + S_UNLOCK(is_ja_locale); return is_ja_locale != 0; } diff --git a/src/query_search.c b/src/query_search.c index 0e74a808..ff6a31ef 100644 --- a/src/query_search.c +++ b/src/query_search.c @@ -573,15 +573,17 @@ typedef struct _QueryData GTimeVal tv_prev; #if USE_THREADS GAsyncQueue *queue; + guint timer_tag; #endif } QueryData; -static void query_search_folder_show_progress(QueryData *data) +static void query_search_folder_show_progress(const gchar *name, gint count, + gint total) { gchar *str; str = g_strdup_printf(_("Searching %s (%d / %d)..."), - data->folder_name, data->count, data->total); + name, count, total); gtk_label_set_text(GTK_LABEL(search_window.status_label), str); g_free(str); #ifndef USE_THREADS @@ -589,6 +591,24 @@ static void query_search_folder_show_progress(QueryData *data) #endif } +#if USE_THREADS +static gboolean query_search_progress_func(gpointer data) +{ + QueryData *qdata = (QueryData *)data; + MsgInfo *msginfo; + + gdk_threads_enter(); + query_search_folder_show_progress(qdata->folder_name, + g_atomic_int_get(&qdata->count), + qdata->total); + while ((msginfo = g_async_queue_try_pop(qdata->queue))) + query_search_append_msg(msginfo); + gdk_threads_leave(); + + return TRUE; +} +#endif + static gpointer query_search_folder_func(gpointer data) { QueryData *qdata = (QueryData *)data; @@ -616,16 +636,16 @@ static gpointer query_search_folder_func(gpointer data) MsgInfo *msginfo = (MsgInfo *)cur->data; GSList *hlist; - ++qdata->count; + g_atomic_int_add(&qdata->count, 1); g_get_current_time(&tv_cur); if ((tv_cur.tv_sec - qdata->tv_prev.tv_sec) * G_USEC_PER_SEC + tv_cur.tv_usec - qdata->tv_prev.tv_usec > PROGRESS_UPDATE_INTERVAL * 1000) { -#ifdef USE_THREADS - g_main_context_wakeup(NULL); -#else - query_search_folder_show_progress(qdata); +#ifndef USE_THREADS + query_search_folder_show_progress(qdata->folder_name, + qdata->count, + qdata->total); #endif qdata->tv_prev = tv_cur; } @@ -679,7 +699,6 @@ static void query_search_folder(FolderItem *item) QueryData data = {item}; #if USE_THREADS GThread *thread; - gint prev_count = 0; MsgInfo *msginfo; #endif @@ -707,22 +726,18 @@ static void query_search_folder(FolderItem *item) #if USE_THREADS data.queue = g_async_queue_new(); + data.timer_tag = g_timeout_add(PROGRESS_UPDATE_INTERVAL, + query_search_progress_func, &data); thread = g_thread_create(query_search_folder_func, &data, TRUE, NULL); debug_print("query_search_folder: thread started\n"); - while (g_atomic_int_get(&data.flag) == 0) { + while (g_atomic_int_get(&data.flag) == 0) gtk_main_iteration(); - if (prev_count != data.count) { - prev_count = data.count; - query_search_folder_show_progress(&data); - while ((msginfo = g_async_queue_try_pop(data.queue))) - query_search_append_msg(msginfo); - } - } while ((msginfo = g_async_queue_try_pop(data.queue))) query_search_append_msg(msginfo); + g_source_remove(data.timer_tag); g_thread_join(thread); debug_print("query_search_folder: thread exited\n"); |