diff options
author | Suchang Woo <suchang.woo@samsung.com> | 2015-09-10 20:26:42 +0900 |
---|---|---|
committer | Suchang Woo <suchang.woo@samsung.com> | 2015-09-10 20:37:59 +0900 |
commit | b64f00d374be7a878d308cabf2e8c1a3929e08df (patch) | |
tree | a372412b989a1e21cfa2c1d2b8da0e34232a1d5e | |
parent | b40ab9b047bbbe8ebee9b71ab5f58d17888186ba (diff) | |
download | buxton2-tizen_3.0.m1_tv.tar.gz buxton2-tizen_3.0.m1_tv.tar.bz2 buxton2-tizen_3.0.m1_tv.zip |
library: add client mutex lock for multi-threadtizen_3.0.m1_tv_releasetizen_3.0.m1_mobile_releasesubmit/tizen_common/20151026.085049submit/tizen_common/20151023.083358submit/tizen/20150910.115012accepted/tizen/wearable/20150911.091325accepted/tizen/tv/20150911.091316accepted/tizen/mobile/20150911.091309tizen_3.0.m1_tvtizen_3.0.m1_mobile
For multi-thread, a mutex lock is added to the client library.
This patch is workaround. Because a function protected by a lock can
be reentered in a callback function. To prevent dead-lock, a mutex
lock should be unlocked when it calls a callback function.
Change-Id: Ic40a6ba0715c5f9bd9f24bc7fd03bc23f1f9519e
-rw-r--r-- | lib/buxton2.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/lib/buxton2.c b/lib/buxton2.c index a7933f6..fe3e17a 100644 --- a/lib/buxton2.c +++ b/lib/buxton2.c @@ -28,6 +28,7 @@ #include <unistd.h> #include <poll.h> #include <time.h> +#include <pthread.h> #include <glib.h> #include <glib-unix.h> @@ -89,6 +90,7 @@ struct buxton_client { }; static GList *clients; /* data: buxton_client */ +static pthread_mutex_t clients_lock = PTHREAD_MUTEX_INITIALIZER; static guint32 client_msgid; static struct buxton_value *value_create(enum buxton_key_type type, void *value) @@ -643,6 +645,8 @@ static void proc_msg_cb(void *user_data, assert(client); + pthread_mutex_unlock(&clients_lock); + switch (type) { case MSG_NOTI: proc_msg_noti(client, data, len); @@ -664,13 +668,27 @@ static void proc_msg_cb(void *user_data, bxt_err("proc msg: unknown message type %d", type); break; } + + pthread_mutex_lock(&clients_lock); } static int proc_msg(struct buxton_client *client) { int r; + GList *f; + + assert(client); + + pthread_mutex_lock(&clients_lock); + f = g_list_find(clients, client); + if (!f) { + bxt_dbg("recv msg: cli %p removed\n", client); + pthread_mutex_unlock(&clients_lock); + return 0; + } r = proto_recv_async(client->fd, proc_msg_cb, client); + pthread_mutex_unlock(&clients_lock); if (r == -1) { bxt_err("recv msg: fd %d errno %d", client->fd, errno); return -1; @@ -1852,11 +1870,22 @@ static void free_noti(struct bxt_noti *noti) static gboolean close_conn(gpointer data) { struct buxton_client *cli = data; + GList *f; assert(cli); - if (cli->fd == -1) + pthread_mutex_lock(&clients_lock); + f = g_list_find(clients, cli); + if (!f) { + bxt_dbg("%s: cli %p removed\n", __func__, cli); + pthread_mutex_unlock(&clients_lock); return G_SOURCE_REMOVE; + } + + if (cli->fd == -1) { + pthread_mutex_unlock(&clients_lock); + return G_SOURCE_REMOVE; + } if (cli->fd_id) { g_source_remove(cli->fd_id); @@ -1865,6 +1894,7 @@ static gboolean close_conn(gpointer data) close(cli->fd); cli->fd = -1; + pthread_mutex_unlock(&clients_lock); if (cli->st_callback) cli->st_callback(BUXTON_STATUS_DISCONNECTED, cli->st_data); @@ -1878,6 +1908,7 @@ static void free_client(struct buxton_client *cli) close_conn(cli); + pthread_mutex_lock(&clients_lock); clients = g_list_remove(clients, cli); if (cli->req_cbs) @@ -1887,6 +1918,7 @@ static void free_client(struct buxton_client *cli) g_hash_table_destroy(cli->noti_cbs); free(cli); + pthread_mutex_unlock(&clients_lock); } int connect_server(const char *addr) @@ -1927,9 +1959,18 @@ static gboolean recv_cb(gint fd, GIOCondition cond, gpointer data) { struct buxton_client *cli = data; int r; + GList *f; assert(cli); + pthread_mutex_lock(&clients_lock); + f = g_list_find(clients, cli); + if (!f) { + bxt_dbg("recv %d: cli %p removed\n", fd, cli); + pthread_mutex_unlock(&clients_lock); + return G_SOURCE_CONTINUE; + } + bxt_dbg("recv %d: cond %x", fd, cond); if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) { @@ -1937,8 +1978,10 @@ static gboolean recv_cb(gint fd, GIOCondition cond, gpointer data) cli->fd_id = 0; g_idle_add(close_conn, cli); + pthread_mutex_unlock(&clients_lock); return G_SOURCE_REMOVE; } + pthread_mutex_unlock(&clients_lock); r = proc_msg(cli); if (r == -1) { @@ -2014,7 +2057,9 @@ EXPORT int buxton_open(struct buxton_client **client, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, recv_cb, cli); + pthread_mutex_lock(&clients_lock); clients = g_list_append(clients, cli); + pthread_mutex_unlock(&clients_lock); *client = cli; if (callback) |