clear deadlock issue
[platform/core/system/haptic-module-tizen.git] / tizen / DEVICE / src / sysnoti.c
1 /*
2  * haptic-module-tizen
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <sys/un.h>
25 #include <stdarg.h>
26 #include <errno.h>
27
28 #include "haptic_module_log.h"
29
30 #define HAPTIC_RETRY_READ_COUNT                 5
31 #define HAPTIC_PARAM_CNT                                3
32 #define HAPTIC_MAXSTR                                   100
33 #define HAPTIC_MAXARG                                   16
34 #define PREDEF_HAPTIC                                   "haptic"
35 #define SYSNOTI_SOCKET_PATH                             "/tmp/sn"
36
37 enum sysnoti_cmd {
38         ADD_HAPTIC_ACTION,
39         CALL_HAPTIC_ACTION,
40 };
41
42 struct sysnoti_type {
43         int pid;
44         int cmd;
45         char *type;
46         char *path;
47         int argc;
48         char *argv[HAPTIC_MAXARG];
49 };
50
51 static inline int __send_int(int fd, int val)
52 {
53         return write(fd, &val, sizeof(int));
54 }
55
56 static inline int __send_str(int fd, char *str)
57 {
58         int len;
59         int r;
60
61         if (str == NULL) {
62                 len = 0;
63                 r = write(fd, &len, sizeof(int));
64         } else {
65                 len = strlen(str);
66                 if (len > HAPTIC_MAXSTR)
67                         len = HAPTIC_MAXSTR;
68                 r = write(fd, &len, sizeof(int));
69                 r = write(fd, str, len);
70         }
71
72         return r;
73 }
74
75 static int __sysnoti_send(struct sysnoti_type *msg)
76 {
77         int sockfd;
78         int len;
79         struct sockaddr_un addr;
80         int retry_cnt;
81         int ret;
82         int i;
83         int r;
84
85         sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
86         if (sockfd == -1) {
87                 MODULE_ERROR("socket create failed");
88                 return -1;
89         }
90
91         bzero(&addr, sizeof(addr));
92         addr.sun_family = AF_UNIX;
93         strncpy(addr.sun_path, SYSNOTI_SOCKET_PATH, sizeof(addr.sun_path) - 1);
94         len = sizeof(addr);
95
96         if (connect(sockfd, (struct sockaddr *)&addr, len) < 0) {
97                 MODULE_ERROR("connect failed");
98                 close(sockfd);
99                 return -1;
100         }
101         MODULE_LOG("connect : %x", sockfd);
102
103         __send_int(sockfd, msg->pid);
104         __send_int(sockfd, msg->cmd);
105         __send_str(sockfd, msg->type);
106         __send_str(sockfd, msg->path);
107         __send_int(sockfd, msg->argc);
108         for (i = 0; i < msg->argc; i++)
109                 __send_str(sockfd, msg->argv[i]);
110
111         MODULE_LOG("read");
112         retry_cnt = 0;
113         while ((r = read(sockfd, &ret, sizeof(int))) < 0) {
114
115                 if (errno != EINTR) {
116                         MODULE_LOG("read fail : %s(%d)", strerror(errno), errno);
117                         ret = -1;
118                         break;
119                 }
120
121                 if (retry_cnt == HAPTIC_RETRY_READ_COUNT) {
122                         MODULE_ERROR("retry(%d) fail", retry_cnt);
123                         ret = -1;
124                         break;
125                 }
126
127                 MODULE_ERROR("Re-read for error(EINTR)");
128                 ++retry_cnt;
129         }
130
131         MODULE_LOG("close (ret : %d) : %x", ret, sockfd);
132         close(sockfd);
133         return ret;
134 }
135
136 int __haptic_call_predef_action(const char *type, int num, ...)
137 {
138         struct sysnoti_type msg;
139         char *args;
140         va_list argptr;
141         int i;
142
143         if (type == NULL || num > HAPTIC_MAXARG) {
144                 errno = EINVAL;
145                 return -1;
146         }
147
148         msg.pid = getpid();
149         msg.cmd = CALL_HAPTIC_ACTION;
150         msg.type = (char *)type;
151         msg.path = NULL;
152         msg.argc = num;
153
154         va_start(argptr, num);
155         for (i = 0; i < num; i++) {
156                 args = va_arg(argptr, char *);
157                 msg.argv[i] = args;
158         }
159         va_end(argptr);
160
161         return __sysnoti_send(&msg);
162 }
163