Changeset 84 for trunk/src/corelib/kernel
- Timestamp:
- Jul 26, 2009, 1:19:03 AM (16 years ago)
- Location:
- trunk/src/corelib/kernel
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/corelib/kernel/qeventdispatcher_pm.cpp
r83 r84 49 49 #include "qmutex.h" 50 50 #include "qwaitcondition.h" 51 52 53 54 51 55 52 56 #include "qabstracteventdispatcher_p.h" … … 59 63 60 64 #include <sys/socket.h> 65 66 61 67 62 68 QT_BEGIN_NAMESPACE 63 69 64 70 extern uint qGlobalPostedEventsCount(); 65 66 class QEventDispatcherPMPrivate;67 68 // @todo later: timers69 #if 070 71 struct WinTimerInfo { // internal timer info72 QObject *dispatcher;73 int timerId;74 int interval;75 QObject *obj; // - object to receive events76 bool inTimerEvent;77 int fastTimerId;78 };79 80 class QZeroTimerEvent : public QTimerEvent81 {82 public:83 inline QZeroTimerEvent(int timerId)84 : QTimerEvent(timerId)85 { t = QEvent::ZeroTimerEvent; }86 };87 88 typedef QList<WinTimerInfo*> WinTimerVec; // vector of TimerInfo structs89 typedef QHash<int, WinTimerInfo*> WinTimerDict; // fast dict of timers90 91 #if !defined(DWORD_PTR) && !defined(Q_WS_WIN64)92 #define DWORD_PTR DWORD93 #endif94 95 typedef MMRESULT(WINAPI *ptimeSetEvent)(UINT, UINT, LPTIMECALLBACK, DWORD_PTR, UINT);96 typedef MMRESULT(WINAPI *ptimeKillEvent)(UINT);97 98 static ptimeSetEvent qtimeSetEvent = 0;99 static ptimeKillEvent qtimeKillEvent = 0;100 101 LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);102 103 static void resolveTimerAPI()104 {105 static bool triedResolve = false;106 if (!triedResolve) {107 #ifndef QT_NO_THREAD108 QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve));109 if (triedResolve)110 return;111 #endif112 triedResolve = true;113 #if !defined(Q_OS_WINCE)114 qtimeSetEvent = (ptimeSetEvent)QLibrary::resolve(QLatin1String("winmm"), "timeSetEvent");115 qtimeKillEvent = (ptimeKillEvent)QLibrary::resolve(QLatin1String("winmm"), "timeKillEvent");116 #else117 qtimeSetEvent = (ptimeSetEvent)QLibrary::resolve(QLatin1String("Mmtimer"), "timeSetEvent");118 qtimeKillEvent = (ptimeKillEvent)QLibrary::resolve(QLatin1String("Mmtimer"), "timeKillEvent");119 #endif120 }121 }122 123 #endif124 71 125 72 /***************************************************************************** … … 272 219 273 220 274 // socket select notification (highe stpriority)221 // socket select notification (highe priority) 275 222 #define WM_U_SEM_SELECT WM_SEM1 276 // zero timer notification (lowest priority) 277 #define WM_U_SEM_ZEROTIMER WM_SEM4 223 // timer notification (lower priority) 224 #define WM_U_SEM_TIMER WM_SEM3 // scheduled right before WM_TIMER 225 226 // Internal operator functions for timevals 227 228 inline bool operator<(const timeval &t1, const timeval &t2) 229 { 230 return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec); 231 } 232 233 inline bool operator==(const timeval &t1, const timeval &t2) 234 { 235 return t1.tv_sec == t2.tv_sec && t1.tv_usec == t2.tv_usec; 236 } 237 238 inline timeval &operator+=(timeval &t1, const timeval &t2) 239 { 240 t1.tv_sec += t2.tv_sec; 241 if ((t1.tv_usec += t2.tv_usec) >= 1000000l) { 242 ++t1.tv_sec; 243 t1.tv_usec -= 1000000l; 244 } 245 return t1; 246 } 247 inline timeval operator+(const timeval &t1, const timeval &t2) 248 { 249 timeval tmp; 250 tmp.tv_sec = t1.tv_sec + t2.tv_sec; 251 if ((tmp.tv_usec = t1.tv_usec + t2.tv_usec) >= 1000000l) { 252 ++tmp.tv_sec; 253 tmp.tv_usec -= 1000000l; 254 } 255 return tmp; 256 } 257 inline timeval operator-(const timeval &t1, const timeval &t2) 258 { 259 timeval tmp; 260 tmp.tv_sec = t1.tv_sec - t2.tv_sec; 261 if ((tmp.tv_usec = t1.tv_usec - t2.tv_usec) < 0l) { 262 --tmp.tv_sec; 263 tmp.tv_usec += 1000000l; 264 } 265 return tmp; 266 } 278 267 279 268 /***************************************************************************** 280 socket select() thread269 socket select() thread 281 270 *****************************************************************************/ 282 271 283 272 #if !defined(QT_NO_THREAD) 284 273 285 class QS ockSelectThread : public QThread274 class QSelectThread : public QThread 286 275 { 287 276 public: 277 288 278 typedef QSocketNotifier::Type Type; 289 279 … … 292 282 static QSocketNotifier *getSocketNotifier(int key); 293 283 284 285 286 287 288 289 290 294 291 static void attachThread(); 295 292 static void detachThread(); 296 293 297 294 private: 298 QSockSelectThread() : finish(false), refcnt(0), maxSockfd(-1) {}; 295 QSelectThread(); 296 ~QSelectThread(); 299 297 300 298 void run(); 301 299 void cancelSelectOrIdle(); 300 301 302 303 304 305 306 307 308 309 310 311 302 312 303 313 bool finish; … … 305 315 QWaitCondition cond; 306 316 317 318 307 319 typedef QHash<int, QSocketNotifier*> Sockets; 308 320 Sockets sockets; … … 310 322 311 323 enum Op { Add, Remove }; 312 struct Pending Op {324 struct PendingOp { 313 325 Op op; 314 326 int sockfd; … … 316 328 HWND hwnd; 317 329 }; 318 typedef QList<PendingOp> Pending; 319 Pending pending; 320 321 static int toKey(int sockfd, Type type) { 330 331 typedef QList<PendingSockOp> PendingSockets; 332 PendingSockets pendingSockets; 333 334 // timer stuff 335 336 struct TimerInfo { 337 int id; // - timer identifier 338 timeval interval; // - timer interval 339 timeval timeout; // - when to sent event 340 QObject *obj; // - object to receive event 341 HWND hwnd; // - where to post the timer message 342 }; 343 344 typedef QHash<int, TimerInfo*> TimerInfoMap; 345 TimerInfoMap timers; 346 347 typedef QMap<timeval, TimerInfo*> TimevalMap; 348 TimevalMap timersByTimeout; 349 350 timeval currentTime; 351 timeval previousTime; 352 clock_t previousTicks; 353 int ticksPerSecond; 354 int msPerTick; 355 356 static int toSockKey(int sockfd, Type type) { 322 357 // as a hash key, we use first two bits of int for the type and the rest 323 358 // for the sockfd which should be enough in the real world … … 325 360 return (sockfd << 2) + type; 326 361 } 327 // opposite to to Key()362 // opposite to toKey() 328 363 static int toSocket(int key) { return key >> 2; } 329 static Type to Type(int key) { return Type(key & 0x3); }330 331 static QS ockSelectThread *instance;364 static Type toType(int key) { return Type(key & 0x3); } 365 366 static QSelectThread *instance; 332 367 static QMutex mutex; 333 368 }; 334 369 335 370 // static 336 QS ockSelectThread *QSockSelectThread::instance = 0;337 QMutex QS ockSelectThread::mutex;371 QSSelectThread::instance = 0; 372 QMutex QSelectThread::mutex; 338 373 339 374 // static 340 void QS ockSelectThread::addSelect(QSocketNotifier *notifier, HWND hwnd)375 void QSelectThread::addSelect(QSocketNotifier *notifier, HWND hwnd) 341 376 { 342 377 Q_ASSERT(hwnd != NULLHANDLE); … … 346 381 int sockfd = notifier->socket(); 347 382 Type type = notifier->type(); 348 int key = to Key(sockfd, type);383 int key = toKey(sockfd, type); 349 384 350 385 QMutexLocker locker(&mutex); 351 386 Q_ASSERT(instance); 352 387 388 353 389 instance->start(); 354 390 … … 360 396 } 361 397 instance->sockets.insert(key, notifier); 362 Pending Op op = {Add, sockfd, type, hwnd};363 instance->pending .append(op);398 PendingOp op = {Add, sockfd, type, hwnd}; 399 instance->pending.append(op); 364 400 instance->cancelSelectOrIdle(); 365 401 } 366 402 367 403 // static 368 void QS ockSelectThread::removeSelect(QSocketNotifier *notifier)404 void QSelectThread::removeSelect(QSocketNotifier *notifier) 369 405 { 370 406 QMutexLocker locker(&mutex); … … 373 409 int sockfd = notifier->socket(); 374 410 Type type = notifier->type(); 375 int key = to Key(sockfd, notifier->type());411 int key = toKey(sockfd, notifier->type()); 376 412 377 413 if (instance->sockets.contains(key)) { 378 414 instance->sockets.remove(key); 379 Pending Op op = {Remove, sockfd, type};380 instance->pending .append(op);415 PendingOp op = {Remove, sockfd, type}; 416 instance->pending.append(op); 381 417 instance->cancelSelectOrIdle(); 382 418 } … … 389 425 390 426 May return 0 if the socket notifier object is disabled/deleted after 391 WM_U_SEM_SELECT is issued for it but before this message gets processed by427 WM_U_SEM_SELECT s issued for it but before this message gets processed by 392 428 the owning thread. 393 429 */ 394 430 // static 395 QSocketNotifier *QS ockSelectThread::getSocketNotifier(int key)431 QSocketNotifier *QSelectThread::getSocketNotifier(int key) 396 432 { 397 433 QMutexLocker locker(&mutex); … … 405 441 } 406 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 407 539 /*! 408 Incrreases the usage count of the QSockSelectThread instance by one. If no 409 QSockSelectThread instance exists yet, creates it. Note that the thread is 540 Returns the timer object corresponding to the given timer ID from the 541 WM_U_SEM_TIMER message. The return value is only correct for the thread 542 that owns the timer (creates/registers/unregisters it). 543 544 May return 0 if the timer is stopped/deleted after WM_U_SEM_TIMER was issued 545 for it but before this message gets processed by the owning thread. 546 */ 547 // static 548 QObject *QSelectThread::getTimerObject(int timerId) 549 { 550 QMutexLocker locker(&mutex); 551 Q_ASSERT(instance); 552 553 TimerInfo *t = instance->timers.value(timerId); 554 if (t) 555 return t->obj; 556 557 return 0; 558 } 559 560 /*! 561 Incrreases the usage count of the QSelectThread instance by one. If no 562 QSelectThread instance exists yet, creates it. Note that the thread is 410 563 started on demand by addSelect(), not by this method. 411 564 … … 415 568 */ 416 569 // static 417 void QS ockSelectThread::attachThread()570 void QSelectThread::attachThread() 418 571 { 419 572 QMutexLocker locker(&mutex); 420 573 421 574 if (instance == 0) { 422 instance = new QS ockSelectThread();575 instance = new QSelectThread(); 423 576 instance->start(); 424 577 } … … 429 582 /*! 430 583 Removes all socket notifiers owned by the current thread and decreases the 431 usage count of the QS ockSelectThread instance by one. When the usage count584 usage count of the QSelectThread instance by one. When the usage count 432 585 goes to zero, the socket select thread is stopped and the instance is 433 586 deleted. … … 437 590 */ 438 591 // static 439 void QS ockSelectThread::detachThread()592 void QSelectThread::detachThread() 440 593 { 441 594 QMutexLocker locker(&mutex); 442 595 Q_ASSERT(instance); 443 596 597 444 598 for (Sockets::iterator it = instance->sockets.begin(); 445 599 it != instance->sockets.end();) { 446 600 QSocketNotifier *notifier = it.value(); 447 601 if (notifier->thread() == QThread::currentThread()) { 448 Pending Op op = {Remove, notifier->socket(), notifier->type()};449 instance->pending .append(op);602 PendingOp op = {Remove, notifier->socket(), notifier->type()}; 603 instance->pending.append(op); 450 604 it = instance->sockets.erase(it); 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 451 624 } else { 452 625 ++it; … … 464 637 } 465 638 } 466 void QSockSelectThread::run() 639 640 QSelectThread::QSelectThread() : finish(false), refcnt(0) 641 { 642 // initialize socket stuff 643 maxSockfd = -1; 644 645 // initialize timer stuff 646 getTime(currentTime); 647 648 // initialize the timeChanged() machinery 649 previousTime = currentTime; 650 651 tms unused; 652 previousTicks = times(&unused); 653 654 ticksPerSecond = sysconf(_SC_CLK_TCK); 655 msPerTick = 1000 / ticksPerSecond; 656 } 657 658 QSelectThread::~QSelectThread() 659 { 660 // detachThread() calls must clean up sockets/timers they own 661 Q_ASSERT(sockets.isEmpty()); 662 Q_ASSERT(timers.isEmpty()); 663 Q_ASSERT(timersByTimeout.isEmpty()); 664 665 // but, still, be nice and cleanup timers (we allocate them with new) 666 qDeleteAll(timers); 667 } 668 669 void QSelectThread::run() 467 670 { 468 671 // maintain a separate hash for HWNDs to avoid mutex locking every time … … 476 679 FD_ZERO(&exS); 477 680 681 682 478 683 do { 479 mutex.lock();480 481 684 while (!finish && sockets.isEmpty()) { 482 685 cond.wait(&mutex); 483 686 } 484 687 485 if (finish) { 486 mutex.unlock(); 688 if (finish) 487 689 break; 488 } 489 490 while (!pending .isEmpty()) {491 Pending Op p = pending.takeFirst();690 691 // process pending socket operations 692 while (!pending.isEmpty()) { 693 Pending.takeFirst(); 492 694 switch (p.op) { 493 695 case Add: … … 500 702 FD_SET(p.sockfd, &exS); break; 501 703 } 502 hwnds.insert(to Key(p.sockfd, p.type), p.hwnd);704 hwnds.insert(toKey(p.sockfd, p.type), p.hwnd); 503 705 maxSockfd = qMax(maxSockfd, p.sockfd); 504 706 break; … … 512 714 FD_CLR(p.sockfd, &exS); break; 513 715 } 514 hwnds.remove(to Key(p.sockfd, p.type));716 hwnds.remove(toKey(p.sockfd, p.type)); 515 717 if (maxSockfd == p.sockfd) { 516 718 // find the new hignest socket … … 528 730 } 529 731 732 733 734 735 736 737 738 739 530 740 // do select 531 mutex.unlock(); 532 int nsel = ::select(maxSockfd + 1, &readS, &writeS, &exS, NULL); 741 int nsel = ::select(maxSockfd + 1, &readS, &writeS, &exS, timeout); 533 742 if (nsel > 0) { 534 743 for (Hwnds::const_iterator it = hwnds.constBegin(); … … 536 745 int sockfd = toSocket(it.key()); 537 746 bool isSet = false; 538 switch (to Type(it.key())) {747 switch (toType(it.key())) { 539 748 case QSocketNotifier::Read: 540 749 isSet = FD_ISSET(sockfd, &readS); break; … … 548 757 } 549 758 } 759 760 761 762 763 764 765 550 766 } while(true); 551 } 552 553 // Must be called from under QSockSelectThread::mutex 554 void QSockSelectThread::cancelSelectOrIdle() 767 768 mutex.unlock(); 769 } 770 771 // Must be called from under QSelectThread::mutex 772 void QSelectThread::cancelSelectOrIdle() 555 773 { 556 774 if (maxSockfd >= 0) { … … 563 781 } 564 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 565 932 #else 566 933 567 class QSockSelectThread 568 { 934 class QSelectThread 935 { 936 // dummy implementation 937 569 938 public: 570 939 static void addSelect(QSocketNotifier *notifier, HWND hwnd) { … … 577 946 static QSocketNotifier *getSocketNotifier(int key); { return 0; } 578 947 948 949 950 951 952 953 954 955 956 957 958 959 960 579 961 static void attachThread() {} 580 962 static void detachThread() {} … … 593 975 void createAuxWnd(); 594 976 595 // Auxiliary object window to process WM_U_SEM_SELECT and WM_ TIMER messages.977 // Auxiliary object window to process WM_U_SEM_SELECT and WM_TIMER messages. 596 978 // We need a dedicated window along with processing these messages directly in 597 979 // QEventLoop::processEvents() to make sure they are processed even if the … … 607 989 MRESULT message(ULONG msg, MPARAM mp1, MPARAM mp2); 608 990 QEventDispatcherPMPrivate *dispatcher; 991 992 609 993 } auxWnd; 610 994 … … 615 999 616 1000 // @todo later 617 //618 // // timers619 // WinTimerVec timerVec;620 // WinTimerDict timerDict;621 // void registerTimer(WinTimerInfo *t);622 // void unregisterTimer(WinTimerInfo *t);623 // void sendTimerEvent(int timerId);624 1001 // 625 1002 // QList<QMSG> queuedUserInputEvents; … … 685 1062 case WM_U_SEM_SELECT: { 686 1063 QSocketNotifier *notifier = 687 QS ockSelectThread::getSocketNotifier(LONGFROMMP(mp1));688 689 690 691 1064 QSelectThread::getSocketNotifier(LONGFROMMP(mp1)); 1065 if (notifier) { 1066 QEvent event(QEvent::SockAct); 1067 QCoreApplication::sendEvent(notifier, &event); 1068 } 692 1069 break; 693 1070 } 694 case WM_U_SEM_ZEROTIMER: { 695 // @todo later 696 // if (numZeroTimers) { 697 // activateZeroTimers(); 698 // // repost the message if there are still zero timers left 699 // if (numZeroTimers) 700 // WinPostMsg(hwnd(), WM_U_SEM_ZEROTIMER, 0, 0); 701 // } 1071 case WM_U_SEM_TIMER: { 1072 int timerId = LONGFROMMP(mp1); 1073 QObject *obj = QSelectThread::getTimerObject(timerId); 1074 1075 if (obj && !timersInSend.contains(timerId)) { 1076 // send event, but don't allow it to recurse 1077 timersInSend += timerId; 1078 1079 QTimerEvent e(timerId); 1080 QCoreApplication::sendEvent(obj, &e); 1081 1082 timersInSend -= timerId; 1083 } 702 1084 break; 703 1085 } 704 case WM_TIMER: { 705 // @todo later 706 // USHORT id = SHORT1FROMMP(mp1); 707 // dispatchTimer((uint) id, &qmsg); 1086 default: 708 1087 break; 709 }710 1088 } 711 1089 712 1090 return FALSE; 713 1091 } 714 715 // @todo remove716 #if 0717 718 LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)719 {720 if (message == WM_NCCREATE) {721 return true;722 } else if (message == WM_USER) {723 724 // socket notifier message725 MSG msg;726 msg.hwnd = hwnd;727 msg.message = message;728 msg.wParam = wp;729 msg.lParam = lp;730 731 QCoreApplication *app = QCoreApplication::instance();732 long result;733 if (app && app->filterEvent(&msg, &result))734 return result;735 736 int type = -1;737 switch (WSAGETSELECTEVENT(lp)) {738 case FD_READ:739 case FD_CLOSE:740 case FD_ACCEPT:741 type = 0;742 break;743 case FD_WRITE:744 case FD_CONNECT:745 type = 1;746 break;747 case FD_OOB:748 type = 2;749 break;750 }751 if (type >= 0) {752 753 #ifdef GWLP_USERDATA754 QEventDispatcherPM *eventDispatcher =755 (QEventDispatcherPM *) GetWindowLongPtrA(hwnd, GWLP_USERDATA);756 #else757 QEventDispatcherPM *eventDispatcher =758 (QEventDispatcherPM *) GetWindowLongA(hwnd, GWL_USERDATA);759 #endif760 if (eventDispatcher) {761 QEventDispatcherPMPrivate *d = eventDispatcher->d_func();762 QSNDict *sn_vec[3] = { &d->sn_read, &d->sn_write, &d->sn_except };763 QSNDict *dict = sn_vec[type];764 765 QSockNot *sn = dict ? dict->value(wp) : 0;766 if (sn) {767 QEvent event(QEvent::SockAct);768 QCoreApplication::sendEvent(sn->obj, &event);769 }770 }771 }772 return 0;773 774 } else if (message == WM_TIMER) {775 776 MSG msg;777 msg.hwnd = hwnd;778 msg.message = message;779 msg.wParam = wp;780 msg.lParam = lp;781 782 QCoreApplication *app = QCoreApplication::instance();783 Q_ASSERT_X(app, "qt_interal_proc", "Timer fired, but no QCoreApplication");784 if (!app) {785 KillTimer(hwnd, wp);786 return 0;787 }788 789 long result;790 if (app->filterEvent(&msg, &result))791 return result;792 793 QEventDispatcherPM *eventDispatcher =794 qobject_cast<QEventDispatcherPM *>(QAbstractEventDispatcher::instance());795 Q_ASSERT(eventDispatcher != 0);796 QEventDispatcherPMPrivate *d = eventDispatcher->d_func();797 d->sendTimerEvent(wp);798 return 0;799 }800 801 return DefWindowProc(hwnd, message, wp, lp);802 }803 804 void QEventDispatcherPMPrivate::registerTimer(WinTimerInfo *t)805 {806 Q_ASSERT(internalHwnd);807 808 Q_Q(QEventDispatcherPM);809 810 int ok = 0;811 812 if (t->interval > 10 || !t->interval || !qtimeSetEvent) {813 ok = 1;814 if (!t->interval) // optimization for single-shot-zero-timer815 QCoreApplication::postEvent(q, new QZeroTimerEvent(t->timerId));816 else817 ok = SetTimer(internalHwnd, t->timerId, (uint) t->interval, 0);818 } else {819 ok = t->fastTimerId = qtimeSetEvent(t->interval, 1, qt_fast_timer_proc, (DWORD_PTR)t,820 TIME_CALLBACK_FUNCTION | TIME_PERIODIC | TIME_KILL_SYNCHRONOUS);821 if (ok == 0) { // fall back to normal timer if no more multimedia timers avaiable822 ok = SetTimer(internalHwnd, t->timerId, (uint) t->interval, 0);823 }824 }825 826 if (ok == 0)827 qErrnoWarning("QEventDispatcherPM::registerTimer: Failed to create a timer");828 }829 830 void QEventDispatcherPMPrivate::unregisterTimer(WinTimerInfo *t)831 {832 // mark timer as unused833 if (!QObjectPrivate::get(t->obj)->inThreadChangeEvent)834 QAbstractEventDispatcherPrivate::releaseTimerId(t->timerId);835 836 if (t->interval == 0) {837 QCoreApplicationPrivate::removePostedTimerEvent(t->dispatcher, t->timerId);838 } else if (t->fastTimerId != 0) {839 qtimeKillEvent(t->fastTimerId);840 QCoreApplicationPrivate::removePostedTimerEvent(t->dispatcher, t->timerId);841 } else if (internalHwnd) {842 KillTimer(internalHwnd, t->timerId);843 }844 delete t;845 }846 847 void QEventDispatcherPMPrivate::sendTimerEvent(int timerId)848 {849 WinTimerInfo *t = timerDict.value(timerId);850 if (t && !t->inTimerEvent) {851 // send event, but don't allow it to recurse852 t->inTimerEvent = true;853 854 QTimerEvent e(t->timerId);855 QCoreApplication::sendEvent(t->obj, &e);856 857 // timer could have been removed858 t = timerDict.value(timerId);859 if (t) {860 t->inTimerEvent = false;861 }862 }863 }864 865 void QEventDispatcherPM::createInternalHwnd()866 {867 Q_D(QEventDispatcherPM);868 869 Q_ASSERT(!d->internalHwnd);870 if (d->internalHwnd)871 return;872 d->internalHwnd = qt_create_internal_window(this);873 874 // register all socket notifiers875 QList<int> sockets = (d->sn_read.keys().toSet()876 + d->sn_write.keys().toSet()877 + d->sn_except.keys().toSet()).toList();878 for (int i = 0; i < sockets.count(); ++i)879 d->doWsaAsyncSelect(sockets.at(i));880 881 // start all normal timers882 for (int i = 0; i < d->timerVec.count(); ++i)883 d->registerTimer(d->timerVec.at(i));884 }885 886 #endif887 1092 888 1093 QEventDispatcherPM::QEventDispatcherPM(QObject *parent) … … 1022 1227 d->createAuxWnd(); 1023 1228 1024 QS ockSelectThread::addSelect(notifier, d->auxWnd.hwnd());1229 QSelectThread::addSelect(notifier, d->auxWnd.hwnd()); 1025 1230 } 1026 1231 … … 1041 1246 #endif 1042 1247 1043 QS ockSelectThread::removeSelect(notifier);1248 QSelectThread::removeSelect(notifier); 1044 1249 } 1045 1250 1046 1251 void QEventDispatcherPM::registerTimer(int timerId, int interval, QObject *object) 1047 1252 { 1048 // @todo later 1049 #if 0 1253 #ifndef QT_NO_DEBUG 1050 1254 if (timerId < 1 || interval < 0 || !object) { 1051 1255 qWarning("QEventDispatcherPM::registerTimer: invalid arguments"); … … 1055 1259 return; 1056 1260 } 1261 1057 1262 1058 1263 Q_D(QEventDispatcherPM); 1059 1060 register WinTimerInfo *t = new WinTimerInfo; 1061 t->dispatcher = this; 1062 t->timerId = timerId; 1063 t->interval = interval; 1064 t->obj = object; 1065 t->inTimerEvent = false; 1066 t->fastTimerId = 0; 1067 1068 if (d->internalHwnd) 1069 d->registerTimer(t); 1070 1071 d->timerVec.append(t); // store in timer vector 1072 d->timerDict.insert(t->timerId, t); // store timers in dict 1073 #endif 1264 d->createAuxWnd(); 1265 1266 QSelectThread::addTimer(timerId, interval, object, d->auxWnd.hwnd()); 1074 1267 } 1075 1268 1076 1269 bool QEventDispatcherPM::unregisterTimer(int timerId) 1077 1270 { 1078 // @todo later 1079 #if 0 1271 #ifndef QT_NO_DEBUG 1080 1272 if (timerId < 1) { 1081 1273 qWarning("QEventDispatcherPM::unregisterTimer: invalid argument"); 1082 1274 return false; 1083 } 1084 QThread *currentThread = QThread::currentThread(); 1085 if (thread() != currentThread) { 1275 } else if (thread() != QThread::currentThread()) { 1086 1276 qWarning("QObject::killTimer: timers cannot be stopped from another thread"); 1087 1277 return false; 1088 1278 } 1089 1090 Q_D(QEventDispatcherPM);1091 if (d->timerVec.isEmpty() || timerId <= 0)1092 return false;1093 1094 WinTimerInfo *t = d->timerDict.value(timerId);1095 if (!t)1096 return false;1097 1098 d->timerDict.remove(t->timerId);1099 d->timerVec.removeAll(t);1100 d->unregisterTimer(t);1101 return true;1102 #else1103 return false;1104 1279 #endif 1280 1281 1105 1282 } 1106 1283 1107 1284 bool QEventDispatcherPM::unregisterTimers(QObject *object) 1108 1285 { 1109 // @todo later 1110 #if 0 1286 #ifndef QT_NO_DEBUG 1111 1287 if (!object) { 1112 1288 qWarning("QEventDispatcherPM::unregisterTimers: invalid argument"); 1113 1289 return false; 1114 } 1115 QThread *currentThread = QThread::currentThread(); 1116 if (object->thread() != thread() || thread() != currentThread) { 1290 } else if (object->thread() != thread() || thread() != QThread::currentThread()) { 1117 1291 qWarning("QObject::killTimers: timers cannot be stopped from another thread"); 1118 1292 return false; 1119 1293 } 1120 1121 Q_D(QEventDispatcherPM);1122 if (d->timerVec.isEmpty())1123 return false;1124 register WinTimerInfo *t;1125 for (int i=0; i<d->timerVec.size(); i++) {1126 t = d->timerVec.at(i);1127 if (t && t->obj == object) { // object found1128 d->timerDict.remove(t->timerId);1129 d->timerVec.removeAt(i);1130 d->unregisterTimer(t);1131 --i;1132 }1133 }1134 return true;1135 #else1136 return false;1137 1294 #endif 1295 1296 1138 1297 } 1139 1298 … … 1141 1300 QEventDispatcherPM::registeredTimers(QObject *object) const 1142 1301 { 1143 // @todo later 1144 #if 0 1302 #ifndef QT_NO_DEBUG 1145 1303 if (!object) { 1146 1304 qWarning("QEventDispatcherPM:registeredTimers: invalid argument"); 1147 1305 return QList<TimerInfo>(); 1148 1306 } 1149 1150 Q_D(const QEventDispatcherPM);1151 QList<TimerInfo> list;1152 for (int i = 0; i < d->timerVec.size(); ++i) {1153 const WinTimerInfo *t = d->timerVec.at(i);1154 if (t && t->obj == object)1155 list << TimerInfo(t->timerId, t->interval);1156 }1157 return list;1158 #else1159 return QList<TimerInfo>();1160 1307 #endif 1308 1309 1161 1310 } 1162 1311 … … 1185 1334 void QEventDispatcherPM::startingUp() 1186 1335 { 1187 QS ockSelectThread::attachThread();1336 QSelectThread::attachThread(); 1188 1337 } 1189 1338 1190 1339 void QEventDispatcherPM::closingDown() 1191 1340 { 1192 QSockSelectThread::detachThread(); 1193 1194 // @todo remove later 1195 #if 0 1196 Q_D(QEventDispatcherPM); 1197 1198 // clean up any timers 1199 while (!d->timerDict.isEmpty()) 1200 unregisterTimer((*(d->timerDict.begin()))->timerId); 1201 #endif 1202 } 1203 1204 // @todo remove later 1205 #if 0 1206 bool QEventDispatcherPM::event(QEvent *e) 1207 { 1208 Q_D(QEventDispatcherPM); 1209 if (e->type() == QEvent::ZeroTimerEvent) { 1210 QZeroTimerEvent *zte = static_cast<QZeroTimerEvent*>(e); 1211 WinTimerInfo *t = d->timerDict.value(zte->timerId()); 1212 if (t) { 1213 t->inTimerEvent = true; 1214 1215 QTimerEvent te(zte->timerId()); 1216 QCoreApplication::sendEvent(t->obj, &te); 1217 1218 t = d->timerDict.value(zte->timerId()); 1219 if (t) { 1220 if (t->interval == 0 && t->inTimerEvent) { 1221 // post the next zero timer event as long as the timer was not restarted 1222 QCoreApplication::postEvent(this, new QZeroTimerEvent(zte->timerId())); 1223 } 1224 1225 t->inTimerEvent = false; 1226 } 1227 } 1228 return true; 1229 } else if (e->type() == QEvent::Timer) { 1230 QTimerEvent *te = static_cast<QTimerEvent*>(e); 1231 d->sendTimerEvent(te->timerId()); 1232 } 1233 return QAbstractEventDispatcher::event(e); 1234 } 1235 #endif 1341 QSelectThread::detachThread(); 1342 } 1236 1343 1237 1344 QT_END_NAMESPACE -
trunk/src/corelib/kernel/qeventdispatcher_pm_p.h
r67 r84 91 91 void startingUp(); 92 92 void closingDown(); 93 94 // @todo remove later95 // bool event(QEvent *e);96 93 }; 97 94
Note:
See TracChangeset
for help on using the changeset viewer.