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. |
* Lease берётся до открытия backend, сохраняется при recovery и освобождается после close/join. |
||||||
* Inline состояние общее для translation units; callback не обращается к lease. */ |
* Каждый lease использует управляющий поток, общее atomic состояние доступно из разных потоков. */ |
||||||
#pragma once |
#pragma once |
||||||
#include <atomic> |
#include <atomic> |
||||||
class AudioCaptureLease { |
class AudioCaptureLease { |
||||||
public: |
public: |
||||||
AudioCaptureLease() = default; |
enum class Mode { Shared, Exclusive }; |
||||||
|
explicit AudioCaptureLease(Mode mode = Mode::Shared) : m_mode(mode) {} |
||||||
~AudioCaptureLease() { release(); } |
~AudioCaptureLease() { release(); } |
||||||
AudioCaptureLease(const AudioCaptureLease&) = delete; |
AudioCaptureLease(const AudioCaptureLease&) = delete; |
||||||
AudioCaptureLease& operator=(const AudioCaptureLease&) = delete; |
AudioCaptureLease& operator=(const AudioCaptureLease&) = delete; |
||||||
bool acquire() { |
bool acquire() { |
||||||
const void* expected = nullptr; |
if (m_held) return true; |
||||||
return owner.compare_exchange_strong(expected, this) || expected == this; |
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); } |
void release() { |
||||||
bool held() const { return owner.load() == this; } |
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: |
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