Changeset 163 for trunk/src


Ignore:
Timestamp:
May 7, 2002, 10:49:29 PM (23 years ago)
Author:
umoeller
Message:

Misc fixes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/helpers/timer.c

    r142 r163  
    111111#include "helpers\timer.h"
    112112
     113#define DEBUG_XTIMERS
     114
    113115/*
    114116 *@@category: Helpers\PM helpers\Timer replacements
     
    224226
    225227static VOID RemoveTimer(PXTIMERSET pSet,       // in: timer set (from tmrCreateSet)
    226                         PXTIMER pTimer)        // in: timer to remove.
     228                        PXTIMER pTimer)        // in: timer to remove
    227229{
    228230    PLINKLIST pllXTimers;
     
    231233       )
    232234    {
     235        #ifdef DEBUG_XTIMERS
     236        _Pmpf((__FUNCTION__ ": removing timer %d", pTimer->usTimerID));
     237        #endif
    233238        lstRemoveItem(pllXTimers,
    234239                      pTimer);       // auto-free!
     
    458463 *@@changed V0.9.14 (2001-08-03) [umoeller]: fixed "half frequency" regression caused by frequency optimizations
    459464 *@@changed V0.9.16 (2001-12-18) [umoeller]: now using WinDispatchMsg to avoid crashes during win destruction
     465 *@@changed V0.9.19 (2002-05-04) [umoeller]: added excpt handling to avoid hanging all timers on the mutex
    460466 */
    461467
    462468VOID tmrTimerTick(PXTIMERSET pSet)      // in: timer set (from tmrCreateSet)
    463469{
    464     if (LockTimers())
    465     {
    466         PLINKLIST pllXTimers;
    467         if (    (pSet)
    468              && (pllXTimers = (PLINKLIST)pSet->pvllXTimers)
    469            )
    470         {
    471             // go thru all XTimers and see which one
    472             // has elapsed; for all of these, post WM_TIMER
    473             // to the target window proc
    474             PLISTNODE pTimerNode = lstQueryFirstNode(pllXTimers);
    475 
    476             if (!pTimerNode)
     470    BOOL fLocked = FALSE;
     471
     472    TRY_LOUD(excpt1)
     473    {
     474        if (fLocked = LockTimers())
     475        {
     476            PLINKLIST pllXTimers;
     477            if (    (pSet)
     478                 && (pllXTimers = (PLINKLIST)pSet->pvllXTimers)
     479               )
    477480            {
    478                 // no timers left:
    479                 if (pSet->idPMTimerRunning)
     481                // go thru all XTimers and see which one
     482                // has elapsed; for all of these, post WM_TIMER
     483                // to the target window proc
     484                PLISTNODE pTimerNode;
     485
     486                if (!(pTimerNode = lstQueryFirstNode(pllXTimers)))
    480487                {
    481                     // but PM timer running:
    482                     // stop it
    483                     WinStopTimer(pSet->hab,
    484                                  pSet->hwndOwner,
    485                                  pSet->idPMTimer);
    486                     pSet->idPMTimerRunning = 0;
     488                    // no timers left:
     489                    if (pSet->idPMTimerRunning)
     490                    {
     491                        // but PM timer running:
     492                        // stop it
     493                        WinStopTimer(pSet->hab,
     494                                     pSet->hwndOwner,
     495                                     pSet->idPMTimer);
     496                        pSet->idPMTimerRunning = 0;
     497                    }
     498
     499                    pSet->ulPMTimeout = 0;
    487500                }
    488 
    489                 pSet->ulPMTimeout = 0;
    490             }
    491             else
    492             {
    493                 // we have timers:
    494                 BOOL    fFoundInvalid = FALSE;
    495 
    496                 // get current time
    497                 ULONG   ulTimeNow = 0;
    498                 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT,
    499                                 &ulTimeNow, sizeof(ulTimeNow));
    500 
    501                 #ifdef DEBUG_XTIMERS
    502                     _Pmpf((__FUNCTION__ ": ulTimeNow = %d", ulTimeNow));
    503                 #endif
    504 
    505                 while (pTimerNode)
     501                else
    506502                {
    507                     // get next node first because the
    508                     // list can get modified while processing
    509                     // V0.9.12 (2001-05-24) [umoeller]
    510                     PLISTNODE pNext = pTimerNode->pNext;
    511 
    512                     PXTIMER pTimer = (PXTIMER)pTimerNode->pItemData;
     503                    // we have timers:
     504                    BOOL    fFoundInvalid = FALSE;
     505
     506                    // get current time
     507                    ULONG   ulTimeNow = 0;
     508                    DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT,
     509                                    &ulTimeNow, sizeof(ulTimeNow));
    513510
    514511                    #ifdef DEBUG_XTIMERS
    515                         _Pmpf(("   timer %d: ulNextFire = %d",
    516                                 lstIndexFromItem(pllXTimers, pTimer),
    517                                 pTimer->ulNextFire));
     512                        _Pmpf((__FUNCTION__ ": ulTimeNow = %d", ulTimeNow));
    518513                    #endif
    519514
    520                     if (    (pTimer)
    521                          // && (pTimer->ulNextFire < ulTimeNow)
    522                             // V0.9.14 (2001-08-01) [umoeller]
    523                             // use <= because otherwise we'll get
    524                             // only half the frequency...
    525                             // we get here frequently where the
    526                             // two values are EXACTLY equal due
    527                             // to the above optimization (DosQuerySysInfo
    528                             // called once only for the entire loop)
    529                          && (pTimer->ulNextFire <= ulTimeNow)
    530                        )
     515                    while (pTimerNode)
    531516                    {
    532                         // this timer has elapsed:
    533                         // fire!
     517                        // get next node first because the
     518                        // list can get modified while processing
     519                        // V0.9.12 (2001-05-24) [umoeller]
     520                        PLISTNODE pNext = pTimerNode->pNext;
     521
     522                        PXTIMER pTimer = (PXTIMER)pTimerNode->pItemData;
    534523
    535524                        #ifdef DEBUG_XTIMERS
    536                             _Pmpf(("   --> fire!"));
     525                            _Pmpf(("   timer %d: ulNextFire = %d",
     526                                    lstIndexFromItem(pllXTimers, pTimer),
     527                                    pTimer->ulNextFire));
    537528                        #endif
    538529
    539                         if (WinIsWindow(pSet->hab,
    540                                         pTimer->hwndTarget))
     530                        if (    (pTimer)
     531                             // && (pTimer->ulNextFire < ulTimeNow)
     532                                // V0.9.14 (2001-08-01) [umoeller]
     533                                // use <= because otherwise we'll get
     534                                // only half the frequency...
     535                                // we get here frequently where the
     536                                // two values are EXACTLY equal due
     537                                // to the above optimization (DosQuerySysInfo
     538                                // called once only for the entire loop)
     539                             && (pTimer->ulNextFire <= ulTimeNow)
     540                           )
    541541                        {
    542                             // window still valid:
    543                             // get the window's window proc
    544                             QMSG qmsg;
    545                             /* PFNWP pfnwp = (PFNWP)WinQueryWindowPtr(pTimer->hwndTarget,
    546                                                                    QWP_PFNWP); */
    547 
    548                             // moved this up V0.9.14 (2001-08-01) [umoeller]
    549                             pTimer->ulNextFire = ulTimeNow + pTimer->ulTimeout;
    550 
    551                             // call the window proc DIRECTLY
    552                             // V0.9.16 (2001-12-18) [umoeller]:
    553                             // now using WinDispatchMsg to avoid crashes
    554                             // while hwndTarget is being destroyed
    555                             qmsg.hwnd = pTimer->hwndTarget;
    556                             qmsg.msg = WM_TIMER;
    557                             qmsg.mp1 = (MPARAM)pTimer->usTimerID;
    558                             qmsg.mp2 = (MPARAM)0;
    559                             qmsg.time = 0;
    560                             qmsg.ptl.x = 0;
    561                             qmsg.ptl.y = 0;
    562                             qmsg.reserved = 0;
    563                             WinDispatchMsg(pSet->hab,
    564                                            &qmsg);
    565 
    566                             /* pfnwp(pTimer->hwndTarget,
    567                                   WM_TIMER,
    568                                   (MPARAM)pTimer->usTimerID,
    569                                   0); */
    570                                 // V0.9.12 (2001-05-24) [umoeller]
    571                                 // if the winproc chooses to start or
    572                                 // stop a timer, pNext still points
    573                                 // to a valid node...
    574                                 // -- if a timer is removed, that's OK
    575                                 // -- if a timer is added, it is added to
    576                                 //    the list, so we'll see it in this loop
    577 
    578                             // V0.9.14 (2001-08-01) [umoeller]
    579 
    580                             // DO NOT REFERENCE pTimer AFTER THIS CODE;
    581                             // the winproc might have removed the timer,
    582                             // and since the list is auto-free, pTimer
    583                             // might have been freed!!
    584                         }
    585                         else
    586                         {
    587                             // window has been destroyed:
    588                             lstRemoveNode(pllXTimers,
    589                                           pTimerNode);
    590                                 // pNext is still valid
    591 
    592                             fFoundInvalid = TRUE;
    593                         }
    594 
    595                     } // end if (pTimer->ulNextFire < ulTimeNow)
    596 
    597                     // next timer
    598                     pTimerNode = pNext; // V0.9.12 (2001-05-24) [umoeller]
    599                 } // end while (pTimerNode)
    600 
    601                 // destroy invalid timers, if any
    602                 if (fFoundInvalid)
    603                     AdjustPMTimer(pSet);
    604 
    605             } // end else if (!pTimerNode)
    606         } // end if (pllXTimers)
    607 
     542                            // this timer has elapsed:
     543                            // fire!
     544
     545                            #ifdef DEBUG_XTIMERS
     546                                _Pmpf(("   --> fire!"));
     547                            #endif
     548
     549                            if (WinIsWindow(pSet->hab,
     550                                            pTimer->hwndTarget))
     551                            {
     552                                // window still valid:
     553                                // get the window's window proc
     554                                QMSG qmsg;
     555                                PFNWP pfnwp = (PFNWP)WinQueryWindowPtr(pTimer->hwndTarget,
     556                                                                       QWP_PFNWP);
     557
     558                                // moved this up V0.9.14 (2001-08-01) [umoeller]
     559                                pTimer->ulNextFire = ulTimeNow + pTimer->ulTimeout;
     560
     561                                // call the window proc DIRECTLY
     562                                // V0.9.16 (2001-12-18) [umoeller]:
     563                                // now using WinDispatchMsg to avoid crashes
     564                                // while hwndTarget is being destroyed
     565                                /* qmsg.hwnd = pTimer->hwndTarget;
     566                                qmsg.msg = WM_TIMER;
     567                                qmsg.mp1 = (MPARAM)pTimer->usTimerID;
     568                                qmsg.mp2 = (MPARAM)0;
     569                                qmsg.time = 0;
     570                                qmsg.ptl.x = 0;
     571                                qmsg.ptl.y = 0;
     572                                qmsg.reserved = 0;
     573                                WinDispatchMsg(pSet->hab,
     574                                               &qmsg); */
     575
     576                                pfnwp(pTimer->hwndTarget,
     577                                      WM_TIMER,
     578                                      (MPARAM)pTimer->usTimerID,
     579                                      0);
     580                                    // V0.9.12 (2001-05-24) [umoeller]
     581                                    // if the winproc chooses to start or
     582                                    // stop a timer, pNext still points
     583                                    // to a valid node...
     584                                    // -- if a timer is removed, that's OK
     585                                    // -- if a timer is added, it is added to
     586                                    //    the list, so we'll see it in this loop
     587
     588                                // V0.9.14 (2001-08-01) [umoeller]
     589
     590                                // DO NOT REFERENCE pTimer AFTER THIS CODE;
     591                                // the winproc might have removed the timer,
     592                                // and since the list is auto-free, pTimer
     593                                // might have been freed!!
     594                            }
     595                            else
     596                            {
     597                                // window has been destroyed:
     598                                lstRemoveNode(pllXTimers,
     599                                              pTimerNode);
     600                                    // pNext is still valid
     601
     602                                fFoundInvalid = TRUE;
     603                            }
     604
     605                        } // end if (pTimer->ulNextFire < ulTimeNow)
     606
     607                        // next timer
     608                        pTimerNode = pNext; // V0.9.12 (2001-05-24) [umoeller]
     609                    } // end while (pTimerNode)
     610
     611                    // destroy invalid timers, if any
     612                    if (fFoundInvalid)
     613                        AdjustPMTimer(pSet);
     614
     615                } // end else if (!pTimerNode)
     616            } // end if (pllXTimers)
     617        } // end if (LockTimers())
     618    }
     619    CATCH(excpt1) {} END_CATCH();
     620
     621    if (fLocked)
    608622        UnlockTimers();
    609     } // end if (LockTimers())
    610623}
    611624
     
    743756    {
    744757        PXTIMER pTimer;
     758        #ifdef DEBUG_XTIMERS
     759        _Pmpf((__FUNCTION__ ": finding timer %d", usTimerID));
     760        #endif
    745761        if (pTimer = FindTimer(pSet,
    746762                               hwnd,
Note: See TracChangeset for help on using the changeset viewer.