Conditions for when QThread::currentThread()->isRunning() can return false.
-
wrote on 28 Apr 2022, 17:14 last edited by SpencerMellar 5 Mar 2022, 10:25
Hello Everyone,
I am working on a codebase that seems to have some memory leaks. I traced the leaks to be coming from something that looks like this:
static QThreadStorage<std::shared_ptr<Example>> requestContextThreadLocal; class Example; std::shared_ptr<Example>& set_up() { if (!requestContextThreadLocal.hasLocalData()) { std::shared_ptr<Example> ptr = nullptr; requestContextThreadLocal.setLocalData(ptr); } return requestContextThreadLocal.localData(); }
It seems that when we setLocalData, internally Qt does the following:
template <typename T> inline void qThreadStorage_setLocalData(QThreadStorageData &d, T *t) { (void) d.set(new T(*t)); } inline void setLocalData(T t) { qThreadStorage_setLocalData(d, &t); }
My understanding from reading about QThreadStorage, is that the owning thread will delete/destruct the data when the thread exits. Therefore since the leak from ASAN was pointing to this place my first assumption was that it is possible we assigned the data to a thread that was not running and thus I added print statements to set_up method to check if the current running thread is null. The beginning of set_up I added the below:
QThread* thread = QThread::currentThread(); qDebug() << "thread " << thread << " is Running: " << thread->isRunning() << " are we going to create new data "
To my surprise, I had a couple current threads that reported as not running. I wanted to check if this is makes logical sense. My assumption was that since I am calling currentThread it means that the currentThread is already processing these instructions or these instructions are currently running on the current thread, it means that the current thread should be running.
I therefore wanted to check:
- Is my analysis from the last paragraph correct, if it is, can someone help me understand why the isRunning from the current Thread returns false.
- If the understanding from above is wrong is it still possible to get an understanding of what is going on.
- Lastly if anyone has pointers on how to solve the memory leak, I would very much appreciate that.
-
Hi and welcome to devnet,
Something that comes to mind is the use of QThreadPool where you have a set of threads ready to be used but not running permanently.
How are you using threads ?
-
wrote on 3 May 2022, 10:32 last edited by
How are you using threads ?
I am using the threads to move all computations that I don't want done in the main thread to that. On the app initialisation I create a lot of threads and move Objects that handle different functionalities to the threads so that they are going to be run on these threads.
Let me know if there is something that you wanted me to provide.
-
What do you mean by lots ?
As requested are you using a QThreadPool ?
Did you also consider using QtConcurrent ? -
What do you mean by lots ?
As requested are you using a QThreadPool ?
Did you also consider using QtConcurrent ?wrote on 6 May 2022, 14:08 last edited byWhat do you mean by lots ?
To give a number its north of 21 created threads in the duration of the execution.
As requested are you using a QThreadPool ?
Yeah these are used, but deleted by the time we get to the place where the issue is.
Did you also consider using QtConcurrent ?
There are some places where this is used. -
Your design is really not clear. Can you please explain your threading architecture ? You seem to using all possible threading capabilities at some point.
1/6