• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
pa_mutex_new(bool recursive,bool inherit_priority)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 
pa_mutex_free(pa_mutex * m)49 void pa_mutex_free(pa_mutex *m) {
50     assert(m);
51 
52     DeleteCriticalSection(&m->mutex);
53     pa_xfree(m);
54 }
55 
pa_mutex_lock(pa_mutex * m)56 void pa_mutex_lock(pa_mutex *m) {
57     assert(m);
58 
59     EnterCriticalSection(&m->mutex);
60 }
61 
pa_mutex_unlock(pa_mutex * m)62 void pa_mutex_unlock(pa_mutex *m) {
63     assert(m);
64 
65     LeaveCriticalSection(&m->mutex);
66 }
67 
pa_cond_new(void)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 
pa_cond_free(pa_cond * c)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 
pa_cond_signal(pa_cond * c,int broadcast)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 
pa_cond_wait(pa_cond * c,pa_mutex * m)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 /* This is a copy of the function in mutex-posix.c */
pa_static_mutex_get(pa_static_mutex * s,bool recursive,bool inherit_priority)134 pa_mutex* pa_static_mutex_get(pa_static_mutex *s, bool recursive, bool inherit_priority) {
135     pa_mutex *m;
136 
137     pa_assert(s);
138 
139     /* First, check if already initialized and short cut */
140     if ((m = pa_atomic_ptr_load(&s->ptr)))
141         return m;
142 
143     /* OK, not initialized, so let's allocate, and fill in */
144     m = pa_mutex_new(recursive, inherit_priority);
145     if ((pa_atomic_ptr_cmpxchg(&s->ptr, NULL, m)))
146         return m;
147 
148     pa_mutex_free(m);
149 
150     /* Him, filling in failed, so someone else must have filled in
151      * already */
152     pa_assert_se(m = pa_atomic_ptr_load(&s->ptr));
153     return m;
154 }
155