// Unit test for the keyed-mutex acquire decision behind SharedTextureSource::update() // (host/src/capture/keyed_mutex.hpp). The bug: AcquireSync returning WAIT_ABANDONED -- a prior owner // (e.g. a host that crashed mid-acquire) died holding the mutex, which GRANTS us ownership -- was // treated as failure, so the host skipped the frame AND never released, freezing the mirror forever. // The predicate must treat WAIT_ABANDONED as "acquired" (copy + release) while still rejecting the // real "didn't get it" cases. Deterministic; no D3D device. #include #include #include #include "capture/keyed_mutex.hpp" using namespace coop; namespace { int g_failures = 0; void check(bool ok, const char* what) { std::printf("%s %s\n", ok ? " ok:" : "FAIL:", what); if (!ok) { ++g_failures; } } } // namespace int main() { check(keyed_mutex_acquired(S_OK), "S_OK -> acquired (copy + release)"); check(keyed_mutex_acquired(static_cast(WAIT_ABANDONED)), "WAIT_ABANDONED -> acquired (recover: prior owner died holding it; we own it now)"); check(!keyed_mutex_acquired(static_cast(WAIT_TIMEOUT)), "WAIT_TIMEOUT -> not acquired (producer busy; skip this frame)"); check(!keyed_mutex_acquired(E_FAIL), "E_FAIL -> not acquired"); check(!keyed_mutex_acquired(DXGI_ERROR_DEVICE_REMOVED), "DEVICE_REMOVED -> not acquired"); std::printf(g_failures == 0 ? "PASS keyed_mutex_test\n" : "FAILED keyed_mutex_test (%d)\n", g_failures); return g_failures == 0 ? 0 : 1; }