5d6848767e111c8ce39b033ebf6b5a313eacb4f8
[platform/core/pim/contacts-service.git] / common / ctsvc_mutex.c
1 /*
2  * Contacts Service
3  *
4  * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Youngjae Shin <yj99.shin@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 #include <pthread.h>
22
23 #include "contacts.h"
24 #include "ctsvc_internal.h"
25 #include "ctsvc_mutex.h"
26
27 typedef struct {
28         int (* lock) (pthread_mutex_t *mutex);
29         int (* unlock) (pthread_mutex_t *mutex);
30 }cts_mutex_fns;
31
32 static cts_mutex_fns __ctsvc_mutex_funtions =
33 {
34         pthread_mutex_lock,
35         pthread_mutex_unlock
36 };
37
38 static pthread_mutex_t conn_mutex = PTHREAD_MUTEX_INITIALIZER;
39 static pthread_mutex_t sockfd_mutex = PTHREAD_MUTEX_INITIALIZER;
40 static pthread_mutex_t trans_mutex = PTHREAD_MUTEX_INITIALIZER;
41 static pthread_mutex_t ipc_mutex = PTHREAD_MUTEX_INITIALIZER;
42 static pthread_mutex_t ipc_pubsub_mutex = PTHREAD_MUTEX_INITIALIZER;
43 static pthread_mutex_t access_control_mutex = PTHREAD_MUTEX_INITIALIZER;
44 static pthread_mutex_t socket_client_info_mutex = PTHREAD_MUTEX_INITIALIZER;
45 static pthread_mutex_t cynara_mutex = PTHREAD_MUTEX_INITIALIZER;
46
47 static int __old_type = 0;
48 static int __defered_ref = 0;
49
50 static inline pthread_mutex_t* __ctsvc_mutex_get_mutex(int type)
51 {
52         pthread_mutex_t *ret_val;
53
54         switch (type) {
55         case CTS_MUTEX_CONNECTION:
56                 ret_val = &conn_mutex;
57                 break;
58         case CTS_MUTEX_SOCKET_FD:
59                 ret_val = &sockfd_mutex;
60                 break;
61         case CTS_MUTEX_TRANSACTION:
62                 ret_val = &trans_mutex;
63                 break;
64         case CTS_MUTEX_PIMS_IPC_CALL:
65                 ret_val = &ipc_mutex;
66                 break;
67         case CTS_MUTEX_PIMS_IPC_PUBSUB:
68                 ret_val = &ipc_pubsub_mutex;
69                 break;
70         case CTS_MUTEX_ACCESS_CONTROL:
71                 ret_val = &access_control_mutex;
72                 break;
73         case CTS_MUTEX_SOCKET_CLIENT_INFO:
74                 ret_val = &socket_client_info_mutex;
75                 break;
76         case CTS_MUTEX_CYNARA:
77                 ret_val = &cynara_mutex;
78                 break;
79         default:
80                 CTS_ERR("unknown type(%d)", type);
81                 ret_val = NULL;
82                 break;
83         }
84         return ret_val;
85 }
86
87 void ctsvc_mutex_lock(int type)
88 {
89         int ret;
90         pthread_mutex_t *mutex;
91
92         // If user use pthread_cancel, lock can be occured
93         // protect it, call pthread_set_canceltype as PTHREAD_CANCEL_DEFERRED
94         // But, if another module call PTHREAD_CANCEL_ASYNCHRONOUS,
95         // it can be occured again
96         // So, Do not use the pthread_cancel with contacts_service API
97         if (__defered_ref == 0)
98                 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &__old_type);
99         else
100                 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
101
102         __defered_ref++;
103
104         mutex = __ctsvc_mutex_get_mutex(type);
105
106         if (__ctsvc_mutex_funtions.lock) {
107                 ret = __ctsvc_mutex_funtions.lock(mutex);
108                 WARN_IF(ret, "mutex_lock Failed(%d)", ret);
109         }
110 }
111
112 void ctsvc_mutex_unlock(int type)
113 {
114         int ret;
115         pthread_mutex_t *mutex;
116
117         mutex = __ctsvc_mutex_get_mutex(type);
118
119         if (__ctsvc_mutex_funtions.unlock) {
120                 ret = __ctsvc_mutex_funtions.unlock(mutex);
121                 WARN_IF(ret, "mutex_unlock Failed(%d)", ret);
122         }
123
124         __defered_ref--;
125         if (__defered_ref == 0) {
126                 pthread_setcanceltype(__old_type, NULL);
127         }
128 }
129