[Bug 28464] New: winmm causes DSOUND_callback Wave queue corrupted

wine-bugs at winehq.org wine-bugs at winehq.org
Wed Sep 21 19:54:24 CDT 2011


http://bugs.winehq.org/show_bug.cgi?id=28464

           Summary: winmm causes DSOUND_callback Wave queue corrupted
           Product: Wine
           Version: 1.3.25
          Platform: x86
        OS/Version: All
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: winmm&mci
        AssignedTo: wine-bugs at winehq.org
        ReportedBy: hoehle at users.sourceforge.net


WHDR_DONE should only be set immediately before invoking the DriverCallback,
because some apps poll for that flag and don't depend on notifications or
callbacks.

WOD_MarkDoneHeaders must find another way to isolate done headers.

Because the queue of done headers is not isolated properly,
attachment #36494 to bug #28056
exhibits a log (around line 4250) where 2 threads, namely the app calling
waveOutWrite and the winmm feeder thread both grab the same list and send the
same notifications.

0034:trace:driver:DriverCallback (, 32bit function 0003,, 03BD,, 017D3A90,
00000000)
0036:trace:winmm:WINMM_BeginPlaying ...
0036:trace:oss:AudioRenderClient_ReleaseBuffer (0x17d34f0)->(512, 0)
0034:trace:driver:DriverCallback (, 32bit function 0003,, 03BD,, 017D3AB0,
00000000)
0034:trace:driver:DriverCallback (, 32bit function 0003,, 03BD,, 017D3AD0,
00000000)
0034:trace:winmm:WOD_PushData (0xc000)
0036:trace:driver:DriverCallback (, 32bit function 0003,, 03BD,, 017D3AB0,
00000000)
0036:trace:driver:DriverCallback (, 32bit function 0003,, 03BD,, 017D3AD0,
00000000)

What happens is that the first thread removes the first header from
device>first. At the time the second thread kicks in, apparently more headers
are marked done. But since they are all part of the same linked queue, the
later ones trigger 2 notifications each.

err:dsound:DSOUND_callback Wave queue corrupted!
is the result of getting notifications twice.

Nice race condition!

BTW, but that's another issue, the code says "NotifyClient should never be
called while holding the device lock". However that's exactly what can happen
via waveOutWrite -> WINMM_ValidateAndLock -> WINMM_BeginPlaying -> WOD_PushData
-> NotifyClient.
I suggest a per device slot updated via InterlockedExchangePointer holding the
queue of pending notifications. The top-level wave* commands (and the winmm
feeder thread too) would then drain that queue. (The feeder thread could even
delegate that to another (timer?) thread.) Alternatively, Push/PullData return
that queue.

-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
Do not reply to this email, post in Bugzilla using the
above URL to reply.
------- You are receiving this mail because: -------
You are watching all bug changes.



More information about the wine-bugs mailing list