>> > Now let me dig into qthread_unix.cpp, see how QThreadData::current() > works: > > QThreadData *QThreadData::current() > { > QThreadData *data = get_thread_data(); > if (!data) { > void *a; > if > (QInternal::activateCallbacks(QInternal::AdoptCurrentThread, &a)) { > QThread *adopted = static_cast<QThread*>(a); > Q_ASSERT(adopted); > data = QThreadData::get2(adopted); > set_thread_data(data); > adopted->d_func()->running = true; > adopted->d_func()->finished = false; > static_cast<QAdoptedThread *>(adopted)->init(); > } else { > data = new QThreadData; > QT_TRY { > set_thread_data(data); > data->thread = new QAdoptedThread(data); > } QT_CATCH(...) { > clear_thread_data(); > data->deref(); > data = 0; > QT_RETHROW; > } > data->deref(); > } > if (!QCoreApplicationPrivate::theMainThread) > QCoreApplicationPrivate::theMainThread = data->thread; > } > return data; > } > > it calls get_thread_data(), if it returns NULL, it create a new > thread, and try to > set the new thread as "current thread data", it calls set_thread_data(). > > let's see how get_thread_data() and set_thread_data() work : > > static QThreadData *get_thread_data() > { > #ifdef Q_OS_SYMBIAN > return reinterpret_cast<QThreadData *>(Dll::Tls()); > #else > pthread_once(¤t_thread_data_once, > create_current_thread_data_key); > return reinterpret_cast<QThreadData > *>(pthread_getspecific(current_thread_data_key)); > #endif > } > > static void set_thread_data(QThreadData *data) > { > #ifdef Q_OS_SYMBIAN > qt_symbian_throwIfError(Dll::SetTls(data)); > #endif > pthread_once(¤t_thread_data_once, > create_current_thread_data_key); > pthread_setspecific(current_thread_data_key, data); > } > > > They just use pthread_getspecific and pthread_setspecific, the > current_thread_data_key was only > created once which is guarded by pthread_once(), but as you know, the > key has already > been deleted by Q_DESTRUCTOR_FUNCTION(destroy_current_thread_data_key) > which is a global > object which has been destructed early, the key is no longer > recreated, it is a stale key. > I was able to debug until the point where qthread_unix.cpp spawns a new thread because the get_thread_data call returns 0. I was unable to reach the full analysis, but now I get it. The explanation seems fine to me, thanks. What I don't get is why it works in stable. The functions registered to be executed at exit (atexit_register hasn't changed) get registered in same order in both branches (at least I checked them by printing the two atexit structures when calling exit in both stable and head). Wouldn't that mean that the problem of deleting the current_thread_data_key should happen in both branches? GusReceived on Mon May 21 2012 - 09:16:44 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:27 UTC