tizen beta release
[platform/core/multimedia/avsystem.git] / avsys-audio-sync.c
1 /*
2  * avsystem
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jonghyuk Choi <jhchoi.choi@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 #include <string.h>
23 #include <dirent.h>
24 #include <errno.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27
28 #include "avsys-common.h"
29 #include "avsys-audio-sync.h"
30 #include "avsys-error.h"
31 #include "avsys-debug.h"
32 #include "avsys-audio-shm.h"
33 #include "avsys-audio-path.h"
34
35 static avsys_sync_param_t g_presettings[AVSYS_AUDIO_SYNC_IDEN_CNT] = {
36         {"audio_handle_lock", AVSYS_KEY_PREFIX_GEN(AVSYS_KEY_PREFIX_AUDIO, AVSYS_AUDIO_SYNC_IDEN_HANDLE)},
37         {"audio_path_lock", AVSYS_KEY_PREFIX_GEN(AVSYS_KEY_PREFIX_AUDIO, AVSYS_AUDIO_SYNC_IDEN_PATH)},
38         {"audio_route_policy_lock", AVSYS_KEY_PREFIX_GEN(AVSYS_KEY_PREFIX_AUDIO, AVSYS_AUDIO_SYNC_IDEN_SOUNDPATH)},
39         {"av_volume_sem", AVSYS_KEY_PREFIX_GEN(AVSYS_KEY_PREFIX_AUDIO, AVSYS_AUDIO_SYNC_IDEN_VOLUME)},
40 };
41
42 int avsys_audio_create_sync(const avsys_audio_sync_iden_t iden)
43 {
44         if (iden >= AVSYS_AUDIO_SYNC_IDEN_CNT || 0 > iden)
45                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
46         return avsys_create_sync(&g_presettings[iden]);
47 }
48
49 int avsys_audio_remove_sync(const avsys_audio_sync_iden_t iden)
50 {
51         if (iden >= AVSYS_AUDIO_SYNC_IDEN_CNT || 0 > iden)
52                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
53         return avsys_remove_sync(&g_presettings[iden]);
54 }
55
56 int avsys_audio_lock_sync(const avsys_audio_sync_iden_t iden)
57 {
58         pid_t pid = -1;
59         int index = 0;
60         int err = AVSYS_STATE_SUCCESS;
61
62         if (iden >= AVSYS_AUDIO_SYNC_IDEN_CNT || 0 > iden) {
63                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
64         }
65         //avsys_info(AVAUDIO,"lock[%d]\n",(int)iden);
66
67         err = avsys_lock_sync(&g_presettings[iden]);
68
69         pid = getpid();
70         if ((iden == AVSYS_AUDIO_SYNC_IDEN_PATH) && (err == AVSYS_STATE_SUCCESS)) {
71                 avsys_audio_path_ex_info_t *control = NULL;
72                 avsys_audio_path_ex_info_t **temp = NULL;
73
74                 temp = &control;
75                 if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) {
76                         avsys_error_r(AVAUDIO, "avsys_audio_get_shm() for path failed in %s\n", __func__);
77                         return AVSYS_STATE_ERR_INTERNAL;
78                 }
79
80                 do {
81                         /* Add mark */
82                         if (control->pathlock_pid[index] < 0) { /* find empty slot */
83                                 control->pathlock_pid[index] = pid;
84                                 break;
85                         }
86                         index++;
87                         if (index == AVSYS_AUDIO_LOCK_SLOT_MAX) {
88                                 int i;
89                                 avsys_critical(AVAUDIO, "path lock pid slot is full. print stored pid before clear all slot\n");
90                                 /* print and cleanup all stored pid */
91                                 for (i = 0; i < AVSYS_AUDIO_LOCK_SLOT_MAX; i++) {
92                                         avsys_critical(AVAUDIO, "path lock pid : %d\n", control->pathlock_pid[i]);
93                                         control->pathlock_pid[i] = -1;
94                                 }
95                                 control->pathlock_pid[0] = pid; /* add current pid */
96                         }
97                 } while (index < AVSYS_AUDIO_LOCK_SLOT_MAX);
98         } else if ((iden == AVSYS_AUDIO_SYNC_IDEN_HANDLE) && (err == AVSYS_STATE_SUCCESS)) {
99                 avsys_audio_handle_info_t *control = NULL;
100                 avsys_audio_handle_info_t **temp = NULL;
101
102                 temp = &control;
103                 if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_HANDLE, (void **)temp))) {
104                         avsys_error(AVAUDIO, "avsys_audio_get_shm() for handle failed in %s\n", __func__);
105                         return AVSYS_STATE_ERR_INTERNAL;
106                 }
107
108                 do {
109                         /* Add mark */
110                         if (control->handlelock_pid[index] < 0) {       /* find empty slot */
111                                 control->handlelock_pid[index] = pid;
112                                 break;
113                         }
114                         index++;
115                         if (index == AVSYS_AUDIO_LOCK_SLOT_MAX) {
116                                 int i;
117                                 avsys_critical(AVAUDIO, "handle lock pid slot is full. print stored pid before clear all slot\n");
118                                 /* print and cleanup all stored pid */
119                                 for (i = 0; i < AVSYS_AUDIO_LOCK_SLOT_MAX; i++) {
120                                         avsys_critical(AVAUDIO, "handle lock pid : %d\n", control->handlelock_pid[i]);
121                                         control->handlelock_pid[i] = -1;
122                                 }
123                                 control->handlelock_pid[0] = pid; /*add current pid */
124                         }
125                 } while (index < AVSYS_AUDIO_LOCK_SLOT_MAX);
126         }
127         return err;
128 }
129
130 int avsys_audio_unlock_sync(const avsys_audio_sync_iden_t iden)
131 {
132         pid_t pid = -1;
133         int index = 0;
134         int err = AVSYS_STATE_SUCCESS;
135
136         if (iden >= AVSYS_AUDIO_SYNC_IDEN_CNT || 0 > iden) {
137                 return AVSYS_STATE_ERR_INVALID_PARAMETER;
138         }
139         //avsys_info(AVAUDIO,"unlock[%d]\n",(int)iden);
140
141         err = avsys_unlock_sync(&g_presettings[iden]);
142
143         pid = getpid();
144         if ((iden == AVSYS_AUDIO_SYNC_IDEN_PATH) && (err == AVSYS_STATE_SUCCESS)) {
145                 avsys_audio_path_ex_info_t *control = NULL;
146                 avsys_audio_path_ex_info_t **temp = NULL;
147
148                 temp = &control;
149                 if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) {
150                         avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed in %s\n", __func__);
151                         return AVSYS_STATE_ERR_INTERNAL;
152                 }
153
154                 do {
155                         /* Remove mark */
156                         if (control->pathlock_pid[index] == pid) {      /* find empty slot */
157                                 control->pathlock_pid[index] = -1;
158                                 break;
159                         }
160                         index++;
161                         if (index == AVSYS_AUDIO_LOCK_SLOT_MAX)
162                                 avsys_error(AVAUDIO, "Can not find pid (%d) in path_lock_pid slot\n", pid);
163                 } while (index < AVSYS_AUDIO_LOCK_SLOT_MAX);
164         } else if ((iden == AVSYS_AUDIO_SYNC_IDEN_HANDLE) && (err == AVSYS_STATE_SUCCESS)) {
165                 avsys_audio_handle_info_t *control = NULL;
166                 avsys_audio_handle_info_t **temp = NULL;
167
168                 temp = &control;
169                 if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_HANDLE, (void **)temp))) {
170                         avsys_error(AVAUDIO, "avsys_audio_get_shm() for handle failed in %s\n", __func__);
171                         return AVSYS_STATE_ERR_INTERNAL;
172                 }
173
174                 do {
175                         /* Add mark */
176                         if (control->handlelock_pid[index] == pid) {    /* find empty slot */
177                                 control->handlelock_pid[index] = -1;
178                                 break;
179                         }
180                         index++;
181                         if (index == AVSYS_AUDIO_LOCK_SLOT_MAX)
182                                 avsys_error(AVAUDIO, "Can not find pid (%d) in handlelock_pid slot\n", pid);
183                 } while (index < AVSYS_AUDIO_LOCK_SLOT_MAX);
184         }
185
186         return err;
187 }
188
189 /* find pid information in proc filesystem */
190 /* if pid exist, return AVSYS_STATE_SUCCESS */
191 /* if pid does not exist, return AVSYS_STATE_ERR_ALLOCATION */
192 int avsys_check_process(int check_pid)
193 {
194         DIR *dir = NULL;
195         char check_path[128] = "";
196         int exist = AVSYS_STATE_SUCCESS;
197
198         memset(check_path, '\0', sizeof(check_path));
199         snprintf(check_path, sizeof(check_path) - 1, "/proc/%d", check_pid);
200
201         dir = opendir(check_path);
202         if (dir == NULL) {
203                 switch (errno) {
204                 case ENOENT:
205                         avsys_error(AVAUDIO, "pid %d does not exist anymore\n", check_pid);
206                         exist = AVSYS_STATE_ERR_ALLOCATION;
207                         break;
208                 case EACCES:
209                         avsys_error(AVAUDIO, "Permission denied\n");
210                         break;
211                 case EMFILE:
212                         avsys_error(AVAUDIO, "Too many file descriptors in use by process\n");
213                         break;
214                 case ENFILE:
215                         avsys_error(AVAUDIO, "Too many files are currently open in the system\n");
216                         break;
217                 default:
218                         avsys_error(AVAUDIO, "Other error : %d\n", errno);
219                         break;
220                 }
221         } else {
222                 avsys_warning(AVAUDIO, "pid : %d still alive\n", check_pid);
223                 if (-1 == closedir(dir)) {
224                         avsys_error(AVAUDIO, "[%s] closedir failed with errno : %d\n", __func__, errno);
225                 }
226         }
227         return exist;
228 }
229
230 int avsys_audio_dump_sync(void)
231 {
232         pid_t pid = -1;
233         int index = 0;
234         int err = AVSYS_STATE_SUCCESS;
235         int i = 0;
236         int sem_value = 0;
237
238         fprintf(stdout, "Dump sync : Start\n");
239         for (i = 0; i < AVSYS_AUDIO_SYNC_IDEN_CNT; i++) {
240                 err = avsys_dump_sync(&g_presettings[i]);
241         }
242         fprintf(stdout, "Dump sync : End\n");
243         return err;
244 }