Changeset 561 for trunk/src/corelib/kernel/qeventdispatcher_unix.cpp
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/vendor/nokia/qt/4.6.1 merged eligible /branches/vendor/nokia/qt/current merged eligible /branches/vendor/trolltech/qt/current 3-149
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/corelib/kernel/qeventdispatcher_unix.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information ([email protected]) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation ([email protected]) 5 6 ** 6 7 ** This file is part of the QtCore module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you 37 ** @nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 50 50 #include <private/qthread_p.h> 51 51 #include <private/qcoreapplication_p.h> 52 52 53 53 54 #include <errno.h> … … 55 56 #include <stdlib.h> 56 57 58 59 60 61 62 63 64 65 66 67 57 68 #if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED) 58 69 # include <sys/times.h> … … 77 88 78 89 90 79 91 static void initThreadPipeFD(int fd) 80 92 { … … 91 103 perror("QEventDispatcherUNIXPrivate: Unable to set flags on thread pipe"); 92 104 } 93 105 #endif 94 106 95 107 QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate() … … 97 109 extern Qt::HANDLE qt_application_thread_id; 98 110 mainThread = (QThread::currentThreadId() == qt_application_thread_id); 111 99 112 100 113 // initialize the common parts of the event loop 101 #if def Q_OS_INTEGRITY114 #if 102 115 // INTEGRITY doesn't like a "select" on pipes, so use socketpair instead 103 if (socketpair(AF_INET, SOCK_STREAM, PF_INET, thread_pipe) == -1) 116 if (socketpair(AF_INET, SOCK_STREAM, PF_INET, thread_pipe) == -1) 104 117 perror("QEventDispatcherUNIXPrivate(): Unable to create socket pair"); 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 105 142 #else 106 if ( pipe(thread_pipe) == -1)143 if ( 107 144 perror("QEventDispatcherUNIXPrivate(): Unable to create thread pipe"); 108 #endif 109 110 initThreadPipeFD(thread_pipe[0]); 111 initThreadPipeFD(thread_pipe[1]); 145 pipefail = true; 146 } 147 #endif 148 149 if (pipefail) 150 qFatal("QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe"); 112 151 113 152 sn_highest = -1; … … 118 157 QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate() 119 158 { 159 160 161 162 163 164 165 166 120 167 // cleanup the common parts of the event loop 121 168 close(thread_pipe[0]); 122 169 close(thread_pipe[1]); 170 123 171 124 172 // cleanup timers … … 185 233 186 234 for (int i = 0; i < list.size(); ++i) { 187 QSockNot *sn = list .at(i);235 QSockNot *sn = list; 188 236 189 237 FD_ZERO(&fdset); … … 225 273 int nevents = 0; 226 274 if (nsel > 0 && FD_ISSET(thread_pipe[0], &sn_vec[0].select_fds)) { 275 276 277 278 279 227 280 char c[16]; 228 281 while (::read(thread_pipe[0], c, sizeof(c)) > 0) 229 282 ; 283 230 284 if (!wakeUps.testAndSetRelease(1, 0)) { 231 285 // hopefully, this is dead code … … 242 296 QSockNotType::List &list = sn_vec[i].list; 243 297 for (int j = 0; j < list.size(); ++j) { 244 QSockNot *sn = list .at(j);298 QSockNot *sn = list; 245 299 if (FD_ISSET(sn->fd, &sn_vec[i].select_fds)) 246 300 q->setSocketNotifierPending(sn->obj); … … 258 312 QTimerInfoList::QTimerInfoList() 259 313 { 260 #if (_POSIX_MONOTONIC_CLOCK-0 <= 0) 261 useMonotonicTimers = false; 262 263 # if (_POSIX_MONOTONIC_CLOCK == 0) 264 // detect if the system support monotonic timers 265 long x = sysconf(_SC_MONOTONIC_CLOCK); 266 useMonotonicTimers = x >= 200112L; 267 # endif 268 269 getTime(currentTime); 270 271 if (!useMonotonicTimers) { 314 currentTime = qt_gettime(); 315 316 #if (_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC) 317 if (!qt_gettime_is_monotonic()) { 272 318 // not using monotonic timers, initialize the timeChanged() machinery 273 319 previousTime = currentTime; … … 285 331 msPerTick = 0; 286 332 } 287 #else288 // using monotonic timers unconditionally289 getTime(currentTime);290 333 #endif 291 334 … … 295 338 timeval QTimerInfoList::updateCurrentTime() 296 339 { 297 getTime(currentTime); 298 return currentTime; 299 } 300 301 #if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED) 340 return (currentTime = qt_gettime()); 341 } 342 343 #if ((_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC)) || defined(QT_BOOTSTRAPPED) 344 345 template <> 346 timeval qAbs(const timeval &t) 347 { 348 timeval tmp = t; 349 if (tmp.tv_sec < 0) { 350 tmp.tv_sec = -tmp.tv_sec - 1; 351 tmp.tv_usec -= 1000000; 352 } 353 if (tmp.tv_sec == 0 && tmp.tv_usec < 0) { 354 tmp.tv_usec = -tmp.tv_usec; 355 } 356 return normalizedTimeval(tmp); 357 } 302 358 303 359 /* … … 310 366 bool QTimerInfoList::timeChanged(timeval *delta) 311 367 { 312 tms unused;368 tms unused; 313 369 clock_t currentTicks = times(&unused); 314 370 315 int elapsedTicks = currentTicks - previousTicks;371 t elapsedTicks = currentTicks - previousTicks; 316 372 timeval elapsedTime = currentTime - previousTime; 317 int elapsedMsecTicks = (elapsedTicks * 1000) / ticksPerSecond; 318 int deltaMsecs = (elapsedTime.tv_sec * 1000 + elapsedTime.tv_usec / 1000) 319 - elapsedMsecTicks; 320 321 if (delta) { 322 delta->tv_sec = deltaMsecs / 1000; 323 delta->tv_usec = (deltaMsecs % 1000) * 1000; 324 } 373 374 timeval elapsedTimeTicks; 375 elapsedTimeTicks.tv_sec = elapsedTicks / ticksPerSecond; 376 elapsedTimeTicks.tv_usec = (((elapsedTicks * 1000) / ticksPerSecond) % 1000) * 1000; 377 378 timeval dummy; 379 if (!delta) 380 delta = &dummy; 381 *delta = elapsedTime - elapsedTimeTicks; 382 325 383 previousTicks = currentTicks; 326 384 previousTime = currentTime; … … 328 386 // If tick drift is more than 10% off compared to realtime, we assume that the clock has 329 387 // been set. Of course, we have to allow for the tick granularity as well. 330 331 return (qAbs(deltaMsecs) - msPerTick) * 10 > elapsedMsecTicks; 332 } 333 334 void QTimerInfoList::getTime(timeval &t) 335 { 336 #if !defined(QT_NO_CLOCK_MONOTONIC) && !defined(QT_BOOTSTRAPPED) 337 if (useMonotonicTimers) { 338 timespec ts; 339 clock_gettime(CLOCK_MONOTONIC, &ts); 340 t.tv_sec = ts.tv_sec; 341 t.tv_usec = ts.tv_nsec / 1000; 342 return; 343 } 344 #endif 345 346 gettimeofday(&t, 0); 347 // NTP-related fix 348 while (t.tv_usec >= 1000000l) { 349 t.tv_usec -= 1000000l; 350 ++t.tv_sec; 351 } 352 while (t.tv_usec < 0l) { 353 if (t.tv_sec > 0l) { 354 t.tv_usec += 1000000l; 355 --t.tv_sec; 356 } else { 357 t.tv_usec = 0l; 358 break; 359 } 360 } 388 timeval tickGranularity; 389 tickGranularity.tv_sec = 0; 390 tickGranularity.tv_usec = msPerTick * 1000; 391 return elapsedTimeTicks < ((qAbs(*delta) - tickGranularity) * 10); 361 392 } 362 393 363 394 void QTimerInfoList::repairTimersIfNeeded() 364 395 { 365 if ( useMonotonicTimers)396 if () 366 397 return; 367 398 timeval delta; … … 371 402 372 403 #else // !(_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(QT_BOOTSTRAPPED) 373 374 void QTimerInfoList::getTime(timeval &t)375 {376 timespec ts;377 clock_gettime(CLOCK_MONOTONIC, &ts);378 t.tv_sec = ts.tv_sec;379 t.tv_usec = ts.tv_nsec / 1000;380 }381 404 382 405 void QTimerInfoList::repairTimersIfNeeded() … … 408 431 for (int i = 0; i < size(); ++i) { 409 432 register QTimerInfo *t = at(i); 410 t->timeout = t->timeout -diff;433 t->timeout = t->timeout diff; 411 434 } 412 435 } … … 421 444 repairTimersIfNeeded(); 422 445 423 if (isEmpty()) 424 return false; 425 426 QTimerInfo *t = first(); // first waiting timer 446 // Find first waiting timer not already active 447 QTimerInfo *t = 0; 448 for (QTimerInfoList::const_iterator it = constBegin(); it != constEnd(); ++it) { 449 if (!(*it)->inTimerEvent) { 450 t = *it; 451 break; 452 } 453 } 454 455 if (!t) 456 return false; 457 427 458 if (currentTime < t->timeout) { 428 459 // time to wait … … 592 623 593 624 QEventDispatcherUNIX::~QEventDispatcherUNIX() 594 { } 625 { 626 Q_D(QEventDispatcherUNIX); 627 d->threadData->eventDispatcher = 0; 628 } 595 629 596 630 int QEventDispatcherUNIX::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 597 631 timeval *timeout) 598 632 { 599 Q_D(QEventDispatcherUNIX); 600 if (timeout) { 601 // handle the case where select returns with a timeout, too 602 // soon. 603 timeval tvStart = d->timerList.currentTime; 604 timeval tvCurrent = tvStart; 605 timeval originalTimeout = *timeout; 606 607 int nsel; 608 do { 609 timeval tvRest = originalTimeout + tvStart - tvCurrent; 610 nsel = ::select(nfds, readfds, writefds, exceptfds, &tvRest); 611 d->timerList.getTime(tvCurrent); 612 } while (nsel == 0 && (tvCurrent - tvStart) < originalTimeout); 613 614 return nsel; 615 } 616 617 return ::select(nfds, readfds, writefds, exceptfds, timeout); 633 return qt_safe_select(nfds, readfds, writefds, exceptfds, timeout); 618 634 } 619 635 … … 699 715 QSockNotType::~QSockNotType() 700 716 { 701 while (!list.isEmpty())702 delete list .takeFirst();717 ) 718 delete list; 703 719 } 704 720 … … 736 752 int i; 737 753 for (i = 0; i < list.size(); ++i) { 738 QSockNot *p = list .at(i);754 QSockNot *p = list; 739 755 if (p->fd < sockfd) 740 756 break; … … 774 790 int i; 775 791 for (i = 0; i < list.size(); ++i) { 776 sn = list .at(i);792 sn = list; 777 793 if(sn->obj == notifier && sn->fd == sockfd) 778 794 break; … … 792 808 if (!d->sn_vec[i].list.isEmpty()) 793 809 d->sn_highest = qMax(d->sn_highest, // list is fd-sorted 794 d->sn_vec[i].list .first()->fd);810 d->sn_vec[i].list->fd); 795 811 } 796 812 } … … 816 832 int i; 817 833 for (i = 0; i < list.size(); ++i) { 818 sn = list .at(i);834 sn = list; 819 835 if(sn->obj == notifier && sn->fd == sockfd) 820 836 break; … … 924 940 if (d->wakeUps.testAndSetAcquire(0, 1)) { 925 941 char c = 0; 926 ::write( d->thread_pipe[1], &c, 1 );942 write( d->thread_pipe[1], &c, 1 ); 927 943 } 928 944 }
Note:
See TracChangeset
for help on using the changeset viewer.