diff --git a/idd/LGCommon/CPipeEndpoint.cpp b/idd/LGCommon/CPipeEndpoint.cpp index dee5a9dc..b8290b79 100644 --- a/idd/LGCommon/CPipeEndpoint.cpp +++ b/idd/LGCommon/CPipeEndpoint.cpp @@ -224,13 +224,14 @@ bool CPipeEndpoint::Start( DEBUG_ERROR_HR(GetLastError(), "Failed to create named pipe thread"); m_running.store(false); - AcquireSRWLockExclusive(&m_pipeLock); - if (m_pipe != INVALID_HANDLE_VALUE) { - CloseHandle(m_pipe); - m_pipe = INVALID_HANDLE_VALUE; + CSRWExclusiveLock lock(m_pipeLock); + if (m_pipe != INVALID_HANDLE_VALUE) + { + CloseHandle(m_pipe); + m_pipe = INVALID_HANDLE_VALUE; + } } - ReleaseSRWLockExclusive(&m_pipeLock); CloseHandle(m_stopEvent); m_stopEvent = nullptr; @@ -249,10 +250,11 @@ void CPipeEndpoint::Stop() if (m_stopEvent) SetEvent(m_stopEvent); - AcquireSRWLockShared(&m_pipeLock); - if (m_pipe != INVALID_HANDLE_VALUE) - CancelIoEx(m_pipe, nullptr); - ReleaseSRWLockShared(&m_pipeLock); + { + CSRWSharedLock lock(m_pipeLock); + if (m_pipe != INVALID_HANDLE_VALUE) + CancelIoEx(m_pipe, nullptr); + } if (m_thread) { @@ -261,13 +263,14 @@ void CPipeEndpoint::Stop() m_thread = nullptr; } - AcquireSRWLockExclusive(&m_pipeLock); - if (m_pipe != INVALID_HANDLE_VALUE) { - CloseHandle(m_pipe); - m_pipe = INVALID_HANDLE_VALUE; + CSRWExclusiveLock lock(m_pipeLock); + if (m_pipe != INVALID_HANDLE_VALUE) + { + CloseHandle(m_pipe); + m_pipe = INVALID_HANDLE_VALUE; + } } - ReleaseSRWLockExclusive(&m_pipeLock); if (m_stopEvent) { @@ -290,7 +293,7 @@ bool CPipeEndpoint::Send(const void * message, size_t size) return false; bool success = false; - AcquireSRWLockExclusive(&m_pipeLock); + CSRWExclusiveLock lock(m_pipeLock); if (m_pipe != INVALID_HANDLE_VALUE && IsConnected()) { const PipeIoResult result = WriteMessage( @@ -304,7 +307,6 @@ bool CPipeEndpoint::Send(const void * message, size_t size) CancelIoEx(m_pipe, nullptr); } } - ReleaseSRWLockExclusive(&m_pipeLock); return success; } @@ -350,18 +352,21 @@ void CPipeEndpoint::RunServer() if (!ioEvent) { DEBUG_ERROR_HR(GetLastError(), "Failed to create named pipe I/O event"); - AcquireSRWLockShared(&m_pipeLock); - const HANDLE pipe = m_pipe; - ReleaseSRWLockShared(&m_pipeLock); + HANDLE pipe; + { + CSRWSharedLock lock(m_pipeLock); + pipe = m_pipe; + } if (pipe != INVALID_HANDLE_VALUE) ClosePipe(pipe); return; } HANDLE pipe = INVALID_HANDLE_VALUE; - AcquireSRWLockShared(&m_pipeLock); - pipe = m_pipe; - ReleaseSRWLockShared(&m_pipeLock); + { + CSRWSharedLock lock(m_pipeLock); + pipe = m_pipe; + } while (IsRunning()) { @@ -581,16 +586,14 @@ bool CPipeEndpoint::WaitForRetry(DWORD delayMs) void CPipeEndpoint::PublishPipe(HANDLE pipe) { - AcquireSRWLockExclusive(&m_pipeLock); + CSRWExclusiveLock lock(m_pipeLock); m_pipe = pipe; - ReleaseSRWLockExclusive(&m_pipeLock); } void CPipeEndpoint::ClosePipe(HANDLE pipe) { - AcquireSRWLockExclusive(&m_pipeLock); + CSRWExclusiveLock lock(m_pipeLock); if (m_pipe == pipe) m_pipe = INVALID_HANDLE_VALUE; CloseHandle(pipe); - ReleaseSRWLockExclusive(&m_pipeLock); } diff --git a/idd/LGCommon/CPipeEndpoint.h b/idd/LGCommon/CPipeEndpoint.h index 409d6768..761cf24f 100644 --- a/idd/LGCommon/CPipeEndpoint.h +++ b/idd/LGCommon/CPipeEndpoint.h @@ -20,6 +20,8 @@ #pragma once +#include "CSRWLock.h" + #include #include @@ -124,7 +126,7 @@ private: std::atomic m_running { false }; std::atomic m_connected { false }; - SRWLOCK m_pipeLock = SRWLOCK_INIT; + CSRWLock m_pipeLock; HANDLE m_pipe = INVALID_HANDLE_VALUE; HANDLE m_thread = nullptr; HANDLE m_stopEvent = nullptr; diff --git a/idd/LGCommon/CSRWLock.h b/idd/LGCommon/CSRWLock.h index 8eaabeec..42eb0ad8 100644 --- a/idd/LGCommon/CSRWLock.h +++ b/idd/LGCommon/CSRWLock.h @@ -22,42 +22,110 @@ #include +class CSRWSharedLock; +class CSRWExclusiveLock; + +class CSRWLock +{ +private: + friend class CSRWSharedLock; + friend class CSRWExclusiveLock; + + SRWLOCK m_lock = SRWLOCK_INIT; + +public: + CSRWLock() = default; + + CSRWLock(const CSRWLock&) = delete; + CSRWLock& operator=(const CSRWLock&) = delete; +}; + class CSRWSharedLock { private: SRWLOCK * m_lock; public: - explicit CSRWSharedLock(SRWLOCK * lock) : m_lock(lock) + explicit CSRWSharedLock(CSRWLock& lock) : m_lock(&lock.m_lock) { AcquireSRWLockShared(m_lock); } ~CSRWSharedLock() { + Unlock(); + } + + void Unlock() + { + if (!m_lock) + return; + ReleaseSRWLockShared(m_lock); + m_lock = nullptr; } CSRWSharedLock(const CSRWSharedLock&) = delete; CSRWSharedLock& operator=(const CSRWSharedLock&) = delete; + + CSRWSharedLock(CSRWSharedLock&& other) noexcept : m_lock(other.m_lock) + { + other.m_lock = nullptr; + } + + CSRWSharedLock& operator=(CSRWSharedLock&&) = delete; }; class CSRWExclusiveLock { private: + struct TryTag {}; + SRWLOCK * m_lock; + CSRWExclusiveLock(CSRWLock& lock, TryTag) : + m_lock(TryAcquireSRWLockExclusive(&lock.m_lock) ? &lock.m_lock : nullptr) + { + } + public: - explicit CSRWExclusiveLock(SRWLOCK * lock) : m_lock(lock) + explicit CSRWExclusiveLock(CSRWLock& lock) : m_lock(&lock.m_lock) { AcquireSRWLockExclusive(m_lock); } ~CSRWExclusiveLock() { + Unlock(); + } + + static CSRWExclusiveLock Try(CSRWLock& lock) + { + return CSRWExclusiveLock(lock, TryTag {}); + } + + explicit operator bool() const + { + return m_lock != nullptr; + } + + void Unlock() + { + if (!m_lock) + return; + ReleaseSRWLockExclusive(m_lock); + m_lock = nullptr; } CSRWExclusiveLock(const CSRWExclusiveLock&) = delete; CSRWExclusiveLock& operator=(const CSRWExclusiveLock&) = delete; + + CSRWExclusiveLock(CSRWExclusiveLock&& other) noexcept : + m_lock(other.m_lock) + { + other.m_lock = nullptr; + } + + CSRWExclusiveLock& operator=(CSRWExclusiveLock&&) = delete; }; diff --git a/idd/LGIdd/capture/CFrameProcessor.cpp b/idd/LGIdd/capture/CFrameProcessor.cpp index bbce75f5..6348b5d0 100644 --- a/idd/LGIdd/capture/CFrameProcessor.cpp +++ b/idd/LGIdd/capture/CFrameProcessor.cpp @@ -30,7 +30,7 @@ CFrameProcessor::CFrameProcessor(IFrameTransport * transport, std::shared_ptr dx12, CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS], - SRWLOCK * pipelineLock, HANDLE terminateEvent) : + CSRWLock * pipelineLock, HANDLE terminateEvent) : m_transport(transport), m_dx12(std::move(dx12)), m_postProcessors(postProcessors), @@ -53,12 +53,11 @@ void CFrameProcessor::Reset() void CFrameProcessor::Invalidate() { - AcquireSRWLockExclusive(&m_damageLock); + CSRWExclusiveLock lock(m_damageLock); m_previousDamageCount = 0; m_hasPendingDamage = true; m_pendingDamageCount = 0; SetFullDamageLocked(); - ReleaseSRWLockExclusive(&m_damageLock); } void CFrameProcessor::ResetPipeline() @@ -69,21 +68,19 @@ void CFrameProcessor::ResetPipeline() void CFrameProcessor::AccumulateDamage( const RECT dirtyRects[], unsigned count) { - AcquireSRWLockExclusive(&m_damageLock); + CSRWExclusiveLock lock(m_damageLock); CFrameProcessorUtil::AccumulateDamage( m_pendingDamage, &m_pendingDamageCount, &m_hasPendingDamage, dirtyRects, count); AccumulateDamageLocked(dirtyRects, count); - ReleaseSRWLockExclusive(&m_damageLock); } void CFrameProcessor::SetFullDamage() { - AcquireSRWLockExclusive(&m_damageLock); + CSRWExclusiveLock lock(m_damageLock); m_hasPendingDamage = true; m_pendingDamageCount = 0; SetFullDamageLocked(); - ReleaseSRWLockExclusive(&m_damageLock); } void CFrameProcessor::AccumulateDamageLocked( @@ -97,16 +94,15 @@ void CFrameProcessor::SetFullDamageLocked() bool CFrameProcessor::HasPendingDamage() const { - AcquireSRWLockShared(&m_damageLock); + CSRWSharedLock lock(m_damageLock); const bool result = m_hasPendingDamage; - ReleaseSRWLockShared(&m_damageLock); return result; } bool CFrameProcessor::TakePendingDamage( RECT dirtyRects[], unsigned * count) { - AcquireSRWLockExclusive(&m_damageLock); + CSRWExclusiveLock lock(m_damageLock); const bool hasDamage = m_hasPendingDamage; *count = hasDamage ? m_pendingDamageCount : 0; if (*count) @@ -114,7 +110,6 @@ bool CFrameProcessor::TakePendingDamage( *count * sizeof(*dirtyRects)); m_hasPendingDamage = false; m_pendingDamageCount = 0; - ReleaseSRWLockExclusive(&m_damageLock); return hasDamage; } @@ -124,40 +119,37 @@ void CFrameProcessor::RestorePendingDamage( if (!hasDamage) return; - AcquireSRWLockExclusive(&m_damageLock); + CSRWExclusiveLock lock(m_damageLock); CFrameProcessorUtil::AccumulateDamage( m_pendingDamage, &m_pendingDamageCount, &m_hasPendingDamage, dirtyRects, count); - ReleaseSRWLockExclusive(&m_damageLock); } void CFrameProcessor::CommitDamage( const RECT dirtyRects[], unsigned count) { - AcquireSRWLockExclusive(&m_damageLock); + CSRWExclusiveLock lock(m_damageLock); m_previousDamageCount = count; if (count) memcpy(m_previousDamage, dirtyRects, count * sizeof(*m_previousDamage)); - ReleaseSRWLockExclusive(&m_damageLock); } void CFrameProcessor::GetPreviousDamage( RECT dirtyRects[], unsigned * count) const { - AcquireSRWLockShared(&m_damageLock); + CSRWSharedLock lock(m_damageLock); *count = m_previousDamageCount; if (*count) memcpy(dirtyRects, m_previousDamage, *count * sizeof(*dirtyRects)); - ReleaseSRWLockShared(&m_damageLock); } std::unique_ptr CreateFrameProcessor( bool software, IFrameTransport * transport, std::shared_ptr dx12, CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS], - SRWLOCK * pipelineLock, HANDLE terminateEvent) + CSRWLock * pipelineLock, HANDLE terminateEvent) { std::unique_ptr processor; if (software) diff --git a/idd/LGIdd/capture/CFrameProcessor.h b/idd/LGIdd/capture/CFrameProcessor.h index eb8afd40..5c1f3385 100644 --- a/idd/LGIdd/capture/CFrameProcessor.h +++ b/idd/LGIdd/capture/CFrameProcessor.h @@ -20,6 +20,7 @@ #pragma once +#include "CSRWLock.h" #include "d3d/CD3D12Device.h" #include "capture/CFrameBufferPool.h" #include "d3d/CInteropResource.h" @@ -51,17 +52,17 @@ protected: IFrameTransport * m_transport; std::shared_ptr m_dx12; CPostProcessor * m_postProcessors; - SRWLOCK * m_pipelineLock; + CSRWLock * m_pipelineLock; HANDLE m_terminateEvent; CFrameBufferPool m_frameBuffers; Wrappers::Event m_readyEvent; - mutable SRWLOCK m_damageLock = SRWLOCK_INIT; - RECT m_previousDamage[LG_MAX_DIRTY_RECTS] = {}; - unsigned m_previousDamageCount = 0; - RECT m_pendingDamage[LG_MAX_DIRTY_RECTS] = {}; - unsigned m_pendingDamageCount = 0; - bool m_hasPendingDamage = true; + mutable CSRWLock m_damageLock; + RECT m_previousDamage[LG_MAX_DIRTY_RECTS] = {}; + unsigned m_previousDamageCount = 0; + RECT m_pendingDamage[LG_MAX_DIRTY_RECTS] = {}; + unsigned m_pendingDamageCount = 0; + bool m_hasPendingDamage = true; bool HasPendingDamage() const; bool TakePendingDamage(RECT dirtyRects[], unsigned * count); @@ -77,7 +78,7 @@ public: CFrameProcessor(IFrameTransport * transport, std::shared_ptr dx12, CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS], - SRWLOCK * pipelineLock, HANDLE terminateEvent); + CSRWLock * pipelineLock, HANDLE terminateEvent); virtual ~CFrameProcessor() = default; virtual bool IsValid() const; @@ -99,4 +100,4 @@ std::unique_ptr CreateFrameProcessor( bool software, IFrameTransport * transport, std::shared_ptr dx12, CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS], - SRWLOCK * pipelineLock, HANDLE terminateEvent); + CSRWLock * pipelineLock, HANDLE terminateEvent); diff --git a/idd/LGIdd/capture/CFrameScheduler.cpp b/idd/LGIdd/capture/CFrameScheduler.cpp index b3c409fb..596a65bc 100644 --- a/idd/LGIdd/capture/CFrameScheduler.cpp +++ b/idd/LGIdd/capture/CFrameScheduler.cpp @@ -247,7 +247,7 @@ bool CFrameScheduler::ElectOwner(uint64_t now, uint32_t resetClientID) void CFrameScheduler::Reset() { - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); for (Client& client : m_clients) client = {}; m_schedule = {}; @@ -278,7 +278,7 @@ void CFrameScheduler::Reset() m_lastLogAcquired = 0; m_lastLogSkipped = 0; m_lastLogPublished = 0; - ReleaseSRWLockExclusive(&m_lock); + lock.Unlock(); WakePublisher(); } @@ -286,7 +286,7 @@ void CFrameScheduler::UpdateSubscribers(const uint32_t * clientIDs, unsigned count, const uint32_t * ownerClientIDs, unsigned ownerCount, uint64_t now) { - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); uint32_t oldClientIDs [MAX_CLIENTS] = {}; bool wasSubscribed [MAX_CLIENTS] = {}; @@ -343,7 +343,7 @@ void CFrameScheduler::UpdateSubscribers(const uint32_t * clientIDs, } const bool changed = ElectOwner(now) || subscribersChanged; - ReleaseSRWLockExclusive(&m_lock); + lock.Unlock(); if (changed) WakePublisher(); } @@ -363,7 +363,7 @@ bool CFrameScheduler::UpdateSchedule(uint32_t sourceClientID, if (schedule.flags & FRAME_SCHEDULE_RELEASE) { - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); Client * client = FindClient(schedule.clientID); bool wake = false; if (client) @@ -375,7 +375,7 @@ bool CFrameScheduler::UpdateSchedule(uint32_t sourceClientID, wake = true; wake |= ElectOwner(now); } - ReleaseSRWLockExclusive(&m_lock); + lock.Unlock(); if (wake) WakePublisher(); return true; @@ -390,14 +390,11 @@ bool CFrameScheduler::UpdateSchedule(uint32_t sourceClientID, schedule.lease < MIN_LEASE_MS || schedule.lease > MAX_LEASE_MS) return false; - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); Client * client = FindOrAllocateClient(schedule.clientID); if (!client) - { - ReleaseSRWLockExclusive(&m_lock); return false; - } const bool explicitReset = (schedule.flags & FRAME_SCHEDULE_RESET) != 0; @@ -432,7 +429,7 @@ bool CFrameScheduler::UpdateSchedule(uint32_t sourceClientID, wake = true; } wake |= ApplyFeedback(*client, schedule); - ReleaseSRWLockExclusive(&m_lock); + lock.Unlock(); if (wake) WakePublisher(); return true; @@ -555,18 +552,17 @@ void CFrameScheduler::AdvanceDelivery(Client& client, uint64_t now) bool CFrameScheduler::GetSchedule(Schedule& schedule) const { - AcquireSRWLockShared(&m_lock); + CSRWSharedLock lock(m_lock); const bool result = m_scheduling; if (result) schedule = m_schedule; - ReleaseSRWLockShared(&m_lock); return result; } void CFrameScheduler::ObserveFrame(uint64_t now) { bool wake = false; - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); ++m_acquiredFrames; if (m_lastArrival && now > m_lastArrival) { @@ -587,16 +583,17 @@ void CFrameScheduler::ObserveFrame(uint64_t now) } } m_lastArrival = now; - ReleaseSRWLockExclusive(&m_lock); + lock.Unlock(); if (wake) WakePublisher(); } void CFrameScheduler::ForceFrame() { - AcquireSRWLockExclusive(&m_lock); - ++m_forceRequestTicket; - ReleaseSRWLockExclusive(&m_lock); + { + CSRWExclusiveLock lock(m_lock); + ++m_forceRequestTicket; + } WakePublisher(); } @@ -607,12 +604,9 @@ bool CFrameScheduler::GetPublishTarget(uint64_t now, uint64_t& target, schedule = {}; periodic = false; republish = false; - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); if (!m_scheduling) - { - ReleaseSRWLockExclusive(&m_lock); return true; - } schedule = m_schedule; schedule.forceTicket = m_forceRequestTicket; @@ -634,7 +628,6 @@ bool CFrameScheduler::GetPublishTarget(uint64_t now, uint64_t& target, target = periodicTarget; schedule.deliveryDeadlineSerial = periodic ? m_deadlineSerial : 0; schedule.phaseEligible = periodic; - ReleaseSRWLockExclusive(&m_lock); return true; } @@ -642,7 +635,6 @@ bool CFrameScheduler::GetPublishTarget(uint64_t now, uint64_t& target, schedule.deliveryDeadlineSerial = m_deadlineSerial; schedule.phaseEligible = true; target = periodicTarget; - ReleaseSRWLockExclusive(&m_lock); return true; } @@ -652,7 +644,7 @@ void CFrameScheduler::FrameMissed(const Schedule& schedule, uint64_t now, if (!periodic) return; - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); if (m_scheduling && schedule.clientID == m_schedule.clientID && schedule.generation == m_schedule.generation && schedule.epoch == m_schedule.epoch && @@ -666,14 +658,12 @@ void CFrameScheduler::FrameMissed(const Schedule& schedule, uint64_t now, if (client) client->nextDelivery = m_nextDeadline; } - ReleaseSRWLockExclusive(&m_lock); } void CFrameScheduler::FrameSuperseded() { - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); ++m_skippedFrames; - ReleaseSRWLockExclusive(&m_lock); } bool CFrameScheduler::TryFrameSubmitted(const Schedule& schedule, @@ -683,7 +673,8 @@ bool CFrameScheduler::TryFrameSubmitted(const Schedule& schedule, schedule.deliveryDeadlineSerial != schedule.deadlineSerial) return false; - if (!TryAcquireSRWLockExclusive(&m_lock)) + auto lock = CSRWExclusiveLock::Try(m_lock); + if (!lock) return false; bool registered = false; @@ -704,14 +695,13 @@ bool CFrameScheduler::TryFrameSubmitted(const Schedule& schedule, publication.committed = true; registered = true; } - ReleaseSRWLockExclusive(&m_lock); return registered; } void CFrameScheduler::FramePublished(const Schedule& schedule, uint32_t frameSerial, uint64_t now, bool periodic) { - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); if (m_scheduling && schedule.clientID == m_schedule.clientID && schedule.generation == m_schedule.generation && schedule.epoch == m_schedule.epoch && @@ -744,14 +734,13 @@ void CFrameScheduler::FramePublished(const Schedule& schedule, if (client) client->nextDelivery = m_nextDeadline; } - ReleaseSRWLockExclusive(&m_lock); } void CFrameScheduler::FrameRetained(const Schedule& schedule, uint64_t now, bool periodic) { bool wake = false; - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); if (m_scheduling && schedule.clientID == m_schedule.clientID && schedule.generation == m_schedule.generation && schedule.epoch == m_schedule.epoch && @@ -779,7 +768,7 @@ void CFrameScheduler::FrameRetained(const Schedule& schedule, if (client) client->nextDelivery = m_nextDeadline; } - ReleaseSRWLockExclusive(&m_lock); + lock.Unlock(); if (wake) WakePublisher(); @@ -793,7 +782,8 @@ bool CFrameScheduler::TryFrameCompleted(const Schedule& schedule, !schedule.deadline) return false; - if (!TryAcquireSRWLockExclusive(&m_lock)) + auto lock = CSRWExclusiveLock::Try(m_lock); + if (!lock) return false; bool phaseValid = false; @@ -809,14 +799,13 @@ bool CFrameScheduler::TryFrameCompleted(const Schedule& schedule, phaseValid = publication->phaseValid; } } - ReleaseSRWLockExclusive(&m_lock); return phaseValid; } void CFrameScheduler::FrameRepublished(const Schedule& schedule, uint32_t frameSerial) { - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); if (m_scheduling && schedule.clientID == m_schedule.clientID && schedule.generation == m_schedule.generation && schedule.epoch == m_schedule.epoch) @@ -835,13 +824,12 @@ void CFrameScheduler::FrameRepublished(const Schedule& schedule, } ++m_publishedFrames; } - ReleaseSRWLockExclusive(&m_lock); } void CFrameScheduler::RequestRepublish() { bool wake = false; - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); Client * client = FindClient(m_schedule.clientID); if (m_scheduling && client && !client->deliveredFrameValid && m_republishRequestTicket == m_republishAckTicket) @@ -849,7 +837,7 @@ void CFrameScheduler::RequestRepublish() ++m_republishRequestTicket; wake = true; } - ReleaseSRWLockExclusive(&m_lock); + lock.Unlock(); if (wake) WakePublisher(); @@ -859,7 +847,7 @@ unsigned CFrameScheduler::GetSecondaryRecipients( const uint32_t * clientIDs, unsigned count, uint32_t frameSerial, uint64_t now, uint32_t * recipients) const { - AcquireSRWLockShared(&m_lock); + CSRWSharedLock lock(m_lock); unsigned recipientCount = 0; for (unsigned i = 0; i < count; ++i) { @@ -891,7 +879,6 @@ unsigned CFrameScheduler::GetSecondaryRecipients( if (due) recipients[recipientCount++] = clientIDs[i]; } - ReleaseSRWLockShared(&m_lock); return recipientCount; } @@ -902,7 +889,7 @@ bool CFrameScheduler::GetSecondaryTarget(uint32_t frameSerial, bool found = false; target = now; - AcquireSRWLockShared(&m_lock); + CSRWSharedLock lock(m_lock); for (const Client& client : m_clients) { if (!client.clientID || !client.subscribed || @@ -935,14 +922,13 @@ bool CFrameScheduler::GetSecondaryTarget(uint32_t frameSerial, found = true; } } - ReleaseSRWLockShared(&m_lock); return found; } void CFrameScheduler::FrameDelivered(const uint32_t * clientIDs, unsigned count, uint32_t frameSerial, uint64_t now) { - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); for (unsigned i = 0; i < count; ++i) { Client * client = FindClient(clientIDs[i]); @@ -972,17 +958,13 @@ void CFrameScheduler::FrameDelivered(const uint32_t * clientIDs, if (!immediate || periodic) AdvanceDelivery(*client, now); } - ReleaseSRWLockExclusive(&m_lock); } void CFrameScheduler::LogStatistics(uint64_t now) { - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); if (!m_scheduling || now - m_lastLog < LOG_INTERVAL_NS) - { - ReleaseSRWLockExclusive(&m_lock); return; - } const uint32_t clientID = m_schedule.clientID; const uint64_t period = m_schedule.period; @@ -997,7 +979,7 @@ void CFrameScheduler::LogStatistics(uint64_t now) m_lastLogAcquired = m_acquiredFrames; m_lastLogSkipped = m_skippedFrames; m_lastLogPublished = m_publishedFrames; - ReleaseSRWLockExclusive(&m_lock); + lock.Unlock(); const double acquiredRate = static_cast(acquired) * 1000000000.0 / elapsed; @@ -1019,7 +1001,8 @@ void CFrameScheduler::TryRecordFrameTiming(uint64_t duration) if (!duration) return; - if (!TryAcquireSRWLockExclusive(&m_lock)) + auto lock = CSRWExclusiveLock::Try(m_lock); + if (!lock) return; m_workTiming[m_workTimingIndex] = duration; @@ -1052,5 +1035,4 @@ void CFrameScheduler::TryRecordFrameTiming(uint64_t duration) m_workEstimate = sorted[m_workTimingCount - discarded - 1]; } - ReleaseSRWLockExclusive(&m_lock); } diff --git a/idd/LGIdd/capture/CFrameScheduler.h b/idd/LGIdd/capture/CFrameScheduler.h index cd3dce4d..0630c887 100644 --- a/idd/LGIdd/capture/CFrameScheduler.h +++ b/idd/LGIdd/capture/CFrameScheduler.h @@ -20,6 +20,8 @@ #pragma once +#include "CSRWLock.h" + #include #include @@ -100,12 +102,12 @@ private: static const unsigned PUBLICATION_HISTORY_SIZE = 128; static const unsigned WORK_TIMING_HISTORY_SIZE = 32; - mutable SRWLOCK m_lock = SRWLOCK_INIT; - HANDLE m_wakeEvent = nullptr; - Client m_clients[MAX_CLIENTS] = {}; - Schedule m_schedule = {}; - bool m_scheduling = false; - uint32_t m_epoch = 0; + mutable CSRWLock m_lock; + HANDLE m_wakeEvent = nullptr; + Client m_clients[MAX_CLIENTS] = {}; + Schedule m_schedule = {}; + bool m_scheduling = false; + uint32_t m_epoch = 0; // A result acknowledges only the request tickets captured by its attempt. uint64_t m_forceRequestTicket = 0; diff --git a/idd/LGIdd/capture/CHardwareFrameProcessor.cpp b/idd/LGIdd/capture/CHardwareFrameProcessor.cpp index abd4a742..d05def87 100644 --- a/idd/LGIdd/capture/CHardwareFrameProcessor.cpp +++ b/idd/LGIdd/capture/CHardwareFrameProcessor.cpp @@ -35,21 +35,20 @@ static_assert(CAPTURE_PIPELINE_SLOTS == 2, class CPublishPending { private: - SRWLOCK * m_lock; + CSRWLock& m_lock; bool * m_pending; HANDLE m_event; bool m_active = true; public: - CPublishPending(SRWLOCK * lock, bool * pending, HANDLE event) : - m_lock(lock), + CPublishPending(CSRWLock& stateLock, bool * pending, HANDLE event) : + m_lock(stateLock), m_pending(pending), m_event(event) { - AcquireSRWLockExclusive(m_lock); + CSRWExclusiveLock guard(m_lock); *m_pending = true; ResetEvent(m_event); - ReleaseSRWLockExclusive(m_lock); } ~CPublishPending() @@ -62,10 +61,11 @@ public: if (!m_active) return; - AcquireSRWLockExclusive(m_lock); - *m_pending = false; - SetEvent(m_event); - ReleaseSRWLockExclusive(m_lock); + { + CSRWExclusiveLock lock(m_lock); + *m_pending = false; + SetEvent(m_event); + } m_active = false; } }; @@ -73,7 +73,7 @@ public: CHardwareFrameProcessor::CHardwareFrameProcessor( IFrameTransport * transport, std::shared_ptr dx12, CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS], - SRWLOCK * pipelineLock, HANDLE terminateEvent) : + CSRWLock * pipelineLock, HANDLE terminateEvent) : CFrameProcessor(transport, std::move(dx12), postProcessors, pipelineLock, terminateEvent) { @@ -116,15 +116,17 @@ void CHardwareFrameProcessor::AccumulateDamageLocked( void CHardwareFrameProcessor::ResetCandidates() { - AcquireSRWLockExclusive(&m_candidateLock); - for (FrameCandidate& candidate : m_candidates) - candidate = {}; - ReleaseSRWLockExclusive(&m_candidateLock); + { + CSRWExclusiveLock lock(m_candidateLock); + for (FrameCandidate& candidate : m_candidates) + candidate = {}; + } - AcquireSRWLockExclusive(&m_damageLock); - for (CandidateDamageTail& tail : m_candidateDamageTail) - tail = {}; - ReleaseSRWLockExclusive(&m_damageLock); + { + CSRWExclusiveLock lock(m_damageLock); + for (CandidateDamageTail& tail : m_candidateDamageTail) + tail = {}; + } SignalCandidateState(); } @@ -143,14 +145,13 @@ void CHardwareFrameProcessor::ResetPipeline() bool CHardwareFrameProcessor::HasReadyFrame() const { bool ready = false; - AcquireSRWLockShared(&m_candidateLock); + CSRWSharedLock lock(m_candidateLock); for (const FrameCandidate& candidate : m_candidates) if (candidate.state == CANDIDATE_READY) { ready = true; break; } - ReleaseSRWLockShared(&m_candidateLock); return ready; } @@ -163,46 +164,47 @@ int CHardwareFrameProcessor::AcquireCandidate( bool idle = true; bool publishing = false; - AcquireSRWLockExclusive(&m_candidateLock); - for (unsigned i = 0; i < ARRAYSIZE(m_candidates); ++i) { - if (m_candidates[i].state != CANDIDATE_FREE) - { - idle = false; - if (m_candidates[i].state == CANDIDATE_PUBLISHING) - publishing = true; - } - else if (selected < 0) - selected = static_cast(i); - } - - if (exclusiveSample && !idle) - selected = -1; - - unsigned readyCount = 0; - for (const FrameCandidate& candidate : m_candidates) - if (candidate.state == CANDIDATE_READY) - ++readyCount; - - if (allowSupersede && !exclusiveSample && selected < 0 && - readyCount > (publishing ? 0U : 1U)) + CSRWExclusiveLock lock(m_candidateLock); for (unsigned i = 0; i < ARRAYSIZE(m_candidates); ++i) - if (m_candidates[i].state == CANDIDATE_READY && - m_candidates[i].sequence < oldest) + { + if (m_candidates[i].state != CANDIDATE_FREE) { - selected = static_cast(i); - oldest = m_candidates[i].sequence; + idle = false; + if (m_candidates[i].state == CANDIDATE_PUBLISHING) + publishing = true; } + else if (selected < 0) + selected = static_cast(i); + } - if (selected >= 0) - { - FrameCandidate& candidate = - m_candidates[static_cast(selected)]; - superseded = candidate.state == CANDIDATE_READY; - candidate.state = CANDIDATE_PREPARING; - candidate.sequence = ++m_candidateSequence; + if (exclusiveSample && !idle) + selected = -1; + + unsigned readyCount = 0; + for (const FrameCandidate& candidate : m_candidates) + if (candidate.state == CANDIDATE_READY) + ++readyCount; + + if (allowSupersede && !exclusiveSample && selected < 0 && + readyCount > (publishing ? 0U : 1U)) + for (unsigned i = 0; i < ARRAYSIZE(m_candidates); ++i) + if (m_candidates[i].state == CANDIDATE_READY && + m_candidates[i].sequence < oldest) + { + selected = static_cast(i); + oldest = m_candidates[i].sequence; + } + + if (selected >= 0) + { + FrameCandidate& candidate = + m_candidates[static_cast(selected)]; + superseded = candidate.state == CANDIDATE_READY; + candidate.state = CANDIDATE_PREPARING; + candidate.sequence = ++m_candidateSequence; + } } - ReleaseSRWLockExclusive(&m_candidateLock); if (superseded) m_transport->FrameSuperseded(); @@ -214,9 +216,10 @@ void CHardwareFrameProcessor::ReleaseCandidate(unsigned candidateIndex) if (candidateIndex >= ARRAYSIZE(m_candidates)) return; - AcquireSRWLockExclusive(&m_candidateLock); - m_candidates[candidateIndex].state = CANDIDATE_FREE; - ReleaseSRWLockExclusive(&m_candidateLock); + { + CSRWExclusiveLock lock(m_candidateLock); + m_candidates[candidateIndex].state = CANDIDATE_FREE; + } SignalCandidateState(); } @@ -280,14 +283,11 @@ bool CHardwareFrameProcessor::ExecuteCandidateCopy( for (;;) { - AcquireSRWLockExclusive(&m_copySubmitLock); - if (!m_publishPending) { - const bool result = copySlot->Execute(); - ReleaseSRWLockExclusive(&m_copySubmitLock); - return result; + CSRWExclusiveLock lock(m_copySubmitLock); + if (!m_publishPending) + return copySlot->Execute(); } - ReleaseSRWLockExclusive(&m_copySubmitLock); const DWORD result = WaitForMultipleObjects( ARRAYSIZE(waitHandles), waitHandles, FALSE, INFINITE); @@ -313,18 +313,19 @@ void CHardwareFrameProcessor::CandidateCompletionFunction( const bool timingValid = result && slot->GetGPUTimes(gpuStart, gpuEnd); bool forceFrame = false; - AcquireSRWLockExclusive(&processor->m_candidateLock); - if (candidate->state == CANDIDATE_PREPARING) { - candidate->prepareReady = CFrameScheduler::Nanotime(); - candidate->prepareGPUStart = gpuStart; - candidate->prepareGPUEnd = gpuEnd; - candidate->prepareTimingValid = timingValid; - candidate->state = - result ? CANDIDATE_READY : CANDIDATE_FREE; - forceFrame = result && candidate->timingToken != 0; + CSRWExclusiveLock lock(processor->m_candidateLock); + if (candidate->state == CANDIDATE_PREPARING) + { + candidate->prepareReady = CFrameScheduler::Nanotime(); + candidate->prepareGPUStart = gpuStart; + candidate->prepareGPUEnd = gpuEnd; + candidate->prepareTimingValid = timingValid; + candidate->state = + result ? CANDIDATE_READY : CANDIDATE_FREE; + forceFrame = result && candidate->timingToken != 0; + } } - ReleaseSRWLockExclusive(&processor->m_candidateLock); if (!result) { @@ -358,16 +359,17 @@ void CHardwareFrameProcessor::CompletionFunction( uint64_t prepareGPUEnd; uint64_t timingStart; bool prepareTimingValid; - AcquireSRWLockShared(&processor->m_candidateLock); - const FrameCandidate& candidate = - processor->m_candidates[candidateIndex]; - prepareCopyStart = candidate.prepareCopyStart; - prepareReady = candidate.prepareReady; - prepareGPUStart = candidate.prepareGPUStart; - prepareGPUEnd = candidate.prepareGPUEnd; - timingStart = candidate.timingStart; - prepareTimingValid = candidate.prepareTimingValid; - ReleaseSRWLockShared(&processor->m_candidateLock); + { + CSRWSharedLock lock(processor->m_candidateLock); + const FrameCandidate& candidate = + processor->m_candidates[candidateIndex]; + prepareCopyStart = candidate.prepareCopyStart; + prepareReady = candidate.prepareReady; + prepareGPUStart = candidate.prepareGPUStart; + prepareGPUEnd = candidate.prepareGPUEnd; + timingStart = candidate.timingStart; + prepareTimingValid = candidate.prepareTimingValid; + } const uint64_t publishStart = fbRes->GetCopyStart(); uint64_t gpuCopyStart = 0; @@ -443,26 +445,27 @@ bool CHardwareFrameProcessor::Publish( uint64_t publishStart) { CPublishPending publishPending( - &m_copySubmitLock, &m_publishPending, m_copySubmitEvent.Get()); - CSRWSharedLock pipelineLock(m_pipelineLock); + m_copySubmitLock, &m_publishPending, m_copySubmitEvent.Get()); + CSRWSharedLock pipelineLock(*m_pipelineLock); int selectedCandidate = -1; uint64_t newestSequence = 0; - AcquireSRWLockExclusive(&m_candidateLock); - for (unsigned i = 0; i < ARRAYSIZE(m_candidates); ++i) - if (m_candidates[i].state == CANDIDATE_READY && - (selectedCandidate < 0 || - m_candidates[i].sequence > newestSequence)) - { - selectedCandidate = static_cast(i); - newestSequence = m_candidates[i].sequence; - } + { + CSRWExclusiveLock lock(m_candidateLock); + for (unsigned i = 0; i < ARRAYSIZE(m_candidates); ++i) + if (m_candidates[i].state == CANDIDATE_READY && + (selectedCandidate < 0 || + m_candidates[i].sequence > newestSequence)) + { + selectedCandidate = static_cast(i); + newestSequence = m_candidates[i].sequence; + } - if (selectedCandidate >= 0) - m_candidates[static_cast(selectedCandidate)].state = - CANDIDATE_PUBLISHING; - ReleaseSRWLockExclusive(&m_candidateLock); + if (selectedCandidate >= 0) + m_candidates[static_cast(selectedCandidate)].state = + CANDIDATE_PUBLISHING; + } if (selectedCandidate < 0) return false; @@ -471,18 +474,21 @@ bool CHardwareFrameProcessor::Publish( const auto restoreCandidate = [this, candidateIndex]() { - AcquireSRWLockExclusive(&m_candidateLock); - if (m_candidates[candidateIndex].state == CANDIDATE_PUBLISHING) - m_candidates[candidateIndex].state = CANDIDATE_READY; - ReleaseSRWLockExclusive(&m_candidateLock); + { + CSRWExclusiveLock lock(m_candidateLock); + if (m_candidates[candidateIndex].state == CANDIDATE_PUBLISHING) + m_candidates[candidateIndex].state = CANDIDATE_READY; + } SignalCandidateState(); }; - AcquireSRWLockShared(&m_candidateLock); - const bool candidateValid = - m_candidates[candidateIndex].state == CANDIDATE_PUBLISHING && - m_candidates[candidateIndex].resource.Get(); - ReleaseSRWLockShared(&m_candidateLock); + bool candidateValid; + { + CSRWSharedLock lock(m_candidateLock); + candidateValid = + m_candidates[candidateIndex].state == CANDIDATE_PUBLISHING && + m_candidates[candidateIndex].resource.Get(); + } if (!candidateValid) { restoreCandidate(); @@ -564,33 +570,35 @@ bool CHardwareFrameProcessor::Publish( frameSchedule.phaseEligible = false; fbRes->SetSchedule(frameSchedule); - AcquireSRWLockExclusive(&m_damageLock); - if (candidate.nbDirtyRects) - memcpy(m_previousDamage, candidate.dirtyRects, - candidate.nbDirtyRects * sizeof(*m_previousDamage)); - m_previousDamageCount = candidate.nbDirtyRects; - CandidateDamageTail& tail = m_candidateDamageTail[candidateIndex]; - if (tail.active && tail.ownerSequence == candidateSequence) { - m_hasPendingDamage = tail.hasDamage; - m_pendingDamageCount = tail.nbDirtyRects; - if (tail.hasDamage && tail.nbDirtyRects) - memcpy(m_pendingDamage, tail.dirtyRects, - tail.nbDirtyRects * sizeof(*m_pendingDamage)); - tail.ownerSequence = 0; - tail.active = false; + CSRWExclusiveLock lock(m_damageLock); + if (candidate.nbDirtyRects) + memcpy(m_previousDamage, candidate.dirtyRects, + candidate.nbDirtyRects * sizeof(*m_previousDamage)); + m_previousDamageCount = candidate.nbDirtyRects; + CandidateDamageTail& tail = m_candidateDamageTail[candidateIndex]; + if (tail.active && tail.ownerSequence == candidateSequence) + { + m_hasPendingDamage = tail.hasDamage; + m_pendingDamageCount = tail.nbDirtyRects; + if (tail.hasDamage && tail.nbDirtyRects) + memcpy(m_pendingDamage, tail.dirtyRects, + tail.nbDirtyRects * sizeof(*m_pendingDamage)); + tail.ownerSequence = 0; + tail.active = false; + } } - ReleaseSRWLockExclusive(&m_damageLock); const bool submitted = copySlot->Execute(); publishPending.Clear(); if (!submitted) { SetFullDamage(); - AcquireSRWLockShared(&m_candidateLock); - const bool callbackPending = - candidate.state == CANDIDATE_PUBLISHING; - ReleaseSRWLockShared(&m_candidateLock); + bool callbackPending; + { + CSRWSharedLock lock(m_candidateLock); + callbackPending = candidate.state == CANDIDATE_PUBLISHING; + } if (callbackPending && !copySlot->HasSubmittedWork()) { m_transport->FailFrameBuffer(buffer.frameIndex); @@ -605,15 +613,16 @@ bool CHardwareFrameProcessor::Publish( buffer.frameIndex, schedule, periodic, deliveredToOwner); unsigned superseded = 0; - AcquireSRWLockExclusive(&m_candidateLock); - for (FrameCandidate& ready : m_candidates) - if (ready.state == CANDIDATE_READY && - ready.sequence < candidateSequence) - { - ready.state = CANDIDATE_FREE; - ++superseded; - } - ReleaseSRWLockExclusive(&m_candidateLock); + { + CSRWExclusiveLock lock(m_candidateLock); + for (FrameCandidate& ready : m_candidates) + if (ready.state == CANDIDATE_READY && + ready.sequence < candidateSequence) + { + ready.state = CANDIDATE_FREE; + ++superseded; + } + } for (unsigned i = 0; i < superseded; ++i) m_transport->FrameSuperseded(); SignalCandidateState(); @@ -654,26 +663,27 @@ bool CHardwareFrameProcessor::Submit(const FrameSubmission& submission) static_cast(selectedCandidate); FrameCandidate& candidate = m_candidates[candidateIndex]; - CSRWSharedLock pipelineLock(m_pipelineLock); + CSRWSharedLock pipelineLock(*m_pipelineLock); CPostProcessor& postProcessor = m_postProcessors[candidateIndex]; const D12FrameFormat& dstFormat = postProcessor.GetOutputFormat(); RECT currentDirtyRects[LG_MAX_DIRTY_RECTS] = {}; unsigned nbDirtyRects = 0; - AcquireSRWLockExclusive(&m_damageLock); - if (m_hasPendingDamage) { - nbDirtyRects = m_pendingDamageCount; - if (nbDirtyRects) - memcpy(currentDirtyRects, m_pendingDamage, - nbDirtyRects * sizeof(*currentDirtyRects)); + CSRWExclusiveLock lock(m_damageLock); + if (m_hasPendingDamage) + { + nbDirtyRects = m_pendingDamageCount; + if (nbDirtyRects) + memcpy(currentDirtyRects, m_pendingDamage, + nbDirtyRects * sizeof(*currentDirtyRects)); + } + CandidateDamageTail& tail = m_candidateDamageTail[candidateIndex]; + tail.ownerSequence = candidate.sequence; + tail.nbDirtyRects = 0; + tail.hasDamage = false; + tail.active = true; } - CandidateDamageTail& tail = m_candidateDamageTail[candidateIndex]; - tail.ownerSequence = candidate.sequence; - tail.nbDirtyRects = 0; - tail.hasDamage = false; - tail.active = true; - ReleaseSRWLockExclusive(&m_damageLock); CD3D12CommandSlot * copySlot = m_dx12->GetCopySlot(candidateIndex); if (!copySlot) diff --git a/idd/LGIdd/capture/CHardwareFrameProcessor.h b/idd/LGIdd/capture/CHardwareFrameProcessor.h index 025a2b28..b21708a4 100644 --- a/idd/LGIdd/capture/CHardwareFrameProcessor.h +++ b/idd/LGIdd/capture/CHardwareFrameProcessor.h @@ -67,8 +67,8 @@ private: FrameCandidate m_candidates[CAPTURE_PIPELINE_SLOTS]; CandidateDamageTail m_candidateDamageTail[CAPTURE_PIPELINE_SLOTS]; - mutable SRWLOCK m_candidateLock = SRWLOCK_INIT; - SRWLOCK m_copySubmitLock = SRWLOCK_INIT; + mutable CSRWLock m_candidateLock; + CSRWLock m_copySubmitLock; uint64_t m_candidateSequence = 0; bool m_publishPending = false; Wrappers::Event m_candidateAvailableEvent; @@ -92,7 +92,7 @@ public: CHardwareFrameProcessor(IFrameTransport * transport, std::shared_ptr dx12, CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS], - SRWLOCK * pipelineLock, HANDLE terminateEvent); + CSRWLock * pipelineLock, HANDLE terminateEvent); bool IsValid() const override; bool Submit(const FrameSubmission& submission) override; diff --git a/idd/LGIdd/capture/CSoftwareFrameProcessor.cpp b/idd/LGIdd/capture/CSoftwareFrameProcessor.cpp index fad3575c..3cbc3b1d 100644 --- a/idd/LGIdd/capture/CSoftwareFrameProcessor.cpp +++ b/idd/LGIdd/capture/CSoftwareFrameProcessor.cpp @@ -30,7 +30,7 @@ CSoftwareFrameProcessor::CSoftwareFrameProcessor( IFrameTransport * transport, std::shared_ptr dx12, CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS], - SRWLOCK * pipelineLock, HANDLE terminateEvent) : + CSRWLock * pipelineLock, HANDLE terminateEvent) : CFrameProcessor(transport, std::move(dx12), postProcessors, pipelineLock, terminateEvent) { @@ -112,7 +112,7 @@ void CSoftwareFrameProcessor::CompletionFunction( bool CSoftwareFrameProcessor::Submit(const FrameSubmission& submission) { - CSRWSharedLock pipelineLock(m_pipelineLock); + CSRWSharedLock pipelineLock(*m_pipelineLock); CPostProcessor& postProcessor = m_postProcessors[0]; const D12FrameFormat& dstFormat = postProcessor.GetOutputFormat(); diff --git a/idd/LGIdd/capture/CSoftwareFrameProcessor.h b/idd/LGIdd/capture/CSoftwareFrameProcessor.h index 4c8dbbbc..12eead0d 100644 --- a/idd/LGIdd/capture/CSoftwareFrameProcessor.h +++ b/idd/LGIdd/capture/CSoftwareFrameProcessor.h @@ -32,7 +32,7 @@ public: CSoftwareFrameProcessor(IFrameTransport * transport, std::shared_ptr dx12, CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS], - SRWLOCK * pipelineLock, HANDLE terminateEvent); + CSRWLock * pipelineLock, HANDLE terminateEvent); bool Submit(const FrameSubmission& submission) override; bool HasReadyFrame() const override { return false; } diff --git a/idd/LGIdd/capture/CSwapChainProcessor.cpp b/idd/LGIdd/capture/CSwapChainProcessor.cpp index d40baeb9..287d39b3 100644 --- a/idd/LGIdd/capture/CSwapChainProcessor.cpp +++ b/idd/LGIdd/capture/CSwapChainProcessor.cpp @@ -655,7 +655,7 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr acquiredBuffer unsigned timingEffectIndex = 0; uint64_t timingToken = 0; { - CSRWExclusiveLock pipelineLock(&m_pipelineLock); + CSRWExclusiveLock pipelineLock(m_pipelineLock); m_postProcessors[0].Update(srcFormat); frameMetadataChanged = noImageUpdate && diff --git a/idd/LGIdd/capture/CSwapChainProcessor.h b/idd/LGIdd/capture/CSwapChainProcessor.h index e736e5bc..48964447 100644 --- a/idd/LGIdd/capture/CSwapChainProcessor.h +++ b/idd/LGIdd/capture/CSwapChainProcessor.h @@ -59,7 +59,7 @@ private: CPostProcessor m_postProcessors[CAPTURE_PIPELINE_SLOTS]; std::unique_ptr m_frameProcessor; // Reconfiguration is exclusive while per-candidate recording is shared. - SRWLOCK m_pipelineLock = SRWLOCK_INIT; + CSRWLock m_pipelineLock; Wrappers::HandleT m_thread[3]; Wrappers::Event m_terminateEvent; diff --git a/idd/LGIdd/d3d/CD3D12CommandQueue.cpp b/idd/LGIdd/d3d/CD3D12CommandQueue.cpp index 62557182..3dc12c5b 100644 --- a/idd/LGIdd/d3d/CD3D12CommandQueue.cpp +++ b/idd/LGIdd/d3d/CD3D12CommandQueue.cpp @@ -575,7 +575,7 @@ void CD3D12CommandQueue::WaitForIdle() bool CD3D12CommandQueue::Submit(CD3D12CommandSlot& slot) { bool result = false; - AcquireSRWLockExclusive(&m_submitLock); + CSRWExclusiveLock lock(m_submitLock); do { @@ -636,7 +636,6 @@ bool CD3D12CommandQueue::Submit(CD3D12CommandSlot& slot) } while (false); - ReleaseSRWLockExclusive(&m_submitLock); return result; } diff --git a/idd/LGIdd/d3d/CD3D12CommandQueue.h b/idd/LGIdd/d3d/CD3D12CommandQueue.h index 1c3534aa..4a0a98ab 100644 --- a/idd/LGIdd/d3d/CD3D12CommandQueue.h +++ b/idd/LGIdd/d3d/CD3D12CommandQueue.h @@ -20,6 +20,8 @@ #pragma once +#include "CSRWLock.h" + #include #include #include @@ -147,7 +149,7 @@ class CD3D12CommandQueue ComPtr m_queue; ComPtr m_fence; UINT64 m_fenceValue = 0; - SRWLOCK m_submitLock = SRWLOCK_INIT; + CSRWLock m_submitLock; std::atomic m_failed = false; CD3D12CommandSlot m_slots[MAX_SLOTS]; diff --git a/idd/LGIdd/display/CDisplayConfiguration.cpp b/idd/LGIdd/display/CDisplayConfiguration.cpp index a2fc511e..ab6b5d6e 100644 --- a/idd/LGIdd/display/CDisplayConfiguration.cpp +++ b/idd/LGIdd/display/CDisplayConfiguration.cpp @@ -178,7 +178,7 @@ bool CDisplayConfiguration::LoadModes(const FrameMemoryLimits& limits) if (!hasPreferred) newModes.front().preferred = true; - CSRWExclusiveLock lock(&m_modeLock); + CSRWExclusiveLock lock(m_modeLock); m_modes = std::move(newModes); return true; } @@ -193,7 +193,7 @@ bool CDisplayConfiguration::ReloadSettings( { bool modesLoaded = false; { - CSRWExclusiveLock reloadLock(&m_reloadLock); + CSRWExclusiveLock reloadLock(m_reloadLock); bool settingsUpdated = true; CSettings::DisplayMode extraMode = {}; @@ -252,7 +252,7 @@ CDisplayConfiguration::SetResolution( mode.preferred = true; { - CSRWExclusiveLock reloadLock(&m_reloadLock); + CSRWExclusiveLock reloadLock(m_reloadLock); if (!m_settings.SetExtraMode(mode)) result.status = ResolutionStatus::SETTINGS_FAILED; else if (!LoadModes(limits)) @@ -271,7 +271,7 @@ CDisplayConfiguration::SetResolution( void CDisplayConfiguration::InitializeEdid(bool hdr) { - CSRWExclusiveLock lock(&m_modeLock); + CSRWExclusiveLock lock(m_modeLock); if (m_edid.Size()) return; @@ -281,7 +281,7 @@ void CDisplayConfiguration::InitializeEdid(bool hdr) void CDisplayConfiguration::RebuildEdid(bool hdr) { - CSRWExclusiveLock lock(&m_modeLock); + CSRWExclusiveLock lock(m_modeLock); m_edid.Build(hdr); m_hdrEnabled = hdr; } @@ -290,7 +290,7 @@ CDisplayConfiguration::Description CDisplayConfiguration::GetDescription() const { Description result; - CSRWSharedLock lock(&m_modeLock); + CSRWSharedLock lock(m_modeLock); result.modeCount = m_modes.size(); if (m_edid.Size()) result.edid.assign(m_edid.Data(), m_edid.Data() + m_edid.Size()); @@ -300,7 +300,7 @@ CDisplayConfiguration::GetDescription() const CSettings::DisplayModes CDisplayConfiguration::SnapshotModes( bool * hdrEnabled) const { - CSRWSharedLock lock(&m_modeLock); + CSRWSharedLock lock(m_modeLock); if (hdrEnabled) *hdrEnabled = m_hdrEnabled; return m_modes; diff --git a/idd/LGIdd/display/CDisplayConfiguration.h b/idd/LGIdd/display/CDisplayConfiguration.h index 68b3f2e2..ff7dbdbd 100644 --- a/idd/LGIdd/display/CDisplayConfiguration.h +++ b/idd/LGIdd/display/CDisplayConfiguration.h @@ -20,6 +20,8 @@ #pragma once +#include "CSRWLock.h" + #include "config/CSettings.h" #include "display/CEdid.h" #include "display/IddCxCompat.h" @@ -59,8 +61,8 @@ private: // Registry-backed changes are serialized before publishing a replacement // mode list. Readers only hold m_modeLock long enough to take a snapshot. - SRWLOCK m_reloadLock = SRWLOCK_INIT; - mutable SRWLOCK m_modeLock = SRWLOCK_INIT; + CSRWLock m_reloadLock; + mutable CSRWLock m_modeLock; CSettings::DisplayModes m_modes; CEdid m_edid; diff --git a/idd/LGIdd/display/CMonitorContext.cpp b/idd/LGIdd/display/CMonitorContext.cpp index aebe98fb..93d838fc 100644 --- a/idd/LGIdd/display/CMonitorContext.cpp +++ b/idd/LGIdd/display/CMonitorContext.cpp @@ -62,10 +62,10 @@ NTSTATUS CMonitorContext::AssignSwapChain( return STATUS_GRAPHICS_INDIRECT_DISPLAY_ABANDON_SWAPCHAIN; } - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); if (!IsAssignmentCurrent(assignmentGeneration)) { - ReleaseSRWLockExclusive(&m_lock); + lock.Unlock(); DEBUG_INFO("Swap chain assignment canceled before processor startup"); return STATUS_GRAPHICS_INDIRECT_DISPLAY_ABANDON_SWAPCHAIN; } @@ -82,13 +82,12 @@ NTSTATUS CMonitorContext::AssignSwapChain( { auto processor = std::move(m_swapChain); dx11Device = std::move(m_dx11Device); - ReleaseSRWLockExclusive(&m_lock); + lock.Unlock(); processor.reset(); dx11Device.reset(); m_devContext->OnSwapChainReleased(); return STATUS_GRAPHICS_INDIRECT_DISPLAY_ABANDON_SWAPCHAIN; } - ReleaseSRWLockExclusive(&m_lock); return STATUS_SUCCESS; } @@ -105,10 +104,11 @@ void CMonitorContext::DetachSwapChain() std::unique_ptr processor; std::shared_ptr dx11Device; - AcquireSRWLockExclusive(&m_lock); - processor = std::move(m_swapChain); - dx11Device = std::move(m_dx11Device); - ReleaseSRWLockExclusive(&m_lock); + { + CSRWExclusiveLock lock(m_lock); + processor = std::move(m_swapChain); + dx11Device = std::move(m_dx11Device); + } const bool hadSwapChain = !!processor; processor.reset(); diff --git a/idd/LGIdd/display/CMonitorContext.h b/idd/LGIdd/display/CMonitorContext.h index 70ab31a0..460429a0 100644 --- a/idd/LGIdd/display/CMonitorContext.h +++ b/idd/LGIdd/display/CMonitorContext.h @@ -20,6 +20,8 @@ #pragma once +#include "CSRWLock.h" + #include #include #include @@ -40,7 +42,7 @@ private: // Guards the swap chain and device pointers. Assign and unassign can run // concurrently (an unassign triggered by the worker's WdfObjectDelete can // race the next assign), and shared_ptr copy/reset is not thread safe. - SRWLOCK m_lock = SRWLOCK_INIT; + CSRWLock m_lock; // IddCx can issue a replacement assignment before an earlier assignment // has finished creating its devices. Serialize those expensive setup paths diff --git a/idd/LGIdd/display/CMonitorManager.cpp b/idd/LGIdd/display/CMonitorManager.cpp index 08407f7a..9409d146 100644 --- a/idd/LGIdd/display/CMonitorManager.cpp +++ b/idd/LGIdd/display/CMonitorManager.cpp @@ -30,9 +30,11 @@ void CMonitorManager::Create(UINT connectorIndex, IDDCX_ADAPTER adapter, // We support a single monitor; never create a second one if one already // exists (a replug must clear m_monitor via departure first). - AcquireSRWLockExclusive(&m_lock); - const bool haveMonitor = m_monitor != WDF_NO_HANDLE; - ReleaseSRWLockExclusive(&m_lock); + bool haveMonitor; + { + CSRWExclusiveLock lock(m_lock); + haveMonitor = m_monitor != WDF_NO_HANDLE; + } if (haveMonitor) { DEBUG_WARN("FinishInit skipped: a monitor already exists"); @@ -76,9 +78,10 @@ void CMonitorManager::Create(UINT connectorIndex, IDDCX_ADAPTER adapter, DEBUG_INFO("Monitor object created (%p)", createOut.MonitorObject); - AcquireSRWLockExclusive(&m_lock); - m_monitor = createOut.MonitorObject; - ReleaseSRWLockExclusive(&m_lock); + { + CSRWExclusiveLock lock(m_lock); + m_monitor = createOut.MonitorObject; + } auto * wrapper = WdfObjectGet_CMonitorContextWrapper(m_monitor); wrapper->context = new CMonitorContext(m_monitor, owner); @@ -96,56 +99,65 @@ void CMonitorManager::Create(UINT connectorIndex, IDDCX_ADAPTER adapter, CMonitorManager::ReplugAction CMonitorManager::Replug() { - AcquireSRWLockExclusive(&m_lock); - - if (m_replugMonitor || (m_swapChainAssigned && !m_swapChainReady)) + IDDCX_MONITOR monitor; { - // Coalesce changes received while a swap chain is being initialized, the - // old one is draining, or its replacement is being initialized. - m_replugPending = true; - ReleaseSRWLockExclusive(&m_lock); - return ReplugAction::NONE; + CSRWExclusiveLock lock(m_lock); + + if (m_replugMonitor || (m_swapChainAssigned && !m_swapChainReady)) + { + // Coalesce changes received while a swap chain is being initialized, + // the old one is draining, or its replacement is being initialized. + m_replugPending = true; + return ReplugAction::NONE; + } + + monitor = m_monitor; + if (monitor == WDF_NO_HANDLE) + { + m_replugMonitor = true; + m_monitorDeparted = true; + } + else + { + // Clear the handle before departing so nothing calls an IddCx monitor + // API on a departing/destroyed handle. Create publishes the new one. + m_replugMonitor = true; + m_monitorDeparted = false; + m_waitForSwapChainRelease = m_swapChainAssigned; + m_monitor = nullptr; + } } - IDDCX_MONITOR monitor = m_monitor; if (monitor == WDF_NO_HANDLE) { - m_replugMonitor = true; - m_monitorDeparted = true; - ReleaseSRWLockExclusive(&m_lock); // Either no monitor yet, or one is already pending; build it now and // cancel any queued rebuild so we do not create two. m_createQueued.store(0); return ReplugAction::CREATE; } - // Clear the handle before departing so nothing calls an IddCx monitor API - // on a departing/destroyed handle. Create publishes the new one. - m_replugMonitor = true; - m_monitorDeparted = false; - m_waitForSwapChainRelease = m_swapChainAssigned; - m_monitor = nullptr; - ReleaseSRWLockExclusive(&m_lock); - DEBUG_TRACE("ReplugMonitor"); NTSTATUS status = IddCxMonitorDeparture(monitor); if (!NT_SUCCESS(status)) { - AcquireSRWLockExclusive(&m_lock); - m_replugMonitor = false; - m_replugPending = false; - m_monitorDeparted = false; - m_waitForSwapChainRelease = false; - m_monitor = monitor; - ReleaseSRWLockExclusive(&m_lock); + { + CSRWExclusiveLock lock(m_lock); + m_replugMonitor = false; + m_replugPending = false; + m_monitorDeparted = false; + m_waitForSwapChainRelease = false; + m_monitor = monitor; + } DEBUG_ERROR("IddCxMonitorDeparture Failed (0x%08x)", status); return ReplugAction::NONE; } - AcquireSRWLockExclusive(&m_lock); - m_monitorDeparted = true; - const bool rebuild = !m_waitForSwapChainRelease; - ReleaseSRWLockExclusive(&m_lock); + bool rebuild; + { + CSRWExclusiveLock departedLock(m_lock); + m_monitorDeparted = true; + rebuild = !m_waitForSwapChainRelease; + } // If there was no swap chain there will be no unassign callback to queue // the rebuild. Otherwise OnSwapChainReleased does so after teardown drains. @@ -157,41 +169,39 @@ CMonitorManager::ReplugAction CMonitorManager::Replug() void CMonitorManager::RequestMode(const CSettings::DisplayMode& mode) { - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); m_setMode = mode; m_doSetMode = true; - ReleaseSRWLockExclusive(&m_lock); } void CMonitorManager::OnDestroyed(IDDCX_MONITOR monitor) { - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); if (m_monitor == monitor) m_monitor = nullptr; - ReleaseSRWLockExclusive(&m_lock); } void CMonitorManager::OnSwapChainAssigned() { - AcquireSRWLockExclusive(&m_lock); + CSRWExclusiveLock lock(m_lock); m_swapChainAssigned = true; m_swapChainReady = false; - ReleaseSRWLockExclusive(&m_lock); } void CMonitorManager::OnSwapChainReleased() { bool rebuild = false; - AcquireSRWLockExclusive(&m_lock); - m_swapChainAssigned = false; - m_swapChainReady = false; - if (m_replugMonitor && m_waitForSwapChainRelease) { - m_waitForSwapChainRelease = false; - rebuild = m_monitorDeparted; + CSRWExclusiveLock lock(m_lock); + m_swapChainAssigned = false; + m_swapChainReady = false; + if (m_replugMonitor && m_waitForSwapChainRelease) + { + m_waitForSwapChainRelease = false; + rebuild = m_monitorDeparted; + } } - ReleaseSRWLockExclusive(&m_lock); if (rebuild) m_createQueued.store(1); @@ -202,33 +212,34 @@ CMonitorManager::ReadyAction CMonitorManager::OnSwapChainReady() ReadyAction action = {}; bool replug = false; - AcquireSRWLockExclusive(&m_lock); - m_swapChainReady = true; - if (m_replugMonitor) { - m_replugMonitor = false; - m_monitorDeparted = false; - if (m_replugPending) + CSRWExclusiveLock lock(m_lock); + m_swapChainReady = true; + if (m_replugMonitor) + { + m_replugMonitor = false; + m_monitorDeparted = false; + if (m_replugPending) + { + m_replugPending = false; + replug = true; + } + } + else if (m_replugPending) { m_replugPending = false; replug = true; } - } - else if (m_replugPending) - { - m_replugPending = false; - replug = true; - } - // Do not consume the requested mode on an intermediate replacement swap - // chain. The last coalesced replug must be the one that applies it. - if (!replug && m_doSetMode) - { - action.mode = m_setMode; - m_doSetMode = false; - action.setMode = true; + // Do not consume the requested mode on an intermediate replacement swap + // chain. The last coalesced replug must be the one that applies it. + if (!replug && m_doSetMode) + { + action.mode = m_setMode; + m_doSetMode = false; + action.setMode = true; + } } - ReleaseSRWLockExclusive(&m_lock); action.replug = replug; diff --git a/idd/LGIdd/display/CMonitorManager.h b/idd/LGIdd/display/CMonitorManager.h index 87008cf8..af03a967 100644 --- a/idd/LGIdd/display/CMonitorManager.h +++ b/idd/LGIdd/display/CMonitorManager.h @@ -20,6 +20,7 @@ #pragma once +#include "CSRWLock.h" #include #include #include @@ -58,7 +59,7 @@ private: // Guards the monitor/replug/swap-chain state. These values are touched by // IddCx callback threads, the swap-chain thread, and the transport timer. - SRWLOCK m_lock = SRWLOCK_INIT; + CSRWLock m_lock; bool m_replugMonitor = false; bool m_replugPending = false; diff --git a/idd/LGIdd/ipc/CInputPipeServer.cpp b/idd/LGIdd/ipc/CInputPipeServer.cpp index 47226350..3ca48a36 100644 --- a/idd/LGIdd/ipc/CInputPipeServer.cpp +++ b/idd/LGIdd/ipc/CInputPipeServer.cpp @@ -95,7 +95,7 @@ void CInputPipeServer::DeInit() m_stopEvent = nullptr; } - CSRWExclusiveLock lock(&m_queueLock); + CSRWExclusiveLock lock(m_queueLock); m_queueHead = 0; m_queueCount = 0; m_mouseMode = MouseMode::NONE; @@ -269,7 +269,7 @@ bool CInputPipeServer::SendMouseRelative( payload.mouseRelative.deltaY = deltaY; payload.mouseRelative.wheel = wheel; - CSRWExclusiveLock lock(&m_queueLock); + CSRWExclusiveLock lock(m_queueLock); const bool pureMotion = wheel == 0 && buttons == m_relativeButtons; const bool switching = m_mouseMode == MouseMode::ABSOLUTE_INPUT; bool queued = (m_state.load(std::memory_order_relaxed) & 1) != 0; @@ -316,7 +316,7 @@ bool CInputPipeServer::SendMouseAbsolute( payload.mouseAbsolute.y = y; payload.mouseAbsolute.wheel = wheel; - CSRWExclusiveLock lock(&m_queueLock); + CSRWExclusiveLock lock(m_queueLock); const bool pureMotion = wheel == 0 && buttons == m_absoluteButtons; const bool switching = m_mouseMode == MouseMode::RELATIVE_INPUT; bool queued = (m_state.load(std::memory_order_relaxed) & 1) != 0; @@ -360,7 +360,7 @@ bool CInputPipeServer::SendKeyboard( payload.keyboard.keys[i] = keys[i]; } - CSRWExclusiveLock lock(&m_queueLock); + CSRWExclusiveLock lock(m_queueLock); const bool queued = (m_state.load(std::memory_order_relaxed) & 1) && QueueLocked(LG_INPUT_PIPE_MESSAGE_KEYBOARD, payload, false); if (!queued) @@ -373,7 +373,7 @@ bool CInputPipeServer::Reset() if (!(m_state.load(std::memory_order_acquire) & 1)) return false; - CSRWExclusiveLock lock(&m_queueLock); + CSRWExclusiveLock lock(m_queueLock); bool queued = (m_state.load(std::memory_order_relaxed) & 1) != 0; if (queued) queued = QueueResetLocked(); @@ -384,7 +384,7 @@ bool CInputPipeServer::Reset() bool CInputPipeServer::Pop(QueueItem& item) { - CSRWExclusiveLock lock(&m_queueLock); + CSRWExclusiveLock lock(m_queueLock); if (!m_queueCount) return false; @@ -411,7 +411,7 @@ bool CInputPipeServer::Send(const QueueItem& item) LARGE_INTEGER start = {}; LARGE_INTEGER end = {}; { - CSRWSharedLock lock(&m_connectionLock); + CSRWSharedLock lock(m_connectionLock); const uint64_t state = m_state.load(std::memory_order_acquire); current = (state & 1) && item.state == state; if (current) @@ -465,7 +465,7 @@ void CInputPipeServer::LogStatistics() uint64_t resyncDiscarded; size_t queueHighWater; { - CSRWExclusiveLock lock(&m_queueLock); + CSRWExclusiveLock lock(m_queueLock); enqueued = m_statEnqueued; relativeCoalesced = m_statRelativeCoalesced; absoluteCoalesced = m_statAbsoluteCoalesced; @@ -526,7 +526,7 @@ void CInputPipeServer::LogStatistics() void CInputPipeServer::Invalidate(uint64_t state, bool requireMatch) { - CSRWExclusiveLock connectionLock(&m_connectionLock); + CSRWExclusiveLock connectionLock(m_connectionLock); uint64_t current = m_state.load(std::memory_order_relaxed); for (;;) { @@ -537,7 +537,7 @@ void CInputPipeServer::Invalidate(uint64_t state, bool requireMatch) break; } - CSRWExclusiveLock queueLock(&m_queueLock); + CSRWExclusiveLock queueLock(m_queueLock); m_queueHead = 0; m_queueCount = 0; } @@ -578,8 +578,8 @@ void CInputPipeServer::Thread() void CInputPipeServer::OnPipeConnected() { - CSRWExclusiveLock connectionLock(&m_connectionLock); - CSRWExclusiveLock queueLock(&m_queueLock); + CSRWExclusiveLock connectionLock(m_connectionLock); + CSRWExclusiveLock queueLock(m_queueLock); uint64_t state = m_state.load(std::memory_order_relaxed); if (state & 1) diff --git a/idd/LGIdd/ipc/CInputPipeServer.h b/idd/LGIdd/ipc/CInputPipeServer.h index 0aa9b889..906a2d02 100644 --- a/idd/LGIdd/ipc/CInputPipeServer.h +++ b/idd/LGIdd/ipc/CInputPipeServer.h @@ -21,6 +21,7 @@ #pragma once #include "CPipeEndpoint.h" +#include "CSRWLock.h" #include "InputPipeProtocol.h" #include "input/IInputSink.h" @@ -55,11 +56,11 @@ private: // Odd states are available. Endpoint changes and resyncs advance the state. std::atomic m_state { 0 }; - SRWLOCK m_queueLock = SRWLOCK_INIT; - SRWLOCK m_connectionLock = SRWLOCK_INIT; - HANDLE m_stopEvent = nullptr; - HANDLE m_queueEvent = nullptr; - HANDLE m_thread = nullptr; + CSRWLock m_queueLock; + CSRWLock m_connectionLock; + HANDLE m_stopEvent = nullptr; + HANDLE m_queueEvent = nullptr; + HANDLE m_thread = nullptr; QueueItem m_queue[QUEUE_LENGTH] = {}; size_t m_queueHead = 0; diff --git a/idd/LGIdd/ipc/CPipeServer.cpp b/idd/LGIdd/ipc/CPipeServer.cpp index b4ab96e2..53902c48 100644 --- a/idd/LGIdd/ipc/CPipeServer.cpp +++ b/idd/LGIdd/ipc/CPipeServer.cpp @@ -20,6 +20,7 @@ #include "ipc/CPipeServer.h" #include "CDebug.h" +#include "CSRWLock.h" #include "display/CDeviceContext.h" CPipeServer g_pipe; @@ -40,7 +41,7 @@ void CPipeServer::DeInit() void CPipeServer::OnPipeConnected() { - AcquireSRWLockExclusive(&m_queueLock); + CSRWExclusiveLock lock(m_queueLock); std::vector queued; queued.swap(m_queue); @@ -51,7 +52,6 @@ void CPipeServer::OnPipeConnected() QueueMsgLocked(queued[i]); break; } - ReleaseSRWLockExclusive(&m_queueLock); } bool CPipeServer::OnPipeMessage(const void * message, size_t size) @@ -89,27 +89,24 @@ void CPipeServer::QueueMsgLocked(const LGPipeMsg & msg) void CPipeServer::WriteMsg(const LGPipeMsg & msg) { - AcquireSRWLockExclusive(&m_queueLock); + CSRWExclusiveLock lock(m_queueLock); if (!m_endpoint.Send(&msg, sizeof(msg))) QueueMsgLocked(msg); - ReleaseSRWLockExclusive(&m_queueLock); } void CPipeServer::HandleReloadSettings() { DEBUG_INFO("Reloading settings"); - AcquireSRWLockShared(&m_deviceContextLock); + CSRWSharedLock lock(m_deviceContextLock); if (m_deviceContext) m_deviceContext->ReloadSettings(); - ReleaseSRWLockShared(&m_deviceContextLock); } void CPipeServer::SetDeviceContext(CDeviceContext * context) { - AcquireSRWLockExclusive(&m_deviceContextLock); + CSRWExclusiveLock lock(m_deviceContextLock); m_deviceContext = context; - ReleaseSRWLockExclusive(&m_deviceContextLock); } void CPipeServer::SetCursorPos(uint32_t x, uint32_t y) diff --git a/idd/LGIdd/ipc/CPipeServer.h b/idd/LGIdd/ipc/CPipeServer.h index 3bba819b..e3e8044a 100644 --- a/idd/LGIdd/ipc/CPipeServer.h +++ b/idd/LGIdd/ipc/CPipeServer.h @@ -26,6 +26,7 @@ #include #include "CPipeEndpoint.h" +#include "CSRWLock.h" #include "PipeMsg.h" class CDeviceContext; @@ -34,10 +35,10 @@ class CPipeServer : private IPipeEndpointHandler { private: CPipeEndpoint m_endpoint; - SRWLOCK m_queueLock = SRWLOCK_INIT; + CSRWLock m_queueLock; std::vector m_queue; - SRWLOCK m_deviceContextLock = SRWLOCK_INIT; + CSRWLock m_deviceContextLock; CDeviceContext * m_deviceContext = nullptr; void WriteMsg(const LGPipeMsg & msg); diff --git a/idd/LGIdd/postprocess/effect/CRGB24Effect.cpp b/idd/LGIdd/postprocess/effect/CRGB24Effect.cpp index 134121f6..38e0a73c 100644 --- a/idd/LGIdd/postprocess/effect/CRGB24Effect.cpp +++ b/idd/LGIdd/postprocess/effect/CRGB24Effect.cpp @@ -21,6 +21,7 @@ #include "CRGB24Effect.h" #include "CDebug.h" +#include "CSRWLock.h" #include "config/CSettings.h" #include "capture/FramePipeline.h" @@ -65,7 +66,7 @@ struct CRGB24Effect::State static const unsigned SampleCount = 64; static const unsigned TrimCount = SampleCount / 8; - SRWLOCK lock = SRWLOCK_INIT; + CSRWLock lock; Phase phase = Phase::DISABLED; FormatKey format = {}; bool formatValid = false; @@ -125,7 +126,7 @@ struct CRGB24Effect::State void Update(const D12FrameFormat& next) { - AcquireSRWLockExclusive(&lock); + CSRWExclusiveLock guard(lock); const bool formatChanged = !formatValid || format.resourceDimension != next.desc.Dimension || @@ -218,51 +219,46 @@ struct CRGB24Effect::State break; } - ReleaseSRWLockExclusive(&lock); } bool WantsPacked() { - AcquireSRWLockShared(&lock); + CSRWSharedLock guard(lock); const bool result = WantsPackedLocked(); - ReleaseSRWLockShared(&lock); return result; } bool IsBenchmarking() { - AcquireSRWLockShared(&lock); + CSRWSharedLock guard(lock); const bool result = IsBenchmarkingLocked(); - ReleaseSRWLockShared(&lock); return result; } uint64_t GetTimingToken(bool packed) { - AcquireSRWLockShared(&lock); + CSRWSharedLock guard(lock); const uint64_t result = IsBenchmarkingLocked() && packed == WantsPackedLocked() ? generation : 0; - ReleaseSRWLockShared(&lock); return result; } void Reject() { - AcquireSRWLockExclusive(&lock); + CSRWExclusiveLock guard(lock); if (WantsPackedLocked()) { phase = Phase::LOCKED_NATIVE; ++generation; ResetStageLocked(); } - ReleaseSRWLockExclusive(&lock); } void RecordTiming(uint64_t token, bool fullCopy, uint64_t totalTime) { - AcquireSRWLockExclusive(&lock); + CSRWExclusiveLock guard(lock); if (token == generation && fullCopy) switch (phase) @@ -282,7 +278,6 @@ struct CRGB24Effect::State break; } - ReleaseSRWLockExclusive(&lock); } }; diff --git a/idd/LGIdd/transport/lgmp/CLGMPControl.cpp b/idd/LGIdd/transport/lgmp/CLGMPControl.cpp index 5a43d57f..bba7473c 100644 --- a/idd/LGIdd/transport/lgmp/CLGMPControl.cpp +++ b/idd/LGIdd/transport/lgmp/CLGMPControl.cpp @@ -207,18 +207,18 @@ void CLGMPControl::SendCursor(const IDARG_OUT_QUERY_HWCURSOR& info, void CLGMPControl::SetColorTransform( std::shared_ptr transform) { - AcquireSRWLockExclusive(&m_colorTransformLock); - m_colorTransform = std::move(transform); - ReleaseSRWLockExclusive(&m_colorTransformLock); + { + CSRWExclusiveLock lock(m_colorTransformLock); + m_colorTransform = std::move(transform); + } SendColorTransform(); } std::shared_ptr CLGMPControl::GetColorTransform() const { - AcquireSRWLockShared(&m_colorTransformLock); + CSRWSharedLock lock(m_colorTransformLock); std::shared_ptr transform = m_colorTransform; - ReleaseSRWLockShared(&m_colorTransformLock); return transform; } diff --git a/idd/LGIdd/transport/lgmp/CLGMPControl.h b/idd/LGIdd/transport/lgmp/CLGMPControl.h index c4d773af..3540b629 100644 --- a/idd/LGIdd/transport/lgmp/CLGMPControl.h +++ b/idd/LGIdd/transport/lgmp/CLGMPControl.h @@ -20,6 +20,8 @@ #pragma once +#include "CSRWLock.h" + #include "transport/lgmp/CLGMPHost.h" #include "transport/IControlTransport.h" @@ -55,7 +57,7 @@ private: int m_cursorX = 0; int m_cursorY = 0; - mutable SRWLOCK m_colorTransformLock = SRWLOCK_INIT; + mutable CSRWLock m_colorTransformLock; std::shared_ptr m_colorTransform; void SendColorTransform(); diff --git a/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.cpp b/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.cpp index ebb199f8..d014100f 100644 --- a/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.cpp +++ b/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.cpp @@ -216,19 +216,20 @@ void CLGMPFrameTransport::DeInit() { m_frameScheduler.Reset(); - AcquireSRWLockExclusive(&m_framePublishLock); - m_submittedFrameIndex.store(-1, std::memory_order_release); - m_readyFrameIndex.store(-1, std::memory_order_release); - m_deferredOwnerFrameIndex = -1; - m_framePublishSequence = 0; - memset(m_frameLastPublishSequence, 0, - sizeof(m_frameLastPublishSequence)); - memset(m_frameCompleted, 0, sizeof(m_frameCompleted)); - for (FrameDelivery& delivery : m_frameDelivery) - delivery = {}; - for (OwnerDelivery& delivery : m_ownerDelivery) - delivery = {}; - ReleaseSRWLockExclusive(&m_framePublishLock); + { + CSRWExclusiveLock lock(m_framePublishLock); + m_submittedFrameIndex.store(-1, std::memory_order_release); + m_readyFrameIndex.store(-1, std::memory_order_release); + m_deferredOwnerFrameIndex = -1; + m_framePublishSequence = 0; + memset(m_frameLastPublishSequence, 0, + sizeof(m_frameLastPublishSequence)); + memset(m_frameCompleted, 0, sizeof(m_frameCompleted)); + for (FrameDelivery& delivery : m_frameDelivery) + delivery = {}; + for (OwnerDelivery& delivery : m_ownerDelivery) + delivery = {}; + } for (int i = 0; i < LGMP_Q_FRAME_BUFFER_LEN; ++i) { @@ -444,7 +445,7 @@ void CLGMPFrameTransport::ProcessFrameDeliveries() if (!m_frameOwnerQueue[i]) return; - AcquireSRWLockExclusive(&m_framePublishLock); + CSRWExclusiveLock lock(m_framePublishLock); bool released = false; for (unsigned i = 0; i < LGMP_Q_FRAME_BUFFER_LEN; ++i) @@ -482,7 +483,7 @@ void CLGMPFrameTransport::ProcessFrameDeliveries() owner = {}; released = true; } - ReleaseSRWLockExclusive(&m_framePublishLock); + lock.Unlock(); if (released) m_frameScheduler.NotifyPublisher(); @@ -632,7 +633,7 @@ bool CLGMPFrameTransport::FrameBufferAvailable( if (!m_frameOwnerQueue[i]) return false; - AcquireSRWLockShared(&m_framePublishLock); + CSRWSharedLock lock(m_framePublishLock); bool allowReady = false; // Pipeline one frame through each independent owner lane. Count the shared // fallback against the same limit so it cannot become a third delivery for @@ -647,15 +648,11 @@ bool CLGMPFrameTransport::FrameBufferAvailable( (ownerBlocked || ownerQueuesBlocked); } else if (lgmpHostQueuePending(m_frameQueue) != 0) - { - ReleaseSRWLockShared(&m_framePublishLock); return false; - } // With no owner delivery lane available, a copy can still replace an // unreferenced retained frame and be republished when a lane clears. const bool available = FindAvailableFrameBuffer(allowReady) >= 0; - ReleaseSRWLockShared(&m_framePublishLock); return available; } @@ -679,16 +676,13 @@ bool CLGMPFrameTransport::GetPendingDeliveryTarget(uint64_t now, if (!m_frameQueue) return false; - AcquireSRWLockShared(&m_framePublishLock); + CSRWSharedLock lock(m_framePublishLock); const LONG frameIndex = m_readyFrameIndex.load(std::memory_order_acquire); if (frameIndex < 0 || m_frameInFlight[frameIndex].load(std::memory_order_acquire) || lgmpHostQueuePending(m_frameQueue) != 0) - { - ReleaseSRWLockShared(&m_framePublishLock); return false; - } uint32_t blockedClientIDs[LGMP_Q_FRAME_LEN] = {}; unsigned blockedCount = 0; @@ -699,7 +693,6 @@ bool CLGMPFrameTransport::GetPendingDeliveryTarget(uint64_t now, const bool result = m_frameScheduler.GetSecondaryTarget( m_frame[frameIndex]->frameSerial, now, blockedClientIDs, blockedCount, target); - ReleaseSRWLockShared(&m_framePublishLock); return result; } @@ -709,20 +702,17 @@ bool CLGMPFrameTransport::RetryPendingDelivery(uint64_t now, bool& retry) if (!m_frameQueue) return false; - AcquireSRWLockExclusive(&m_framePublishLock); + CSRWExclusiveLock lock(m_framePublishLock); const LONG frameIndex = m_readyFrameIndex.load(std::memory_order_acquire); if (frameIndex < 0 || m_frameInFlight[frameIndex].load(std::memory_order_acquire) || lgmpHostQueuePending(m_frameQueue) != 0) - { - ReleaseSRWLockExclusive(&m_framePublishLock); return false; - } const SharedFramePostResult result = PostSharedFrame( static_cast(frameIndex), 0, now); - ReleaseSRWLockExclusive(&m_framePublishLock); + lock.Unlock(); retry = result == SHARED_FRAME_FAILED; return result == SHARED_FRAME_POSTED; } @@ -746,7 +736,7 @@ PreparedFrameBuffer CLGMPFrameTransport::PrepareFrameBuffer( return result; } - AcquireSRWLockExclusive(&m_framePublishLock); + CSRWExclusiveLock lock(m_framePublishLock); const bool ownerBlocked = schedule.clientID && CountOwnerDeliveries(schedule.clientID) >= LGMP_Q_FRAME_LEN; const bool allowReady = allowReadyReplacement && @@ -774,7 +764,7 @@ PreparedFrameBuffer CLGMPFrameTransport::PrepareFrameBuffer( (!m_frameLastPublishSequence[availableFrameIndex] || m_framePublishSequence > m_frameLastPublishSequence[availableFrameIndex] + 1); - ReleaseSRWLockExclusive(&m_framePublishLock); + lock.Unlock(); if (!acquired) return result; const unsigned frameIndex = static_cast(availableFrameIndex); @@ -939,16 +929,13 @@ bool CLGMPFrameTransport::PublishFrameBuffer(unsigned frameIndex, return false; const uint64_t now = CFrameScheduler::Nanotime(); - AcquireSRWLockExclusive(&m_framePublishLock); + CSRWExclusiveLock lock(m_framePublishLock); CFrameScheduler::Schedule currentSchedule = {}; const bool scheduling = m_frameScheduler.GetSchedule(currentSchedule); if (scheduling != (schedule.clientID != 0) || (scheduling && !FrameScheduleMatches(schedule, currentSchedule))) - { - ReleaseSRWLockExclusive(&m_framePublishLock); return false; - } KVMFRFrame * frame = m_frame[frameIndex]; frame->timingFlags = 0; @@ -1023,7 +1010,7 @@ bool CLGMPFrameTransport::PublishFrameBuffer(unsigned frameIndex, m_submittedFrameIndex.store( static_cast(frameIndex), std::memory_order_release); } - ReleaseSRWLockExclusive(&m_framePublishLock); + lock.Unlock(); if (!published) { @@ -1042,14 +1029,11 @@ bool CLGMPFrameTransport::RepublishFrameBuffer( if (!schedule.clientID) return false; - AcquireSRWLockExclusive(&m_framePublishLock); + CSRWExclusiveLock lock(m_framePublishLock); CFrameScheduler::Schedule currentSchedule = {}; if (!m_frameScheduler.GetSchedule(currentSchedule) || !FrameScheduleMatches(schedule, currentSchedule)) - { - ReleaseSRWLockExclusive(&m_framePublishLock); return false; - } LONG frameIndex = m_deferredOwnerFrameIndex; if (frameIndex >= 0 && @@ -1063,10 +1047,7 @@ bool CLGMPFrameTransport::RepublishFrameBuffer( frameIndex = m_readyFrameIndex.load(std::memory_order_acquire); if (frameIndex < 0 || m_frameInFlight[frameIndex].load(std::memory_order_acquire)) - { - ReleaseSRWLockExclusive(&m_framePublishLock); return false; - } CFrameScheduler::Schedule deliverySchedule = schedule; deliverySchedule.deliveryDeadlineSerial = 0; @@ -1078,16 +1059,13 @@ bool CLGMPFrameTransport::RepublishFrameBuffer( { if (m_deferredOwnerFrameIndex == frameIndex) m_deferredOwnerFrameIndex = -1; - ReleaseSRWLockExclusive(&m_framePublishLock); + lock.Unlock(); m_frameScheduler.FrameRepublished(schedule, frameSerial); return true; } if (CountOwnerDeliveries(schedule.clientID) >= LGMP_Q_FRAME_LEN) - { - ReleaseSRWLockExclusive(&m_framePublishLock); return false; - } const int ownerQueueIndex = FindAvailableOwnerQueue(static_cast(frameIndex)); @@ -1097,7 +1075,7 @@ bool CLGMPFrameTransport::RepublishFrameBuffer( static_cast(frameIndex), deliverySchedule); if (published && m_deferredOwnerFrameIndex == frameIndex) m_deferredOwnerFrameIndex = -1; - ReleaseSRWLockExclusive(&m_framePublishLock); + lock.Unlock(); if (published) m_frameScheduler.FrameRepublished(schedule, frameSerial); return published; @@ -1123,7 +1101,7 @@ bool CLGMPFrameTransport::RepublishFrameBuffer( if (m_deferredOwnerFrameIndex == frameIndex) m_deferredOwnerFrameIndex = -1; } - ReleaseSRWLockExclusive(&m_framePublishLock); + lock.Unlock(); if (status != LGMP_OK || !recipientCount) { @@ -1201,7 +1179,7 @@ void CLGMPFrameTransport::AbortFrameBuffer(unsigned frameIndex) if (frameIndex >= LGMP_Q_FRAME_BUFFER_LEN) return; - AcquireSRWLockExclusive(&m_framePublishLock); + CSRWExclusiveLock lock(m_framePublishLock); m_frameBuffer[frameIndex]->wp = 0; InterlockedExchange( (volatile LONG *)&m_frame[frameIndex]->timingValid, 0); @@ -1209,7 +1187,6 @@ void CLGMPFrameTransport::AbortFrameBuffer(unsigned frameIndex) if (m_deferredOwnerFrameIndex == static_cast(frameIndex)) m_deferredOwnerFrameIndex = -1; m_frameInFlight[frameIndex].store(false, std::memory_order_release); - ReleaseSRWLockExclusive(&m_framePublishLock); } void CLGMPFrameTransport::FailFrameBuffer(unsigned frameIndex) @@ -1229,7 +1206,7 @@ void CLGMPFrameTransport::CompleteFrameBuffer( if (frameIndex >= LGMP_Q_FRAME_BUFFER_LEN) return; - AcquireSRWLockExclusive(&m_framePublishLock); + CSRWExclusiveLock lock(m_framePublishLock); m_frameCompleted[frameIndex] = succeeded; if (!succeeded && m_deferredOwnerFrameIndex == static_cast(frameIndex)) @@ -1248,7 +1225,6 @@ void CLGMPFrameTransport::CompleteFrameBuffer( static_cast(frameIndex), std::memory_order_release); } m_frameInFlight[frameIndex].store(false, std::memory_order_release); - ReleaseSRWLockExclusive(&m_framePublishLock); } void CLGMPFrameTransport::SetFrameTiming(unsigned frameIndex, diff --git a/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.h b/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.h index 22948649..d68f694b 100644 --- a/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.h +++ b/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.h @@ -20,6 +20,8 @@ #pragma once +#include "CSRWLock.h" + #include #include #include @@ -97,7 +99,7 @@ private: LONG m_deferredOwnerFrameIndex = -1; std::atomic m_frameInFlight[LGMP_Q_FRAME_BUFFER_LEN] = {}; bool m_frameCompleted[LGMP_Q_FRAME_BUFFER_LEN] = {}; - SRWLOCK m_framePublishLock = SRWLOCK_INIT; + CSRWLock m_framePublishLock; uint64_t m_framePublishSequence = 0; uint64_t m_frameLastPublishSequence[LGMP_Q_FRAME_BUFFER_LEN] = {}; diff --git a/idd/LGIdd/transport/lgmp/CLGMPHost.cpp b/idd/LGIdd/transport/lgmp/CLGMPHost.cpp index 8420b174..16812261 100644 --- a/idd/LGIdd/transport/lgmp/CLGMPHost.cpp +++ b/idd/LGIdd/transport/lgmp/CLGMPHost.cpp @@ -137,9 +137,8 @@ void CLGMPHost::DeInit() LGMP_STATUS CLGMPHost::Process() { - AcquireSRWLockExclusive(&m_processLock); + CSRWExclusiveLock lock(m_processLock); const LGMP_STATUS status = lgmpHostProcess(m_host); - ReleaseSRWLockExclusive(&m_processLock); return status; } diff --git a/idd/LGIdd/transport/lgmp/CLGMPHost.h b/idd/LGIdd/transport/lgmp/CLGMPHost.h index 55eac167..09966f1a 100644 --- a/idd/LGIdd/transport/lgmp/CLGMPHost.h +++ b/idd/LGIdd/transport/lgmp/CLGMPHost.h @@ -20,6 +20,8 @@ #pragma once +#include "CSRWLock.h" + #include #include @@ -34,8 +36,8 @@ class CIVSHMEM; class CLGMPHost { private: - PLGMPHost m_host = nullptr; - SRWLOCK m_processLock = SRWLOCK_INIT; + PLGMPHost m_host = nullptr; + CSRWLock m_processLock; public: CLGMPHost() = default; diff --git a/idd/LGIdd/transport/lgmp/CLGMPInputTransport.cpp b/idd/LGIdd/transport/lgmp/CLGMPInputTransport.cpp index 25799394..280731f7 100644 --- a/idd/LGIdd/transport/lgmp/CLGMPInputTransport.cpp +++ b/idd/LGIdd/transport/lgmp/CLGMPInputTransport.cpp @@ -179,7 +179,7 @@ void CLGMPInputTransport::PublishStatus() bool CLGMPInputTransport::Start(IInputSink& sink) { - CSRWExclusiveLock lock(&m_lifecycleLock); + CSRWExclusiveLock lock(m_lifecycleLock); if (m_thread) { const DWORD state = WaitForSingleObject(m_thread, 0); @@ -249,7 +249,7 @@ bool CLGMPInputTransport::Start(IInputSink& sink) void CLGMPInputTransport::Stop() { - CSRWExclusiveLock lock(&m_lifecycleLock); + CSRWExclusiveLock lock(m_lifecycleLock); if (m_stopEvent) SetEvent(m_stopEvent); diff --git a/idd/LGIdd/transport/lgmp/CLGMPInputTransport.h b/idd/LGIdd/transport/lgmp/CLGMPInputTransport.h index 44e4c133..74b3c233 100644 --- a/idd/LGIdd/transport/lgmp/CLGMPInputTransport.h +++ b/idd/LGIdd/transport/lgmp/CLGMPInputTransport.h @@ -20,6 +20,7 @@ #pragma once +#include "CSRWLock.h" #include "transport/IInputTransport.h" #include "common/LGMPConfig.h" @@ -64,10 +65,10 @@ private: PLGMPMemory m_statusMemory[LGMP_Q_INPUT_LEN] = {}; IInputSink * m_sink = nullptr; - SRWLOCK m_lifecycleLock = SRWLOCK_INIT; - HANDLE m_stopEvent = nullptr; - HANDLE m_pollTimer = nullptr; - HANDLE m_thread = nullptr; + CSRWLock m_lifecycleLock; + HANDLE m_stopEvent = nullptr; + HANDLE m_pollTimer = nullptr; + HANDLE m_thread = nullptr; uint32_t m_ownerClientID = 0; uint32_t m_ownerGeneration = 0; diff --git a/idd/LGIddHelper/CPipeClient.cpp b/idd/LGIddHelper/CPipeClient.cpp index 5970c906..7cfa32f8 100644 --- a/idd/LGIddHelper/CPipeClient.cpp +++ b/idd/LGIddHelper/CPipeClient.cpp @@ -20,6 +20,7 @@ #include "CPipeClient.h" #include "CDebug.h" +#include "CSRWLock.h" #include "CNotifyWindow.h" #include @@ -323,10 +324,8 @@ bool CPipeClient::EnsureOnlyDisplayLocked() bool CPipeClient::EnsureOnlyDisplay() { - AcquireSRWLockExclusive(&m_displayLock); - const bool result = EnsureOnlyDisplayLocked(); - ReleaseSRWLockExclusive(&m_displayLock); - return result; + CSRWExclusiveLock lock(m_displayLock); + return EnsureOnlyDisplayLocked(); } bool CPipeClient::OnPipeMessage(const void * message, size_t size) @@ -370,32 +369,32 @@ void CPipeClient::HandleSetCursorPos(const LGPipeMsg& msg) void CPipeClient::HandleSetDisplayMode(const LGPipeMsg& msg) { - AcquireSRWLockExclusive(&m_displayLock); - - std::vector displays; - size_t lgIndex; - if (!GetDisplayStates(displays, lgIndex)) + LONG result; { - ReleaseSRWLockExclusive(&m_displayLock); - DEBUG_ERROR("Looking Glass display not found while setting its mode"); - return; + CSRWExclusiveLock lock(m_displayLock); + + std::vector displays; + size_t lgIndex; + if (!GetDisplayStates(displays, lgIndex)) + { + DEBUG_ERROR("Looking Glass display not found while setting its mode"); + return; + } + + DEVMODE dm = displays[lgIndex].mode; + dm.dmPelsWidth = msg.displayMode.width; + dm.dmPelsHeight = msg.displayMode.height; + dm.dmDisplayFrequency = + (msg.displayMode.refreshMilliHz + 500) / 1000; + dm.dmFields = + DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY; + + result = ChangeDisplaySettingsEx(displays[lgIndex].device.DeviceName, + &dm, NULL, CDS_UPDATEREGISTRY, NULL); + if (result != DISP_CHANGE_SUCCESSFUL) + DEBUG_ERROR("ChangeDisplaySettingsEx Failed (0x%08x)", result); } - DEVMODE dm = displays[lgIndex].mode; - dm.dmPelsWidth = msg.displayMode.width; - dm.dmPelsHeight = msg.displayMode.height; - dm.dmDisplayFrequency = - (msg.displayMode.refreshMilliHz + 500) / 1000; - dm.dmFields = - DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY; - - LONG result = ChangeDisplaySettingsEx(displays[lgIndex].device.DeviceName, - &dm, NULL, CDS_UPDATEREGISTRY, NULL); - if (result != DISP_CHANGE_SUCCESSFUL) - DEBUG_ERROR("ChangeDisplaySettingsEx Failed (0x%08x)", result); - - ReleaseSRWLockExclusive(&m_displayLock); - if (result == DISP_CHANGE_SUCCESSFUL) EnsureOnlyDisplay(); } diff --git a/idd/LGIddHelper/CPipeClient.h b/idd/LGIddHelper/CPipeClient.h index b51a64a4..a3581e0b 100644 --- a/idd/LGIddHelper/CPipeClient.h +++ b/idd/LGIddHelper/CPipeClient.h @@ -24,13 +24,14 @@ #include #include "CPipeEndpoint.h" +#include "CSRWLock.h" #include "PipeMsg.h" class CPipeClient : private IPipeEndpointHandler { private: CPipeEndpoint m_endpoint; - SRWLOCK m_displayLock = SRWLOCK_INIT; + CSRWLock m_displayLock; void WriteMsg(const LGPipeMsg& msg); diff --git a/idd/LGInput/CHIDDevice.cpp b/idd/LGInput/CHIDDevice.cpp index 09d6ec92..8b68e705 100644 --- a/idd/LGInput/CHIDDevice.cpp +++ b/idd/LGInput/CHIDDevice.cpp @@ -64,8 +64,8 @@ struct HIDDeviceContext HID_DEVICE_ATTRIBUTES attributes; HID_DESCRIPTOR descriptor; UCHAR keyboardLeds; - SRWLOCK lifecycleLock; - SRWLOCK reportLock; + CSRWLock lifecycleLock; + CSRWLock reportLock; bool active; bool stopping; UCHAR mouseMode; @@ -83,8 +83,8 @@ struct HIDDeviceContext WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(HIDDeviceContext, HIDGetDeviceContext); -static SRWLOCK s_deviceLock = SRWLOCK_INIT; -static HIDDeviceContext * s_device = nullptr; +static CSRWLock s_deviceLock; +static HIDDeviceContext * s_device = nullptr; EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL HIDEvtIoDeviceControl; EVT_WDF_OBJECT_CONTEXT_CLEANUP HIDEvtReportQueueCleanup; @@ -312,7 +312,7 @@ static NTSTATUS ReadReport( NTSTATUS status; { - CSRWExclusiveLock lock(&context->reportLock); + CSRWExclusiveLock lock(context->reportLock); if (context->stopping || !context->active) status = STATUS_DEVICE_NOT_READY; else if (context->reportCount) @@ -335,8 +335,8 @@ static NTSTATUS ReadReport( static NTSTATUS ActivateDevice(_Inout_ HIDDeviceContext * context) { - CSRWExclusiveLock lifecycleLock(&context->lifecycleLock); - CSRWExclusiveLock lock(&context->reportLock); + CSRWExclusiveLock lifecycleLock(context->lifecycleLock); + CSRWExclusiveLock lock(context->reportLock); if (context->stopping) return STATUS_DEVICE_NOT_READY; @@ -347,9 +347,9 @@ static NTSTATUS ActivateDevice(_Inout_ HIDDeviceContext * context) static NTSTATUS DeactivateDevice(_Inout_ HIDDeviceContext * context) { - CSRWExclusiveLock lifecycleLock(&context->lifecycleLock); + CSRWExclusiveLock lifecycleLock(context->lifecycleLock); { - CSRWExclusiveLock lock(&context->reportLock); + CSRWExclusiveLock lock(context->reportLock); if (context->stopping) return STATUS_DEVICE_NOT_READY; @@ -412,10 +412,8 @@ NTSTATUS CHIDDevice::Create(_Inout_ PWDFDEVICE_INIT deviceInit) return status; HIDDeviceContext * context = HIDGetDeviceContext(device); - RtlZeroMemory(context, sizeof(*context)); - InitializeSRWLock(&context->lifecycleLock); - InitializeSRWLock(&context->reportLock); - context->active = true; + new (context) HIDDeviceContext {}; + context->active = true; context->inputPipe = new (std::nothrow) CInputPipeClient; if (!context->inputPipe) return STATUS_INSUFFICIENT_RESOURCES; @@ -442,7 +440,7 @@ NTSTATUS CHIDDevice::Create(_Inout_ PWDFDEVICE_INIT deviceInit) return status; { - CSRWExclusiveLock lock(&s_deviceLock); + CSRWExclusiveLock lock(s_deviceLock); if (s_device) { DEBUG_ERROR("Only one LGInput device instance is supported"); @@ -464,7 +462,7 @@ NTSTATUS CHIDDevice::SubmitReport( if (HIDGetInputReportSize(reportId) != size) return STATUS_INVALID_PARAMETER; - CSRWSharedLock deviceLock(&s_deviceLock); + CSRWSharedLock deviceLock(s_deviceLock); HIDDeviceContext * context = s_device; if (!context) return STATUS_DEVICE_NOT_READY; @@ -472,7 +470,7 @@ NTSTATUS CHIDDevice::SubmitReport( WDFREQUEST request = nullptr; NTSTATUS status; { - CSRWExclusiveLock reportLock(&context->reportLock); + CSRWExclusiveLock reportLock(context->reportLock); if (context->stopping || !context->active) status = STATUS_DEVICE_NOT_READY; else @@ -574,12 +572,12 @@ NTSTATUS CHIDDevice::ResetReports() uint16_t absoluteX = 0; uint16_t absoluteY = 0; { - CSRWSharedLock deviceLock(&s_deviceLock); + CSRWSharedLock deviceLock(s_deviceLock); HIDDeviceContext * context = s_device; if (!context) return STATUS_DEVICE_NOT_READY; - CSRWExclusiveLock reportLock(&context->reportLock); + CSRWExclusiveLock reportLock(context->reportLock); if (context->stopping) return STATUS_DEVICE_NOT_READY; @@ -655,12 +653,12 @@ void CHIDDevice::LogStatistics() { HIDStatistics statistics = {}; { - CSRWSharedLock deviceLock(&s_deviceLock); + CSRWSharedLock deviceLock(s_deviceLock); HIDDeviceContext * context = s_device; if (!context) return; - CSRWExclusiveLock reportLock(&context->reportLock); + CSRWExclusiveLock reportLock(context->reportLock); statistics = context->statistics; context->statistics = {}; context->statistics.queueHighWater = context->reportCount; @@ -752,12 +750,12 @@ VOID HIDEvtReportQueueCleanup(_In_ WDFOBJECT object) HIDDeviceContext * context = HIDGetDeviceContext(WdfIoQueueGetDevice((WDFQUEUE)object)); - CSRWExclusiveLock deviceLock(&s_deviceLock); + CSRWExclusiveLock deviceLock(s_deviceLock); if (s_device == context) s_device = nullptr; { - CSRWExclusiveLock reportLock(&context->reportLock); + CSRWExclusiveLock reportLock(context->reportLock); context->stopping = true; context->reportHead = 0; context->reportCount = 0; @@ -774,7 +772,7 @@ VOID HIDEvtDeviceCleanup(_In_ WDFOBJECT object) context->inputPipe = nullptr; } - CSRWExclusiveLock deviceLock(&s_deviceLock); + CSRWExclusiveLock deviceLock(s_deviceLock); if (s_device == context) s_device = nullptr; }