- Timestamp:
- Sep 3, 2006, 10:42:48 PM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel/qeventloop_pm.cpp
r116 r121 40 40 #include "qapplication.h" 41 41 #include "qptrlist.h" 42 #include "qvaluelist.h" 42 43 43 44 #include <sys/socket.h> … … 426 427 QObject *obj; // - object to receive events 427 428 }; 428 typedef QPtrVector<TimerInfo> TimerVec; 429 typedef QPtrVector<TimerInfo> TimerVec; // vector of TimerInfo structs 429 430 typedef QIntDict<TimerInfo> TimerDict; // fast dict of timers 430 431 … … 432 433 static TimerDict *timerDict = 0; // timer dict 433 434 435 template <typename T> // template to track availability 436 class QFreeValueList // of free (unused) integer 437 { // values within some interval 438 public: 439 QFreeValueList( T min, T max ) : intMin( min ), intMax( max ) { 440 freeValues.push_front( Span( min, max ) ); 441 } 442 T take() { 443 Q_ASSERT( !isEmpty() ); 444 Span &free = freeValues.first(); 445 T freeValue = free.min; 446 if ( free.min == free.max ) freeValues.pop_front(); 447 else free.min ++; 448 return freeValue; 449 } 450 void give( T val ) { 451 Q_ASSERT( val >= intMin && val <= intMax ); 452 typename FreeList::iterator it = freeValues.begin(); 453 for ( ; it != freeValues.end(); ++ it ) { 454 Span &span = (*it); 455 if ( val == span.min - 1 ) { 456 span.min --; 457 typename FreeList::iterator it2 = it; 458 if ( it2 != freeValues.begin() && (*--it2).max + 1 == span.min ) { 459 span.min = (*it2).min; 460 freeValues.erase( it2 ); 461 } 462 return; 463 } else if ( val == span.max + 1 ) { 464 span.max ++; 465 typename FreeList::iterator it2 = it; 466 if ( ++it2 != freeValues.end() && (*it2).min - 1 == span.max ) { 467 span.max = (*it2).max; 468 freeValues.erase( it2 ); 469 } 470 return; 471 } 472 else if ( val < span.min ) 473 break; 474 Q_ASSERT( val > span.max ); 475 } 476 if ( it == freeValues.end() ) freeValues.push_back( Span( val, val ) ); 477 else freeValues.insert( it, Span( val, val ) ); 478 } 479 bool isEmpty() { return freeValues.isEmpty(); } 480 T min() const { return intMin; } 481 T max() const { return intMax; } 482 private: 483 struct Span { 484 Span() : min( 0 ), max( 0 ) {} 485 Span( T mn, T mx ) : min( mn ), max( mx ) {} 486 T min; 487 T max; 488 }; 489 typedef QValueList<Span> FreeList; 490 FreeList freeValues; 491 T intMin; 492 T intMax; 493 }; 494 495 typedef QFreeValueList<int> FreeQtTIDList; // list of free Qt timer IDs 496 static FreeQtTIDList *freeQtTIDs = 0; 497 typedef QFreeValueList<ULONG> FreePMTIDList; // list of free PM timer IDs 498 static FreePMTIDList *freePMTIDs = 0; 434 499 435 500 // Activate a timer, used by both event-loop based and simple timers. … … 492 557 timerDict = new TimerDict( 29 ); 493 558 Q_CHECK_PTR( timerDict ); 559 freeQtTIDs = new FreeQtTIDList( 0, INT_MAX ); 560 Q_CHECK_PTR( freeQtTIDs ); 561 freePMTIDs = new FreePMTIDList( 1, TID_USERMAX - 1 ); 562 Q_CHECK_PTR( freePMTIDs ); 494 563 } 495 564 … … 512 581 WinStopTimer( 0, qt_aux_win.hwnd(), t->id ); 513 582 } 583 delete freePMTIDs; 584 freePMTIDs = 0; 585 delete freeQtTIDs; 586 freeQtTIDs = 0; 514 587 delete timerDict; 515 588 timerDict = 0; … … 539 612 initTimers(); 540 613 541 int ind = timerVec->findRef( 0 ); // get free timer 542 if ( ind == -1 ) { 543 ind = timerVec->size(); // increase the size 544 if ( ind >= TID_USERMAX ) { 614 if ( freeQtTIDs->isEmpty() ) { 545 615 #if defined(QT_CHECK_STATE) 546 qWarning( "qStartTimer: Maximum number of timers (%d) is reached.", 547 TID_USERMAX ); 548 return 0; 616 qWarning( "qStartTimer: Maximum number of timers (%d) is reached.", 617 freeQtTIDs->max() - freeQtTIDs->min() + 1 ); 549 618 #endif 550 } 551 timerVec->resize( ind * 4 ); 619 return 0; 620 } 621 622 if ( freePMTIDs->isEmpty() ) { 623 #if defined(QT_CHECK_STATE) 624 qWarning( "qStartTimer: Maximum number of non-zero timers (%ld) is reached.", 625 freePMTIDs->max() - freePMTIDs->min() + 1 ); 626 #endif 627 return 0; 628 } 629 630 int ind = freeQtTIDs->take(); // get free timer 631 if ( (uint) ind >= timerVec->size() ) { 632 uint newSize = timerVec->size() * 4; // increase the size 633 if ( newSize <= (uint) ind ) 634 newSize = (uint) ind + 1; 635 timerVec->resize( newSize ); 552 636 } 553 637 t = new TimerInfo; // create timer entry … … 563 647 WinPostMsg( qt_aux_win.hwnd(), WM_U_SEM_ZEROTIMER, 0, 0 ); 564 648 } else { 565 t->id = WinStartTimer( 0, qt_aux_win.hwnd(), ind + 1, (ULONG) interval );566 }567 if ( !t->zero &&t->id == 0 ) {649 ULONG freeId = freePMTIDs->take(); // get free timer ID 650 t->id = WinStartTimer( 0, qt_aux_win.hwnd(), freeId, (ULONG) interval ); 651 if ( t->id == 0 ) { 568 652 #if defined(QT_CHECK_STATE) 569 653 qSystemWarning( "qStartTimer: Failed to create a timer." ); 570 654 #endif 571 delete t; // could not set timer 572 return 0; 655 freePMTIDs->give( freeId ); // could not start timer 656 freeQtTIDs->give( ind ); 657 delete t; 658 return 0; 659 } 573 660 } 574 661 timerVec->insert( ind, t ); // store in timer vector … … 588 675 numZeroTimers--; 589 676 } else { 590 WinStopTimer( 0, 0, t->id ); 677 WinStopTimer( 0, qt_aux_win.hwnd(), t->id ); 678 freePMTIDs->give( t->id ); 591 679 timerDict->remove( t->id ); 592 680 } 681 freeQtTIDs->give( t->ind ); 593 682 timerVec->remove( ind-1 ); 594 683 return TRUE; … … 606 695 numZeroTimers--; 607 696 } else { 608 WinStopTimer( 0, 0, t->id ); 697 WinStopTimer( 0, qt_aux_win.hwnd(), t->id ); 698 freePMTIDs->give( t->id ); 609 699 timerDict->remove( t->id ); 610 700 } 701 freeQtTIDs->give( t->ind ); 611 702 timerVec->remove( i ); 612 703 }
Note:
See TracChangeset
for help on using the changeset viewer.