Changeset 141 for trunk/src/corelib
- Timestamp:
- Aug 29, 2009, 5:44:05 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/corelib/kernel/qeventdispatcher_pm.cpp
r98 r141 219 219 220 220 // socket select notification (higher priority) 221 #define WM_U_SEM_SELECT WM_ SEM1221 #define WM_U_SEM_SELECT WM_ 222 222 // timer notification (lower priority) 223 #define WM_U_SEM_TIMER WM_ SEM3 // scheduled right before WM_TIMER223 #define WM_U_SEM_TIMER WM_TIMER 224 224 225 225 // Internal operator functions for timevals … … 313 313 int refcnt; 314 314 QWaitCondition cond; 315 315 316 316 317 // socket stuff … … 465 466 instance->timers.insert(t->id, t); 466 467 // QMap is sorted by key (timeval), which is exactly what we need 467 instance->timersByTimeout.insert (t->timeout, t);468 instance->timersByTimeout.insert(t->timeout, t); 468 469 469 470 instance->cancelSelectOrIdle(); … … 573 574 if (instance == 0) { 574 575 instance = new QSelectThread(); 575 instance->start(); 576 } 577 578 ++instance->refcnt; 576 } else { 577 while (instance->finish) { 578 // the previous instance is still getting finished; let it go 579 locker.unlock(); 580 QThread::yieldCurrentThread(); 581 locker.relock(); 582 } 583 } 584 585 // don't count on ourselves 586 if (instance != QThread::currentThread()) 587 ++instance->refcnt; 579 588 } 580 589 … … 592 601 { 593 602 QMutexLocker locker(&mutex); 594 Q_ASSERT(instance); 603 604 // don't count on ourselves 605 if (instance == QThread::currentThread()) 606 return; 595 607 596 608 // remove socket notifiers owned by this thread … … 629 641 instance->finish = true; 630 642 instance->cancelSelectOrIdle(); 643 644 631 645 instance->wait(); 646 632 647 delete instance; 633 648 instance = 0; … … 637 652 } 638 653 639 QSelectThread::QSelectThread() : finish(false), refcnt(0) 654 QSelectThread::QSelectThread() : finish(false), refcnt(0) 640 655 { 641 656 // initialize socket stuff … … 681 696 682 697 do { 683 while (!finish && sockets.isEmpty()) { 684 cond.wait(&mutex); 698 while (!finish && sockets.isEmpty() && timers.isEmpty()) { 699 if (!cancelWait) 700 cond.wait(&mutex); 701 cancelWait = false; 685 702 } 686 703 … … 735 752 timeout = &wait_tm; 736 753 737 mutex.unlock(); 738 739 // do select 740 int nsel = ::select(maxSockfd + 1, &readS, &writeS, &exS, timeout); 741 if (nsel > 0) { 742 for (Hwnds::const_iterator it = hwnds.constBegin(); 743 it != hwnds.constEnd(); ++it) { 744 int sockfd = toSocket(it.key()); 745 bool isSet = false; 746 switch (toSockType(it.key())) { 747 case QSocketNotifier::Read: 748 isSet = FD_ISSET(sockfd, &readS); break; 749 case QSocketNotifier::Write: 750 isSet = FD_ISSET(sockfd, &writeS); break; 751 case QSocketNotifier::Exception: 752 isSet = FD_ISSET(sockfd, &exS); break; 754 // do select or simple wait 755 int nsel = 0; 756 if (maxSockfd >= 0) { 757 mutex.unlock(); 758 nsel = ::select(maxSockfd + 1, &readS, &writeS, &exS, timeout); 759 if (nsel > 0) { 760 for (Hwnds::const_iterator it = hwnds.constBegin(); 761 it != hwnds.constEnd(); ++it) { 762 int sockfd = toSocket(it.key()); 763 bool isSet = false; 764 switch (toSockType(it.key())) { 765 case QSocketNotifier::Read: 766 isSet = FD_ISSET(sockfd, &readS); break; 767 case QSocketNotifier::Write: 768 isSet = FD_ISSET(sockfd, &writeS); break; 769 case QSocketNotifier::Exception: 770 isSet = FD_ISSET(sockfd, &exS); break; 771 } 772 if (isSet) 773 WinPostMsg(it.value(), WM_U_SEM_SELECT, MPFROMLONG(it.key()), 0); 753 774 } 754 if (isSet)755 WinPostMsg(it.value(), WM_U_SEM_SELECT, MPFROMLONG(it.key()), 0);756 775 } 757 } 758 759 mutex.lock(); 776 mutex.lock(); 777 } else { 778 ulong msecs = timeout ? 779 timeout->tv_sec * 1000 + timeout->tv_usec / 1000 : ULONG_MAX; 780 if (!cancelWait) { 781 if (cond.wait(&mutex, msecs)) 782 nsel = -2; // avoid activation on when cancelled 783 } else { 784 nsel = -2; // same as above 785 } 786 cancelWait = false; 787 } 760 788 761 789 if (nsel == 0 || (nsel == -1 && errno == EINTR)) { … … 775 803 ::so_cancel(maxSockfd); 776 804 } else { 777 // terminate the idle state 778 cond.wakeOne(); 805 // terminate the idle or simple wait state 806 if (!cancelWait) { 807 cancelWait = true; 808 cond.wakeOne(); 809 } 779 810 } 780 811 } … … 856 887 { 857 888 // repair all timers 889 858 890 for (TimerInfoMap::iterator it = instance->timers.begin(); 859 891 it != instance->timers.end(); ++it) { 860 892 register TimerInfo *t = it.value(); 861 893 t->timeout = t->timeout - diff; 894 862 895 } 863 896 } … … 920 953 921 954 // reinsert timer (in proper sort order) 922 timersByTimeout.insert (t->timeout, t);955 timersByTimeout.insert(t->timeout, t); 923 956 924 957 // post the timer message
Note:
See TracChangeset
for help on using the changeset viewer.