dolphin/Source/Core
Dentomologist 3b97a7bded CubebStream: Use WorkQueueThread::PushBlocking instead of sync_event
Push and wait on WorkQueueThread items using PushBlocking. Previously we
created a Common::Event sync_event on the caller's stack, called Wait on
it, then had the WorkQueueThread call Set on the sync_event once the
thread was done.

In addition to being simpler the new way avoids a use-after-free that
could happen in convoluted and unlikely yet possible thread scheduling
sequences.

One such case can be triggered as follows:

* Set your audio backend to Cubeb
* In CubebStream::SetVolume set a breakpoint at the call to Wait and at
  the call to cubeb_stream_set_volume.
* Start a game.
* Continue until the Cubeb Worker thread hits the
  cubeb_stream_set_volume breakpoint and Emuthread hits the Wait
  breakpoint, freezing each thread when it hits its breakpoint.
* Unfreeze Cubeb Worker.
* In Event::Set set a breakpoint at the end of the scope containing the
  lock_guard such that the guard has been constructed but not destructed
  when the breakpoint is hit.
* Continue until that breakpoint is hit by Cubeb Worker. If other
  threads hit it first keep going.
* Freeze Cubeb Worker.
* For convenience remove the breakpoint in Event::Set so other threads
  don't trigger it.
* In CubebStream::SetRunning set a breakpoint at the call to Wait.
* Unfreeze Emuthread and continue until the breakpoint is hit.
* In Cubeb Worker go to Event::Set and examine the values of m_mutex's
  member variables. In Visual Studio Debug these are locking_thread_id
  == 0xcccccc01 and ownership_levels == 0xcccccccc. This is the result
  of Visual Studio overwriting the memory used on the stack by
  sync_event in CubebStream::SetVolume with cc bytes to represent
  uninitialized memory on the stack (since that function already
  returned), and then allocating enough memory on the stack when calling
  AudioCommon::SetSoundStreamRunning and then CubebStream::SetRunning
  that it overwrote one byte of the memory formerly occupied by
  locking_thread_id.
* If you unfreeze Cubeb Worker at this point it will trigger the lock
  guard's destructor which will then try to unlock m_mutex. Since
  m_mutex is no longer in scope this is a use-after-free, and in VS
  debug triggers a debug assert due to locking_thread_id not matching
  the current thread id.
2025-11-07 13:19:18 -08:00
..
AudioCommon CubebStream: Use WorkQueueThread::PushBlocking instead of sync_event 2025-11-07 13:19:18 -08:00
Common Merge pull request #14061 from jordan-woyak/config-info-spin-mutex 2025-11-04 14:09:35 -06:00
Core CubebStream: Use WorkQueueThread::PushBlocking instead of sync_event 2025-11-07 13:19:18 -08:00
DiscIO MMU: Use templates for Read/Write functions 2025-10-08 11:27:06 +02:00
DolphinNoGUI Visual Studio: Fix DolphinNoGUI build 2025-10-05 15:38:43 -07:00
DolphinQt Merge pull request #13626 from jordan-woyak/non-global-hookable-event 2025-11-04 13:57:08 -06:00
DolphinTool Externals / VideoCommon: update glslang to latest, turn into submodule 2025-09-23 23:45:38 -05:00
InputCommon Merge pull request #13963 from jordan-woyak/point-passthru-needs-bound-inputs 2025-10-09 14:05:16 -04:00
MacUpdater
UICommon Common: Make HookableEvent use non-static data. 2025-11-02 17:30:43 -06:00
UpdaterCommon
VideoBackends Merge pull request #14042 from iwubcode/bp_functions_global 2025-11-02 13:17:38 -05:00
VideoCommon Common: Make HookableEvent use non-static data. 2025-11-02 17:30:43 -06:00
WinUpdater
CMakeLists.txt
DolphinLib.ARM64.props
DolphinLib.props Common: Add AtomicMutex and SpinMutex classes as faster alternatives to std::mutex. 2025-11-02 20:45:55 -06:00
DolphinLib.vcxproj Core/HW: Add Broadband Adapter (IPC). 2025-10-28 18:50:59 +00:00
DolphinLib.vcxproj.user
DolphinLib.x64.props
VersionInfo.plist.in