Initialize Tizen 2.3
[framework/system/deviced.git] / src / core / core.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19
20 #include "data.h"
21 #include "queue.h"
22 #include "log.h"
23 #include "predefine.h"
24 #include "core.h"
25 #include "devices.h"
26 #include "common.h"
27
28 enum core_cmd_type {
29         CORE_ACT_RUN,
30         CORE_ACT_CLEAR
31 };
32
33 struct _internal_msg {
34         int type;
35         int pid;
36 };
37
38 static int core_pipe[2];
39 Ecore_Fd_Handler *g_pipe_efd = NULL;
40
41 static int __pipe_start(struct main_data *ad);
42 static int __pipe_stop(int fd);
43
44 static int _core_action_run(void *user_data,
45                                struct run_queue_entry *rq_entry)
46 {
47         struct action_entry *act_entry = rq_entry->action_entry;
48         int ret;
49         char tmp[128];
50
51         rq_entry->state = STATE_RUNNING;
52         ret = act_entry->predefine_action(rq_entry->argc, rq_entry->argv);
53         if (ret <= 0) {
54                 if (ret < 0)
55                         _E("predefine action failed");
56                 goto fast_done;
57         } else {
58                 snprintf(tmp, sizeof(tmp), "/proc/%d/status", ret);
59                 if (access(tmp, R_OK) == 0)
60                         rq_entry->forked_pid = ret;
61                 else
62                         goto fast_done;
63         }
64         return 0;
65
66  fast_done:
67         rq_entry->forked_pid = -1;
68         rq_entry->state = STATE_DONE;
69         core_action_clear(-1);
70         return 0;
71 }
72
73 static Eina_Bool core_pipe_cb(void *userdata, Ecore_Fd_Handler * fd_handler)
74 {
75         struct main_data *ad = (struct main_data *)userdata;
76         struct _internal_msg p_msg;
77         int retry_count = 0;
78         int r = -1;
79         if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
80                 _E("ecore_main_fd_handler_active_get error , return");
81                 return EINA_TRUE;
82         }
83
84         while (retry_count < 5) {
85                 r = read(core_pipe[0], &p_msg, sizeof(struct _internal_msg));
86                 if (r < 0) {
87                         if (errno == EINTR) {
88                                 _D("Re-read for error(EINTR)");
89                                 retry_count++;
90                                 continue;
91                         } else {
92                                 __pipe_stop(core_pipe[0]);
93                                 __pipe_stop(core_pipe[1]);
94                                 _D("restart pipe fd");
95                                 __pipe_start(ad);
96                         }
97                 } else {
98                         break;
99                 }
100         }
101
102         switch (p_msg.type) {
103         case CORE_ACT_RUN:
104                 run_queue_run(STATE_INIT, _core_action_run, ad);
105                 break;
106         case CORE_ACT_CLEAR:
107                 run_queue_del_bypid(p_msg.pid);
108                 break;
109         }
110         return EINA_TRUE;
111 }
112
113 int core_action_run()
114 {
115         struct _internal_msg p_msg;
116
117         p_msg.type = CORE_ACT_RUN;
118         p_msg.pid = 0;
119         write(core_pipe[1], &p_msg, sizeof(struct _internal_msg));
120
121         return 0;
122 }
123
124 int core_action_clear(int pid)
125 {
126         struct _internal_msg p_msg;
127
128         p_msg.type = CORE_ACT_CLEAR;
129         p_msg.pid = pid;
130         write(core_pipe[1], &p_msg, sizeof(struct _internal_msg));
131
132         return 0;
133 }
134
135 static int __pipe_start(struct main_data *ad)
136 {
137         if (pipe(core_pipe) < 0) {
138                 _E("pipe cannot create");
139                 exit(EXIT_FAILURE);
140         }
141
142         g_pipe_efd = ecore_main_fd_handler_add(core_pipe[0], ECORE_FD_READ,
143                                   core_pipe_cb, ad, NULL, NULL);
144         if (!g_pipe_efd) {
145                 _E("error ecore_main_fd_handler_add");
146                 return -1;
147         }
148         return 0;
149 }
150
151 static int __pipe_stop(int fd)
152 {
153         if (g_pipe_efd) {
154                 ecore_main_fd_handler_del(g_pipe_efd);
155                 g_pipe_efd = NULL;
156         }
157         if (fd >=0)
158                 close(fd);
159
160         return 0;
161 }
162
163 static void core_init(void *data)
164 {
165         struct main_data *ad = (struct main_data*)data;
166
167         __pipe_stop(core_pipe[0]);
168         __pipe_stop(core_pipe[1]);
169
170         if (__pipe_start(ad) == -1)
171                 _E("fail pipe control fd init");
172 }
173
174 static const struct device_ops core_device_ops = {
175         .priority = DEVICE_PRIORITY_NORMAL,
176         .name     = "core",
177         .init     = core_init,
178 };
179
180 DEVICE_OPS_REGISTER(&core_device_ops)