Commit cf8a25f0 authored by Alexandre Julliard's avatar Alexandre Julliard

Do not kill the animation thread with TerminateThread, let it finish

properly. Fixed a couple of races with the animation thread.
parent 3c6956d3
...@@ -71,6 +71,7 @@ typedef struct ...@@ -71,6 +71,7 @@ typedef struct
LPVOID outdata; LPVOID outdata;
/* data for the background mechanism */ /* data for the background mechanism */
CRITICAL_SECTION cs; CRITICAL_SECTION cs;
HANDLE hStopEvent;
HANDLE hThread; HANDLE hThread;
UINT uTimer; UINT uTimer;
/* data for playing the file */ /* data for playing the file */
...@@ -145,9 +146,17 @@ static LRESULT ANIMATE_DoStop(ANIMATE_INFO *infoPtr) ...@@ -145,9 +146,17 @@ static LRESULT ANIMATE_DoStop(ANIMATE_INFO *infoPtr)
/* should stop playing */ /* should stop playing */
if (infoPtr->hThread) if (infoPtr->hThread)
{ {
if (!TerminateThread(infoPtr->hThread,0)) HANDLE handle = infoPtr->hThread;
WARN("could not destroy animation thread!\n");
infoPtr->hThread = 0; TRACE("stopping animation thread\n");
SetEvent( infoPtr->hStopEvent );
LeaveCriticalSection(&infoPtr->cs); /* leave it a chance to run */
WaitForSingleObject( handle, INFINITE );
TRACE("animation thread stopped\n");
EnterCriticalSection(&infoPtr->cs);
CloseHandle( infoPtr->hThread );
CloseHandle( infoPtr->hStopEvent );
infoPtr->hThread = 0;
} }
if (infoPtr->uTimer) { if (infoPtr->uTimer) {
KillTimer(infoPtr->hwndSelf, infoPtr->uTimer); KillTimer(infoPtr->hwndSelf, infoPtr->uTimer);
...@@ -378,33 +387,20 @@ static LRESULT ANIMATE_DrawFrame(ANIMATE_INFO* infoPtr) ...@@ -378,33 +387,20 @@ static LRESULT ANIMATE_DrawFrame(ANIMATE_INFO* infoPtr)
static DWORD CALLBACK ANIMATE_AnimationThread(LPVOID ptr_) static DWORD CALLBACK ANIMATE_AnimationThread(LPVOID ptr_)
{ {
ANIMATE_INFO* infoPtr = (ANIMATE_INFO*)ptr_; ANIMATE_INFO* infoPtr = (ANIMATE_INFO*)ptr_;
HDC hDC; HANDLE event;
DWORD timeout;
if(!infoPtr)
{
WARN("animation structure undefined!\n");
return FALSE;
}
while(1) while(1)
{ {
if(GetWindowLongA(infoPtr->hwndSelf, GWL_STYLE) & ACS_TRANSPARENT)
{
hDC = GetDC(infoPtr->hwndSelf);
/* sometimes the animation window will be destroyed in between
* by the main program, so a ReleaseDC() error msg is possible */
infoPtr->hbrushBG = (HBRUSH)SendMessageA(infoPtr->hwndNotify,
WM_CTLCOLORSTATIC, (WPARAM)hDC,
(LPARAM)infoPtr->hwndSelf);
ReleaseDC(infoPtr->hwndSelf,hDC);
}
EnterCriticalSection(&infoPtr->cs); EnterCriticalSection(&infoPtr->cs);
ANIMATE_DrawFrame(infoPtr); ANIMATE_DrawFrame(infoPtr);
timeout = infoPtr->mah.dwMicroSecPerFrame;
event = infoPtr->hStopEvent;
LeaveCriticalSection(&infoPtr->cs); LeaveCriticalSection(&infoPtr->cs);
/* time is in microseconds, we should convert it to milliseconds */ /* time is in microseconds, we should convert it to milliseconds */
Sleep((infoPtr->mah.dwMicroSecPerFrame+500)/1000); if (WaitForSingleObject( event, (timeout+500)/1000) == WAIT_OBJECT_0)
break;
} }
return TRUE; return TRUE;
} }
...@@ -445,13 +441,22 @@ static LRESULT ANIMATE_Play(HWND hWnd, WPARAM wParam, LPARAM lParam) ...@@ -445,13 +441,22 @@ static LRESULT ANIMATE_Play(HWND hWnd, WPARAM wParam, LPARAM lParam)
} else { } else {
DWORD threadID; DWORD threadID;
if(GetWindowLongA(hWnd, GWL_STYLE) & ACS_TRANSPARENT)
{
HDC hDC = GetDC(hWnd);
infoPtr->hbrushBG = (HBRUSH)SendMessageA(infoPtr->hwndNotify,
WM_CTLCOLORSTATIC, 0, (LPARAM)hWnd);
ReleaseDC(hWnd,hDC);
}
TRACE("Using an animation thread\n"); TRACE("Using an animation thread\n");
infoPtr->hStopEvent = CreateEventW( NULL, TRUE, FALSE, NULL );
infoPtr->hThread = CreateThread(0,0,ANIMATE_AnimationThread,(LPVOID)infoPtr, 0, &threadID); infoPtr->hThread = CreateThread(0,0,ANIMATE_AnimationThread,(LPVOID)infoPtr, 0, &threadID);
if(!infoPtr->hThread) if(!infoPtr->hThread)
{ {
ERR("Could not create animation thread!\n"); ERR("Could not create animation thread!\n");
return FALSE; return FALSE;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment