ReactOS 0.4.15-dev-7906-g1b85a5f
thread.c File Reference
#include "precomp.h"
Include dependency graph for thread.c:

Go to the source code of this file.

Functions

DWORD WINAPI SoundThreadMain (IN LPVOID lpParameter OPTIONAL)
 
MMRESULT CallSoundThread (IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN SOUND_THREAD_REQUEST_HANDLER RequestHandler, IN PVOID Parameter OPTIONAL)
 
MMRESULT SoundThreadTerminator (IN PSOUND_DEVICE_INSTANCE Instance, IN PVOID Parameter)
 
MMRESULT TerminateSoundThread (IN PSOUND_THREAD Thread)
 
MMRESULT CreateSoundThreadEvents (OUT HANDLE *ReadyEvent, OUT HANDLE *RequestEvent, OUT HANDLE *DoneEvent)
 
MMRESULT DestroySoundThreadEvents (IN HANDLE ReadyEvent, IN HANDLE RequestEvent, IN HANDLE DoneEvent)
 
MMRESULT CreateSoundThread (OUT PSOUND_THREAD *Thread)
 
MMRESULT DestroySoundThread (IN PSOUND_THREAD Thread)
 

Function Documentation

◆ CallSoundThread()

MMRESULT CallSoundThread ( IN PSOUND_DEVICE_INSTANCE  SoundDeviceInstance,
IN SOUND_THREAD_REQUEST_HANDLER  RequestHandler,
IN PVOID Parameter  OPTIONAL 
)

Definition at line 71 of file thread.c.

75{
77
80
81 Thread = SoundDeviceInstance->Thread;
82
83 SND_TRACE(L"Waiting for READY event\n");
84 WaitForSingleObject(Thread->Events.Ready, INFINITE);
85
86 Thread->Request.Result = MMSYSERR_NOTSUPPORTED;
87 Thread->Request.Handler = RequestHandler;
88 Thread->Request.SoundDeviceInstance = SoundDeviceInstance;
89 Thread->Request.Parameter = Parameter;
90
91 /* Notify the thread it has work to do */
92 SND_TRACE(L"Setting REQUEST event\n");
93 SetEvent(Thread->Events.Request);
94
95 /* Wait for the work to be done */
96 SND_TRACE(L"Waiting for DONE event\n");
97 WaitForSingleObject(Thread->Events.Done, INFINITE);
98
99 return Thread->Request.Result;
100}
#define INFINITE
Definition: serial.h:102
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define VALIDATE_MMSYS_PARAMETER(parameter_condition)
Definition: mmebuddy.h:71
BOOLEAN IsValidSoundDeviceInstance(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
#define SND_TRACE(...)
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
#define L(x)
Definition: ntvdm.h:50
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323

Referenced by StopStreaming(), WaveActivateSoundStreaming(), WaveHeaderOperation(), and WriteWaveHeader().

◆ CreateSoundThread()

MMRESULT CreateSoundThread ( OUT PSOUND_THREAD Thread)

Definition at line 209 of file thread.c.

211{
213 PSOUND_THREAD NewThread;
214
216
217 NewThread = AllocateStruct(SOUND_THREAD);
218 if ( ! NewThread )
219 return MMSYSERR_NOMEM;
220
221 /* Prepare the events we'll be using to sync. everything */
222 Result = CreateSoundThreadEvents(&NewThread->Events.Ready,
223 &NewThread->Events.Request,
224 &NewThread->Events.Done);
225
226 if ( ! MMSUCCESS(Result) )
227 {
228 FreeMemory(NewThread);
230 }
231
232 SND_TRACE(L"Creating a sound thread\n");
233 NewThread->Handle = CreateThread(NULL,
234 0,
236 (LPVOID) NewThread,
238 NULL);
239
240 /* Something went wrong, bail out! */
241 if ( NewThread->Handle == INVALID_HANDLE_VALUE )
242 {
243 SND_ERR(L"Sound thread creation failed!\n");
244 DestroySoundThreadEvents(NewThread->Events.Ready,
245 NewThread->Events.Request,
246 NewThread->Events.Done);
247
248 FreeMemory(NewThread);
249
251 }
252
253 /* Wake the thread up */
254 if ( ResumeThread(NewThread->Handle) == -1 )
255 {
256 SND_ERR(L"Failed to resume thread!\n");
257 CloseHandle(NewThread->Handle);
258 DestroySoundThreadEvents(NewThread->Events.Ready,
259 NewThread->Events.Request,
260 NewThread->Events.Done);
261
262 FreeMemory(NewThread);
264 }
265
266 /* If all is well we can now give the thread to the caller */
267 *Thread = NewThread;
268 return MMSYSERR_NOERROR;
269}
static VOID FreeMemory(PCREATE_DATA Data)
Definition: create.c:134
#define NULL
Definition: types.h:112
#define CloseHandle
Definition: compat.h:739
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:567
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
#define AllocateStruct(thing)
Definition: mmebuddy.h:27
MMRESULT TranslateInternalMmResult(IN MMRESULT Result)
Definition: utility.c:132
#define MMSUCCESS(result)
Definition: mmebuddy.h:80
MMRESULT Win32ErrorToMmResult(IN UINT ErrorCode)
Definition: utility.c:87
#define SND_ERR(...)
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
UINT MMRESULT
Definition: mmsystem.h:962
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
DWORD WINAPI SoundThreadMain(IN LPVOID lpParameter OPTIONAL)
Definition: thread.c:14
MMRESULT DestroySoundThreadEvents(IN HANDLE ReadyEvent, IN HANDLE RequestEvent, IN HANDLE DoneEvent)
Definition: thread.c:190
MMRESULT CreateSoundThreadEvents(OUT HANDLE *ReadyEvent, OUT HANDLE *RequestEvent, OUT HANDLE *DoneEvent)
Definition: thread.c:151
HANDLE Handle
Definition: mmebuddy.h:237
struct _SOUND_THREAD::@3474 Events
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CREATE_SUSPENDED
Definition: winbase.h:178
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by CreateSoundDeviceInstance().

◆ CreateSoundThreadEvents()

MMRESULT CreateSoundThreadEvents ( OUT HANDLE ReadyEvent,
OUT HANDLE RequestEvent,
OUT HANDLE DoneEvent 
)

Definition at line 151 of file thread.c.

155{
156 BOOL ok;
157
158 VALIDATE_MMSYS_PARAMETER( ReadyEvent );
159 VALIDATE_MMSYS_PARAMETER( RequestEvent );
160 VALIDATE_MMSYS_PARAMETER( DoneEvent );
161
162 SND_TRACE(L"Creating thread events\n");
163
164 /* Initialise these so we can identify them upon failure */
165 *ReadyEvent = *RequestEvent = *DoneEvent = INVALID_HANDLE_VALUE;
166
167 ok = (*ReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) != INVALID_HANDLE_VALUE;
168 ok &= (*RequestEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) != INVALID_HANDLE_VALUE;
169 ok &= (*DoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) != INVALID_HANDLE_VALUE;
170
171 /* If something went wrong, clean up */
172 if ( ! ok )
173 {
174 if ( *ReadyEvent != INVALID_HANDLE_VALUE )
175 CloseHandle(*ReadyEvent);
176
177 if ( *RequestEvent != INVALID_HANDLE_VALUE )
178 CloseHandle(*RequestEvent);
179
180 if ( *DoneEvent != INVALID_HANDLE_VALUE )
181 CloseHandle(*DoneEvent);
182
183 return MMSYSERR_NOMEM;
184 }
185
186 return MMSYSERR_NOERROR;
187}
#define ok(value,...)
Definition: atltest.h:57
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define CreateEvent
Definition: winbase.h:3748

Referenced by CreateSoundThread().

◆ DestroySoundThread()

MMRESULT DestroySoundThread ( IN PSOUND_THREAD  Thread)

Definition at line 272 of file thread.c.

274{
277
278 SND_TRACE(L"Terminating sound thread\n");
279
280 /* Tell the thread to terminate itself */
282
283 SND_TRACE(L"Sound thread terminated, performing cleanup of thread resources\n");
284
285 CloseHandle(Thread->Handle); /* Is this needed? */
287
288 DestroySoundThreadEvents(Thread->Events.Ready,
289 Thread->Events.Request,
290 Thread->Events.Done);
291
292 /* Wipe and free the memory used for the thread */
295
296 SND_TRACE(L"Finished thread cleanup\n");
297
298 return MMSYSERR_NOERROR;
299}
#define SND_ASSERT(condition)
MMRESULT TerminateSoundThread(IN PSOUND_THREAD Thread)
Definition: thread.c:119
#define ZeroMemory
Definition: winbase.h:1712

Referenced by DestroySoundDeviceInstance().

◆ DestroySoundThreadEvents()

MMRESULT DestroySoundThreadEvents ( IN HANDLE  ReadyEvent,
IN HANDLE  RequestEvent,
IN HANDLE  DoneEvent 
)

Definition at line 190 of file thread.c.

194{
198
199 SND_TRACE(L"Destroying thread events\n");
200
201 CloseHandle(ReadyEvent);
202 CloseHandle(RequestEvent);
203 CloseHandle(DoneEvent);
204
205 return MMSYSERR_NOERROR;
206}

Referenced by CreateSoundThread(), and DestroySoundThread().

◆ SoundThreadMain()

DWORD WINAPI SoundThreadMain ( IN LPVOID lpParameter  OPTIONAL)

Definition at line 14 of file thread.c.

16{
17 PSOUND_THREAD Thread = (PSOUND_THREAD) lpParameter;
18
19 SND_TRACE(L"SoundThread running :)\n");
20
21 /* Callers will wait for us to be ready */
22 Thread->Running = TRUE;
23 SetEvent(Thread->Events.Ready);
24
25 while ( Thread->Running )
26 {
27 DWORD WaitResult;
28
29 /* Wait for a request, or an I/O completion */
30 WaitResult = WaitForSingleObjectEx(Thread->Events.Request, INFINITE, TRUE);
31 SND_TRACE(L"SoundThread - Came out of waiting\n");
32
33 if ( WaitResult == WAIT_OBJECT_0 )
34 {
35 SND_TRACE(L"SoundThread - Processing request\n");
36
37 if ( Thread->Request.Handler )
38 {
39 Thread->Request.Result = Thread->Request.Handler(Thread->Request.SoundDeviceInstance,
40 Thread->Request.Parameter);
41 }
42 else
43 {
44 Thread->Request.Result = MMSYSERR_ERROR;
45 }
46
47 /* Announce completion of the request */
48 SetEvent(Thread->Events.Done);
49 /* Accept new requests */
50 SetEvent(Thread->Events.Ready);
51 }
52 else if ( WaitResult == WAIT_IO_COMPLETION )
53 {
54 SND_TRACE(L"SoundThread - Processing IO completion\n");
55 /* TODO? What do we do here? Stream stuff? */
56 }
57 else
58 {
59 /* This should not happen! */
61 }
62
63 }
64
65 SND_TRACE(L"Sound thread terminated\n");
66
67 return 0;
68}
#define TRUE
Definition: types.h:120
unsigned long DWORD
Definition: ntddk_ex.h:95
struct _SOUND_THREAD * PSOUND_THREAD
#define MMSYSERR_ERROR
Definition: mmsystem.h:97
DWORD WINAPI WaitForSingleObjectEx(IN HANDLE hHandle, IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:94
#define WAIT_IO_COMPLETION
Definition: winbase.h:411
#define WAIT_OBJECT_0
Definition: winbase.h:406

Referenced by CreateSoundThread().

◆ SoundThreadTerminator()

MMRESULT SoundThreadTerminator ( IN PSOUND_DEVICE_INSTANCE  Instance,
IN PVOID  Parameter 
)

Definition at line 104 of file thread.c.

107{
109
110 SND_TRACE(L"Sound thread terminator routine called\n");
112
113 Thread->Running = FALSE;
114
115 return MMSYSERR_NOERROR;
116}

Referenced by TerminateSoundThread().

◆ TerminateSoundThread()

MMRESULT TerminateSoundThread ( IN PSOUND_THREAD  Thread)

Definition at line 119 of file thread.c.

121{
122 DWORD WaitResult;
123
125
126 SND_TRACE(L"Waiting for READY event\n");
127 WaitForSingleObject(Thread->Events.Ready, INFINITE);
128
129 Thread->Request.Result = MMSYSERR_NOTSUPPORTED;
130 Thread->Request.Handler = SoundThreadTerminator;
131 Thread->Request.SoundDeviceInstance = NULL;
132 Thread->Request.Parameter = (PVOID) Thread;
133
134 /* Notify the thread it has work to do */
135 SND_TRACE(L"Setting REQUEST event\n");
136 SetEvent(Thread->Events.Request);
137
138 /* Wait for the work to be done */
139 SND_TRACE(L"Waiting for DONE event\n");
140 WaitForSingleObject(Thread->Events.Done, INFINITE);
141
142 /* Wait for the thread to actually end */
143 WaitResult = WaitForSingleObject(Thread->Handle, INFINITE);
144 SND_ASSERT( WaitResult == WAIT_OBJECT_0 );
145
146 return MMSYSERR_NOERROR;
147}
MMRESULT SoundThreadTerminator(IN PSOUND_DEVICE_INSTANCE Instance, IN PVOID Parameter)
Definition: thread.c:104
void * PVOID
Definition: typedefs.h:50

Referenced by DestroySoundThread().