Monday, February 09, 2009 7:53 AM
I got a deadlock when I am developing a DirectShow application. I found that deadlock occurs when the Sample Graber is calling the callback function. And the main thread call control->Stop(), then the program gose into deadlock. I trace it with Visual C++ 2008 Express. I see there are two thread is waiting for something. One is the main thread calling Stop, another is the graph thread is waitting for a lock in Sample Graber callback function.
The doc from MSDN http://msdn.microsoft.com/en-us/library/ms786692(VS.85).aspx said:
"If the sample is a Microsoft® DirectDraw® surface, the surface is locked during the callback. The Win16 lock (also called Win16Mutex) might be locked as well. Both of these locks create the potential for deadlock. If the callback thread waits for a thread that is trying to call a DirectDraw API, it can cause deadlock. In addition, if the Win16 lock is being held, deadlock can result if the callback holds a critical section or waits for another thread to complete any activity.
Therefore, the callback should not perform any actions with the potential to block, such as holding a critical section or waiting on another thread. Also, do not call any GDI or USER32.DLL APIs that might cause a window to move. For more information about the Win16 lock, see Knowledge Base article Q125867, Understanding Win16Mutex."
So to avoid deadlock, I should not acquire any lock in the graber callback function? How can I do if I want to output audio to another thread?
Monday, February 09, 2009 8:03 AMSample Grabber calls the callback on internal worker thread, typically owned by source filter, and you should be very much accurate entering critical sections in the callback function or using other synchronization techniques. If you want to send data outside graph, do this asynchronously by taking a copy of data and signaling by setting an event or posting a message (see PostMessage discussed in a neighboring thread) so that this signal is caught outside of the graph and the callback and processing continues without blocking the original graph.
- Marked As Answer by VictorLin Monday, February 09, 2009 12:35 PM
Tuesday, February 10, 2009 4:20 AM
I think I know why I got a deadlock, that might not be the problem of DirectShow.
The main thread is own by Python, it call stop, namely, it hold GIL. And the stop wait for callback of DirectShow in thread return. But callback acquire the GIL.
It looks like this
Main(Hold GIL) -> Stop(Wait callback) -> Callback(Wait GIL) -> GIL(Hold by Main thread)
Damn it! That's why I don't like multi-thread so much.
No matter what, thanks your help.