Ignore:
Timestamp:
May 15, 2001, 6:15:18 PM (24 years ago)
Author:
umoeller
Message:

Lotsa fixes from the last two weeks.

File:
1 edited

Legend:

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

    r44 r68  
    144144 ********************************************************************/
    145145
    146 // timers thread
    147 // HMTX                G_hmtxTimers = NULLHANDLE;  // timers lock mutex
    148 // THREADINFO          G_tiTimers = {0};           // timers thread (only running
    149                                                 // if any timers were requested)
    150 // BOOL                G_fTimersThreadRunning = FALSE;
    151 // LINKLIST            G_llTimers;         // linked list of XTIMER pointers
    152 
    153 /*
    154  *@@ fntTimersThread:
    155  *      the actual thread which fires the timers by
    156  *      posting WM_TIMER messages to the respecive
    157  *      target windows when a timer has elapsed.
    158  *
    159  *      This thread is dynamically started when the
    160  *      first timer is started thru tmrStartXTimer.
    161  *      It is automatically stopped (to be precise:
    162  *      it terminates itself) when the last timer
    163  *      is stopped thru tmrStopXTimer, which then
    164  *      sets the thread's fExit flag to TRUE.
    165  *
    166  *@@changed V0.9.7 (2000-12-08) [umoeller]: got rid of dtGetULongTime
    167  */
    168 
    169 /* void _Optlink fntTimersThread(PTHREADINFO ptiMyself)
    170 {
    171     ULONG       ulInterval = 25;
    172     HAB         hab = WinInitialize(0);
    173     BOOL        fLocked = FALSE;
    174 
    175     // linked list of timers found to be invalid;
    176     // this holds LISTNODE pointers from the global
    177     // list to be removed
    178     LINKLIST    llInvalidTimers;
    179     lstInit(&llInvalidTimers,
    180             FALSE);     // no auto-free
    181 
    182     #ifdef __DEBUG__
    183         DosBeep(3000, 30);
    184     #endif
    185 
    186     // keep running while we have timers
    187     while (!ptiMyself->fExit)
    188     {
    189         // ULONG ulNesting = 0;
    190 
    191         ULONG ulTimeNow;
    192 
    193         DosSleep(ulInterval);
    194 
    195         // minimum interval: 100 ms; this is lowered
    196         // if we find any timers in the list which
    197         // have a lower timeout to make sure we can
    198         // fire at a lower interval...
    199         ulInterval = 100;
    200 
    201         // DosEnterMustComplete(&ulNesting);
    202 
    203         TRY_LOUD(excpt1)
    204         {
    205             fLocked = LockTimers();
    206             if (fLocked)
    207             {
    208             } // end if (fLocked)
    209         }
    210         CATCH(excpt1) { } END_CATCH();
    211 
    212         if (fLocked)
    213         {
    214             UnlockTimers();
    215             fLocked = FALSE;
    216         }
    217 
    218         // DosExitMustComplete(&ulNesting);
    219 
    220     } // end while (!ptiMyself->fExit)
    221 
    222     WinTerminate(hab);
    223 
    224     #ifdef __DEBUG__
    225         DosBeep(1500, 30);
    226     #endif
    227 } */
     146HMTX                G_hmtxTimers = NULLHANDLE;  // timers lock mutex
    228147
    229148/* ******************************************************************
     
    232151 *
    233152 ********************************************************************/
     153
     154/*
     155 *@@ LockTimers:
     156 *
     157 *@@added V0.9.12 (2001-05-12) [umoeller]
     158 */
     159
     160BOOL LockTimers(VOID)
     161{
     162    if (!G_hmtxTimers)
     163        return (!DosCreateMutexSem(NULL,
     164                                   &G_hmtxTimers,
     165                                   0,
     166                                   TRUE));      // request!
     167    else
     168        return (!WinRequestMutexSem(G_hmtxTimers, SEM_INDEFINITE_WAIT));
     169}
     170
     171/*
     172 *@@ UnlockTimers:
     173 *
     174 *@@added V0.9.12 (2001-05-12) [umoeller]
     175 */
     176
     177VOID UnlockTimers(VOID)
     178{
     179    DosReleaseMutexSem(G_hmtxTimers);
     180}
    234181
    235182/*
     
    239186 *      _and_ timer ID.
    240187 *
    241  *      Internal function.
     188 *      Internal function. Caller must hold the mutex.
    242189 */
    243190
     
    272219 *      the global linked list of running timers.
    273220 *
    274  *      Internal function.
     221 *      Internal function. Caller must hold the mutex.
    275222 */
    276223
     
    339286 *
    340287 *@@added V0.9.9 (2001-02-28) [umoeller]
     288 *@@changed V0.9.12 (2001-05-12) [umoeller]: added mutex protection
    341289 */
    342290
     
    347295        if (pSet->pvllXTimers)
    348296        {
    349             PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
    350 
    351             PLISTNODE pTimerNode;
    352 
    353             while (pTimerNode = lstQueryFirstNode(pllXTimers))
     297            if (LockTimers())
    354298            {
    355                 PXTIMER pTimer = (PXTIMER)pTimerNode->pItemData;
    356                 RemoveTimer(pSet, pTimer);
     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();
    357312            }
    358 
    359             lstFree(pllXTimers);
    360313        }
    361314
     
    373326 *      goes thru all XTimers in the sets and starts
    374327 *      or stops the PM timer with a decent frequency.
     328 *
     329 *      Internal function. Caller must hold the mutex.
    375330 *
    376331 *@@added V0.9.9 (2001-03-07) [umoeller]
     
    435390 *
    436391 *@@added V0.9.9 (2001-02-28) [umoeller]
     392 *@@changed V0.9.12 (2001-05-12) [umoeller]: added mutex protection
    437393 */
    438394
     
    441397    if (pSet && pSet->pvllXTimers)
    442398    {
    443         PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
    444         // go thru all XTimers and see which one
    445         // has elapsed; for all of these, post WM_TIMER
    446         // to the target window proc
    447         PLISTNODE pTimerNode = lstQueryFirstNode(pllXTimers);
    448 
    449         if (!pTimerNode)
     399        if (LockTimers())
    450400        {
    451             // no timers left:
    452             if (pSet->idPMTimerRunning)
     401            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)
    453408            {
    454                 // but PM timer running:
    455                 // stop it
    456                 WinStopTimer(pSet->hab,
    457                              pSet->hwndOwner,
    458                              pSet->idPMTimer);
    459                 pSet->idPMTimerRunning = 0;
     409                // no timers left:
     410                if (pSet->idPMTimerRunning)
     411                {
     412                    // but PM timer running:
     413                    // stop it
     414                    WinStopTimer(pSet->hab,
     415                                 pSet->hwndOwner,
     416                                 pSet->idPMTimer);
     417                    pSet->idPMTimerRunning = 0;
     418                }
     419
     420                pSet->ulPMTimeout = 0;
    460421            }
    461 
    462             pSet->ulPMTimeout = 0;
    463         }
    464         else
    465         {
    466             // we have timers:
    467             BOOL    fFoundInvalid = FALSE;
    468 
    469             ULONG   // ulInterval = 100,
    470                     ulTimeNow = 0;
    471 
    472             // linked list of timers found to be invalid;
    473             // this holds LISTNODE pointers from the global
    474             // list to be removed
    475             LINKLIST    llInvalidTimers;
    476             lstInit(&llInvalidTimers,
    477                     FALSE);     // no auto-free
    478 
    479             // get current time
    480             DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT,
    481                             &ulTimeNow, sizeof(ulTimeNow));
    482 
    483             while (pTimerNode)
     422            else
    484423            {
    485                 PXTIMER pTimer = (PXTIMER)pTimerNode->pItemData;
    486 
    487                 if (pTimer->ulNextFire < ulTimeNow)
     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)
    488442                {
    489                     // this timer has elapsed:
    490                     // fire!
    491                     if (WinIsWindow(pSet->hab,
    492                                     pTimer->hwndTarget))
     443                    PXTIMER pTimer = (PXTIMER)pTimerNode->pItemData;
     444
     445                    if (pTimer->ulNextFire < ulTimeNow)
    493446                    {
    494                         // window still valid:
    495                         // get the window's window proc
    496                         PFNWP pfnwp = (PFNWP)WinQueryWindowPtr(pTimer->hwndTarget,
    497                                                                QWP_PFNWP);
    498                         // call the window proc DIRECTLY
    499                         pfnwp(pTimer->hwndTarget,
    500                               WM_TIMER,
    501                               (MPARAM)pTimer->usTimerID,
    502                               0);
    503                         pTimer->ulNextFire = ulTimeNow + pTimer->ulTimeout;
     447                        // this timer has elapsed:
     448                        // fire!
     449                        if (WinIsWindow(pSet->hab,
     450                                        pTimer->hwndTarget))
     451                        {
     452                            // window still valid:
     453                            // get the window's window proc
     454                            PFNWP pfnwp = (PFNWP)WinQueryWindowPtr(pTimer->hwndTarget,
     455                                                                   QWP_PFNWP);
     456                            // call the window proc DIRECTLY
     457                            pfnwp(pTimer->hwndTarget,
     458                                  WM_TIMER,
     459                                  (MPARAM)pTimer->usTimerID,
     460                                  0);
     461                            pTimer->ulNextFire = ulTimeNow + pTimer->ulTimeout;
     462                        }
     463                        else
     464                        {
     465                            // window has been destroyed:
     466                            lstAppendItem(&llInvalidTimers,
     467                                          (PVOID)pTimerNode);
     468                            fFoundInvalid = TRUE;
     469                        }
     470                    } // end if (pTimer->ulNextFire < ulTimeNow)
     471
     472                    // next timer
     473                    pTimerNode = pTimerNode->pNext;
     474                } // end while (pTimerNode)
     475
     476                // destroy invalid timers, if any
     477                if (fFoundInvalid)
     478                {
     479                    PLISTNODE pNodeNode = lstQueryFirstNode(&llInvalidTimers);
     480                    while (pNodeNode)
     481                    {
     482                        PLISTNODE pNode2Remove = (PLISTNODE)pNodeNode->pItemData;
     483                        lstRemoveNode(pllXTimers,
     484                                      pNode2Remove);
     485                        pNodeNode = pNodeNode->pNext;
    504486                    }
    505                     else
    506                     {
    507                         // window has been destroyed:
    508                         lstAppendItem(&llInvalidTimers,
    509                                       (PVOID)pTimerNode);
    510                         fFoundInvalid = TRUE;
    511                     }
    512                 } // end if (pTimer->ulNextFire < ulTimeNow)
    513 
    514                 // next timer
    515                 pTimerNode = pTimerNode->pNext;
    516             } // end while (pTimerNode)
    517 
    518             // destroy invalid timers, if any
    519             if (fFoundInvalid)
    520             {
    521                 PLISTNODE pNodeNode = lstQueryFirstNode(&llInvalidTimers);
    522                 while (pNodeNode)
    523                 {
    524                     PLISTNODE pNode2Remove = (PLISTNODE)pNodeNode->pItemData;
    525                     lstRemoveNode(pllXTimers,
    526                                   pNode2Remove);
    527                     pNodeNode = pNodeNode->pNext;
     487                    lstClear(&llInvalidTimers);
     488
     489                    AdjustPMTimer(pSet);
    528490                }
    529                 lstClear(&llInvalidTimers);
    530 
    531                 AdjustPMTimer(pSet);
    532             }
    533         } // end else if (!pTimerNode)
    534     }
     491            } // end else if (!pTimerNode)
     492
     493            UnlockTimers();
     494        } // end if (LockTimers())
     495    } // end if (pSet && pSet->pvllXTimers)
    535496}
    536497
     
    552513 *
    553514 *@@changed V0.9.7 (2000-12-08) [umoeller]: got rid of dtGetULongTime
     515 *@@changed V0.9.12 (2001-05-12) [umoeller]: added mutex protection
    554516 */
    555517
     
    565527    if (pSet && pSet->pvllXTimers)
    566528    {
    567         PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
    568 
    569         if ((hwnd) && (ulTimeout))
     529        if (LockTimers())
    570530        {
    571             PXTIMER pTimer;
    572 
    573             // check if this timer exists already
    574             pTimer = FindTimer(pSet,
    575                                hwnd,
    576                                usTimerID);
    577             if (pTimer)
     531            PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
     532
     533            if ((hwnd) && (ulTimeout))
    578534            {
    579                 // exists already: reset only
    580                 ULONG ulTimeNow;
    581                 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT,
    582                                 &ulTimeNow, sizeof(ulTimeNow));
    583                 pTimer->ulNextFire = ulTimeNow + ulTimeout;
    584                 usrc = pTimer->usTimerID;
    585             }
    586             else
    587             {
    588                 // new timer needed:
    589                 pTimer = (PXTIMER)malloc(sizeof(XTIMER));
     535                PXTIMER pTimer;
     536
     537                // check if this timer exists already
     538                pTimer = FindTimer(pSet,
     539                                   hwnd,
     540                                   usTimerID);
    590541                if (pTimer)
    591542                {
     543                    // exists already: reset only
    592544                    ULONG ulTimeNow;
    593545                    DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT,
    594546                                    &ulTimeNow, sizeof(ulTimeNow));
    595                     pTimer->usTimerID = usTimerID;
    596                     pTimer->hwndTarget = hwnd;
    597                     pTimer->ulTimeout = ulTimeout;
    598547                    pTimer->ulNextFire = ulTimeNow + ulTimeout;
    599 
    600                     lstAppendItem(pllXTimers,
    601                                   pTimer);
    602548                    usrc = pTimer->usTimerID;
    603549                }
    604             }
    605 
    606             if (usrc)
    607             {
    608                 // timer created or reset:
    609                 AdjustPMTimer(pSet);
    610             }
    611         } // if ((hwnd) && (ulTimeout))
    612     }
    613 
    614     // _Pmpf((__FUNCTION__ ": leaving, returning %d", usrc));
     550                else
     551                {
     552                    // new timer needed:
     553                    pTimer = (PXTIMER)malloc(sizeof(XTIMER));
     554                    if (pTimer)
     555                    {
     556                        ULONG ulTimeNow;
     557                        DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT,
     558                                        &ulTimeNow, sizeof(ulTimeNow));
     559                        pTimer->usTimerID = usTimerID;
     560                        pTimer->hwndTarget = hwnd;
     561                        pTimer->ulTimeout = ulTimeout;
     562                        pTimer->ulNextFire = ulTimeNow + ulTimeout;
     563
     564                        lstAppendItem(pllXTimers,
     565                                      pTimer);
     566                        usrc = pTimer->usTimerID;
     567                    }
     568                }
     569
     570                if (usrc)
     571                {
     572                    // timer created or reset:
     573                    AdjustPMTimer(pSet);
     574                }
     575            } // if ((hwnd) && (ulTimeout))
     576
     577            UnlockTimers();
     578        }
     579    }
    615580
    616581    return (usrc);
     
    625590 *
    626591 *      Returns TRUE if the timer was stopped.
     592 *
     593 *@@changed V0.9.12 (2001-05-12) [umoeller]: added mutex protection
    627594 */
    628595
     
    634601    if (pSet && pSet->pvllXTimers)
    635602    {
    636         PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
    637         BOOL fLocked = FALSE;
    638 
    639         PXTIMER pTimer = FindTimer(pSet,
    640                                    hwnd,
    641                                    usTimerID);
    642         if (pTimer)
     603        if (LockTimers())
    643604        {
    644             RemoveTimer(pSet, pTimer);
    645             // recalculate
    646             AdjustPMTimer(pSet);
    647             brc = TRUE;
     605            PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
     606            BOOL fLocked = FALSE;
     607
     608            PXTIMER pTimer = FindTimer(pSet,
     609                                       hwnd,
     610                                       usTimerID);
     611            if (pTimer)
     612            {
     613                RemoveTimer(pSet, pTimer);
     614                // recalculate
     615                AdjustPMTimer(pSet);
     616                brc = TRUE;
     617            }
     618
     619            UnlockTimers();
    648620        }
    649621    }
Note: See TracChangeset for help on using the changeset viewer.