Resolve P130730-1900, P130730-1700, Replace CLIENT_PORT with macro
authorSung-jae Park <nicesj.park@samsung.com>
Wed, 31 Jul 2013 06:31:35 +0000 (15:31 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Wed, 31 Jul 2013 13:06:39 +0000 (22:06 +0900)
[model] Redwood
[binary_type] AP
[customer] Docomo/Orange/Open
[issue#] N/A
[problem] data-provider-master is crashed.
[cause] sometimes client object(tcb) of shortcut requestor is not valid when forward the result packet.
[solution] Validate the client object(tcb) before forward the result packet.
[team] HomeTF
[request]
[horizontal_expansion]

Change-Id: Icaec5093ccceed5059ee67173b4fcb2eee48f08e

CMakeLists.txt
include/service_common.h
packaging/data-provider-master.spec
src/server.c
src/service_common.c
src/shortcut_service.c

index 0be9476..94846a0 100755 (executable)
@@ -50,6 +50,8 @@ ADD_DEFINITIONS("-DCLIENT_SOCKET=\"/opt/usr/share/live_magazine/.client.socket\"
 ADD_DEFINITIONS("-DSLAVE_SOCKET=\"/opt/usr/share/live_magazine/.slave.socket\"")
 ADD_DEFINITIONS("-DSERVICE_SOCKET=\"/opt/usr/share/live_magazine/.service.socket\"")
 
+ADD_DEFINITIONS("-DCLIENT_PORT=\"8208\"")
+
 ADD_DEFINITIONS("-DBADGE_SOCKET=\"/tmp/.badge.service\"")
 ADD_DEFINITIONS("-DSHORTCUT_SOCKET=\"/tmp/.shortcut.service\"")
 ADD_DEFINITIONS("-DNOTIFICATION_SOCKET=\"/tmp/.notification.service\"")
index 9cc0885..e60de2b 100644 (file)
@@ -27,6 +27,7 @@ extern int tcb_fd(struct tcb *tcb);
 extern struct service_context *tcb_svc_ctx(struct tcb *tcb);
 extern int tcb_client_type(struct tcb *tcb);
 extern int tcb_client_type_set(struct tcb *tcb, enum tcb_type type);
+extern int tcb_is_valid(struct service_context *svc_ctx, struct tcb *tcb);
 
 extern struct service_context *service_common_create(const char *addr, int (*service_thread_main)(struct tcb *tcb, struct packet *packet, void *data), void *data);
 extern int service_common_destroy(struct service_context *svc_ctx);
index a7d4f3b..b9cad4e 100755 (executable)
@@ -112,6 +112,7 @@ chmod 640 /opt/dbspace/.livebox.db
 chown 0:5000 /opt/dbspace/.livebox.db-journal
 chmod 640 /opt/dbspace/.livebox.db-journal
 vconftool set -t bool "memory/data-provider-master/started" 0 -i -u 5000 -f -s system::vconf_system
+vconftool set -t string "db/data-provider-master/serveraddr" "/opt/usr/share/live_magazine/.client.socket" -i -u 5000 -f -s system::vconf_system
 echo "Successfully installed. Please start a daemon again manually"
 echo "%{_sysconfdir}/init.d/data-provider-master start"
 
index 0c94e46..365d06b 100644 (file)
@@ -6899,7 +6899,7 @@ HAPI int server_init(void)
         * remote://:8208
         * Skip address to use the NULL.
         */
-       s_info.remote_client_fd = com_core_packet_server_init("remote://:8208", s_client_table);
+       s_info.remote_client_fd = com_core_packet_server_init("remote://:"CLIENT_PORT, s_client_table);
        if (s_info.client_fd < 0)
                ErrPrint("Failed to create a remote client socket\n");
 
index d240bed..abe9ff3 100644 (file)
@@ -555,32 +555,6 @@ static void *server_main(void *data)
                        }
                } 
 
-               if (FD_ISSET(svc_ctx->tcb_pipe[PIPE_READ], &set)) {
-                       if (read(svc_ctx->tcb_pipe[PIPE_READ], &tcb, sizeof(tcb)) != sizeof(tcb)) {
-                               ErrPrint("Unable to read pipe: %s\n", strerror(errno));
-                               ret = -EFAULT;
-                               break;
-                       }
-
-                       if (!tcb) {
-                               ErrPrint("Terminate service thread\n");
-                               ret = -ECANCELED;
-                               break;
-                       }
-
-                       /*!
-                        * \note
-                        * Invoke the service thread main, to notify the termination of a TCB
-                        */
-                       ret = svc_ctx->service_thread_main(tcb, NULL, svc_ctx->service_thread_data);
-
-                       /*!
-                        * at this time, the client thread can access this tcb.
-                        * how can I protect this TCB from deletion without disturbing the server thread?
-                        */
-                       tcb_destroy(svc_ctx, tcb);
-               } 
-
                if (FD_ISSET(svc_ctx->evt_pipe[PIPE_READ], &set)) {
                        if (read(svc_ctx->evt_pipe[PIPE_READ], &evt_ch, sizeof(evt_ch)) != sizeof(evt_ch)) {
                                ErrPrint("Unable to read pipe: %s\n", strerror(errno));
@@ -612,6 +586,62 @@ static void *server_main(void *data)
                }
 
                processing_timer_event(svc_ctx, &set);
+
+               /*!
+                * \note
+                * Destroying TCB should be processed at last.
+                */
+               if (FD_ISSET(svc_ctx->tcb_pipe[PIPE_READ], &set)) {
+                       Eina_List *lockfree_packet_list;
+                       Eina_List *l;
+                       Eina_List *n;
+
+                       if (read(svc_ctx->tcb_pipe[PIPE_READ], &tcb, sizeof(tcb)) != sizeof(tcb)) {
+                               ErrPrint("Unable to read pipe: %s\n", strerror(errno));
+                               ret = -EFAULT;
+                               break;
+                       }
+
+                       if (!tcb) {
+                               ErrPrint("Terminate service thread\n");
+                               ret = -ECANCELED;
+                               break;
+                       }
+
+                       lockfree_packet_list = NULL;
+                       CRITICAL_SECTION_BEGIN(&svc_ctx->packet_list_lock);
+                       EINA_LIST_FOREACH_SAFE(svc_ctx->packet_list, l, n, packet_info) {
+                               if (packet_info->tcb != tcb)
+                                       continue;
+
+                               svc_ctx->packet_list = eina_list_remove(svc_ctx->packet_list, packet_info);
+                               lockfree_packet_list = eina_list_append(lockfree_packet_list, packet_info);
+                       }
+                       CRITICAL_SECTION_END(&svc_ctx->packet_list_lock);
+
+                       EINA_LIST_FREE(lockfree_packet_list, packet_info) {
+                               ret = read(svc_ctx->evt_pipe[PIPE_READ], &evt_ch, sizeof(evt_ch));
+                               DbgPrint("Flushing filtered pipe: %d (%c)\n", ret, evt_ch);
+                               ret = svc_ctx->service_thread_main(packet_info->tcb, packet_info->packet, svc_ctx->service_thread_data);
+                               if (ret < 0)
+                                       ErrPrint("Service thread returns: %d\n", ret);
+                               packet_destroy(packet_info->packet);
+                               free(packet_info);
+                       }
+
+                       /*!
+                        * \note
+                        * Invoke the service thread main, to notify the termination of a TCB
+                        */
+                       ret = svc_ctx->service_thread_main(tcb, NULL, svc_ctx->service_thread_data);
+
+                       /*!
+                        * at this time, the client thread can access this tcb.
+                        * how can I protect this TCB from deletion without disturbing the server thread?
+                        */
+                       tcb_destroy(svc_ctx, tcb);
+               } 
+
                /* If there is no such triggered FD? */
        }
 
@@ -765,6 +795,19 @@ HAPI int service_common_destroy(struct service_context *svc_ctx)
        return 0;
 }
 
+HAPI int tcb_is_valid(struct service_context *svc_ctx, struct tcb *tcb)
+{
+       Eina_List *l;
+       struct tcb *tmp;
+
+       EINA_LIST_FOREACH(svc_ctx->tcb_list, l, tmp) {
+               if (tmp == tcb /* && tcb->svc_ctx == svc_ctx */)
+                       return 1;
+       }
+
+       return 0;
+}
+
 /*!
  * \note
  * SERVER THREAD
index 82408a3..ea28b6e 100644 (file)
@@ -171,6 +171,11 @@ static int service_thread_main(struct tcb *tcb, struct packet *packet, void *dat
                        break;
                }
 
+               if (!tcb_is_valid(s_info.svc_ctx, tcb)) {
+                       ErrPrint("TCB is not valid (already disconnected?)\n");
+                       break;
+               }
+
                if (service_common_unicast_packet(tcb, packet) < 0)
                        ErrPrint("Unable to send reply packet\n");
                break;