diff options
author | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2009-10-01 06:56:56 +0000 |
---|---|---|
committer | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2009-10-01 06:56:56 +0000 |
commit | 9654e4020b2d26c716102d143e94a40123c40e28 (patch) | |
tree | e116c9a7e35aee6b2234b0d9e1aa2f73fdbbad84 /libsylph/imap.c | |
parent | b6a7ac64157874fbbf65211aec60850a22929f4f (diff) |
libsylph/imap.c: reimplemented using GThreadPool.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@2265 ee746299-78ed-0310-b773-934348b2243d
Diffstat (limited to 'libsylph/imap.c')
-rw-r--r-- | libsylph/imap.c | 102 |
1 files changed, 65 insertions, 37 deletions
diff --git a/libsylph/imap.c b/libsylph/imap.c index 34d79a0f..0adf4a1a 100644 --- a/libsylph/imap.c +++ b/libsylph/imap.c @@ -74,6 +74,22 @@ } \ } +typedef gint (*IMAPThreadFunc) (IMAPSession *session, + gpointer data); + +typedef struct _IMAPRealSession +{ + IMAPSession imap_session; +#if USE_THREADS + GThreadPool *pool; + IMAPThreadFunc thread_func; + gpointer thread_data; + gboolean is_running; + gint flag; + gint retval; +#endif +} IMAPRealSession; + static GList *session_list = NULL; static void imap_folder_init (Folder *folder, @@ -393,7 +409,7 @@ static gboolean imap_rename_folder_func (GNode *node, #if USE_THREADS static gint imap_thread_run (IMAPSession *session, - GThreadFunc func, + IMAPThreadFunc func, gpointer data); #endif @@ -595,7 +611,7 @@ static Session *imap_session_new(PrefsAccount *account) port = account->set_imapport ? account->imapport : IMAP4_PORT; #endif - session = g_new0(IMAPSession, 1); + session = IMAP_SESSION(g_new0(IMAPRealSession, 1)); session_init(SESSION(session)); @@ -3862,11 +3878,9 @@ typedef struct _IMAPCmdFetchData #define THROW(err) { ok = err; goto catch; } -static gpointer imap_cmd_fetch_func(gpointer data) +static gint imap_cmd_fetch_func(IMAPSession *session, gpointer data) { - IMAPSession *session = IMAP_SESSION(data); - const gchar *filename = - ((IMAPCmdFetchData *)SESSION(data)->data)->filename; + const gchar *filename = ((IMAPCmdFetchData *)data)->filename; gint ok; gchar *buf; gchar *cur_pos; @@ -3877,7 +3891,7 @@ static gpointer imap_cmd_fetch_func(gpointer data) while ((ok = imap_cmd_gen_recv(session, &buf)) == IMAP_SUCCESS) { if (buf[0] != '*' || buf[1] != ' ') { g_free(buf); - return GINT_TO_POINTER(IMAP_ERROR); + return IMAP_ERROR; } if (strstr(buf, "FETCH") != NULL) break; g_free(buf); @@ -3926,12 +3940,7 @@ static gpointer imap_cmd_fetch_func(gpointer data) THROW(IMAP_ERROR); catch: -#if USE_THREADS - SESSION(session)->io_tag = 1; - g_main_context_wakeup(NULL); -#endif - - return GINT_TO_POINTER(ok); + return ok; } #undef THROW @@ -3950,9 +3959,7 @@ static gint imap_cmd_fetch(IMAPSession *session, guint32 uid, #if USE_THREADS ok = imap_thread_run(session, imap_cmd_fetch_func, &fetch_data); #else - SESSION(session)->data = &fetch_data; - ok = (gint)imap_cmd_fetch_func(session); - SESSION(session)->data = NULL; + ok = imap_cmd_fetch_func(session, &fetch_data); #endif g_print("leave imap_cmd_fetch\n"); @@ -4191,19 +4198,16 @@ static gint imap_cmd_ok_real(IMAPSession *session, GPtrArray *argbuf) } #if USE_THREADS -static gpointer imap_cmd_ok_func(gpointer data) +static gint imap_cmd_ok_func(IMAPSession *session, gpointer data) { - IMAPSession *session = IMAP_SESSION(data); - GPtrArray *argbuf = (GPtrArray *)SESSION(session)->data; + GPtrArray *argbuf = (GPtrArray *)data; gint ok; g_print("enter imap_cmd_ok_func\n"); ok = imap_cmd_ok_real(session, argbuf); - SESSION(session)->io_tag = 1; - g_main_context_wakeup(NULL); g_print("leave imap_cmd_ok_func\n"); - return GINT_TO_POINTER(ok); + return ok; } #endif @@ -4695,30 +4699,54 @@ static gboolean imap_rename_folder_func(GNode *node, gpointer data) } #if USE_THREADS -static gint imap_thread_run(IMAPSession *session, GThreadFunc func, +static void imap_thread_run_proxy(gpointer push_data, gpointer data) +{ + IMAPRealSession *real = (IMAPRealSession *)data; + + g_print("imap_thread_run_proxy (%p): calling thread_func\n", g_thread_self()); + real->retval = real->thread_func(IMAP_SESSION(real), real->thread_data); + real->flag = 1; + g_print("imap_thread_run_proxy (%p): thread_func done\n", g_thread_self()); + g_main_context_wakeup(NULL); +} + +static gint imap_thread_run(IMAPSession *session, IMAPThreadFunc func, gpointer data) { - GThread *thread; - gpointer save_data; + IMAPRealSession *real = (IMAPRealSession *)session; gint ret; - save_data = SESSION(session)->data; - SESSION(session)->data = data; - SESSION(session)->io_tag = 0; - - thread = g_thread_create(func, session, TRUE, NULL); - if (!thread) { - SESSION(session)->data = save_data; + if (real->is_running) { + g_warning("imap_thread_run: thread is already running"); return IMAP_ERROR; } - while (SESSION(session)->io_tag == 0) + + if (!real->pool) { + real->pool = g_thread_pool_new(imap_thread_run_proxy, real, + -1, FALSE, NULL); + if (!real->pool) + return IMAP_ERROR; + } + + real->is_running = TRUE; + real->thread_func = func; + real->thread_data = data; + real->flag = 0; + real->retval = 0; + + g_thread_pool_push(real->pool, real, NULL); + + while (real->flag == 0) event_loop_iterate(); - ret = (gint)g_thread_join(thread); - SESSION(session)->data = save_data; - SESSION(session)->io_tag = 0; + real->is_running = FALSE; + real->thread_func = NULL; + real->thread_data = NULL; + real->flag = 0; + ret = real->retval; + real->retval = 0; log_flush(); return ret; } -#endif +#endif /* USE_THREADS */ |