diff options
author | Bradley T. Hughes <bradley.hughes@nokia.com> | 2010-10-06 08:31:06 (GMT) |
---|---|---|
committer | Bradley T. Hughes <bradley.hughes@nokia.com> | 2010-10-06 10:52:47 (GMT) |
commit | ccd3f663c8c96e266b173a6f825bccec830007e1 (patch) | |
tree | c9f83240bcd5f2bca58d9733aa5fac4f8e78ec57 /src/corelib | |
parent | e98962aab2db1c3760b324d6640fa8b510b7e04c (diff) | |
download | Qt-ccd3f663c8c96e266b173a6f825bccec830007e1.zip Qt-ccd3f663c8c96e266b173a6f825bccec830007e1.tar.gz Qt-ccd3f663c8c96e266b173a6f825bccec830007e1.tar.bz2 |
Fix crash when constructing QThreadStorage after global destructors have run
In this particular case, the destructors vector used by
QThreadStorageData has already been destroyed, yet a new QThreadStorage
is being allocated. This can only happen during global destruction, at
which point we assume that there is only one thread. In order to keep
QThreadStorage working, we need somewhere to store the data, and the
best place we have in this situation is at the tail of the current
thread's tls vector. The destructor is ignored, since we have no where
to store it, and no way to actually call it.
Task-number: QTBUG-10084
Reviewed-by: thiago
Reviewed-by: olivier
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/thread/qthreadstorage.cpp | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/src/corelib/thread/qthreadstorage.cpp b/src/corelib/thread/qthreadstorage.cpp index 88d73cc..2fc04f5 100644 --- a/src/corelib/thread/qthreadstorage.cpp +++ b/src/corelib/thread/qthreadstorage.cpp @@ -79,6 +79,21 @@ QThreadStorageData::QThreadStorageData(void (*func)(void *)) { QMutexLocker locker(mutex()); DestructorMap *destr = destructors(); + if (!destr) { + /* + the destructors vector has already been destroyed, yet a new + QThreadStorage is being allocated. this can only happen during global + destruction, at which point we assume that there is only one thread. + in order to keep QThreadStorage working, we need somewhere to store + the data, best place we have in this situation is at the tail of the + current thread's tls vector. the destructor is ignored, since we have + no where to store it, and no way to actually call it. + */ + QThreadData *data = QThreadData::current(); + id = data->tls.count(); + DEBUG_MSG("QThreadStorageData: Allocated id %d, destructor %p cannot be stored", id, func); + return; + } for (id = 0; id < destr->count(); id++) { if (destr->at(id) == 0) break; @@ -139,13 +154,15 @@ void **QThreadStorageData::set(void *p) data->thread); QMutexLocker locker(mutex()); - void (*destructor)(void *) = destructors()->value(id); + DestructorMap *destr = destructors(); + void (*destructor)(void *) = destr ? destr->value(id) : 0; locker.unlock(); void *q = value; value = 0; - destructor(q); + if (destructor) + destructor(q); } // store new data |