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