diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-11-22 22:09:43 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-11-22 22:09:43 (GMT) |
commit | 774a8ff7444001917287524ac57d370c6995dea0 (patch) | |
tree | 9adc84541d1fbe9226e08871979874422c253918 /src/corelib/thread | |
parent | 3fa2a510aae1e0c5e18f3b6962c54fae92f3d176 (diff) | |
parent | 360f596183969a4c690c77df08d94101428c97c0 (diff) | |
download | Qt-774a8ff7444001917287524ac57d370c6995dea0.zip Qt-774a8ff7444001917287524ac57d370c6995dea0.tar.gz Qt-774a8ff7444001917287524ac57d370c6995dea0.tar.bz2 |
Merge branch 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into master-integration
* 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-2:
optimize ligatureHelper by using qBinaryFind instead of the for loop
QFileSystemWatcher: Do not require QApplication in the destructor.
Do not define METHOD if QT_NO_KEYWORD is defined.
QThreadPrivate::finish should not keep mutex locked when calling signals
Make QThreadStorage supports value type and not only pointers.
QThreadStorage: fix memory leak if thread storage are added while destroying
Compile fix.
Fix some warnings on Mac
Diffstat (limited to 'src/corelib/thread')
-rw-r--r-- | src/corelib/thread/qthread_unix.cpp | 36 | ||||
-rw-r--r-- | src/corelib/thread/qthread_win.cpp | 29 | ||||
-rw-r--r-- | src/corelib/thread/qthreadstorage.cpp | 54 | ||||
-rw-r--r-- | src/corelib/thread/qthreadstorage.h | 13 |
4 files changed, 68 insertions, 64 deletions
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index adbbad2..3a3c2bb 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -334,40 +334,44 @@ void QThreadPrivate::finish(void *arg) { QThread *thr = reinterpret_cast<QThread *>(arg); QThreadPrivate *d = thr->d_func(); + #ifdef Q_OS_SYMBIAN - if (lockAnyway) + QMutexLocker locker(lockAnyway ? &d->mutex : 0); +#else + QMutexLocker locker(&d->mutex); #endif - d->mutex.lock(); + d->priority = QThread::InheritPriority; - d->running = false; - d->finished = true; - if (d->terminated) + bool terminated = d->terminated; + void *data = &d->data->tls; + locker.unlock(); + if (terminated) emit thr->terminated(); - d->terminated = false; emit thr->finished(); QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QThreadStorageData::finish((void **)data); + locker.relock(); + d->terminated = false; - if (d->data->eventDispatcher) { - d->data->eventDispatcher->closingDown(); - QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher; + QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher; + if (eventDispatcher) { d->data->eventDispatcher = 0; + locker.unlock(); + eventDispatcher->closingDown(); delete eventDispatcher; + locker.relock(); } - void *data = &d->data->tls; - QThreadStorageData::finish((void **)data); - d->thread_id = 0; #ifdef Q_OS_SYMBIAN if (closeNativeHandle) d->data->symbian_thread_handle.Close(); #endif + d->running = false; + d->finished = true; + d->thread_done.wakeAll(); -#ifdef Q_OS_SYMBIAN - if (lockAnyway) -#endif - d->mutex.unlock(); } diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index 4a967ed..3706da8 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -323,25 +323,32 @@ void QThreadPrivate::finish(void *arg, bool lockAnyway) QThread *thr = reinterpret_cast<QThread *>(arg); QThreadPrivate *d = thr->d_func(); - if (lockAnyway) - d->mutex.lock(); + QMutexLocker locker(lockAnyway ? &d->mutex : 0); d->priority = QThread::InheritPriority; - d->running = false; - d->finished = true; - if (d->terminated) + bool terminated = d->terminated; + void **tls_data = reinterpret_cast<void **>(&d->data->tls); + locker.unlock(); + if (terminated) emit thr->terminated(); - d->terminated = false; emit thr->finished(); QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QThreadStorageData::finish(tls_data); + locker.relock(); + + d->terminated = false; - if (d->data->eventDispatcher) { - d->data->eventDispatcher->closingDown(); - QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher; + QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher; + if (eventDispatcher) { d->data->eventDispatcher = 0; + locker.unlock(); + eventDispatcher->closingDown(); delete eventDispatcher; + locker.relock(); } - QThreadStorageData::finish(reinterpret_cast<void **>(&d->data->tls)); + d->running = false; + d->finished = true; + if (!d->waiters) { CloseHandle(d->handle); @@ -350,8 +357,6 @@ void QThreadPrivate::finish(void *arg, bool lockAnyway) d->id = 0; - if (lockAnyway) - d->mutex.unlock(); } /************************************************************************** diff --git a/src/corelib/thread/qthreadstorage.cpp b/src/corelib/thread/qthreadstorage.cpp index 2fc04f5..8df6f39 100644 --- a/src/corelib/thread/qthreadstorage.cpp +++ b/src/corelib/thread/qthreadstorage.cpp @@ -178,11 +178,12 @@ void QThreadStorageData::finish(void **p) return; // nothing to do DEBUG_MSG("QThreadStorageData: Destroying storage for thread %p", QThread::currentThread()); - - for(int i = tls->size() - 1; i >= 0; i--) { - void *&value = (*tls)[i]; + while (!tls->isEmpty()) { + void *&value = tls->last(); void *q = value; value = 0; + int i = tls->size() - 1; + tls->resize(i); if (!q) { // data already deleted @@ -215,19 +216,18 @@ void QThreadStorageData::finish(void **p) QThreadStorage is a template class that provides per-thread data storage. - \e{Note that due to compiler limitations, QThreadStorage can only - store pointers.} - The setLocalData() function stores a single thread-specific value for the calling thread. The data can be accessed later using - localData(). QThreadStorage takes ownership of the data (which - must be created on the heap with \c new) and deletes it when the - thread exits, either normally or via termination. + localData(). The hasLocalData() function allows the programmer to determine if data has previously been set using the setLocalData() function. This is also useful for lazy initializiation. + If T is a pointer type, QThreadStorage takes ownership of the data + (which must be created on the heap with \c new) and deletes it when + the thread exits, either normally or via termination. + For example, the following code uses QThreadStorage to store a single cache for each thread that calls the cacheObject() and removeFromCache() functions. The cache is automatically @@ -241,9 +241,6 @@ void QThreadStorageData::finish(void **p) \list - \o As noted above, QThreadStorage can only store pointers due to - compiler limitations. - \o The QThreadStorage destructor does not delete per-thread data. QThreadStorage only deletes per-thread data when the thread exits or when setLocalData() is called multiple times. @@ -279,8 +276,11 @@ void QThreadStorageData::finish(void **p) /*! \fn bool QThreadStorage::hasLocalData() const - Returns true if the calling thread has non-zero data available; - otherwise returns false. + If T is a pointer type, returns true if the calling thread has + non-zero data available. + + If T is a value type, returns wether the data has already been + constructed by calling setLocalData or localData. \sa localData() */ @@ -291,10 +291,8 @@ void QThreadStorageData::finish(void **p) Returns a reference to the data that was set by the calling thread. - Note: QThreadStorage can only store pointers. This function - returns a reference to the pointer that was set by the calling - thread. The value of this reference is 0 if no data was set by - the calling thread, + If no data has been set, this will create a default constructed + instance of type T. \sa hasLocalData() */ @@ -305,10 +303,6 @@ void QThreadStorageData::finish(void **p) Returns a copy of the data that was set by the calling thread. - Note: QThreadStorage can only store pointers. This function - returns a pointer to the data that was set by the calling thread. - If no data was set by the calling thread, this function returns 0. - \sa hasLocalData() */ @@ -318,19 +312,9 @@ void QThreadStorageData::finish(void **p) Sets the local data for the calling thread to \a data. It can be accessed later using the localData() functions. - If \a data is 0, this function deletes the previous data (if - any) and returns immediately. - - If \a data is non-zero, QThreadStorage takes ownership of the \a - data and deletes it automatically either when the thread exits - (either normally or via termination) or when setLocalData() is - called again. - - Note: QThreadStorage can only store pointers. The \a data - argument must be either a pointer to an object created on the heap - (i.e. using \c new) or 0. You should not delete \a data - yourself; QThreadStorage takes ownership and will delete the \a - data itself. + If T is a pointer type, QThreadStorage takes ownership of the data + and deletes it automatically either when the thread exits (either + normally or via termination) or when setLocalData() is called again. \sa localData(), hasLocalData() */ diff --git a/src/corelib/thread/qthreadstorage.h b/src/corelib/thread/qthreadstorage.h index 6264674..475d20d 100644 --- a/src/corelib/thread/qthreadstorage.h +++ b/src/corelib/thread/qthreadstorage.h @@ -91,6 +91,11 @@ inline void qThreadStorage_setLocalData(QThreadStorageData &d, T **t) { (void) d.set(*t); } +template <typename T> +inline +void qThreadStorage_deleteData(void *d, T **) +{ delete static_cast<T *>(d); } + // value-based specialization template <typename T> inline @@ -114,6 +119,12 @@ inline void qThreadStorage_setLocalData(QThreadStorageData &d, T *t) { (void) d.set(new T(*t)); } +template <typename T> +inline +void qThreadStorage_deleteData(void *d, T *) +{ delete static_cast<T *>(d); } + + // MOC_SKIP_END #endif @@ -126,7 +137,7 @@ private: Q_DISABLE_COPY(QThreadStorage) static inline void deleteData(void *x) - { delete static_cast<T>(x); } + { qThreadStorage_deleteData(x, reinterpret_cast<T*>(0)); } public: inline QThreadStorage() : d(deleteData) { } |