| 542 | } |
| 543 | |
| 544 | void FreeSource(ALCcontext *context, ALsource *source) |
| 545 | { |
| 546 | const ALuint id{source->id - 1}; |
| 547 | const size_t lidx{id >> 6}; |
| 548 | const ALuint slidx{id & 0x3f}; |
| 549 | |
| 550 | if(IsPlayingOrPaused(source)) |
| 551 | { |
| 552 | ALCdevice *device{context->mDevice.get()}; |
| 553 | BackendLockGuard _{*device->Backend}; |
| 554 | if(ALvoice *voice{GetSourceVoice(source, context)}) |
| 555 | { |
| 556 | voice->mCurrentBuffer.store(nullptr, std::memory_order_relaxed); |
| 557 | voice->mLoopBuffer.store(nullptr, std::memory_order_relaxed); |
| 558 | voice->mSourceID.store(0u, std::memory_order_relaxed); |
| 559 | std::atomic_thread_fence(std::memory_order_release); |
| 560 | /* Don't set the voice to stopping if it was already stopped or |
| 561 | * stopping. |
| 562 | */ |
| 563 | ALvoice::State oldvstate{ALvoice::Playing}; |
| 564 | voice->mPlayState.compare_exchange_strong(oldvstate, ALvoice::Stopping, |
| 565 | std::memory_order_acq_rel, std::memory_order_acquire); |
| 566 | } |
| 567 | } |
| 568 | |
| 569 | al::destroy_at(source); |
| 570 | |
| 571 | context->mSourceList[lidx].FreeMask |= 1_u64 << slidx; |
| 572 | context->mNumSources--; |
| 573 | } |
| 574 | |
| 575 | |
| 576 | inline ALsource *LookupSource(ALCcontext *context, ALuint id) noexcept |
no test coverage detected