Ignore:
Timestamp:
May 24, 2001, 5:21:06 PM (24 years ago)
Author:
umoeller
Message:

Misc updates

File:
1 edited

Legend:

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

    r69 r74  
    233233}
    234234
    235 /* ******************************************************************
    236  *
    237  *   Exported functions
    238  *
    239  ********************************************************************/
    240 
    241 /*
    242  *@@ tmrCreateSet:
    243  *      creates a "timer set" for use with the XTimer functions.
    244  *      This is the first step if you want to use the XTimers.
    245  *
    246  *      hwndOwner must specify the "owner window", the target
    247  *      window for the master PM timer. This window must respond
    248  *      to a WM_TIMER message with the specified usPMTimerID and
    249  *      invoke tmrTimerTick then.
    250  *
    251  *      Note that the master timer is not started until an XTimer
    252  *      is started.
    253  *
    254  *      Use tmrDestroySet to free all resources again.
    255  *
    256  *@@added V0.9.9 (2001-02-28) [umoeller]
    257  */
    258 
    259 PXTIMERSET tmrCreateSet(HWND hwndOwner,         // in: owner window
    260                         USHORT usPMTimerID)
    261 {
    262     PXTIMERSET pSet = NULL;
    263 
    264     pSet = (PXTIMERSET)malloc(sizeof(*pSet));
    265     if (pSet)
    266     {
    267         pSet->hab = WinQueryAnchorBlock(hwndOwner);
    268         pSet->hwndOwner = hwndOwner;
    269         pSet->idPMTimer = usPMTimerID;
    270         pSet->idPMTimerRunning = 0;
    271         pSet->ulPMTimeout = 0;
    272 
    273         pSet->pvllXTimers = (PVOID)lstCreate(TRUE);
    274     }
    275 
    276     return (pSet);
    277 }
    278 
    279 /*
    280  *@@ tmrDestroySet:
    281  *      destroys a timer set previously created using
    282  *      tmrCreateSet.
    283  *
    284  *      Of course, this will stop all XTimers which
    285  *      might still be running with this set.
    286  *
    287  *@@added V0.9.9 (2001-02-28) [umoeller]
    288  *@@changed V0.9.12 (2001-05-12) [umoeller]: added mutex protection
    289  */
    290 
    291 VOID tmrDestroySet(PXTIMERSET pSet)     // in: timer set (from tmrCreateSet)
    292 {
    293     if (pSet)
    294     {
    295         if (pSet->pvllXTimers)
    296         {
    297             if (LockTimers())
    298             {
    299                 PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
    300 
    301                 PLISTNODE pTimerNode;
    302 
    303                 while (pTimerNode = lstQueryFirstNode(pllXTimers))
    304                 {
    305                     PXTIMER pTimer = (PXTIMER)pTimerNode->pItemData;
    306                     RemoveTimer(pSet, pTimer);
    307                 }
    308 
    309                 lstFree(pllXTimers);
    310 
    311                 UnlockTimers();
    312             }
    313         }
    314 
    315         if (pSet->idPMTimerRunning)
    316             WinStopTimer(pSet->hab,
    317                          pSet->hwndOwner,
    318                          pSet->idPMTimer);
    319 
    320         free(pSet);
    321     }
    322 }
    323 
    324235/*
    325236 *@@ AdjustPMTimer:
     
    378289}
    379290
     291/* ******************************************************************
     292 *
     293 *   Exported functions
     294 *
     295 ********************************************************************/
     296
     297/*
     298 *@@ tmrCreateSet:
     299 *      creates a "timer set" for use with the XTimer functions.
     300 *      This is the first step if you want to use the XTimers.
     301 *
     302 *      hwndOwner must specify the "owner window", the target
     303 *      window for the master PM timer. This window must respond
     304 *      to a WM_TIMER message with the specified usPMTimerID and
     305 *      invoke tmrTimerTick then.
     306 *
     307 *      Note that the master timer is not started until an XTimer
     308 *      is started.
     309 *
     310 *      Use tmrDestroySet to free all resources again.
     311 *
     312 *@@added V0.9.9 (2001-02-28) [umoeller]
     313 */
     314
     315PXTIMERSET tmrCreateSet(HWND hwndOwner,         // in: owner window
     316                        USHORT usPMTimerID)
     317{
     318    PXTIMERSET pSet = NULL;
     319
     320    pSet = (PXTIMERSET)malloc(sizeof(*pSet));
     321    if (pSet)
     322    {
     323        pSet->hab = WinQueryAnchorBlock(hwndOwner);
     324        pSet->hwndOwner = hwndOwner;
     325        pSet->idPMTimer = usPMTimerID;
     326        pSet->idPMTimerRunning = 0;
     327        pSet->ulPMTimeout = 0;
     328
     329        pSet->pvllXTimers = (PVOID)lstCreate(TRUE);
     330    }
     331
     332    return (pSet);
     333}
     334
     335/*
     336 *@@ tmrDestroySet:
     337 *      destroys a timer set previously created using
     338 *      tmrCreateSet.
     339 *
     340 *      Of course, this will stop all XTimers which
     341 *      might still be running with this set.
     342 *
     343 *@@added V0.9.9 (2001-02-28) [umoeller]
     344 *@@changed V0.9.12 (2001-05-12) [umoeller]: added mutex protection
     345 */
     346
     347VOID tmrDestroySet(PXTIMERSET pSet)     // in: timer set (from tmrCreateSet)
     348{
     349    if (LockTimers())
     350    {
     351        if (pSet)
     352        {
     353            PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
     354            if (pllXTimers)
     355            {
     356                PLISTNODE pTimerNode = lstQueryFirstNode(pllXTimers);
     357                while (pTimerNode)
     358                {
     359                    PLISTNODE pNext = pTimerNode->pNext;
     360                    PXTIMER pTimer = (PXTIMER)pTimerNode->pItemData;
     361                    RemoveTimer(pSet, pTimer);
     362                    pTimerNode = pNext;
     363                }
     364
     365                lstFree(&pllXTimers);
     366                pSet->pvllXTimers = NULL;
     367            }
     368        }
     369
     370        if (pSet->idPMTimerRunning)
     371        {
     372            WinStopTimer(pSet->hab,
     373                         pSet->hwndOwner,
     374                         pSet->idPMTimer);
     375            pSet->idPMTimerRunning = 0;
     376        }
     377
     378        free(pSet);
     379
     380        UnlockTimers();
     381    }
     382}
     383
    380384/*
    381385 *@@ tmrTimerTick:
     
    391395 *@@added V0.9.9 (2001-02-28) [umoeller]
    392396 *@@changed V0.9.12 (2001-05-12) [umoeller]: added mutex protection
     397 *@@changed V0.9.12 (2001-05-24) [umoeller]: fixed crash if timer was deleted during winproc's WM_TIMER processing
    393398 */
    394399
    395400VOID tmrTimerTick(PXTIMERSET pSet)      // in: timer set (from tmrCreateSet)
    396401{
    397     if (pSet && pSet->pvllXTimers)
    398     {
    399         if (LockTimers())
     402    if (LockTimers())
     403    {
     404        if (pSet)
    400405        {
    401406            PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
    402             // go thru all XTimers and see which one
    403             // has elapsed; for all of these, post WM_TIMER
    404             // to the target window proc
    405             PLISTNODE pTimerNode = lstQueryFirstNode(pllXTimers);
    406 
    407             if (!pTimerNode)
     407            if (pllXTimers)
    408408            {
    409                 // no timers left:
    410                 if (pSet->idPMTimerRunning)
     409                // go thru all XTimers and see which one
     410                // has elapsed; for all of these, post WM_TIMER
     411                // to the target window proc
     412                PLISTNODE pTimerNode = lstQueryFirstNode(pllXTimers);
     413
     414                if (!pTimerNode)
    411415                {
    412                     // but PM timer running:
    413                     // stop it
    414                     WinStopTimer(pSet->hab,
    415                                  pSet->hwndOwner,
    416                                  pSet->idPMTimer);
    417                     pSet->idPMTimerRunning = 0;
     416                    // no timers left:
     417                    if (pSet->idPMTimerRunning)
     418                    {
     419                        // but PM timer running:
     420                        // stop it
     421                        WinStopTimer(pSet->hab,
     422                                     pSet->hwndOwner,
     423                                     pSet->idPMTimer);
     424                        pSet->idPMTimerRunning = 0;
     425                    }
     426
     427                    pSet->ulPMTimeout = 0;
    418428                }
    419 
    420                 pSet->ulPMTimeout = 0;
    421             }
    422             else
    423             {
    424                 // we have timers:
    425                 BOOL    fFoundInvalid = FALSE;
    426 
    427                 ULONG   // ulInterval = 100,
    428                         ulTimeNow = 0;
    429 
    430                 // linked list of timers found to be invalid;
    431                 // this holds LISTNODE pointers from the global
    432                 // list to be removed
    433                 LINKLIST    llInvalidTimers;
    434                 lstInit(&llInvalidTimers,
    435                         FALSE);     // no auto-free
    436 
    437                 // get current time
    438                 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT,
    439                                 &ulTimeNow, sizeof(ulTimeNow));
    440 
    441                 while (pTimerNode)
     429                else
    442430                {
    443                     PXTIMER pTimer = (PXTIMER)pTimerNode->pItemData;
    444 
    445                     if (    (pTimer)
    446                          && (pTimer->ulNextFire < ulTimeNow)
    447                        )
     431                    // we have timers:
     432                    BOOL    fFoundInvalid = FALSE;
     433
     434                    // get current time
     435                    ULONG   ulTimeNow = 0;
     436                    DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT,
     437                                    &ulTimeNow, sizeof(ulTimeNow));
     438
     439                    while (pTimerNode)
    448440                    {
    449                         // this timer has elapsed:
    450                         // fire!
    451                         if (WinIsWindow(pSet->hab,
    452                                         pTimer->hwndTarget))
     441                        // get next node first because the
     442                        // list can get modified while processing
     443                        // V0.9.12 (2001-05-24) [umoeller]
     444                        PLISTNODE pNext = pTimerNode->pNext;
     445
     446                        PXTIMER pTimer = (PXTIMER)pTimerNode->pItemData;
     447
     448                        if (    (pTimer)
     449                             && (pTimer->ulNextFire < ulTimeNow)
     450                           )
    453451                        {
    454                             // window still valid:
    455                             // get the window's window proc
    456                             PFNWP pfnwp = (PFNWP)WinQueryWindowPtr(pTimer->hwndTarget,
    457                                                                    QWP_PFNWP);
    458                             // call the window proc DIRECTLY
    459                             pfnwp(pTimer->hwndTarget,
    460                                   WM_TIMER,
    461                                   (MPARAM)pTimer->usTimerID,
    462                                   0);
    463                             pTimer->ulNextFire = ulTimeNow + pTimer->ulTimeout;
    464                         }
    465                         else
    466                         {
    467                             // window has been destroyed:
    468                             lstAppendItem(&llInvalidTimers,
    469                                           (PVOID)pTimerNode);
    470                             fFoundInvalid = TRUE;
    471                         }
    472                     } // end if (pTimer->ulNextFire < ulTimeNow)
    473 
    474                     // next timer
    475                     pTimerNode = pTimerNode->pNext;
    476                 } // end while (pTimerNode)
    477 
    478                 // destroy invalid timers, if any
    479                 if (fFoundInvalid)
    480                 {
    481                     PLISTNODE pNodeNode = lstQueryFirstNode(&llInvalidTimers);
    482                     while (pNodeNode)
    483                     {
    484                         PLISTNODE pNode2Remove = (PLISTNODE)pNodeNode->pItemData;
    485                         lstRemoveNode(pllXTimers,
    486                                       pNode2Remove);
    487                         pNodeNode = pNodeNode->pNext;
    488                     }
    489                     lstClear(&llInvalidTimers);
    490 
    491                     AdjustPMTimer(pSet);
    492                 }
    493             } // end else if (!pTimerNode)
    494 
    495             UnlockTimers();
    496         } // end if (LockTimers())
    497     } // end if (pSet && pSet->pvllXTimers)
     452                            // this timer has elapsed:
     453                            // fire!
     454                            if (WinIsWindow(pSet->hab,
     455                                            pTimer->hwndTarget))
     456                            {
     457                                // window still valid:
     458                                // get the window's window proc
     459                                PFNWP pfnwp = (PFNWP)WinQueryWindowPtr(pTimer->hwndTarget,
     460                                                                       QWP_PFNWP);
     461                                // call the window proc DIRECTLY
     462                                pfnwp(pTimer->hwndTarget,
     463                                      WM_TIMER,
     464                                      (MPARAM)pTimer->usTimerID,
     465                                      0);
     466                                    // V0.9.12 (2001-05-24) [umoeller]
     467                                    // if the winproc chooses to start or
     468                                    // stop a timer, pNext still points
     469                                    // to a valid node...
     470                                    // -- if a timer is removed, that's OK
     471                                    // -- if a timer is added, it is added to
     472                                    //    the list, so we'll see it in this loop
     473
     474                                pTimer->ulNextFire = ulTimeNow + pTimer->ulTimeout;
     475                            }
     476                            else
     477                            {
     478                                // window has been destroyed:
     479                                lstRemoveNode(pllXTimers,
     480                                              pTimerNode);
     481                                    // pNext is still valid
     482
     483                                fFoundInvalid = TRUE;
     484                            }
     485
     486                        } // end if (pTimer->ulNextFire < ulTimeNow)
     487
     488                        // next timer
     489                        pTimerNode = pNext; // V0.9.12 (2001-05-24) [umoeller]
     490                    } // end while (pTimerNode)
     491
     492                    // destroy invalid timers, if any
     493                    if (fFoundInvalid)
     494                        AdjustPMTimer(pSet);
     495
     496                } // end else if (!pTimerNode)
     497            } // end if (pllXTimers)
     498        } // end if (pSet)
     499
     500        UnlockTimers();
     501    } // end if (LockTimers())
    498502}
    499503
     
    527531    // _Pmpf((__FUNCTION__ ": entering"));
    528532
    529     if (pSet && pSet->pvllXTimers)
    530     {
    531         if (LockTimers())
     533    if (LockTimers())
     534    {
     535        if (pSet)
    532536        {
    533537            PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
    534538
    535             if ((hwnd) && (ulTimeout))
     539            if ((pllXTimers) && (hwnd) && (ulTimeout))
    536540            {
    537541                PXTIMER pTimer;
     
    571575
    572576                if (usrc)
    573                 {
    574577                    // timer created or reset:
    575578                    AdjustPMTimer(pSet);
    576                 }
     579
    577580            } // if ((hwnd) && (ulTimeout))
    578 
    579             UnlockTimers();
    580581        }
     582
     583        UnlockTimers();
    581584    }
    582585
     
    601604{
    602605    BOOL brc = FALSE;
    603     if (pSet && pSet->pvllXTimers)
    604     {
    605         if (LockTimers())
     606    if (LockTimers())
     607    {
     608        if (pSet && pSet->pvllXTimers)
    606609        {
    607610            PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
     
    618621                brc = TRUE;
    619622            }
    620 
    621             UnlockTimers();
    622623        }
     624
     625        UnlockTimers();
    623626    }
    624627
Note: See TracChangeset for help on using the changeset viewer.