1 /*
2 * This file is part of libbluray
3 * Copyright (C) 2010-2014 Petri Hintukainen <phintuka@users.sourceforge.net>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library. If not, see
17 * <http://www.gnu.org/licenses/>.
18 */
19
20 #if HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "mutex.h"
25
26 #include "logging.h"
27 #include "macro.h"
28
29 #if defined(_WIN32)
30 # include <windows.h>
31 #elif defined(HAVE_PTHREAD_H)
32 # include <pthread.h>
33 #else
34 # error no mutex support found
35 #endif
36
37
38 #if defined(_WIN32)
39
40 typedef struct {
41 CRITICAL_SECTION cs;
42 } MUTEX_IMPL;
43
_mutex_lock(MUTEX_IMPL * p)44 static int _mutex_lock(MUTEX_IMPL *p)
45 {
46 EnterCriticalSection(&p->cs);
47 return 0;
48 }
49
_mutex_unlock(MUTEX_IMPL * p)50 static int _mutex_unlock(MUTEX_IMPL *p)
51 {
52 LeaveCriticalSection(&p->cs);
53 return 0;
54 }
55
_mutex_init(MUTEX_IMPL * p)56 static int _mutex_init(MUTEX_IMPL *p)
57 {
58 InitializeCriticalSection(&p->cs);
59 return 0;
60 }
61
_mutex_destroy(MUTEX_IMPL * p)62 static int _mutex_destroy(MUTEX_IMPL *p)
63 {
64 DeleteCriticalSection(&p->cs);
65 return 0;
66 }
67
68
69 #elif defined(HAVE_PTHREAD_H)
70
71 typedef pthread_mutex_t MUTEX_IMPL;
72
_mutex_init(MUTEX_IMPL * p)73 static int _mutex_init(MUTEX_IMPL *p)
74 {
75 pthread_mutexattr_t attr;
76
77 pthread_mutexattr_init(&attr);
78 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
79
80 if (pthread_mutex_init(p, &attr)) {
81 BD_DEBUG(DBG_BLURAY|DBG_CRIT, "pthread_mutex_init() failed !\n");
82 return -1;
83 }
84
85 return 0;
86 }
87
_mutex_lock(MUTEX_IMPL * p)88 static int _mutex_lock(MUTEX_IMPL *p)
89 {
90 if (pthread_mutex_lock(p)) {
91 BD_DEBUG(DBG_BLURAY|DBG_CRIT, "pthread_mutex_lock() failed !\n");
92 return -1;
93 }
94
95 return 0;
96 }
97
_mutex_unlock(MUTEX_IMPL * p)98 static int _mutex_unlock(MUTEX_IMPL *p)
99 {
100 if (pthread_mutex_unlock(p)) {
101 BD_DEBUG(DBG_BLURAY|DBG_CRIT, "pthread_mutex_unlock() failed !\n");
102 return -1;
103 }
104
105 return 0;
106 }
107
_mutex_destroy(MUTEX_IMPL * p)108 static int _mutex_destroy(MUTEX_IMPL *p)
109 {
110 if (pthread_mutex_destroy(p)) {
111 BD_DEBUG(DBG_BLURAY|DBG_CRIT, "pthread_mutex_destroy() failed !\n");
112 return -1;
113 }
114
115 return 0;
116 }
117
118 #endif /* HAVE_PTHREAD_H */
119
bd_mutex_lock(BD_MUTEX * p)120 int bd_mutex_lock(BD_MUTEX *p)
121 {
122 if (!p->impl) {
123 BD_DEBUG(DBG_BLURAY|DBG_CRIT, "bd_mutex_lock() failed !\n");
124 return -1;
125 }
126 return _mutex_lock((MUTEX_IMPL*)p->impl);
127 }
128
bd_mutex_unlock(BD_MUTEX * p)129 int bd_mutex_unlock(BD_MUTEX *p)
130 {
131 if (!p->impl) {
132 BD_DEBUG(DBG_BLURAY|DBG_CRIT, "bd_mutex_unlock() failed !\n");
133 return -1;
134 }
135 return _mutex_unlock((MUTEX_IMPL*)p->impl);
136 }
137
bd_mutex_init(BD_MUTEX * p)138 int bd_mutex_init(BD_MUTEX *p)
139 {
140 p->impl = calloc(1, sizeof(MUTEX_IMPL));
141 if (!p->impl) {
142 BD_DEBUG(DBG_BLURAY|DBG_CRIT, "bd_mutex_init() failed !\n");
143 return -1;
144 }
145
146 if (_mutex_init((MUTEX_IMPL*)p->impl) < 0) {
147 X_FREE(p->impl);
148 return -1;
149 }
150
151 return 0;
152 }
153
bd_mutex_destroy(BD_MUTEX * p)154 int bd_mutex_destroy(BD_MUTEX *p)
155 {
156 if (!p->impl) {
157 BD_DEBUG(DBG_BLURAY|DBG_CRIT, "bd_mutex_destroy() failed !\n");
158 return -1;
159 }
160
161 if (_mutex_destroy((MUTEX_IMPL*)p->impl) < 0) {
162 return -1;
163 }
164
165 X_FREE(p->impl);
166 return 0;
167 }
168