Prevent the animation thread from waiting on itself when it stops.
authorUlrich Czekalla <ulrich@codeweavers.com>
Wed, 1 Dec 2004 15:27:18 +0000 (15:27 +0000)
committerAlexandre Julliard <julliard@winehq.org>
Wed, 1 Dec 2004 15:27:18 +0000 (15:27 +0000)
dlls/comctl32/animate.c

index ac6ddba0d356978aaed866ed5faa892e8ba00619..374b3b1111c31f45fccd910cdb35717f0eeb3b96 100644 (file)
@@ -73,6 +73,7 @@ typedef struct
    CRITICAL_SECTION    cs;
    HANDLE              hStopEvent;
    HANDLE              hThread;
+   DWORD               threadId;
    UINT                        uTimer;
    /* data for playing the file */
    int                 nFromFrame;
@@ -149,14 +150,20 @@ static LRESULT ANIMATE_DoStop(ANIMATE_INFO *infoPtr)
         HANDLE handle = infoPtr->hThread;
 
         TRACE("stopping animation thread\n");
+        infoPtr->hThread = 0;
         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 );
+
+        if (infoPtr->threadId != GetCurrentThreadId())
+        {
+            LeaveCriticalSection(&infoPtr->cs);  /* leave it a chance to run */
+            WaitForSingleObject( handle, INFINITE );
+            TRACE("animation thread stopped\n");
+            EnterCriticalSection(&infoPtr->cs);
+        }
+
+        CloseHandle( handle );
         CloseHandle( infoPtr->hStopEvent );
-        infoPtr->hThread = 0;
+        infoPtr->hStopEvent = 0;
     }
     if (infoPtr->uTimer) {
        KillTimer(infoPtr->hwndSelf, infoPtr->uTimer);
@@ -399,7 +406,7 @@ static DWORD CALLBACK ANIMATE_AnimationThread(LPVOID ptr_)
         LeaveCriticalSection(&infoPtr->cs);
 
         /* time is in microseconds, we should convert it to milliseconds */
-        if (WaitForSingleObject( event, (timeout+500)/1000) == WAIT_OBJECT_0)
+        if ((event == 0) || WaitForSingleObject( event, (timeout+500)/1000) == WAIT_OBJECT_0)
             break;
     }
     return TRUE;
@@ -439,8 +446,6 @@ static LRESULT ANIMATE_Play(HWND hWnd, WPARAM wParam, LPARAM lParam)
        /* create a timer to display AVI */
        infoPtr->uTimer = SetTimer(hWnd, 1, infoPtr->mah.dwMicroSecPerFrame / 1000, NULL);
     } else {
-        DWORD threadID;
-
         if(GetWindowLongA(hWnd, GWL_STYLE) & ACS_TRANSPARENT)
         {
             infoPtr->hbrushBG = (HBRUSH)SendMessageA(infoPtr->hwndNotify,
@@ -449,7 +454,7 @@ static LRESULT ANIMATE_Play(HWND hWnd, WPARAM wParam, LPARAM lParam)
 
        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, &infoPtr->threadId);
         if(!infoPtr->hThread)
         {
            ERR("Could not create animation thread!\n");