winmm/tests: Demonstrate that WOM_DONE is not invoked reentrantly.
Signed-off-by: Andrew Eikum <aeikum@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e385df7d2e
commit
bf65b96b01
|
@ -1626,6 +1626,108 @@ static void test_fragmentsize(void)
|
||||||
CloseHandle(hevent);
|
CloseHandle(hevent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CALLBACK test_reentrant_callback_func(HWAVEOUT hwo, UINT uMsg,
|
||||||
|
DWORD_PTR dwInstance,
|
||||||
|
DWORD_PTR dwParam1, DWORD_PTR dwParam2)
|
||||||
|
{
|
||||||
|
static int wom_done_count = 0;
|
||||||
|
|
||||||
|
switch(uMsg){
|
||||||
|
case WOM_OPEN:
|
||||||
|
case WOM_CLOSE:
|
||||||
|
ok(GetCurrentThreadId() == g_tid, "Got different thread ID\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WOM_DONE:
|
||||||
|
/* verify that WOM_DONE is not sent during the following waveOutWrite */
|
||||||
|
todo_wine_if(wom_done_count == 1)
|
||||||
|
ok(g_tid == 0, "callback called reentrantly\n");
|
||||||
|
|
||||||
|
g_tid = GetCurrentThreadId();
|
||||||
|
|
||||||
|
if(wom_done_count++ == 0){
|
||||||
|
Sleep(125); /* ensure 2nd header is done playing before waveOutWrite */
|
||||||
|
waveOutWrite(hwo, (WAVEHDR *)dwParam1, sizeof(WAVEHDR));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_tid = 0;
|
||||||
|
SetEvent((HANDLE)dwInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_reentrant_callback(void)
|
||||||
|
{
|
||||||
|
MMRESULT rc;
|
||||||
|
WAVEHDR hdr[2];
|
||||||
|
HWAVEOUT wout;
|
||||||
|
WAVEFORMATEX fmt;
|
||||||
|
DWORD wait;
|
||||||
|
HANDLE hevent;
|
||||||
|
|
||||||
|
if(waveOutGetNumDevs() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fmt.wFormatTag = WAVE_FORMAT_PCM;
|
||||||
|
fmt.nChannels = 2;
|
||||||
|
fmt.nSamplesPerSec = 44100;
|
||||||
|
fmt.wBitsPerSample = 16;
|
||||||
|
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
|
||||||
|
fmt.nAvgBytesPerSec = fmt.nBlockAlign * fmt.nSamplesPerSec;
|
||||||
|
fmt.cbSize = sizeof(WAVEFORMATEX);
|
||||||
|
|
||||||
|
hevent = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||||
|
g_tid = GetCurrentThreadId();
|
||||||
|
|
||||||
|
rc = waveOutOpen(&wout, WAVE_MAPPER, &fmt, (DWORD_PTR)test_reentrant_callback_func,
|
||||||
|
(DWORD_PTR)hevent, CALLBACK_FUNCTION);
|
||||||
|
ok(rc == MMSYSERR_NOERROR || rc == WAVERR_BADFORMAT ||
|
||||||
|
rc == MMSYSERR_INVALFLAG || rc == MMSYSERR_INVALPARAM,
|
||||||
|
"waveOutOpen(%s) failed: %s\n", dev_name(WAVE_MAPPER), wave_out_error(rc));
|
||||||
|
if(rc != MMSYSERR_NOERROR){
|
||||||
|
CloseHandle(hevent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wait = WaitForSingleObject(hevent, 1000);
|
||||||
|
ok(wait == WAIT_OBJECT_0, "wave open callback missed\n");
|
||||||
|
|
||||||
|
memset(hdr, 0, sizeof(hdr));
|
||||||
|
hdr[0].dwBufferLength = (fmt.nSamplesPerSec * fmt.nBlockAlign / 10);
|
||||||
|
hdr[1].dwBufferLength = hdr[0].dwBufferLength;
|
||||||
|
hdr[1].lpData = hdr[0].lpData =
|
||||||
|
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, hdr[0].dwBufferLength);
|
||||||
|
|
||||||
|
rc = waveOutPrepareHeader(wout, &hdr[0], sizeof(hdr[0]));
|
||||||
|
ok(rc == MMSYSERR_NOERROR, "waveOutPrepareHeader failed: %s\n", wave_out_error(rc));
|
||||||
|
|
||||||
|
rc = waveOutPrepareHeader(wout, &hdr[1], sizeof(hdr[1]));
|
||||||
|
ok(rc == MMSYSERR_NOERROR, "waveOutPrepareHeader failed: %s\n", wave_out_error(rc));
|
||||||
|
|
||||||
|
rc = waveOutWrite(wout, &hdr[0], sizeof(hdr[0]));
|
||||||
|
ok(rc == MMSYSERR_NOERROR, "waveOutWrite failed: %s\n", wave_out_error(rc));
|
||||||
|
|
||||||
|
rc = waveOutWrite(wout, &hdr[1], sizeof(hdr[1]));
|
||||||
|
ok(rc == MMSYSERR_NOERROR, "waveOutWrite failed: %s\n", wave_out_error(rc));
|
||||||
|
|
||||||
|
wait = WaitForSingleObject(hevent, 1000);
|
||||||
|
ok(wait == WAIT_OBJECT_0, "header 1 callback missed\n");
|
||||||
|
|
||||||
|
wait = WaitForSingleObject(hevent, 1000);
|
||||||
|
ok(wait == WAIT_OBJECT_0, "header 2 callback missed\n");
|
||||||
|
|
||||||
|
wait = WaitForSingleObject(hevent, 1000);
|
||||||
|
ok(wait == WAIT_OBJECT_0, "header 3 callback missed\n");
|
||||||
|
|
||||||
|
g_tid = GetCurrentThreadId();
|
||||||
|
rc = waveOutClose(wout);
|
||||||
|
ok(rc == MMSYSERR_NOERROR, "waveOutClose failed: %s\n", wave_out_error(rc));
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, hdr[0].lpData);
|
||||||
|
CloseHandle(hevent);
|
||||||
|
}
|
||||||
|
|
||||||
static void create_wav_file(char *temp_file)
|
static void create_wav_file(char *temp_file)
|
||||||
{
|
{
|
||||||
WAVEFORMATEX format;
|
WAVEFORMATEX format;
|
||||||
|
@ -1727,5 +1829,6 @@ START_TEST(wave)
|
||||||
wave_out_tests();
|
wave_out_tests();
|
||||||
test_sndPlaySound();
|
test_sndPlaySound();
|
||||||
test_fragmentsize();
|
test_fragmentsize();
|
||||||
|
test_reentrant_callback();
|
||||||
test_PlaySound();
|
test_PlaySound();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue