Add default-monitor-time-sec
[platform/upstream/pulseaudio.git] / src / pulsecore / mutex-win32.c
1 /***
2   This file is part of PulseAudio.
3
4   Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
5
6   PulseAudio is free software; you can redistribute it and/or modify
7   it under the terms of the GNU Lesser General Public License as published
8   by the Free Software Foundation; either version 2.1 of the License,
9   or (at your option) any later version.
10
11   PulseAudio is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public License
17   along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <windows.h>
25
26 #include <pulse/xmalloc.h>
27 #include <pulsecore/hashmap.h>
28
29 #include "mutex.h"
30
31 struct pa_mutex {
32     CRITICAL_SECTION mutex;
33 };
34
35 struct pa_cond {
36     pa_hashmap *wait_events;
37 };
38
39 pa_mutex* pa_mutex_new(bool recursive, bool inherit_priority) {
40     pa_mutex *m;
41
42     m = pa_xnew(pa_mutex, 1);
43
44     InitializeCriticalSection(&m->mutex);
45
46     return m;
47 }
48
49 void pa_mutex_free(pa_mutex *m) {
50     assert(m);
51
52     DeleteCriticalSection(&m->mutex);
53     pa_xfree(m);
54 }
55
56 void pa_mutex_lock(pa_mutex *m) {
57     assert(m);
58
59     EnterCriticalSection(&m->mutex);
60 }
61
62 void pa_mutex_unlock(pa_mutex *m) {
63     assert(m);
64
65     LeaveCriticalSection(&m->mutex);
66 }
67
68 pa_cond *pa_cond_new(void) {
69     pa_cond *c;
70
71     c = pa_xnew(pa_cond, 1);
72     c->wait_events = pa_hashmap_new(NULL, NULL);
73     assert(c->wait_events);
74
75     return c;
76 }
77
78 void pa_cond_free(pa_cond *c) {
79     assert(c);
80
81     pa_hashmap_free(c->wait_events);
82     pa_xfree(c);
83 }
84
85 void pa_cond_signal(pa_cond *c, int broadcast) {
86     assert(c);
87
88     if (pa_hashmap_size(c->wait_events) == 0)
89         return;
90
91     if (broadcast)
92         SetEvent(pa_hashmap_first(c->wait_events));
93     else {
94         void *iter;
95         const void *key;
96         HANDLE event;
97
98         iter = NULL;
99         while (1) {
100             pa_hashmap_iterate(c->wait_events, &iter, &key);
101             if (key == NULL)
102                 break;
103             event = (HANDLE)pa_hashmap_get(c->wait_events, key);
104             SetEvent(event);
105         }
106     }
107 }
108
109 int pa_cond_wait(pa_cond *c, pa_mutex *m) {
110     HANDLE event;
111
112     assert(c);
113     assert(m);
114
115     event = CreateEvent(NULL, FALSE, FALSE, NULL);
116     assert(event);
117
118     pa_hashmap_put(c->wait_events, event, event);
119
120     pa_mutex_unlock(m);
121
122     WaitForSingleObject(event, INFINITE);
123
124     pa_mutex_lock(m);
125
126     pa_hashmap_remove(c->wait_events, event);
127
128     CloseHandle(event);
129
130     return 0;
131 }
132
133 #ifdef __TIZEN__
134 int pa_cond_timedwait(pa_cond *c, pa_mutex *m, int ms_to_wait) {
135     HANDLE event;
136     DWORD ret;
137
138     assert(c);
139     assert(m);
140
141     event = CreateEvent(NULL, FALSE, FALSE, NULL);
142     assert(event);
143
144     pa_hashmap_put(c->wait_events, event, event);
145
146     pa_mutex_unlock(m);
147
148     ret = WaitForSingleObject(event, ms_to_wait);
149
150     pa_mutex_lock(m);
151
152     pa_hashmap_remove(c->wait_events, event);
153
154     CloseHandle(event);
155
156     return ret;
157 }
158 #endif
159 /* This is a copy of the function in mutex-posix.c */
160 pa_mutex* pa_static_mutex_get(pa_static_mutex *s, bool recursive, bool inherit_priority) {
161     pa_mutex *m;
162
163     pa_assert(s);
164
165     /* First, check if already initialized and short cut */
166     if ((m = pa_atomic_ptr_load(&s->ptr)))
167         return m;
168
169     /* OK, not initialized, so let's allocate, and fill in */
170     m = pa_mutex_new(recursive, inherit_priority);
171     if ((pa_atomic_ptr_cmpxchg(&s->ptr, NULL, m)))
172         return m;
173
174     pa_mutex_free(m);
175
176     /* Him, filling in failed, so someone else must have filled in
177      * already */
178     pa_assert_se(m = pa_atomic_ptr_load(&s->ptr));
179     return m;
180 }