PacktPublishing / Mastering-Qt-5

Code repository for Mastering Qt 5 published by Packt
MIT License
205 stars 87 forks source link

Potential duplicated destruction of `Job` from ch09 #14

Open ClaraSchumann opened 1 year ago

ClaraSchumann commented 1 year ago

Environment: Windows 10 Qt 6.3.2 Creator 8.0.1

In debug mode, if I resize the window too frequently, errors may raise stating, "in Job: Called object is not of the correct type(class destructor may have already run)".

After some deduction, I believe the problem is rooted around line 85, ch09, MnadelbrotCalculator.cpp. abortAllJobs() signal is emitted before another call to QThreadPool::clear(), where the destructor might be called twice. Because when I call the QRunnable::autoDeleting(true) for each Job, the issue here is fixed, though the program turned somehow lagged for some Jobs are not released properly.

When this signal is emitted, all the Job instances will set a shared variable mAbort true (in Qt5, load() and store() on atomic variables are of relaxed memory sequence, so I am not totally clear why we bother an atomic variable here), which will in turn hint the run() function in the executing to return, and the QThreadPool which now hold its ownership will delete it since its task has finished(aborted).

And the next line will trigger compulsive destruction for all QRruunables whose autoDeleting is set to true. So it is possible that the destructor could be called on empty objects.

I have looked up the docs of 6.3.2 and 5.9 and found no differences in the relevant sections.

ClaraSchumann commented 1 year ago

I don't know how Qt works internally, but I believe that the process of triggering autoDeleting for one Runnable, and calling clear() to delete a bunch of them, should share much in common. Qt should track which one is going through a destructor, to avoid destruct twice.