diff options
author | Jiyong Min <jiyong.min@samsung.com> | 2017-02-21 08:47:55 +0900 |
---|---|---|
committer | Jiyong Min <jiyong.min@samsung.com> | 2017-02-21 09:07:13 +0900 |
commit | b823bfe94f4b2f14206a81d1ae07010eb94675df (patch) | |
tree | c19a49b095c7cfef50488d003bf7b409e49d9000 | |
parent | cd0bf9d2ec18cffe57abd238ff51be881dff6a78 (diff) | |
download | media-controller-b823bfe94f4b2f14206a81d1ae07010eb94675df.tar.gz media-controller-b823bfe94f4b2f14206a81d1ae07010eb94675df.tar.bz2 media-controller-b823bfe94f4b2f14206a81d1ae07010eb94675df.zip |
Add request queue and code refactoring for media-controllersubmit/tizen_unified/20170310.011401submit/tizen/20170309.045041accepted/tizen/wearable/20170309.072322accepted/tizen/unified/20170310.075712accepted/tizen/tv/20170309.072310accepted/tizen/mobile/20170309.072252accepted/tizen/ivi/20170309.072337accepted/tizen/common/20170309.175456
- Add the request queue for thread of media-controller to performance enhancement
- Add the type of request in message to seperate message in queue
- Code refactoring
Using abbreviation for define
Change-Id: Ic6d44e299299a8b47c561d62b5e5e53e753cb8ab
Signed-off-by: jiyong.min <jiyong.min@samsung.com>
-rwxr-xr-x | include/media_controller_private.h | 12 | ||||
-rwxr-xr-x | packaging/capi-media-controller.spec | 2 | ||||
-rwxr-xr-x | src/media_controller_client.c | 4 | ||||
-rwxr-xr-x | src/media_controller_db.c | 2 | ||||
-rwxr-xr-x | src/media_controller_ipc.c | 19 | ||||
-rwxr-xr-x | src/media_controller_server.c | 17 | ||||
-rwxr-xr-x | src/media_controller_util.c | 4 | ||||
-rwxr-xr-x[-rw-r--r--] | svc/daemon/media_controller_main.c | 23 | ||||
-rwxr-xr-x[-rw-r--r--] | svc/media_controller_socket.h | 1 | ||||
-rwxr-xr-x | svc/media_controller_svc.c | 650 | ||||
-rwxr-xr-x | svc/media_controller_svc.h | 17 |
11 files changed, 546 insertions, 205 deletions
diff --git a/include/media_controller_private.h b/include/media_controller_private.h index 38bc3cd..a6e97f8 100755 --- a/include/media_controller_private.h +++ b/include/media_controller_private.h @@ -118,8 +118,12 @@ extern "C" { * @brief DBus interface type name. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif */ -#define MC_CLIENT "mediacontroller.client" -#define MC_SERVER "mediacontroller.server" +#define MC_CLIENT "mcclient" +#define MC_SERVER "mcserver" + +#define MC_DEFAULT_TYPE 0 +#define MC_CLIENT_TYPE 1 +#define MC_SEVER_TYPE 2 #define MC_DBUS_SIGNAL_NAME_SERVER_STATE "server_state" #define MC_DBUS_SIGNAL_NAME_PLAY_BACK "playback" @@ -236,8 +240,8 @@ int mc_ipc_register_listener(GList *manage_list, GDBusConnection *connection, co int mc_ipc_unregister_listener(GList *manage_list, GDBusConnection *connection, const char *interface_name, const char *signal_name); int mc_ipc_unregister_all_listener(GList *manage_list, GDBusConnection *connection); int mc_ipc_send_message(GDBusConnection *connection, const char *dbus_name, const char *interface_name, const char* signal_name, const char* message, int flags); -int mc_ipc_send_message_to_server(mc_msg_type_e msg_type, const char *request_msg); -int mc_ipc_service_connect(void); +int mc_ipc_send_message_to_server(mc_msg_type_e msg_type, const int type, const char *request_msg); +int mc_ipc_service_connect(const int type); #ifdef __cplusplus } diff --git a/packaging/capi-media-controller.spec b/packaging/capi-media-controller.spec index 04e55dd..c98fff6 100755 --- a/packaging/capi-media-controller.spec +++ b/packaging/capi-media-controller.spec @@ -1,6 +1,6 @@ Name: capi-media-controller Summary: A media controller library in Tizen Native API -Version: 0.1.31 +Version: 0.1.32 Release: 1 Group: Multimedia/API License: Apache-2.0 diff --git a/src/media_controller_client.c b/src/media_controller_client.c index 8601ed1..d5f1f46 100755 --- a/src/media_controller_client.c +++ b/src/media_controller_client.c @@ -352,7 +352,7 @@ int mc_client_create(mc_client_h *client) mc_retvm_if(client == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is NULL"); /*Try Socket Activation by systemd*/ - ret = mc_ipc_service_connect(); + ret = mc_ipc_service_connect(MC_CLIENT_TYPE); if (ret != MEDIA_CONTROLLER_ERROR_NONE) { mc_error("Failed to get mc_ipc_service_connect [%d]", ret); return ret; @@ -1043,7 +1043,7 @@ int mc_client_destroy(mc_client_h client) mc_error("Error mc_ipc_unregister_all_listener [%d]", ret); /*Send Disconnection Msg to Server*/ - ret = mc_ipc_send_message_to_server(MC_MSG_SERVER_DISCONNECTION, MC_SERVER_DISCONNECTION_MSG); + ret = mc_ipc_send_message_to_server(MC_MSG_SERVER_DISCONNECTION, MC_CLIENT_TYPE, MC_SERVER_DISCONNECTION_MSG); if (ret != MEDIA_CONTROLLER_ERROR_NONE) mc_error("Failed to mc_ipc_send_message_to_server [%d]", ret); diff --git a/src/media_controller_db.c b/src/media_controller_db.c index add1c66..570cc62 100755 --- a/src/media_controller_db.c +++ b/src/media_controller_db.c @@ -62,7 +62,7 @@ static int __mc_db_update_db(void *handle, const char *sql_str) mc_retvm_if(!MC_STRING_VALID(sql_str), MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid Query"); - ret = mc_ipc_send_message_to_server(MC_MSG_DB_UPDATE, sql_str); + ret = mc_ipc_send_message_to_server(MC_MSG_DB_UPDATE, MC_DEFAULT_TYPE, sql_str); if (ret != MEDIA_CONTROLLER_ERROR_NONE) mc_error("mc_ipc_send_message_to_server failed : %d", ret); diff --git a/src/media_controller_ipc.c b/src/media_controller_ipc.c index 16ad6b1..e34bb29 100755 --- a/src/media_controller_ipc.c +++ b/src/media_controller_ipc.c @@ -25,10 +25,10 @@ #define MC_SVC_NAME "mediacontroller" /* This checks if service daemon is running */ -static int __is_service_activated() +static int __is_service_activated(const int type) { - int ret = MEDIA_CONTROLLER_ERROR_NONE; - ret = mc_ipc_send_message_to_server(MC_MSG_SERVER_CONNECTION, MC_SERVER_CONNECTION_MSG); + int ret = MEDIA_CONTROLLER_ERROR_NONE; + ret = mc_ipc_send_message_to_server(MC_MSG_SERVER_CONNECTION, type, MC_SERVER_CONNECTION_MSG); return ret; } @@ -284,7 +284,7 @@ int mc_ipc_send_message(GDBusConnection *connection, const char *dbus_name, cons return MEDIA_CONTROLLER_ERROR_NONE; } -int mc_ipc_send_message_to_server(mc_msg_type_e msg_type, const char *request_msg) +int mc_ipc_send_message_to_server(mc_msg_type_e msg_type, const int type, const char *request_msg) { int ret = MEDIA_CONTROLLER_ERROR_NONE; int request_msg_size = 0; @@ -304,10 +304,13 @@ int mc_ipc_send_message_to_server(mc_msg_type_e msg_type, const char *request_ms return MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER; } + mc_error("type [%d], message [%s]", type, request_msg); + mc_comm_msg_s send_msg; memset((void *)&send_msg, 0, sizeof(mc_comm_msg_s)); send_msg.msg_type = msg_type; + send_msg.type = type; send_msg.pid = getpid(); send_msg.uid = getuid(); send_msg.msg_size = request_msg_size; @@ -378,7 +381,7 @@ RETRY: return ret; } -int mc_ipc_service_connect(void) +int mc_ipc_service_connect(const int type) { int ret = MEDIA_CONTROLLER_ERROR_NONE; int sockfd = -1; @@ -386,7 +389,7 @@ int mc_ipc_service_connect(void) struct sockaddr_un serv_addr; unsigned int retrycount = 0; - ret = __is_service_activated(); + ret = __is_service_activated(type); if (ret == MEDIA_CONTROLLER_ERROR_NONE) { mc_debug("service is already running!"); @@ -418,7 +421,7 @@ int mc_ipc_service_connect(void) mc_ipc_delete_client_socket(&sock_info); - ret = __is_service_activated(); + ret = __is_service_activated(type); if (ret == MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED) { mc_error("Permission deny!"); return ret; @@ -426,7 +429,7 @@ int mc_ipc_service_connect(void) while ((ret != MEDIA_CONTROLLER_ERROR_NONE) && (retrycount++ < MAX_WAIT_COUNT)) { MC_MILLISEC_SLEEP(200); mc_error("[No-Error] retry count [%d]", retrycount); - ret = __is_service_activated(); + ret = __is_service_activated(type); if (ret == MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED) { mc_error("Permission deny!"); return ret; diff --git a/src/media_controller_server.c b/src/media_controller_server.c index 916c202..b35e579 100755 --- a/src/media_controller_server.c +++ b/src/media_controller_server.c @@ -104,18 +104,7 @@ static int __mc_server_destoy(media_controller_server_s *mc_server) MC_SAFE_FREE(mc_server->server_name); if (mc_server->metadata) { - MC_SAFE_FREE(mc_server->metadata->title); - MC_SAFE_FREE(mc_server->metadata->artist); - MC_SAFE_FREE(mc_server->metadata->album); - MC_SAFE_FREE(mc_server->metadata->author); - MC_SAFE_FREE(mc_server->metadata->genre); - MC_SAFE_FREE(mc_server->metadata->duration); - MC_SAFE_FREE(mc_server->metadata->date); - MC_SAFE_FREE(mc_server->metadata->copyright); - MC_SAFE_FREE(mc_server->metadata->description); - MC_SAFE_FREE(mc_server->metadata->track_num); - MC_SAFE_FREE(mc_server->metadata->picture); - MC_SAFE_FREE(mc_server->metadata); + mc_client_destroy_metadata(mc_server->metadata); } MC_SAFE_FREE(mc_server); @@ -564,7 +553,7 @@ int mc_server_create(mc_server_h *server) mc_retvm_if(server == NULL, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Handle is null"); /*Try Socket Activation by systemd*/ - ret = mc_ipc_service_connect(); + ret = mc_ipc_service_connect(MC_SEVER_TYPE); if (ret != MEDIA_CONTROLLER_ERROR_NONE) { mc_error("Failed to get mc_ipc_service_connect [%d]", ret); return ret; @@ -665,7 +654,7 @@ int mc_server_destroy(mc_server_h server) mc_error("Error __mc_server_send_message [%d]", ret); /*Send Disconnection Msg to Server*/ - ret = mc_ipc_send_message_to_server(MC_MSG_SERVER_DISCONNECTION, MC_SERVER_DISCONNECTION_MSG); + ret = mc_ipc_send_message_to_server(MC_MSG_SERVER_DISCONNECTION, MC_SEVER_TYPE, MC_SERVER_DISCONNECTION_MSG); if (ret != MEDIA_CONTROLLER_ERROR_NONE) mc_error("Failed to mc_ipc_send_message_to_server [%d]", ret); diff --git a/src/media_controller_util.c b/src/media_controller_util.c index f6c6762..1919a58 100755 --- a/src/media_controller_util.c +++ b/src/media_controller_util.c @@ -126,7 +126,7 @@ int mc_util_set_command_availabe(const char *name, const char *command_type, con else message = g_strdup_printf("%s%s%s", name, command_type, command); - ret = mc_ipc_send_message_to_server(MC_MSG_CLIENT_SET, message); + ret = mc_ipc_send_message_to_server(MC_MSG_CLIENT_SET, MC_DEFAULT_TYPE, message); MC_SAFE_G_FREE(message); @@ -148,7 +148,7 @@ int mc_util_get_command_availabe(const char *name, const char *command_type, con else message = g_strdup_printf("%s%s%s", name, command_type, command); - ret = mc_ipc_send_message_to_server(MC_MSG_CLIENT_GET, message); + ret = mc_ipc_send_message_to_server(MC_MSG_CLIENT_GET, MC_DEFAULT_TYPE, message); MC_SAFE_G_FREE(message); diff --git a/svc/daemon/media_controller_main.c b/svc/daemon/media_controller_main.c index f71cf8c..f561837 100644..100755 --- a/svc/daemon/media_controller_main.c +++ b/svc/daemon/media_controller_main.c @@ -14,6 +14,9 @@ * limitations under the License. */ +#include <sys/stat.h> +#include <systemd/sd-daemon.h> + #include "media_controller_private.h" #include "../media_controller_socket.h" #include "../media_controller_svc.h" @@ -65,6 +68,24 @@ void __mc_main_destroy_timer() g_source_destroy(g_main_context_find_source_by_id(g_main_context_get_thread_default(), g_mc_timer_id)); } +static int __mc_main_create_socket_activation(void) +{ + int fd = -1; + int listen_fds; + + listen_fds = sd_listen_fds(0); + if (listen_fds == 1) { + fd = SD_LISTEN_FDS_START; + return fd; + } else if (listen_fds > 1) { + mc_error("Too many file descriptors received."); + return -1; + } else { + mc_error("There is no socket stream"); + return -1; + } +} + int main(int argc, char **argv) { GThread *svc_thread = NULL; @@ -81,7 +102,7 @@ int main(int argc, char **argv) return -1; } - fd = mc_create_socket_activation(); + fd = __mc_main_create_socket_activation(); if (fd < 0) { mc_error("Failed to socekt creation"); } else { diff --git a/svc/media_controller_socket.h b/svc/media_controller_socket.h index 2a5bba1..fb86a61 100644..100755 --- a/svc/media_controller_socket.h +++ b/svc/media_controller_socket.h @@ -56,6 +56,7 @@ typedef struct { typedef struct { mc_msg_type_e msg_type; + int type; int pid; uid_t uid; int result; diff --git a/svc/media_controller_svc.c b/svc/media_controller_svc.c index 52f4393..c987c8b 100755 --- a/svc/media_controller_svc.c +++ b/svc/media_controller_svc.c @@ -25,8 +25,22 @@ #include "media_controller_db_util.h" #include "media_controller_cynara.h" +#define MAX_MC_REQUEST 1000 + static GMainLoop *g_mc_svc_mainloop = NULL; static int g_connection_cnt = -1; +static int g_queue_work = 0; + +typedef struct { + int client_sock; + int permission; + mc_comm_msg_s *req_msg; +} mc_service_request; + +typedef struct { + mc_comm_msg_s *message; + unsigned int result; +} mc_list_user_data; static int __mc_sys_get_uid(uid_t *uid) { @@ -42,49 +56,437 @@ static int __mc_sys_get_uid(uid_t *uid) return users; } -static int __create_socket_activation(void) +static void __mc_destroy_queue(gpointer data) +{ + mc_service_request *req = (mc_service_request *)data; + if (req != NULL) { +// MC_SAFE_FREE(req->creds.uid); +// MC_SAFE_FREE(req->creds.smack); + MC_SAFE_FREE(req->req_msg); + MC_SAFE_FREE(req); + } +} + +static void __mc_destroy_data_list(gpointer data) +{ + char *_ptr = (char *)data; + MC_SAFE_FREE(_ptr); +} + +static void __mc_destroy_connected_list(gpointer data) +{ + mc_list_data_set_t *_ptr = (mc_list_data_set_t *)data; + if (_ptr == NULL) { + mc_error("invalid parameter"); + return; + } + if (_ptr->s_data != NULL) { + g_list_free_full(_ptr->s_data, __mc_destroy_data_list); + _ptr->s_data = NULL; + } + MC_SAFE_FREE(_ptr); +} + +static int __mc_create_request_queue(mc_manage_queue_t **data) { - int fd = -1; - int listen_fds; - - listen_fds = sd_listen_fds(0); - if (listen_fds == 1) { - fd = SD_LISTEN_FDS_START; - return fd; - } else if (listen_fds > 1) { - mc_error("Too many file descriptors received."); + mc_manage_queue_t *_request = (mc_manage_queue_t *)calloc(1, sizeof(mc_manage_queue_t)); + if (_request == NULL) { + mc_error("Failed to create queue manager"); + return MEDIA_CONTROLLER_ERROR_OUT_OF_MEMORY; + } + _request->queue = g_queue_new(); + if (_request->queue == NULL) { + mc_error("Failed to create new queue"); + return MEDIA_CONTROLLER_ERROR_OUT_OF_MEMORY; + } + *data = _request; + return MEDIA_CONTROLLER_ERROR_NONE; +} + +static void __mc_destroy_request_queue(mc_manage_queue_t *data) +{ + if (data == NULL) { + mc_error("invalid parameter"); + return; + } + if (data->queue != NULL) { + g_queue_free_full(data->queue, __mc_destroy_queue); + data->queue = NULL; + } + if (data->source != NULL) { + g_source_unref(data->source); + data->source = NULL; + } + MC_SAFE_FREE(data); +} + +static void __mc_set_data(gpointer data, gpointer user_data) +{ + mc_list_data_set_t *_data = (mc_list_data_set_t *)data; + mc_comm_msg_s *_user_data = (mc_comm_msg_s *)user_data; + char *_set_data = strdup(_user_data->msg); + if (_data->pid == _user_data->pid) + _data->s_data = g_list_append(_data->s_data, _set_data); +} + +static void __mc_get_data(gpointer data, gpointer user_data) +{ + mc_list_data_set_t *_data = (mc_list_data_set_t *)data; + mc_list_user_data *_user_data = (mc_list_user_data *)user_data; + mc_comm_msg_s *_message = (mc_comm_msg_s *)_user_data->message; + if (_data->pid == _message->pid) { + if (_data->s_data != NULL) { + unsigned int i = 0; + unsigned int length_of_list = g_list_length(_data->s_data); + char *value = NULL; + for (i = 0; i < length_of_list; i++) { + value = (char *)g_list_nth_data(_data->s_data, i); + if ((value != NULL) && (strlen(value) == _message->msg_size)) { + if (strncmp(value, _message->msg, _message->msg_size) == 0) { + _data->s_data = g_list_remove(_data->s_data, value); + MC_SAFE_FREE(value); + _user_data->result++; + } + } + } + if (g_list_length(_data->s_data) == 0) + _data->s_data = NULL; + } + } +} + +static int _mc_service_init(mc_service_t **data) +{ + int res = MEDIA_CONTROLLER_ERROR_NONE; + mc_service_t *_service_data = (mc_service_t *)calloc(1, sizeof(mc_service_t)); + if (_service_data == NULL) { + mc_error("Failed to allocate service data"); + return MEDIA_CONTROLLER_ERROR_OUT_OF_MEMORY; + } + res = __mc_create_request_queue(&(_service_data->request)); + if (res != MEDIA_CONTROLLER_ERROR_NONE) { + mc_error("Failed to create queue data"); + return MEDIA_CONTROLLER_ERROR_OUT_OF_MEMORY; + } + *data = _service_data; + return MEDIA_CONTROLLER_ERROR_NONE; +} + +static void _mc_service_deinit(mc_service_t *data) +{ + if (data != NULL) { + if (data->request != NULL) + __mc_destroy_request_queue(data->request); + if (data->connected != NULL) + g_list_free_full(data->connected, __mc_destroy_connected_list); + MC_SAFE_FREE(data); + } +} + +static int _mc_service_reset_db(uid_t uid) +{ + int res = MEDIA_CONTROLLER_ERROR_NONE; + void *db_handle = NULL; + + /* Connect media controller DB*/ + res = mc_db_util_connect(&db_handle, uid); + if (res != MEDIA_CONTROLLER_ERROR_NONE) { + mc_error("Failed to connect DB"); + return FALSE; + } + + /* Destroy tables */ + res = mc_db_util_delete_whole_server_tables(db_handle); + if (res != MEDIA_CONTROLLER_ERROR_NONE) + mc_error("mc_db_util_delete_whole_server_tables failed [%d]", res); + + /* Create tables */ + res = mc_db_util_create_tables(db_handle); + if (res != MEDIA_CONTROLLER_ERROR_NONE) { + mc_error("mc_db_util_create_tables failed [%d]", res); + return res; + } + + /* Disconnect media controller DB*/ + res = mc_db_util_disconnect(db_handle); + if (res != MEDIA_CONTROLLER_ERROR_NONE) + mc_error("Failed to disconnect DB"); + return MEDIA_CONTROLLER_ERROR_NONE; +} + +static gboolean _mc_service_is_valid_queue(mc_service_t *data) +{ + if ((data == NULL) || (data->request) == NULL || (data->request->queue == NULL)) + return FALSE; + return TRUE; +} + +static int _mc_service_get_list_index(GList *list, int pid, int type) +{ + unsigned int length_of_list = 0; + unsigned int i; + mc_list_data_set_t *ptr = NULL; + + if (list == NULL) return -1; + + length_of_list = (unsigned int)g_list_length(list); + for (i = 0; i < length_of_list; i++) { + ptr = g_list_nth_data(list, i); + if (ptr == NULL) + return -1; + if (ptr->pid == pid) { + if (type == MC_DEFAULT_TYPE) + return i; + if (ptr->type == type) + return i; + } + } + return -1; +} + +static gboolean _mc_service_is_exist_pid(GList *list, int pid, int type) +{ + int res = _mc_service_get_list_index(list, pid, type); + + return (res == -1) ? FALSE : TRUE; +} + +static gboolean _mc_service_is_valid_connection(GList *connected_list, mc_comm_msg_s *request_msg) +{ + if (request_msg->msg_type != MC_MSG_SERVER_CONNECTION) { + if (connected_list == NULL) + return FALSE; + if (!_mc_service_is_exist_pid(connected_list, request_msg->pid, request_msg->type)) + return FALSE; + } + return TRUE; +} + +static int _mc_service_add_connection(GList **connected_list, mc_comm_msg_s *request_msg) +{ + mc_debug_fenter(); + mc_list_data_set_t *data = (mc_list_data_set_t *)calloc(1, sizeof(mc_list_data_set_t)); + if (data == NULL) { + mc_error("memory allocation is failed"); + return MEDIA_CONTROLLER_ERROR_OUT_OF_MEMORY; + } + + if (*connected_list != NULL && _mc_service_is_exist_pid(*connected_list, request_msg->pid, request_msg->type)) { + mc_error("[No-error] connected but do not increase counter [%d]", g_connection_cnt); + return MEDIA_CONTROLLER_ERROR_NONE; + } + data->pid = request_msg->pid; + data->type = request_msg->type; + *connected_list = g_list_append(*connected_list, data); + + if (g_connection_cnt == -1) + g_connection_cnt = 1; + else + g_connection_cnt++; + + mc_error("[No-error] increased connection count [%d]", g_connection_cnt); + mc_debug_fleave(); + return MEDIA_CONTROLLER_ERROR_NONE; +} + +static int _mc_service_remove_connection(GList **connected_list, mc_comm_msg_s *request_msg) +{ + mc_debug_fenter(); + + int idx = _mc_service_get_list_index(*connected_list, request_msg->pid, request_msg->type); + if (idx == -1) { + mc_error("node is null, it is already disconnected!"); + return MEDIA_CONTROLLER_ERROR_NONE; + } + mc_error("[No-error] idx [%d]", idx); + mc_list_data_set_t *data = g_list_nth_data(*connected_list, idx); + if (data != NULL) { + mc_error("[No-error] idx [%p]", data); + *connected_list = g_list_remove(*connected_list, data); + if (data->s_data != NULL) { + mc_error("[No-error] s_data [%p], length [%d]", data->s_data, g_list_length(data->s_data)); + g_list_free_full(data->s_data, __mc_destroy_data_list); + } + mc_error("[No-error] data set will be free"); + MC_SAFE_FREE(data); + } + + g_connection_cnt--; + mc_error("[No-error] decreased connection count [%d]", g_connection_cnt); + mc_debug_fleave(); + return MEDIA_CONTROLLER_ERROR_NONE; +} + +static int _mc_service_set_data(GList **connected_list, mc_comm_msg_s *request_msg) +{ + g_list_foreach(*connected_list, __mc_set_data, request_msg); + + return MEDIA_CONTROLLER_ERROR_NONE; +} + +static int _mc_service_get_data(GList **connected_list, mc_comm_msg_s *request_msg) +{ + mc_list_user_data *user_data = calloc(1, sizeof(mc_list_user_data)); + if (user_data == NULL) + return MEDIA_CONTROLLER_ERROR_OUT_OF_MEMORY; + + user_data->message = request_msg; + user_data->result = 0; + + g_list_foreach(*connected_list, __mc_get_data, user_data); + + mc_debug("user_data->result : %d", user_data->result); + if (user_data->result > 0) { + MC_SAFE_FREE(user_data); + return MEDIA_CONTROLLER_ERROR_NONE; } else { - mc_error("There is no socket stream"); - return -1; + MC_SAFE_FREE(user_data); + return MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED; } } -static void _mc_svc_destroy_data(gpointer data) +gboolean _mc_service_process(gpointer data) { - mc_svc_list_t *svc_data = (mc_svc_list_t *)data; + int res = MEDIA_CONTROLLER_ERROR_NONE; + int length_of_queue = 0; + int send_msg = MEDIA_CONTROLLER_ERROR_NONE; + mc_service_t *_service_data = (mc_service_t*)data; + + if (_service_data == NULL) { + mc_debug("invalid service_data"); + return FALSE; + } + + if (_mc_service_is_valid_queue(_service_data) == FALSE) { + mc_debug("invalid queue"); + return FALSE; + } + GQueue *request_queue = _service_data->request->queue; + length_of_queue = g_queue_get_length(request_queue); + + mc_debug("Queue Length : %d", length_of_queue); + + if (length_of_queue <= 0) { + mc_debug("There is no request job in the queue"); + g_queue_work = 0; + return FALSE; + } - if (svc_data != NULL) { - MC_SAFE_FREE(svc_data->data); - MC_SAFE_FREE(svc_data); - svc_data = NULL; + mc_service_request *req = NULL; + req = (mc_service_request *) g_queue_pop_head(request_queue); + if (req == NULL) { + mc_error("Failed to get a request job from queue"); + return TRUE; + } + + mc_comm_msg_s *request_msg = req->req_msg; + if (request_msg == NULL) { + mc_error("Failed to get a request message from req"); + goto ERROR; + } + + if (!_mc_service_is_valid_connection(_service_data->connected, request_msg)) { + mc_error("Wrong message"); + send_msg = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + goto ERROR; } + + if (request_msg->msg_type == MC_MSG_DB_UPDATE) { +/* if (req->permission != 2) { + mc_error("permission is denied![%d]", res); + send_msg = MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED; + goto ERROR; + }*/ + char *sql_query = NULL; + sql_query = strndup(request_msg->msg, request_msg->msg_size); + if (sql_query != NULL) { + void* _db_handle; + res = mc_db_util_connect(&_db_handle, request_msg->uid); + if (res != MEDIA_CONTROLLER_ERROR_NONE) + mc_error("mc_db_util_connect error : %d", res); + + res = mc_db_util_update_db(_db_handle, sql_query); + if (res != MEDIA_CONTROLLER_ERROR_NONE) + mc_error("media_db_update_db error : %d", res); + + mc_db_util_disconnect(_db_handle); + + send_msg = res; + MC_SAFE_FREE(sql_query); + } else { + send_msg = MEDIA_CONTROLLER_ERROR_OUT_OF_MEMORY; + } + } else if (request_msg->msg_type == MC_MSG_CLIENT_SET) { + send_msg = _mc_service_set_data(&(_service_data->connected), request_msg); + } else if (request_msg->msg_type == MC_MSG_CLIENT_GET) { + send_msg = _mc_service_get_data(&(_service_data->connected), request_msg); + } else if (request_msg->msg_type == MC_MSG_SERVER_CONNECTION) { + if (request_msg->msg_size < strlen(MC_SERVER_CONNECTION_MSG)) { + mc_error("Wrong message!"); + send_msg = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + goto ERROR; + } + if (strncmp(request_msg->msg, MC_SERVER_CONNECTION_MSG, request_msg->msg_size) == 0) { + send_msg = _mc_service_add_connection(&(_service_data->connected), request_msg); + } else { + mc_error("Wrong message!"); + send_msg = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + } + } else if (request_msg->msg_type == MC_MSG_SERVER_DISCONNECTION) { + if (request_msg->msg_size < strlen(MC_SERVER_DISCONNECTION_MSG)) { + mc_error("Wrong message!"); + send_msg = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + goto ERROR; + } + if (strncmp(request_msg->msg, MC_SERVER_DISCONNECTION_MSG, request_msg->msg_size) == 0) { + send_msg = _mc_service_remove_connection(&(_service_data->connected), request_msg); + } else { + mc_error("Wrong message!"); + send_msg = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + } + } else { + mc_error("Wrong message type!"); + send_msg = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + } + +ERROR: + if (write(req->client_sock, &send_msg, sizeof(send_msg)) != sizeof(send_msg)) + mc_stderror("send failed"); + else + mc_debug("Sent successfully"); + + if (close(req->client_sock) < 0) + mc_stderror("close failed"); + +// MC_SAFE_FREE(req->creds.uid); +// MC_SAFE_FREE(req->creds.smack); + MC_SAFE_FREE(req->req_msg); + MC_SAFE_FREE(req); + + return TRUE; } gboolean _mc_read_service_request_tcp_socket(GIOChannel *src, GIOCondition condition, gpointer data) { int sock = -1; int client_sock = -1; - char *sql_query = NULL; mc_comm_msg_s recv_msg; int ret = MEDIA_CONTROLLER_ERROR_NONE; int send_msg = MEDIA_CONTROLLER_ERROR_NONE; - int i = 0; - mc_svc_data_t *mc_svc_data = (mc_svc_data_t*)data; - mc_peer_creds creds = {0, }; + mc_service_request *req = NULL; + mc_service_t *_service_data = (mc_service_t*)data; + GQueue *request_queue = _service_data->request->queue; mc_debug("mc_read_service_request_tcp_socket is called!!!!!"); + req = (mc_service_request *) calloc(1, sizeof(mc_service_request)); + if (req == NULL) { + mc_error("memory allocation is failed"); + send_msg = MEDIA_CONTROLLER_ERROR_OUT_OF_MEMORY; + goto ERROR; + } + sock = g_io_channel_unix_get_fd(src); if (sock < 0) { mc_error("sock fd is invalid!"); @@ -92,135 +494,65 @@ gboolean _mc_read_service_request_tcp_socket(GIOChannel *src, GIOCondition condi } /* get client socket fd */ - ret = mc_ipc_accept_client_tcp(sock, &client_sock); + ret = mc_ipc_accept_client_tcp(sock, &(client_sock)); if (ret != MEDIA_CONTROLLER_ERROR_NONE) return TRUE; - memset(&creds, 0, sizeof(mc_peer_creds)); - - ret = mc_cynara_receive_untrusted_message(client_sock, &recv_msg, &creds); + mc_peer_creds creds; + memset(&creds, 0x00, sizeof(mc_peer_creds)); + req->client_sock = client_sock; + ret = mc_cynara_receive_untrusted_message(req->client_sock, &recv_msg, &creds); if (ret != MEDIA_CONTROLLER_ERROR_NONE) { mc_error("mc_ipc_receive_message_tcp failed [%d]", ret); send_msg = ret; goto ERROR; } - if (recv_msg.msg_type == MC_MSG_DB_UPDATE) { - sql_query = strndup(recv_msg.msg, recv_msg.msg_size); - if (sql_query != NULL) { - ret = mc_db_util_update_db(mc_svc_data->db_handle, sql_query); - if (ret != MEDIA_CONTROLLER_ERROR_NONE) - mc_error("media_db_update_db error : %d", ret); - - send_msg = ret; - MC_SAFE_FREE(sql_query); - } else { - send_msg = MEDIA_CONTROLLER_ERROR_OUT_OF_MEMORY; - } - } else if (recv_msg.msg_type == MC_MSG_CLIENT_SET) { - /* check privileage */ + ret = mc_cynara_check(&creds, MC_SERVER_PRIVILEGE); + if (ret != MEDIA_CONTROLLER_ERROR_NONE) { + mc_error("permission is denied![%d]", ret); ret = mc_cynara_check(&creds, MC_CLIENT_PRIVILEGE); if (ret != MEDIA_CONTROLLER_ERROR_NONE) { mc_error("permission is denied![%d]", ret); + send_msg = MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED; goto ERROR; + } else { + req->permission = 2; } + } else { + req->permission = 1; + } - MC_SAFE_FREE(creds.uid); - MC_SAFE_FREE(creds.smack); - - mc_svc_list_t *set_data = (mc_svc_list_t *)malloc(sizeof(mc_svc_list_t)); - set_data->pid = recv_msg.pid; - set_data->data = strdup(recv_msg.msg); - mc_svc_data->mc_svc_list = g_list_append(mc_svc_data->mc_svc_list, set_data); - } else if (recv_msg.msg_type == MC_MSG_CLIENT_GET) { - send_msg = MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED; - /* check privileage */ - ret = mc_cynara_check(&creds, MC_SERVER_PRIVILEGE); - if (ret != MEDIA_CONTROLLER_ERROR_NONE) { - mc_error("permission is denied![%d]", ret); + if (recv_msg.msg_type >= 0 && recv_msg.msg_type < MC_MSG_MAX) { + if (g_queue_get_length(request_queue) >= MAX_MC_REQUEST) { + send_msg = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; goto ERROR; } - MC_SAFE_FREE(creds.uid); - MC_SAFE_FREE(creds.smack); - - mc_svc_list_t *set_data = NULL; - for (i = 0; i < (int)g_list_length(mc_svc_data->mc_svc_list); i++) { - set_data = (mc_svc_list_t *)g_list_nth_data(mc_svc_data->mc_svc_list, i); - if (set_data != NULL && set_data->data != NULL && strcmp(set_data->data, recv_msg.msg) == 0) { - mc_svc_data->mc_svc_list = g_list_remove(mc_svc_data->mc_svc_list, set_data); - MC_SAFE_FREE(set_data->data); - MC_SAFE_FREE(set_data); - send_msg = MEDIA_CONTROLLER_ERROR_NONE; - break; - } - } - } else if (recv_msg.msg_type == MC_MSG_SERVER_CONNECTION) { - ret = mc_cynara_check(&creds, MC_CLIENT_PRIVILEGE); - if (ret != MEDIA_CONTROLLER_ERROR_NONE) { - mc_error("permission is denied![%d]", ret); - ret = mc_cynara_check(&creds, MC_SERVER_PRIVILEGE); - if (ret != MEDIA_CONTROLLER_ERROR_NONE) { - mc_error("permission is denied![%d]", ret); - - send_msg = MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED; - goto ERROR; - } - } - - MC_SAFE_FREE(creds.uid); - MC_SAFE_FREE(creds.smack); - - if (recv_msg.msg_size > 0) { - if (strncmp(recv_msg.msg, MC_SERVER_CONNECTION_MSG, recv_msg.msg_size) == 0) { - if (g_connection_cnt == -1) - g_connection_cnt = 1; - else - g_connection_cnt++; - - mc_error("[No-error] increased connection count [%d]", g_connection_cnt); - - send_msg = MEDIA_CONTROLLER_ERROR_NONE; - } else { - mc_error("Wrong message!"); - send_msg = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; - } - } else { - mc_error("Wrong message!"); - send_msg = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + req->req_msg = (mc_comm_msg_s *) malloc(sizeof(mc_comm_msg_s)); + if (req->req_msg == NULL) { + send_msg = MEDIA_CONTROLLER_ERROR_OUT_OF_MEMORY; + MC_SAFE_FREE(req->req_msg); + goto ERROR; } - } else if (recv_msg.msg_type == MC_MSG_SERVER_DISCONNECTION) { - if (recv_msg.msg_size > 0) { - if (strncmp(recv_msg.msg, MC_SERVER_DISCONNECTION_MSG, recv_msg.msg_size) == 0) { - g_connection_cnt--; - mc_error("[No-error] decreased connection count [%d]", g_connection_cnt); - - /* remove resource for disconnected process */ - mc_svc_list_t *set_data = NULL; - for (i = (int)(g_list_length(mc_svc_data->mc_svc_list)) - 1; i >= 0; i--) { - set_data = (mc_svc_list_t *)g_list_nth_data(mc_svc_data->mc_svc_list, i); - if ((set_data != NULL) && (set_data->pid == recv_msg.pid)) { - mc_svc_data->mc_svc_list = g_list_remove(mc_svc_data->mc_svc_list, set_data); - MC_SAFE_FREE(set_data->data); - MC_SAFE_FREE(set_data); - } - } - - send_msg = MEDIA_CONTROLLER_ERROR_NONE; - } else { - mc_error("Wrong message!"); - send_msg = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; - } - } else { - mc_error("Wrong message!"); - send_msg = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; + memset(req->req_msg, 0x00, sizeof(mc_comm_msg_s)); + memcpy(req->req_msg, &recv_msg, sizeof(mc_comm_msg_s)); + + mc_debug("msg(%d) is queued", req->req_msg->msg_type); + g_queue_push_tail(request_queue, (gpointer)req); + + /* push received message to queue */ + if (g_queue_work == 0) { + _service_data->request->source = g_idle_source_new(); + g_source_set_callback(_service_data->request->source, _mc_service_process, _service_data, NULL); + g_source_attach(_service_data->request->source, g_main_context_get_thread_default()); + g_queue_work = 1; } - } else { - mc_error("Wrong message type!"); - send_msg = MEDIA_CONTROLLER_ERROR_INVALID_OPERATION; } + return TRUE; + ERROR: if (write(client_sock, &send_msg, sizeof(send_msg)) != sizeof(send_msg)) mc_stderror("send failed"); @@ -230,17 +562,16 @@ ERROR: if (close(client_sock) < 0) mc_stderror("close failed"); + if (req != NULL) { + MC_SAFE_FREE(req->req_msg); + MC_SAFE_FREE(req); + } MC_SAFE_FREE(creds.uid); MC_SAFE_FREE(creds.smack); return TRUE; } -int mc_create_socket_activation(void) -{ - return __create_socket_activation(); -} - gboolean mc_svc_thread(void *data) { int sockfd = -1; @@ -248,39 +579,32 @@ gboolean mc_svc_thread(void *data) GSource *source = NULL; GIOChannel *channel = NULL; GMainContext *context = NULL; - mc_svc_data_t *mc_svc_data = NULL; + mc_service_t *mc_service_data = NULL; uid_t uid = DEFAULT_USER_UID; - mc_svc_data = (mc_svc_data_t *)calloc(1, sizeof(mc_svc_data_t)); - if (mc_svc_data == NULL) { - mc_error("Failed to allocate svc data"); + /* Init data */ + ret = _mc_service_init(&mc_service_data); + if (ret != MEDIA_CONTROLLER_ERROR_NONE) { + mc_error("Failed to create data"); + _mc_service_deinit(mc_service_data); return FALSE; } + /* Get uid for login user */ ret = __mc_sys_get_uid(&uid); if (ret < 0) { mc_debug("Failed to get login user (%d)", ret); - MC_SAFE_FREE(mc_svc_data); + _mc_service_deinit(mc_service_data); return FALSE; } else { mc_debug("%d sys get UID[%d]", ret, uid); } - /* Connect media controller DB*/ - if (mc_db_util_connect(&(mc_svc_data->db_handle), uid) != MEDIA_CONTROLLER_ERROR_NONE) { - mc_error("Failed to connect DB"); - MC_SAFE_FREE(mc_svc_data); - return FALSE; - } - - /* Destroy tables */ - if (mc_db_util_delete_whole_server_tables(mc_svc_data->db_handle) != MEDIA_CONTROLLER_ERROR_NONE) - mc_error("mc_db_util_delete_whole_server_tables failed [%d]", ret); - - /* Create tables */ - if (mc_db_util_create_tables(mc_svc_data->db_handle) != MEDIA_CONTROLLER_ERROR_NONE) { - mc_error("mc_db_util_create_tables failed [%d]", ret); - MC_SAFE_FREE(mc_svc_data); + /* Reset database */ + ret = _mc_service_reset_db(uid); + if (ret != MEDIA_CONTROLLER_ERROR_NONE) { + mc_error("Failed to create data"); + _mc_service_deinit(mc_service_data); return FALSE; } @@ -289,14 +613,14 @@ gboolean mc_svc_thread(void *data) if (ret != MEDIA_CONTROLLER_ERROR_NONE) { /* Disconnect DB*/ mc_error("Failed to create socket"); - MC_SAFE_FREE(mc_svc_data); + _mc_service_deinit(mc_service_data); return FALSE; } ret = mc_cynara_enable_credentials_passing(sockfd); if (ret != MEDIA_CONTROLLER_ERROR_NONE) { mc_error("Failed to append socket options"); - MC_SAFE_FREE(mc_svc_data); + _mc_service_deinit(mc_service_data); close(sockfd); return FALSE; } @@ -315,7 +639,7 @@ gboolean mc_svc_thread(void *data) source = g_io_create_watch(channel, G_IO_IN); /* Set callback to be called when socket is readable */ - g_source_set_callback(source, (GSourceFunc)_mc_read_service_request_tcp_socket, mc_svc_data, NULL); + g_source_set_callback(source, (GSourceFunc)_mc_read_service_request_tcp_socket, mc_service_data, NULL); g_source_attach(source, context); g_main_context_push_thread_default(context); @@ -328,20 +652,14 @@ gboolean mc_svc_thread(void *data) mc_debug("*** Media Controller Service thread will be closed ***"); + _mc_service_deinit(mc_service_data); + + /* Free resources */ g_io_channel_shutdown(channel, FALSE, NULL); g_io_channel_unref(channel); g_source_unref(source); - if (mc_svc_data->mc_svc_list != NULL) - g_list_free_full(mc_svc_data->mc_svc_list, _mc_svc_destroy_data); - - /* Disconnect media controller DB*/ - if (mc_db_util_disconnect(mc_svc_data->db_handle) != MEDIA_CONTROLLER_ERROR_NONE) - mc_error("Failed to connect DB"); - - MC_SAFE_FREE(mc_svc_data); - - /*close socket*/ + /* close socket */ close(sockfd); g_main_loop_unref(g_mc_svc_mainloop); diff --git a/svc/media_controller_svc.h b/svc/media_controller_svc.h index 709c206..2aa8313 100755 --- a/svc/media_controller_svc.h +++ b/svc/media_controller_svc.h @@ -25,15 +25,20 @@ extern "C" { typedef struct { int pid; - char *data; -} mc_svc_list_t; + int type; + GList *s_data; +} mc_list_data_set_t; typedef struct { - void *db_handle; - void *mc_svc_list; -} mc_svc_data_t; + GQueue *queue; + GSource *source; +} mc_manage_queue_t; + +typedef struct { + mc_manage_queue_t *request; + GList *connected; +} mc_service_t; -int mc_create_socket_activation(void); gboolean mc_svc_thread(void *data); GMainLoop *mc_svc_get_main_loop(void); int mc_svc_get_connection_cnt(void); |