aboutsummaryrefslogtreecommitdiff
path: root/libsylph
diff options
context:
space:
mode:
authorhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2009-09-17 07:26:17 +0000
committerhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2009-09-17 07:26:17 +0000
commit71f191b2a609e291a3afcf726ab8aacab572637b (patch)
treefa744ee9944df82548c6afb33451455c4ce7c61a /libsylph
parent24c2edfeacce97b6e4c3783c53cbd2532088af95 (diff)
introduced multi-threading.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@2255 ee746299-78ed-0310-b773-934348b2243d
Diffstat (limited to 'libsylph')
-rw-r--r--libsylph/filter.c2
-rw-r--r--libsylph/session.c12
-rw-r--r--libsylph/socket.c78
-rw-r--r--libsylph/socket.h3
-rw-r--r--libsylph/utils.c56
-rw-r--r--libsylph/utils.h3
6 files changed, 150 insertions, 4 deletions
diff --git a/libsylph/filter.c b/libsylph/filter.c
index 9ea834ff..e61b5095 100644
--- a/libsylph/filter.c
+++ b/libsylph/filter.c
@@ -400,7 +400,7 @@ static gboolean filter_match_cond(FilterCond *cond, MsgInfo *msginfo,
if (!file)
return FALSE;
cmdline = g_strconcat(cond->str_value, " \"", file, "\"", NULL);
- ret = execute_command_line(cmdline, FALSE);
+ ret = execute_command_line_async_wait(cmdline);
matched = (ret == 0);
if (ret == -1)
fltinfo->error = FLT_ERROR_EXEC_FAILED;
diff --git a/libsylph/session.c b/libsylph/session.c
index d64fc72d..0617e402 100644
--- a/libsylph/session.c
+++ b/libsylph/session.c
@@ -120,7 +120,8 @@ void session_init(Session *session)
gint session_connect(Session *session, const gchar *server, gushort port)
{
#ifndef G_OS_UNIX
- SockInfo *sock;
+ SockInfo *sock = NULL;
+ gint flag = 0;
#endif
g_return_val_if_fail(session != NULL, -1);
g_return_val_if_fail(server != NULL, -1);
@@ -143,8 +144,13 @@ gint session_connect(Session *session, const gchar *server, gushort port)
return 0;
#else
- sock = sock_connect(server, port);
- if (sock == NULL) {
+ session->conn_id = sock_connect_async(server, port);
+ if (session->conn_id < 0) {
+ g_warning("can't connect to server.");
+ session->state = SESSION_ERROR;
+ return -1;
+ }
+ if (sock_connect_async_wait(session->conn_id, &sock) < 0) {
g_warning("can't connect to server.");
session->state = SESSION_ERROR;
return -1;
diff --git a/libsylph/socket.c b/libsylph/socket.c
index 97d273d7..431d95f1 100644
--- a/libsylph/socket.c
+++ b/libsylph/socket.c
@@ -81,11 +81,17 @@ struct _SockConnectData {
gint id;
gchar *hostname;
gushort port;
+#ifdef G_OS_UNIX
GList *addr_list;
GList *cur_addr;
SockLookupData *lookup_data;
GIOChannel *channel;
guint io_tag;
+#else
+ gint flag;
+ GThread *thread;
+ SockInfo *sock;
+#endif
SockConnectFunc func;
gpointer data;
};
@@ -1317,6 +1323,78 @@ static gint sock_get_address_info_async_cancel(SockLookupData *lookup_data)
return 0;
}
+#else /* G_OS_UNIX */
+
+gpointer sock_connect_async_func(gpointer data)
+{
+ SockConnectData *conn_data = (SockConnectData *)data;
+
+ g_print("sock_connect_async_func: connect\n");
+ conn_data->sock = sock_connect(conn_data->hostname, conn_data->port);
+ conn_data->flag = 1;
+
+ g_print("sock_connect_async_func: connected\n");
+ g_main_context_wakeup(NULL);
+
+ return GINT_TO_POINTER(0);
+}
+
+gint sock_connect_async(const gchar *hostname, gushort port)
+{
+ static gint id = 1;
+ SockConnectData *data;
+
+ data = g_new0(SockConnectData, 1);
+ data->id = id++;
+ data->hostname = g_strdup(hostname);
+ data->port = port;
+ data->flag = 0;
+
+ data->thread = g_thread_create(sock_connect_async_func, data, TRUE,
+ NULL);
+ if (!data->thread) {
+ g_free(data->hostname);
+ g_free(data);
+ return -1;
+ }
+
+ sock_connect_data_list = g_list_append(sock_connect_data_list, data);
+
+ return data->id;
+}
+
+gint sock_connect_async_wait(gint id, SockInfo **sock)
+{
+ SockConnectData *conn_data = NULL;
+ GList *cur;
+
+ for (cur = sock_connect_data_list; cur != NULL; cur = cur->next) {
+ if (((SockConnectData *)cur->data)->id == id) {
+ conn_data = (SockConnectData *)cur->data;
+ break;
+ }
+ }
+
+ if (!conn_data) {
+ g_warning("sock_connect_async_wait: id %d not found.", id);
+ return -1;
+ }
+
+ g_print("sock_connect_async_wait: waiting thread\n");
+ while (conn_data->flag == 0)
+ g_main_context_iteration(NULL, TRUE);
+
+ g_print("sock_connect_async_wait: flagged\n");
+ g_thread_join(conn_data->thread);
+ g_print("sock_connect_async_wait: thread exited\n");
+
+ *sock = conn_data->sock;
+
+ sock_connect_data_list = g_list_remove(sock_connect_data_list,
+ conn_data);
+ g_free(conn_data->hostname);
+ g_free(conn_data);
+}
#endif /* G_OS_UNIX */
diff --git a/libsylph/socket.h b/libsylph/socket.h
index 5bf8b98f..0ddf0374 100644
--- a/libsylph/socket.h
+++ b/libsylph/socket.h
@@ -103,6 +103,9 @@ SockInfo *sock_connect (const gchar *hostname, gushort port);
gint sock_connect_async (const gchar *hostname, gushort port,
SockConnectFunc func, gpointer data);
gint sock_connect_async_cancel (gint id);
+#else
+gint sock_connect_async (const gchar *hostname, gushort port);
+gint sock_connect_async_wait (gint id, SockInfo **sock);
#endif
/* Basic I/O functions */
diff --git a/libsylph/utils.c b/libsylph/utils.c
index 574f8427..0139302e 100644
--- a/libsylph/utils.c
+++ b/libsylph/utils.c
@@ -3862,6 +3862,62 @@ gint execute_command_line(const gchar *cmdline, gboolean async)
return ret;
}
+typedef struct _CmdData
+{
+ const gchar *cmdline;
+ gint flag;
+ gint status;
+} CmdData;
+
+static gpointer execute_command_line_async_func(gpointer data)
+{
+ CmdData *cmd_data = (CmdData *)data;
+ gchar **argv;
+
+ g_print("execute_command_line_async_func\n");
+ argv = strsplit_with_quote(cmd_data->cmdline, " ", 0);
+ cmd_data->status = execute_sync(argv);
+ g_strfreev(argv);
+
+ g_print("execute_command_line_async_func: exec done.\n");
+ cmd_data->flag = 1;
+ g_main_context_wakeup(NULL);
+
+ return GINT_TO_POINTER(0);
+}
+
+gint execute_command_line_async_wait(const gchar *cmdline)
+{
+ volatile CmdData data = {NULL, 0, 0};
+ GThread *thread;
+
+ if (debug_mode) {
+ gchar *utf8_cmdline;
+
+ utf8_cmdline = g_filename_to_utf8
+ (cmdline, -1, NULL, NULL, NULL);
+ debug_print("execute_command_line(): executing: %s\n",
+ utf8_cmdline ? utf8_cmdline : cmdline);
+ g_free(utf8_cmdline);
+ }
+
+ data.cmdline = cmdline;
+ thread = g_thread_create(execute_command_line_async_func, &data, TRUE,
+ NULL);
+ if (!thread)
+ return -1;
+
+ g_print("execute_command_line_async_wait: waiting thread\n");
+ while (data.flag == 0)
+ g_main_context_iteration(NULL, TRUE);
+
+ g_print("execute_command_line_async_wait: flagged\n");
+ g_thread_join(thread);
+ g_print("execute_command_line_async_wait: thread exited\n");
+
+ return data.status;
+}
+
gint execute_open_file(const gchar *file, const gchar *content_type)
{
g_return_val_if_fail(file != NULL, -1);
diff --git a/libsylph/utils.h b/libsylph/utils.h
index 97221fb9..3bbc42cb 100644
--- a/libsylph/utils.h
+++ b/libsylph/utils.h
@@ -469,6 +469,9 @@ gint execute_async (gchar *const argv[]);
gint execute_sync (gchar *const argv[]);
gint execute_command_line (const gchar *cmdline,
gboolean async);
+gint execute_command_line_async_wait
+ (const gchar *cmdline);
+
gint execute_open_file (const gchar *file,
const gchar *content_type);
gint execute_print_file (const gchar *file);