nvda
3207d485 - Fix race in nvdaController_speakSsml where speechCanceled could be missed (#20220)

Commit
11 days ago
Fix race in nvdaController_speakSsml where speechCanceled could be missed (#20220) Summary of the issue: When nvdaController_speakSsml is called with asynchronous=False, a race condition can cause the call to block indefinitely. onSpeechCanceled was registered inside prefixCallback, a CallbackCommand that runs on the synth thread only after the sequence starts. If speechCanceled fires in the window between queueHandler.queueFunction returning and the synth reaching that CallbackCommand, the signal is missed and markQueue.get() never unblocks. Description of user facing changes: No change under normal operation. Fixes a hang that could occur when speech is cancelled immediately after being queued via the controller client. Description of developer facing changes: speech.speechCanceled.register(onSpeechCanceled) is now called directly before queueHandler.queueFunction, ensuring the handler exists before any cancel signal can fire. onDoneSpeaking stays in prefixCallback because synthDoneSpeaking fires per sequence — registering it earlier would catch a previous sequence still finishing when priority is Next. Description of development approach: Minimal repositioning of one register call. No logic changes. Testing strategy: Call nvdaController_speakSsml with asynchronous=False and cancel speech immediately after queuing, repeatedly. Before this fix the call would occasionally hang; after it should always return promptly with ERROR_CANCELLED.
Author
Parents
Loading