Changeset 68 for trunk/src/helpers/timer.c
- Timestamp:
- May 15, 2001, 6:15:18 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/timer.c
r44 r68 144 144 ********************************************************************/ 145 145 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 } */ 146 HMTX G_hmtxTimers = NULLHANDLE; // timers lock mutex 228 147 229 148 /* ****************************************************************** … … 232 151 * 233 152 ********************************************************************/ 153 154 /* 155 *@@ LockTimers: 156 * 157 *@@added V0.9.12 (2001-05-12) [umoeller] 158 */ 159 160 BOOL 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 177 VOID UnlockTimers(VOID) 178 { 179 DosReleaseMutexSem(G_hmtxTimers); 180 } 234 181 235 182 /* … … 239 186 * _and_ timer ID. 240 187 * 241 * Internal function. 188 * Internal function. Caller must hold the mutex. 242 189 */ 243 190 … … 272 219 * the global linked list of running timers. 273 220 * 274 * Internal function. 221 * Internal function. Caller must hold the mutex. 275 222 */ 276 223 … … 339 286 * 340 287 *@@added V0.9.9 (2001-02-28) [umoeller] 288 *@@changed V0.9.12 (2001-05-12) [umoeller]: added mutex protection 341 289 */ 342 290 … … 347 295 if (pSet->pvllXTimers) 348 296 { 349 PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers; 350 351 PLISTNODE pTimerNode; 352 353 while (pTimerNode = lstQueryFirstNode(pllXTimers)) 297 if (LockTimers()) 354 298 { 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(); 357 312 } 358 359 lstFree(pllXTimers);360 313 } 361 314 … … 373 326 * goes thru all XTimers in the sets and starts 374 327 * or stops the PM timer with a decent frequency. 328 * 329 * Internal function. Caller must hold the mutex. 375 330 * 376 331 *@@added V0.9.9 (2001-03-07) [umoeller] … … 435 390 * 436 391 *@@added V0.9.9 (2001-02-28) [umoeller] 392 *@@changed V0.9.12 (2001-05-12) [umoeller]: added mutex protection 437 393 */ 438 394 … … 441 397 if (pSet && pSet->pvllXTimers) 442 398 { 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()) 450 400 { 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) 453 408 { 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; 460 421 } 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 484 423 { 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) 488 442 { 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) 493 446 { 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; 504 486 } 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); 528 490 } 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) 535 496 } 536 497 … … 552 513 * 553 514 *@@changed V0.9.7 (2000-12-08) [umoeller]: got rid of dtGetULongTime 515 *@@changed V0.9.12 (2001-05-12) [umoeller]: added mutex protection 554 516 */ 555 517 … … 565 527 if (pSet && pSet->pvllXTimers) 566 528 { 567 PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers; 568 569 if ((hwnd) && (ulTimeout)) 529 if (LockTimers()) 570 530 { 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)) 578 534 { 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); 590 541 if (pTimer) 591 542 { 543 // exists already: reset only 592 544 ULONG ulTimeNow; 593 545 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, 594 546 &ulTimeNow, sizeof(ulTimeNow)); 595 pTimer->usTimerID = usTimerID;596 pTimer->hwndTarget = hwnd;597 pTimer->ulTimeout = ulTimeout;598 547 pTimer->ulNextFire = ulTimeNow + ulTimeout; 599 600 lstAppendItem(pllXTimers,601 pTimer);602 548 usrc = pTimer->usTimerID; 603 549 } 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 } 615 580 616 581 return (usrc); … … 625 590 * 626 591 * Returns TRUE if the timer was stopped. 592 * 593 *@@changed V0.9.12 (2001-05-12) [umoeller]: added mutex protection 627 594 */ 628 595 … … 634 601 if (pSet && pSet->pvllXTimers) 635 602 { 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()) 643 604 { 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(); 648 620 } 649 621 }
Note:
See TracChangeset
for help on using the changeset viewer.