With a timeout specified as INFINITE in the following code, a deadlock can occur randomly since no messages will be able to be processed:Use caution when calling the wait functions and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. A thread that uses a wait function with no time-out interval may cause the system to become deadlocked. Two examples of code that indirectly creates windows are DDE and the CoInitialize function. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than WaitForSingleObjectEx.
Code: Select all
do
vlc_testcancel ();
while (WaitForSingleObjectEx (handle, INFINITE, TRUE) == WAIT_IO_COMPLETION);
Code: Select all
private void StopVideo()
{
VlcMediaPlayer p1 = player1MediaPlayer;
VlcMediaPlayer p2 = player2MediaPlayer;
if (p1 != null)
p1.Stop();
if (p2 != null)
p2.Stop();
}
private void VideoForm_FormClosing(object sender, FormClosingEventArgs e)
{
Thread t = new Thread(new ThreadStart(StopVideo));
t.Start();
}
Code: Select all
ret = MsgWaitForMultipleObjects (1, &handle, INFINITE, NULL, NULL);
if (ret == WAIT_OBJECT_0 + 1)
{
/* PROCESS THE MESSAGE */
BOOL bRet;
while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
LOOP again until we receive WAIT_OBJECT_0
}
The documentation cleary state that if a thread process messages, it NEED use MsgWaitForMultipleObjectsIt is not clear to me that the Win32 documentation would require the use of MsgWaitForMultipleObjects(Ex) instead of WaitForMultipleObjects(Ex), WaitForSingleObject(Ex) and Sleep(Ex) in threads that have created windows. In particular, LibVLC should not need any window messages to wait for another thread to complete.
If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. A thread that uses a wait function with no time-out interval may cause the system to become deadlocked. Two examples of code that indirectly creates windows are DDE and the CoInitialize function. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than WaitForMultipleObjects.
I don´t see how this could generate any reentrancy problems. Could explain it ?The proposed change may reentrancy problems in the window events procedures that did not get called from LibVLC and now would get called.
No you got it wrong. The main loop of applications could do anything, if it not create window, MsgWait.. will behave exactly as WaitForMultipleObjects.It might interfere with the main loop of the applications, if they did anything other than just TranslateMessage/DispatchMessage.
The patch is here : http://mailman.videolan.org/pipermail/v ... 81125.htmlNobody has reviewied the proposed patch on vlc-devel.
Code: Select all
---
src/win32/thread.c | 14 +++++++++++++-
1 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/src/win32/thread.c b/src/win32/thread.c
index 00c2781..f4521b1 100644
--- a/src/win32/thread.c
+++ b/src/win32/thread.c
@@ -125,7 +125,19 @@ BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
static DWORD vlc_WaitForMultipleObjects (DWORD count, const HANDLE *handles,
DWORD delay)
{
- DWORD ret = WaitForMultipleObjectsEx (count, handle, FALSE, delay, TRUE);
+ DWORD ret;
+ for (;;)
+ {
+ ret = MsgWaitForMultipleObjectsEx (count, handle, delay,
+ QS_ALLINPUT, MWMO_ALTERTABLE);
+ if (ret == WAIT_OBJECT_0 + count)/* We have a message to process, dispatch it, then come back to processing */
+ {
+ MSG msg;
+
+ while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage (&msg);
+ DispatchMessage (&msg);
+ }
+ }
+ else
+ break;
+ }
/* We do not abandon objects... this would be a bug */
assert (ret < WAIT_ABANDONED_0 || WAIT_ABONDONED_0 + count - 1 < ret);
--
The point is, there is no reason why the the thread would have process a message in the first place. Waiting for another VLC thread to exit does not require processing messages to make any progress. Thus the thread should be perfectly fine postponing the message processing until LibVLC unwinds and the calling application main loop is reached.The documentation cleary state that if a thread process messages, it NEED use MsgWaitForMultipleObjects
It's obvious! You'd be calling the window procedure from a site, within LibVLC, where it was not called earlier.I don´t see how this could generate any reentrancy problems. Could explain it ?
If it does not create a window, then it won't make a difference indeed. But this is a stupid irrelevant point.No you got it wrong. The main loop of applications could do anything, if it not create window, MsgWait.. will behave exactly as WaitForMultipleObjects.It might interfere with the main loop of the applications, if they did anything other than just TranslateMessage/DispatchMessage.
Return to “Development around libVLC”
Users browsing this forum: m1adow and 7 guests