On Monday, September 22, 2014 02:28:06 AM BogDan wrote: > ----- Original Message ----- > From: Simon Hausmann <simon.hausm...@digia.com> > To: BogDan <bog_dan...@yahoo.com> > Cc: Chris Adams <chris.ad...@qinetic.com.au>; Qt Development Group > <development@qt-project.org> Sent: Monday, September 22, 2014 11:56 AM > Subject: Re: SV: [Development] [QML] Singletons are deleted before the > other objects > On Monday 22. September 2014 01.33.14 BogDan wrote: > > On Monday 22. September 2014 01.19.17 BogDan wrote: > > > Hi Simon, > > > > > > I took a look and I'm pretty sure I'm right ;-). BTW I'm using 5.4 > > > branch (sha1 f9ee33f96), is a little bit old, but I bet nobody > > > fixed it. The same problem is in previous releases. > > > > > > So, the singletons are deleted in QQmlEngine::~QQmlEngine():910 > > > The other active objects are deleted in MemoryManager::sweep(*true*) > > > which is called by MemoryManager::~MemoryManager() > > > which is called by ExecutionEngine::~ExecutionEngine() > > > which is called by QV8Engine::~QV8Engine() > > > which is called by QJSEngine::~QJSEngine() > > > which is called *after* QQmlEngine::~QQmlEngine() > > > > > > Check the call-stack: > > > 0 MyObject::~MyObject myobject.cpp 44 0x7fffd141eb4b > > > 1 MyObject::~MyObject myobject.cpp 46 0x7fffd141ec8a > > > 2 (anonymous namespace)::QObjectDeleter::~QObjectDeleter > > > qv4qobjectwrapper.cpp 1018 0x7ffff5f79ee1 f9ee33f96f9ee33f96 3 > > > (anonymous namespace)::QObjectDeleter::~QObjectDeleter > > > qv4qobjectwrapper.cpp 1021 0x7ffff5f79f2e 4 > > > QV4::MemoryManager::sweep qv4mm.cpp 377 0x7ffff5efd080 > > > 5 QV4::MemoryManager::~MemoryManager qv4mm.cpp 515 0x7ffff5efda18 > > > 6 QV4::ExecutionEngine::~ExecutionEngine qv4engine.cpp 421 > > > 0x7ffff5ee4f54 7 QV8Engine::~QV8Engine qv8engine.cpp 116 > > > 0x7ffff606b7f2 > > > 8 QV8Engine::~QV8Engine qv8engine.cpp 117 0x7ffff606b87e > > > 9 QJSEngine::~QJSEngine qjsengine.cpp 203 0x7ffff5e64b1e > > > 10 QQmlEngine::~QQmlEngine qqmlengine.cpp 893 0x7ffff5fb0b5d > > > 11 QQmlEngine::~QQmlEngine qqmlengine.cpp 916 0x7ffff5fb0b8c > > > 12 QObjectPrivate::deleteChildren qobject.cpp 1943 0x7ffff599efd0 > > > 13 QObject::~QObject qobject.cpp 1034 0x7ffff599d760 > > > 14 QWindow::~QWindow qwindow.cpp 210 0x7ffff63f5bdc > > > 15 QQuickWindow::~QQuickWindow qquickwindow.cpp 1099 > > > 0x7ffff6bc0353 > > > 16 QQuickView::~QQuickView qquickview.cpp 220 0x7ffff6c9fe35 > > > 17 main main.cpp 12 0x4021fb > > > > > > IMHO the sequence from QQmlEngine::~QQmlEngine():910 should be moved > > > after/in MemoryManager::~MemoryManager ... > > > > Ahh, so what you're talking about are the _JavaScript_ wrappers for the > > singletons, not the singleton objects themselves. That explains the > > confusion. > > > > Yes, due to the inheritance the final garbage collection runs as the very > > last step - and it has to, conceptually. I'm wondering: What code do you > > have running at that point that gets still called? Is it code in C++ > > destructors? > > > > > > > > > > > > > > Yes, the code from their destructors needs the singletons objects which > > are > > not available anymore. > > When are those destructors called? > > We need a little bit more information here, because it isn't obvious how to > solve this. There's naturally a pool of objects around that haven't been > garbage collected. On engine shutdown the garbage collector sweeps them all, > and there's naturally no way to define an order of destruction if you think > of such an environment. > > > > > > I know that there is a pool of active objects, what I think is wrong is to > delete the register singletons before you delete these objects. > > > The active objects destructors are called by MemoryManager::sweep. > These objects register themselves in the singleton object when they are > created and they must unregister themselves in the destructor when they > are deleted. But as you seen the singletons are deleted before, so there is > no way to properly unregister themselves! This is why I believe that the > singletons must be the very last objects that are deleted (just like in > any other languages). > > So, my proposal is to move the singletons deletion from > QmlEngine::~QQmlEngine():910 to another place which is called after > MemoryManager::sweep(*true*) is doing its job. > > I'd like to mention one more thing, the singletons and the other objects > are register in a standalone plugin. > > Please let me know if you need more info.
I think I see what you mean now. The main issue I have with this is that it would break singletons written in QML. Just like C++ they may also have their Component.onDestruction handlers, and those would naturally not be callable anymore after such a move. Not calling those anymore would be a change in behavior. I'm not convinced that this is a change for the better TBH. Of course we could try to delete first the QML singletons, then the rest of the JavaScript world and then finally the C++ singletons. But you have to admit, that starting to feel like a bunch of hacks. Instead of relying on an order of destruction, why not reference your C++ object with a weak pointer? Simon _______________________________________________ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development