Read/write the cross-process diagnostic counters atomically
present_calls, frames_dropped (VideoShare) and frames_rendered (AudioStreamInfo) were plain `+= 1` / stores in the DLL, read by the host cross-process. On an x86 DLL a 64-bit store is two halves, so the x64 host could read a torn value during a carry. Benign (display-only), but a real data race. Use std::atomic_ref at the access sites rather than changing the field types: the structs stay plain POD so the layout/offset asserts are unchanged and AudioStreamInfo stays trivially copyable (it's published/read as a whole struct). The DLL writers (note_present / note_video_dropped / note_audio_frames) and the host readers (IpcServer::video_share / hook_status) now use relaxed atomic_ref; hook_status reloads frames_rendered atomically after the wholesale struct copy. The dev-tool readers (vk_validate, audio_probe) keep plain reads -- diagnostics of diagnostics, and same-bitness in practice. Validated by present_hook_test (present_calls via atomic_ref) and audio_hook_test (frames_rendered) -- also confirms no atomic_ref alignment fault. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -200,7 +200,10 @@ public:
|
||||
{
|
||||
if (block_ != nullptr && slot < kMaxAudioStreams)
|
||||
{
|
||||
block_->status.audio_streams[slot].frames_rendered = frames;
|
||||
// atomic_ref so the host's cross-process read isn't torn (notably an x86 DLL -> x64 host,
|
||||
// where a plain 64-bit store is two halves). The field stays plain POD so AudioStreamInfo
|
||||
// remains trivially copyable for the wholesale publishes elsewhere.
|
||||
std::atomic_ref(block_->status.audio_streams[slot].frames_rendered).store(frames, std::memory_order_relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +214,7 @@ public:
|
||||
{
|
||||
if (block_ != nullptr)
|
||||
{
|
||||
block_->video.present_calls += 1;
|
||||
std::atomic_ref(block_->video.present_calls).fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +224,7 @@ public:
|
||||
{
|
||||
if (block_ != nullptr)
|
||||
{
|
||||
block_->video.frames_dropped += 1;
|
||||
std::atomic_ref(block_->video.frames_dropped).fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user