Changeset 74 for trunk/src/helpers/timer.c
- Timestamp:
- May 24, 2001, 5:21:06 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/timer.c
r69 r74 233 233 } 234 234 235 /* ******************************************************************236 *237 * Exported functions238 *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 target247 * window for the master PM timer. This window must respond248 * to a WM_TIMER message with the specified usPMTimerID and249 * invoke tmrTimerTick then.250 *251 * Note that the master timer is not started until an XTimer252 * 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 window260 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 using282 * tmrCreateSet.283 *284 * Of course, this will stop all XTimers which285 * 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 protection289 */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 324 235 /* 325 236 *@@ AdjustPMTimer: … … 378 289 } 379 290 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 315 PXTIMERSET 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 347 VOID 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 380 384 /* 381 385 *@@ tmrTimerTick: … … 391 395 *@@added V0.9.9 (2001-02-28) [umoeller] 392 396 *@@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 393 398 */ 394 399 395 400 VOID tmrTimerTick(PXTIMERSET pSet) // in: timer set (from tmrCreateSet) 396 401 { 397 if ( pSet && pSet->pvllXTimers)398 { 399 if ( LockTimers())402 if (LockTimers()) 403 { 404 if (pSet) 400 405 { 401 406 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) 408 408 { 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) 411 415 { 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; 418 428 } 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 442 430 { 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) 448 440 { 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 ) 453 451 { 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()) 498 502 } 499 503 … … 527 531 // _Pmpf((__FUNCTION__ ": entering")); 528 532 529 if ( pSet && pSet->pvllXTimers)530 { 531 if ( LockTimers())533 if (LockTimers()) 534 { 535 if (pSet) 532 536 { 533 537 PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers; 534 538 535 if (( hwnd) && (ulTimeout))539 if ((pllXTimers) && (hwnd) && (ulTimeout)) 536 540 { 537 541 PXTIMER pTimer; … … 571 575 572 576 if (usrc) 573 {574 577 // timer created or reset: 575 578 AdjustPMTimer(pSet); 576 } 579 577 580 } // if ((hwnd) && (ulTimeout)) 578 579 UnlockTimers();580 581 } 582 583 UnlockTimers(); 581 584 } 582 585 … … 601 604 { 602 605 BOOL brc = FALSE; 603 if ( pSet && pSet->pvllXTimers)604 { 605 if ( LockTimers())606 if (LockTimers()) 607 { 608 if (pSet && pSet->pvllXTimers) 606 609 { 607 610 PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers; … … 618 621 brc = TRUE; 619 622 } 620 621 UnlockTimers();622 623 } 624 625 UnlockTimers(); 623 626 } 624 627
Note:
See TracChangeset
for help on using the changeset viewer.