aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--libsylph/codeconv.c114
-rw-r--r--src/query_search.c47
3 files changed, 140 insertions, 26 deletions
diff --git a/ChangeLog b/ChangeLog
index 9b776923..9b91db47 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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");