[Kde-bindings] Problem condition in Qyoto MethodCall

Arno Rehn arno at arnorehn.de
Mon Feb 12 18:39:29 UTC 2007


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 don't think there's any hurry to solve the problem straight away, and
> > > it's best to keep experimenting like you're doing, but not actually
> > > commiting anything.
> >
> > Yes, that's what I thought, too.
> >
> > > If we use the 'Transfer' data in the PyQt sip files we would need to
> > > change ownership when a method, or argument within a method was marked
> > > with 'Transfer'. So that data could either go into the smoke library
> > > runtime, as it would be useful for every language. Another way would be
> > > to add it as C# Attributes, in the 'SmokeMethod' one perhaps.
> >
> > What exactly is this 'Transfer' data used in PyQt? Haven't heard of it
> > before...
>
> Have a look at Phil Thompson's mails from a few days ago. I just gives us
> some metadata about which methods change ownership of an instance.
> Otherwise, we would have to go though every method in Qt and decide whether
> or not in gave or removed an owner for an instance.
Yes, he's already given some explanation and I've looked at the mails.

-- 
Arno Rehn
arno at arnorehn.de



More information about the Kde-bindings mailing list