diff --git a/src/core/cdrom_async_reader.cpp b/src/core/cdrom_async_reader.cpp index c298767a5..07711df68 100644 --- a/src/core/cdrom_async_reader.cpp +++ b/src/core/cdrom_async_reader.cpp @@ -101,9 +101,28 @@ void CDROMAsyncReader::QueueReadSector(CDImage::LBA lba) bool CDROMAsyncReader::ReadSectorUncached(CDImage::LBA lba, CDImage::SubChannelQ* subq, SectorBuffer* data) { - if (IsUsingThread()) - CancelReadahead(); + if (!IsUsingThread()) + return InternalReadSectorUncached(lba, subq, data); + std::unique_lock lock(m_mutex); + + // wait until the read thread is idle + m_notify_read_complete_cv.wait(lock, [this]() { return !m_is_reading.load(); }); + + // read while the lock is held so it has to wait + const CDImage::LBA prev_lba = m_media->GetPositionOnDisc(); + const bool result = InternalReadSectorUncached(lba, subq, data); + if (!m_media->Seek(prev_lba)) + { + Log_ErrorPrintf("Failed to re-seek to cached position %u", prev_lba); + m_can_readahead.store(false); + } + + return result; +} + +bool CDROMAsyncReader::InternalReadSectorUncached(CDImage::LBA lba, CDImage::SubChannelQ* subq, SectorBuffer* data) +{ if (m_media->GetPositionOnDisc() != lba && !m_media->Seek(lba)) { Log_WarningPrintf("Seek to LBA %u failed", lba); diff --git a/src/core/cdrom_async_reader.h b/src/core/cdrom_async_reader.h index 76e3d9273..2664821cc 100644 --- a/src/core/cdrom_async_reader.h +++ b/src/core/cdrom_async_reader.h @@ -52,6 +52,7 @@ private: void EmptyBuffers(); bool ReadSectorIntoBuffer(std::unique_lock& lock); void ReadSectorNonThreaded(CDImage::LBA lba); + bool InternalReadSectorUncached(CDImage::LBA lba, CDImage::SubChannelQ* subq, SectorBuffer* data); void CancelReadahead(); void WorkerThreadEntryPoint(); @@ -67,12 +68,12 @@ private: std::atomic_bool m_next_position_set{false}; std::atomic_bool m_shutdown_flag{true}; - std::atomic_bool m_is_reading{ false }; - std::atomic_bool m_can_readahead{ false }; - std::atomic_bool m_seek_error{ false }; + std::atomic_bool m_is_reading{false}; + std::atomic_bool m_can_readahead{false}; + std::atomic_bool m_seek_error{false}; std::vector m_buffers; - std::atomic m_buffer_front{ 0 }; - std::atomic m_buffer_back{ 0 }; - std::atomic m_buffer_count{ 0 }; + std::atomic m_buffer_front{0}; + std::atomic m_buffer_back{0}; + std::atomic m_buffer_count{0}; };