d01863419f5bcaeb6f8334b83a5e118964e1f924
[framework/messaging/email-service.git] / email-ipc / email-stub / email-stub-socket.c
1 /*
2 *  email-service
3 *
4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5 *
6 * Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com>
7
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 */
21
22
23
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <errno.h>
27 #include <malloc.h>
28 #include <sys/epoll.h>
29 #include <pthread.h>
30
31 #include "email-ipc-build.h"
32 #include "email-ipc-api-info.h"
33 #include "email-ipc-socket.h"
34 #include "email-stub-task.h"
35 #include "email-stub-task-manager.h"
36 #include "email-stub-socket.h"
37
38 #include "email-debug-log.h"
39
40 #define MAX_EPOLL_EVENT 50
41
42 static int stub_socket = 0;
43 static pthread_t stub_socket_thread = 0;
44 static bool stop_thread = false;
45
46 static void *emipc_stub_socket_thread_proc();
47
48 EXPORT_API bool emipc_start_stub_socket()
49 {
50         bool ret = true;
51
52         ret = emipc_init_email_socket(&stub_socket);
53         if (!ret) {
54                 EM_DEBUG_EXCEPTION("emipc_init_email_socket failed");
55                 return ret;
56         }
57
58         ret = emipc_start_stub_socket_thread();
59         if (!ret) {
60                 EM_DEBUG_EXCEPTION("emipc_start_stub_socket_thread failed");
61                 return ret;
62         }
63
64         ret = emipc_start_task_thread();
65         if (!ret) {
66                 EM_DEBUG_EXCEPTION("emipc_start_task_thread failed");
67                 return ret;
68         }
69
70         return ret;
71 }
72
73 EXPORT_API bool emipc_start_stub_socket_thread()
74 {
75         EM_DEBUG_LOG("[IPCLib] emipc_email_stub_socket_thread start");
76         if (stub_socket_thread)
77                 return true;
78                 
79         pthread_attr_t thread_attr;
80         pthread_attr_init(&thread_attr);
81         pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
82         if (pthread_create(&stub_socket_thread, &thread_attr, &emipc_stub_socket_thread_proc, NULL) != 0) {
83                 EM_DEBUG_EXCEPTION("[IPCLib] emipc_start_stub_socket_thread() - fail to create a thread");
84                 return false;
85         }
86         return true;
87 }
88
89 EXPORT_API bool emipc_stop_stub_socket_thread()
90 {
91         if (stub_socket_thread)
92                 stop_thread = true;
93
94         return true;
95 }
96
97 static void *emipc_stub_socket_thread_proc()
98 {
99         emipc_wait_for_ipc_request();
100         stub_socket_thread = 0;
101         return NULL;
102 }
103
104 EXPORT_API void emipc_wait_for_ipc_request()
105 {
106         struct epoll_event ev = {0};
107         struct epoll_event events[MAX_EPOLL_EVENT] = {{0}, };
108         int epfd = 0;
109         int event_num = 0;
110
111         if (!stub_socket) {
112                 EM_DEBUG_EXCEPTION("Server Socket is not initialized");
113                 return;
114         }
115
116         emipc_open_email_socket(stub_socket, EM_SOCKET_PATH);
117         
118         epfd = epoll_create(MAX_EPOLL_EVENT);
119         if (epfd < 0) {
120                 EM_DEBUG_EXCEPTION("epoll_ctl: %s[%d]", strerror(errno), errno);
121                 EM_DEBUG_CRITICAL_EXCEPTION("epoll_create: %s[%d]", strerror(errno), errno);
122                 abort();
123         }
124
125         ev.events = EPOLLIN;
126         ev.data.fd = stub_socket;
127         
128         if (epoll_ctl(epfd, EPOLL_CTL_ADD, stub_socket, &ev) == -1) {
129                 EM_DEBUG_EXCEPTION("epoll_ctl: %s[%d]", strerror(errno), errno);
130                 EM_DEBUG_CRITICAL_EXCEPTION("epoll_ctl:%s[%d]", strerror(errno), errno);        
131         }
132         while (1) {
133                 int i = 0;
134
135                 event_num = epoll_wait(epfd, events, MAX_EPOLL_EVENT, -1);
136                 
137                 if (event_num == -1) {
138                         EM_DEBUG_EXCEPTION("epoll_wait: %s[%d]", strerror(errno), errno);
139                         EM_DEBUG_CRITICAL_EXCEPTION("epoll_wait: %s[%d]", strerror(errno), errno);
140                         if (errno == EINTR) continue; /* resume when interrupted system call*/
141                         else abort();
142                 } else {
143                         for (i = 0; i < event_num; i++) {
144                                 int event_fd = events[i].data.fd;
145
146                                 if (event_fd == stub_socket) { /*  if it is socket connection request */
147                                         int cfd = emipc_accept_email_socket(stub_socket);
148                                         if (cfd < 0) {
149                                                 EM_DEBUG_EXCEPTION("accept error: %s[%d]", strerror(errno), errno);
150                                                 EM_DEBUG_CRITICAL_EXCEPTION("accept error: %s[%d]", strerror(errno), errno);
151                                                 /*  abort(); */
152                                         }
153                                         ev.events = EPOLLIN;
154                                         ev.data.fd = cfd;
155                                         epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &ev);
156                                 } else {
157                                         int recv_len;
158                                         char *sz_buf = NULL;
159                                         
160                                         recv_len = emipc_recv_email_socket(event_fd, &sz_buf);
161                                         
162                                         if(recv_len > 0) {
163                                                 EM_DEBUG_LOG("====================================================================");
164                                                 EM_DEBUG_LOG("[IPCLib]Stub Socket Recv [Socket ID = %d], [recv_len = %d]", event_fd, recv_len);
165                                                 EM_DEBUG_LOG("====================================================================");
166                                                 emipc_create_task((unsigned char *)sz_buf, event_fd);
167                                         }  else {
168                                                 EM_DEBUG_LOG("[IPCLib] Socket [%d] removed - [%d] ", event_fd, recv_len);
169                                                 epoll_ctl(epfd, EPOLL_CTL_DEL, event_fd, events);
170                                                 close(event_fd);
171                                         } 
172                                         EM_SAFE_FREE(sz_buf);
173                                 }
174                         }
175                 }
176         }       
177 }
178
179 EXPORT_API bool emipc_end_stub_socket()
180 {
181         EM_DEBUG_FUNC_BEGIN();
182         
183         if (stub_socket) {
184                 emipc_close_email_socket(stub_socket);
185         }
186
187         if (stub_socket_thread) {
188                 emipc_stop_stub_socket_thread(stub_socket_thread);
189                 pthread_cancel(stub_socket_thread);
190                 stub_socket_thread = 0;
191         }
192
193         if (!emipc_stop_task_thread()) {
194                 EM_DEBUG_EXCEPTION("emipc_stop_task_thread failed");
195                 return false;   
196         }
197                 
198         return true;
199 }
200
201 EXPORT_API int emipc_send_stub_socket(int sock_fd, void *data, int len)
202 {
203         EM_DEBUG_FUNC_BEGIN("Stub socket sending %d bytes", len);
204
205         int sending_bytes = emipc_send_email_socket(sock_fd, data, len);
206         
207         EM_DEBUG_FUNC_END("sending_bytes = %d", sending_bytes);
208         return sending_bytes;
209 }
210 /* stub socket accpet, recv, send */
211