Rémi Bernon (@rbernon) commented about dlls/windows.media.speech/recognizer.c:
- TRACE("iface %p, action %p.\n", iface, action);
- *action = NULL;
- EnterCriticalSection(&impl->cs);
- if (!(running = impl->worker_running))
- {
impl->worker_running = TRUE;
- }
- LeaveCriticalSection(&impl->cs);
- if (running)
hr = COR_E_INVALIDOPERATION;
- else
hr = async_action_create((IInspectable *)iface, session_start_async, action);
I'm not completely sure how this should be done, but you have a race condition here. For instance, if:
1) StartAsync is called, setting worker_running to TRUE,
2) StopAsync is called, setting worker_running to FALSE,
3) session_stop_async is executed, not doing anything as the thread isn't started,
4) session_start_async is executed, starting the thread, setting the thread handle.
The thread will exit quickly as running is false, but you'll end up with an inconsistent state.
I think it's perhaps better to do everything in the async callbacks, serialized with the critical section. Or otherwise in the method itself, and have the callbacks do nothing (not sure if asynchronicity really matters here).