[Kde-bindings] Problem condition in Qyoto MethodCall

Arno Rehn arno at arnorehn.de
Mon Feb 12 19:54:01 UTC 2007


Am Montag, 12. Februar 2007 schrieb Arno Rehn:
> Am Montag, 12. Februar 2007 schrieb Richard Dale:
> > On Monday 12 February 2007, Arno Rehn wrote:
> > > Am Montag, 12. Februar 2007 schrieb Richard Dale:
> > > > On Monday 12 February 2007, Arno Rehn wrote:
> > > > > > [ ... cut ... ]
> > > > >
> > > > > Well, I've hacked a lot around in qyoto.cpp and changed the way we
> > > > > check if it's a contained instance or not: I've added a field to
> > > > > smokeqyoto_object called 'contained' and it is set up when the
> > > > > constructor was just called. This was necessary because sometimes
> > > > > the instance was already destroyed and we still wanted to get the
> > > > > parent of it. The new field is updated when the parent of the
> > > > > widget is changed because it is added to a layout, too. It works
> > > > > better now and up to t10 every tutorial works well. But with t11 it
> > > > > keeps crashing and I can't figure out why it does so. Since I've
> > > > > created quite a mess, I don't want to check in what I have. I've
> > > > > attached a patch with all the changes, if you could take a look at
> > > > > it and tell me what you think...
> > > >
> > > > I'm not sure if this is the best way to do it, as 'contained' seems
> > > > to duplicate the function of 'allocated'. If an instance is 'owned'
> > > > by another instance we can just set 'allocated' to false, and the
> > > > Qyoto runtime won't delete it when the corresponding C# instance is
> > > > garbage collected.
> > >
> > > Yes, didn't think about that, but it's right. Setting allocated to
> > > false would be better.
> > > Do I see that right: If allocated has to be true for a destructor to be
> > > called, we only want to call destructors for instances which have been
> > > created by a C# constructor? Then we'd just have to check if it's a
> > > destructor and if getPointerObject returns something other than 0.
> > >
> > > > What problem does it solve that the current scheme with the
> > > > IsContainedInstance() function doesn't do?
> > >
> > > The problem is the following: We have a QLabel which is a child to a
> > > QWidget, for example. Now the QWidget is destroyed and with it the
> > > QLabel is gone. Nevertheless the Qyoto runtime wants to call the
> > > destructor for the QLabel as it still 'thinks' the QLabel exists. To
> > > check whether QLabel is a child to something and whether to call the
> > > destructor we call IsContainedInstance() which checks for any parents.
> > > Thus it will cause an error when trying to call QLabel->parent() as the
> > > QLabel is already destroyed. Therefore it's better to set this property
> > > up when the instance is created and when the parent is changed.
> >
> > All destructors in the Smoke library have a callback to
> > QyotoSmokeBinding::deleted(), and 'o->ptr' for the instance is set to 0
> > there:
> >
> > 	void deleted(Smoke::Index classId, void *ptr) {
> > 		void * obj = getPointerObject(ptr);
> > 		smokeqyoto_object *o = value_obj_info(obj);
> >
> > 		if(do_debug & qtdb_gc) {
> > 			qWarning("%p->~%s()", ptr, smoke->className(classId));
> > 		}
> >
> > 		if(!o || !o->ptr) {
> > 			return;
> > 		}
> > 		unmapPointer(o, o->classId, 0);
> > 		o->ptr = 0;
> >
> > 		// delete the previously created QSignalSpy
> > 		if (strcmp("QApplication", smoke->className(classId)) == 0
> >
> > 			|| strcmp("QCoreApplication", smoke->className(classId)) == 0) {
> >
> > 			delete qapp_spy;
> > 			qapp_spy = 0;
> > 		}
> >     }
> >
> > I'm not clear why we need to signal spy. Can't you just connect a slot to
> > the QApplication aboutToQuit() signal and set a global flag in there?
>
> We really don't need the aboutToQuit() signal in any way, it's total
> rubbish as you can have a Qt application without ever calling the
> qApp::exec() method. If aboutToQuit() is never emitted the app will crash
> anyway, we have to search for a way around it. Sorry for messing up SVN
> with it, but at that time I thought it was the right way.
I think I've worked it out how to do it right. I tested it with all the 
tutorials t1 - t14 that are currently implemented and the pingpong example 
and it all worked well. Patch attached (against latest SVN, invoke with 
patch -p0 < hack.diff) . I think I've added enough comments. Please tell me 
what you think about it.

-- 
Arno Rehn
arno at arnorehn.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: hack.diff
Type: text/x-diff
Size: 7554 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/kde-bindings/attachments/20070212/d35f06e4/attachment.bin>


More information about the Kde-bindings mailing list