// Copyright (c) 2026 Storm Dragon // SPDX-License-Identifier: GPL-3.0-or-later package app import "context" // revokePresentation drops only the retiring owner's pending speech. If that // owner has reached delivery, cancel it through the existing backend barrier // while preserving newer core requests behind the barrier. The next delivered // request owns backend speech, independently of what is still in the queue. func (worker *speechWorker) revokePresentation(owner context.Context) { worker.mutex.Lock() defer worker.mutex.Unlock() retained := worker.pending[:0] for _, request := range worker.pending { if request.presentationGeneration != nil && request.context == owner { completeSpeechRequest(request, context.Canceled) } else { retained = append(retained, request) } } clear(worker.pending[len(retained):]) worker.pending = retained if worker.presentationDelivery != owner || !worker.running { return } worker.presentationDelivery = nil if worker.beepCancel != nil { worker.beepCancel() } worker.generation++ worker.interrupting = true select { case worker.interrupt <- struct{}{}: default: } }