Sync with trunk head (part 1 of 2)
[reactos.git] / lib / drivers / sound / mmebuddy / reentrancy.c
1 /*
2 * PROJECT: ReactOS Sound System "MME Buddy" Library
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: lib/sound/mmebuddy/reentrancy.c
5 *
6 * PURPOSE: Provides entry-point mutex guards.
7 *
8 * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
9 */
10
11 #include <windows.h>
12 #include <mmsystem.h>
13 #include <mmddk.h>
14 #include <ntddsnd.h>
15 #include <sndtypes.h>
16 #include <mmebuddy.h>
17
18 HANDLE EntrypointMutexes[SOUND_DEVICE_TYPES];
19
20 /*
21 Creates a set of mutexes which are used for the purpose of guarding the
22 device-type specific module entry-points. If any of these fail creation,
23 all of them will be destroyed and the failure reported.
24 */
25 MMRESULT
26 InitEntrypointMutexes()
27 {
28 UCHAR i;
29 MMRESULT Result = MMSYSERR_NOERROR;
30
31 /* Blank all entries ni the table first */
32 for ( i = 0; i < SOUND_DEVICE_TYPES; ++ i )
33 {
34 EntrypointMutexes[i] = NULL;
35 }
36
37 /* Now create the mutexes */
38 for ( i = 0; i < SOUND_DEVICE_TYPES; ++ i )
39 {
40 EntrypointMutexes[i] = CreateMutex(NULL, FALSE, NULL);
41
42 if ( ! EntrypointMutexes[i] )
43 {
44 Result = Win32ErrorToMmResult(GetLastError());
45
46 /* Clean up any mutexes we successfully created */
47 CleanupEntrypointMutexes();
48 break;
49 }
50 }
51
52 return Result;
53 }
54
55 /*
56 Cleans up any of the entry-point guard mutexes. This will only close the
57 handles of mutexes which have been created, making it safe for use as a
58 cleanup routine even within the InitEntrypointMutexes routine above.
59 */
60 VOID
61 CleanupEntrypointMutexes()
62 {
63 UCHAR i;
64
65 /* Only clean up a mutex if it actually exists */
66 for ( i = 0; i < SOUND_DEVICE_TYPES; ++ i )
67 {
68 if ( EntrypointMutexes[i] )
69 {
70 CloseHandle(EntrypointMutexes[i]);
71 EntrypointMutexes[i] = NULL;
72 }
73 }
74 }
75
76 /*
77 Grabs an entry-point mutex.
78 */
79 VOID
80 AcquireEntrypointMutex(
81 IN MMDEVICE_TYPE DeviceType)
82 {
83 UCHAR i;
84
85 SND_ASSERT( IS_VALID_SOUND_DEVICE_TYPE(DeviceType) );
86 i = SOUND_DEVICE_TYPE_TO_INDEX(DeviceType);
87
88 SND_ASSERT( EntrypointMutexes[i] );
89
90 WaitForSingleObject(EntrypointMutexes[i], INFINITE);
91 }
92
93 /*
94 Releases an entry-point mutex.
95 */
96 VOID
97 ReleaseEntrypointMutex(
98 IN MMDEVICE_TYPE DeviceType)
99 {
100 UCHAR i;
101
102 SND_ASSERT( IS_VALID_SOUND_DEVICE_TYPE(DeviceType) );
103 i = SOUND_DEVICE_TYPE_TO_INDEX(DeviceType);
104
105 SND_ASSERT( EntrypointMutexes[i] );
106
107 ReleaseMutex(EntrypointMutexes[i]);
108 }