Changeset 196 for trunk/src/corelib/kernel/qeventdispatcher_pm.cpp
- Timestamp:
- Sep 30, 2009, 6:08:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/corelib/kernel/qeventdispatcher_pm.cpp
r175 r196 284 284 static void addSelect(QSocketNotifier *notifier, HWND hwnd); 285 285 static void removeSelect(QSocketNotifier *notifier); 286 static QSocketNotifier *getSocketNotifier(int key );286 static QSocketNotifier *getSocketNotifier(int key); 287 287 288 288 // timer support is based on QTimerInfoList from the Unix implementation … … 300 300 ~QSelectThread(); 301 301 302 303 304 305 302 306 void run(); 303 307 void cancelSelectOrIdle(); … … 322 326 // socket stuff 323 327 324 typedef QHash<int, QSocketNotifier*> Sockets; 328 typedef QPair<QSocketNotifier*, HWND> SockNot; 329 typedef QHash<int, SockNot> Sockets; 325 330 Sockets sockets; 331 332 326 333 int maxSockfd; 327 328 enum Op { Add, Remove };329 struct PendingSockOp {330 Op op;331 int sockfd;332 Type type;333 HWND hwnd;334 };335 336 typedef QList<PendingSockOp> PendingSockets;337 PendingSockets pendingSockets;338 334 339 335 // timer stuff … … 402 398 403 399 } 404 instance->sockets.insert(key, notifier);405 PendingSockOp op = {Add, sockfd, type, hwnd};406 instance-> pendingSockets.append(op);400 instance->sockets.insert(key, ); 401 ; 402 instance->); 407 403 instance->cancelSelectOrIdle(); 408 404 } … … 420 416 if (instance->sockets.contains(key)) { 421 417 instance->sockets.remove(key); 422 PendingSockOp op = {Remove, sockfd, type};423 instance-> pendingSockets.append(op);418 ; 419 instance->); 424 420 instance->cancelSelectOrIdle(); 425 421 } … … 436 432 */ 437 433 // static 438 QSocketNotifier *QSelectThread::getSocketNotifier(int key )434 QSocketNotifier *QSelectThread::getSocketNotifier(int key) 439 435 { 440 436 QMutexLocker locker(&mutex); 441 437 Q_ASSERT(instance); 442 438 443 if (instance->sockets.contains(key) && 444 instance->sockets[key]->thread() == QThread::currentThread()) 445 return instance->sockets[key]; 439 if (instance->sockets.contains(key)) { 440 QSocketNotifier* notifier = instance->sockets[key].first; 441 if (notifier->thread() == QThread::currentThread()) { 442 if (reset && notifier->isEnabled()) { 443 // add the socket back to the set 444 int sockfd = notifier->socket(); 445 fd_set *set = instance->setForType(notifier->type()); 446 FD_SET(sockfd, set); 447 instance->updateMaxSockFd(sockfd, Add); 448 // inform the select thread that this socket may be included 449 // in the set and posted again 450 instance->cancelSelectOrIdle(); 451 } 452 return notifier; 453 } 454 } 446 455 447 456 return 0; … … 577 586 } else { 578 587 // also wake it up if this timer was skipped when choosing the 579 // shortest wait interval so that a longer on ce could be chosen588 // shortest wait interval so that a longer one could be chosen 580 589 bool haveNonPosted = false; 581 590 for (TimevalMap::const_iterator it = instance->timersByTimeout.begin(); … … 647 656 for (Sockets::iterator it = instance->sockets.begin(); 648 657 it != instance->sockets.end();) { 649 QSocketNotifier *notifier = it.value() ;658 QSocketNotifier *notifier = it.value(); 650 659 if (notifier->thread() == QThread::currentThread()) { 651 PendingSockOp op = {Remove, notifier->socket(), notifier->type()};652 instance->pendingSockets.append(op);653 660 it = instance->sockets.erase(it); 661 662 654 663 } else { 655 664 ++it; … … 694 703 { 695 704 // initialize socket stuff 705 706 707 696 708 maxSockfd = -1; 697 709 … … 720 732 } 721 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 722 771 void QSelectThread::run() 723 772 { 724 // maintain a separate hash for HWNDs to avoid mutex locking every time725 // select() returns an event that we want to post726 typedef QHash<int, HWND> Hwnds;727 Hwnds hwnds;728 729 fd_set readS, writeS, exS;730 FD_ZERO(&readS);731 FD_ZERO(&writeS);732 FD_ZERO(&exS);733 734 773 mutex.lock(); 735 774 736 775 do { 737 // process pending socket operations738 while (!pendingSockets.isEmpty()) {739 PendingSockOp p = pendingSockets.takeFirst();740 switch (p.op) {741 case Add:742 switch (p.type) {743 case QSocketNotifier::Read:744 FD_SET(p.sockfd, &readS); break;745 case QSocketNotifier::Write:746 FD_SET(p.sockfd, &writeS); break;747 case QSocketNotifier::Exception:748 FD_SET(p.sockfd, &exS); break;749 }750 hwnds.insert(toSockKey(p.sockfd, p.type), p.hwnd);751 maxSockfd = qMax(maxSockfd, p.sockfd);752 break;753 case Remove:754 switch (p.type) {755 case QSocketNotifier::Read:756 FD_CLR(p.sockfd, &readS); break;757 case QSocketNotifier::Write:758 FD_CLR(p.sockfd, &writeS); break;759 case QSocketNotifier::Exception:760 FD_CLR(p.sockfd, &exS); break;761 }762 hwnds.remove(toSockKey(p.sockfd, p.type));763 if (maxSockfd == p.sockfd) {764 // find the new hignest socket765 maxSockfd = -1;766 if (!hwnds.isEmpty()) {767 for (Hwnds::const_iterator it = hwnds.constBegin();768 it != hwnds.constEnd(); ++it) {769 maxSockfd = qMax(toSocket(it.key()), maxSockfd);770 }771 }772 }773 break;774 }775 }776 777 776 // get the maximum time we can wait (for the closest timer) 778 777 timeval *timeout = 0; … … 787 786 mutex.unlock(); 788 787 nsel = ::select(maxSockfd + 1, &tmpRead, &tmpWrite, &tmpEx, timeout); 788 789 789 if (nsel > 0) { 790 for (Hwnds::const_iterator it = hwnds.constBegin(); 791 it != hwnds.constEnd(); ++it) { 790 // find out which sockets to post. Note that we remove these 791 // sockets from the main sets to avoid polluting the message 792 // queue with sockett messages if the target window is not fast 793 // enough to process them. They will be put back once processed. 794 for (Sockets::const_iterator it = sockets.constBegin(); 795 it != sockets.constEnd(); ++it) { 792 796 int sockfd = toSocket(it.key()); 797 793 798 bool isSet = false; 794 switch (t oSockType(it.key())) {799 switch (t) { 795 800 case QSocketNotifier::Read: 796 801 isSet = FD_ISSET(sockfd, &tmpRead); break; … … 800 805 isSet = FD_ISSET(sockfd, &tmpEx); break; 801 806 } 802 if (isSet) 803 WinPostMsg(it.value(), WM_U_SEM_SELECT, MPFROMLONG(it.key()), 0); 807 if (isSet) { 808 fd_set *set = setForType(type); 809 FD_CLR(sockfd, set); 810 updateMaxSockFd(sockfd, Remove); 811 WinPostMsg(it.value().second, WM_U_SEM_SELECT, MPFROMLONG(it.key()), 0); 812 } 804 813 } 805 814 } 806 mutex.lock();807 815 } else { 808 816 nsel = -1; … … 1035 1043 } 1036 1044 static void removeSelect(QSocketNotifier *notifier) {} 1037 static QSocketNotifier *getSocketNotifier(int key ); { return 0; }1045 static QSocketNotifier *getSocketNotifier(int key); { return 0; } 1038 1046 1039 1047 static void addTimer(int timerId, int interval, QObject *object, HWND hwnd) { … … 1147 1155 case WM_U_SEM_SELECT: { 1148 1156 QSocketNotifier *notifier = 1149 QSelectThread::getSocketNotifier(LONGFROMMP(mp1) );1157 QSelectThread::getSocketNotifier(LONGFROMMP(mp1)); 1150 1158 if (notifier) { 1151 1159 QEvent event(QEvent::SockAct);
Note:
See TracChangeset
for help on using the changeset viewer.