3 changed files with 24 additions and 9 deletions
@ -1,20 +1,34 @@
|
||||
/* Единственный владелец desktop-микрофона: звонок, рация, запись либо трансляция.
|
||||
/* Desktop-микрофон: publisher получает Exclusive, существующие voice-контуры — Shared.
|
||||
* Сохраняется совместная работа звонка/рации/записи; publisher исключает остальные captures в обе стороны. |
||||
* Lease берётся до открытия backend, сохраняется при recovery и освобождается после close/join. |
||||
* Inline состояние общее для translation units; callback не обращается к lease. */ |
||||
* Каждый lease использует управляющий поток, общее atomic состояние доступно из разных потоков. */ |
||||
#pragma once |
||||
#include <atomic> |
||||
class AudioCaptureLease { |
||||
public: |
||||
AudioCaptureLease() = default; |
||||
enum class Mode { Shared, Exclusive }; |
||||
explicit AudioCaptureLease(Mode mode = Mode::Shared) : m_mode(mode) {} |
||||
~AudioCaptureLease() { release(); } |
||||
AudioCaptureLease(const AudioCaptureLease&) = delete; |
||||
AudioCaptureLease& operator=(const AudioCaptureLease&) = delete; |
||||
bool acquire() { |
||||
const void* expected = nullptr; |
||||
return owner.compare_exchange_strong(expected, this) || expected == this; |
||||
if (m_held) return true; |
||||
int expected = 0; |
||||
if (m_mode == Mode::Exclusive) m_held = owners.compare_exchange_strong(expected, -1); |
||||
else { |
||||
expected = owners.load(); |
||||
while (expected >= 0) if (owners.compare_exchange_weak(expected, expected + 1)) { m_held = true; break; } |
||||
} |
||||
return m_held; |
||||
} |
||||
void release() { const void* expected = this; owner.compare_exchange_strong(expected, nullptr); } |
||||
bool held() const { return owner.load() == this; } |
||||
void release() { |
||||
if (!m_held) return; |
||||
if (m_mode == Mode::Exclusive) owners.store(0); else owners.fetch_sub(1); |
||||
m_held = false; |
||||
} |
||||
bool held() const { return m_held; } |
||||
private: |
||||
static inline std::atomic<const void*> owner{nullptr}; |
||||
Mode m_mode; |
||||
bool m_held = false; |
||||
static inline std::atomic<int> owners{0}; |
||||
}; |
||||
|
||||
Loading…
Reference in new issue