List Info

Thread: Re: Problem condition in Qyoto MethodCall




Re: Problem condition in Qyoto MethodCall
user name
2007-02-10 12:30:20
On Saturday 10 February 2007, Arno Rehn wrote:
> Am Samstag, 10. Februar 2007 schrieb Richard Dale:
> > On Saturday 10 February 2007, Arno Rehn wrote:
> > > Am Samstag, 10. Februar 2007 schrieb Arno
Rehn:
> > > > Am Samstag, 10. Februar 2007 schrieb
Richard Dale:
> > > > > This is wrong, but I still haven't
worked out what the correct
> > > > > version should be:
> > > > >
> > > > > // We have to check here, if our
target does still exists.
> > > > > // If there is no entry in the
weakRef Dictionary, the instance
> > > > > doesn't exist anymore.
> > > > > // There's also no entry, if the
method is a constructor or the
> > > > > method is static.
> > > > > // If the target doesn't exist
anymore, set _called to true so the
> > > > > method won't be invoked.
> > > > > // The other possibility is that
the qApp was just destroyed and we
> > > > > want to call a destructor.
> > > > > // This could lead to a crash when
we interfere with the destroying
> > > > > mechanism of Q(Core)Application.
> > > > > if (
((getPointerObject(_current_object) == 0) && !_ctor
&&
> > > > > !(_tmp.flags &
Smoke::mf_static))
> > > > >
> > > > >         || ((_tmp.flags &
Smoke::mf_dtor) && (qApp == 0)) )
> > > > >
> > > > >         _called = true;
> > > > >
> > > > > Not every instance has an entry in
the weak reference map. For
> > > > > example, I had a QVariant which was
created in C++ code and it
> > > > > failed the condition and '_called'
was set to true. Try the
> > > > > qdbus/pingpong example - it crashes
when trying to access to
> > > > > QVariant returned.
> > > >
> > > > Oops, didn't know that not every
instance is in the weakRef map.
> > > >
> > > > > We should only be looking at the
'o' and 'o->ptr' values and not
> > > > > call the method if they are zero
and it's not a static method or
> > > > > constructor. I don't think we need
to test for destructors at all
> > > > > because 'o->ptr' is set to 0
once something has been deleted (or it
> > > > > should be anyway).
> > > >
> > > > Uhm, actually if we just test for
o->ptr == 0 and the method not
> > > > being a constructor it doesn't work. My
code:
> > > > 		if ((_current_object == 0) &&
!_ctor)
> > > > 			_called = true;
> > > > Result:
> > > > *** glibc detected *** mono: free():
invalid pointer: 0xb6b94c9c ***
> > > > at startup.
> > > > As the problem with destructors just
happens when the qApp is about
> > > > to quit I think we shouldn't test for
something being null at all,
> > > > just if it is a destructor and if the
qApp is about to quit. If so,
> > > > don't call the destructor. If it still
crashes somewhen else because
> > > > the underlying C++ instance doesn't
exist anymore, the problem will
> > > > probably have another cause.
> > >
> > > Ok, that won't work, I didn't think about
that it is possible to not
> > > have called QCoreApplication::exec and still
can do something with Qt.
> > > But just checking for o->ptr being 0 won't
work either, as I've already
> > > stated.
> >
> > Ah, ok. This is the thing I love about systems
programming - you can
> > spend about two weeks thinking about the correct
version of a single
> > line of code. I think o->ptr is only set to
zero for something which
> > was created in the C# side, but for an instance
created in the C++
> > side I think we need to not call the delete method
when the destructor
> > is called, and we do need to set o->ptr to
zero.
>
> Ok, but how do we check whether it was created in C++
or in C#? Should we
> add another field to the smokeqyoto_object struct? What
purpose does
> the "allocated" field in that structure
have?
It indicates whether the instance was constructed in the C++
world, or
in the C# world, when 'allocated' is true it means the
instance was
created via a Qyoto constructor. We don't want to call the
destructor
on any instances which have been constructed in the C++
world. Also we
want to call destructors for instances constructed in the C#
world
only once, and so we must set the o->ptr to 0 once an
instance has
been deleted.

The reason that we don't want to keep C++ instance to C#
instance
mappings for instances in the weak reference pointer map
that were
allocated in the C++ world, is that C++ can delete an
instance and
reallocate another one with the same address without the
Qyoto runtime
knowing anything about it. So we could get a QEvent in an
event
handler that was allocated by the Qt runtime in C++ with
address
0xfoobar, keep a mapping to the corresponding C# QEvent
instance with
address 0xfoobar. But in the C++ world the QEvent could be
deleted,
and a QBrush allocated on the heap with the same address as
the former
QEvent. Subsequently, when we call a method in C# that
returns a
QBrush with a C++ address 0xfoobar, we look it up in the
pointerMap,
and still think it is a QEvent and return it as a C# QEvent
instance.
_______________________________________________
Kde-bindings mailing list
Kde-bindingskde.org
ht
tps://mail.kde.org/mailman/listinfo/kde-bindings

Re: Problem condition in Qyoto MethodCall
country flaguser name
Germany
2007-02-10 15:20:13
Am Samstag, 10. Februar 2007 schrieb Richard Dale:
> On Saturday 10 February 2007, Arno Rehn wrote:
> > Am Samstag, 10. Februar 2007 schrieb Richard
Dale:
> > > On Saturday 10 February 2007, Arno Rehn
wrote:
> > > > Am Samstag, 10. Februar 2007 schrieb
Arno Rehn:
> > > > > Am Samstag, 10. Februar 2007
schrieb Richard Dale:
> > > > > > This is wrong, but I still
haven't worked out what the correct
> > > > > > version should be:
> > > > > >
> > > > > > // We have to check here, if
our target does still exists.
> > > > > > // If there is no entry in the
weakRef Dictionary, the instance
> > > > > > doesn't exist anymore.
> > > > > > // There's also no entry, if
the method is a constructor or the
> > > > > > method is static.
> > > > > > // If the target doesn't exist
anymore, set _called to true so
> > > > > > the method won't be invoked.
> > > > > > // The other possibility is
that the qApp was just destroyed and
> > > > > > we want to call a destructor.
> > > > > > // This could lead to a crash
when we interfere with the
> > > > > > destroying mechanism of
Q(Core)Application.
> > > > > > if (
((getPointerObject(_current_object) == 0) && !_ctor
&&
> > > > > > !(_tmp.flags &
Smoke::mf_static))
> > > > > >
> > > > > >         || ((_tmp.flags &
Smoke::mf_dtor) && (qApp == 0)) )
> > > > > >
> > > > > >         _called = true;
> > > > > >
> > > > > > Not every instance has an
entry in the weak reference map. For
> > > > > > example, I had a QVariant
which was created in C++ code and it
> > > > > > failed the condition and
'_called' was set to true. Try the
> > > > > > qdbus/pingpong example - it
crashes when trying to access to
> > > > > > QVariant returned.
> > > > >
> > > > > Oops, didn't know that not every
instance is in the weakRef map.
> > > > >
> > > > > > We should only be looking at
the 'o' and 'o->ptr' values and not
> > > > > > call the method if they are
zero and it's not a static method or
> > > > > > constructor. I don't think we
need to test for destructors at all
> > > > > > because 'o->ptr' is set to
0 once something has been deleted (or
> > > > > > it should be anyway).
> > > > >
> > > > > Uhm, actually if we just test for
o->ptr == 0 and the method not
> > > > > being a constructor it doesn't
work. My code:
> > > > > 		if ((_current_object == 0)
&& !_ctor)
> > > > > 			_called = true;
> > > > > Result:
> > > > > *** glibc detected *** mono:
free(): invalid pointer: 0xb6b94c9c
> > > > > *** at startup.
> > > > > As the problem with destructors
just happens when the qApp is about
> > > > > to quit I think we shouldn't test
for something being null at all,
> > > > > just if it is a destructor and if
the qApp is about to quit. If so,
> > > > > don't call the destructor. If it
still crashes somewhen else
> > > > > because the underlying C++ instance
doesn't exist anymore, the
> > > > > problem will probably have another
cause.
> > > >
> > > > Ok, that won't work, I didn't think
about that it is possible to not
> > > > have called QCoreApplication::exec and
still can do something with
> > > > Qt. But just checking for o->ptr
being 0 won't work either, as I've
> > > > already stated.
> > >
> > > Ah, ok. This is the thing I love about
systems programming - you can
> > > spend about two weeks thinking about the
correct version of a single
> > > line of code. I think o->ptr is only set
to zero for something which
> > > was created in the C# side, but for an
instance created in the C++
> > > side I think we need to not call the delete
method when the destructor
> > > is called, and we do need to set o->ptr to
zero.
> >
> > Ok, but how do we check whether it was created in
C++ or in C#? Should we
> > add another field to the smokeqyoto_object struct?
What purpose does
> > the "allocated" field in that structure
have?
>
> It indicates whether the instance was constructed in
the C++ world, or
> in the C# world, when 'allocated' is true it means the
instance was
> created via a Qyoto constructor. We don't want to call
the destructor
> on any instances which have been constructed in the C++
world. Also we
> want to call destructors for instances constructed in
the C# world
> only once, and so we must set the o->ptr to 0 once
an instance has
> been deleted.
>
> The reason that we don't want to keep C++ instance to
C# instance
> mappings for instances in the weak reference pointer
map that were
> allocated in the C++ world, is that C++ can delete an
instance and
> reallocate another one with the same address without
the Qyoto runtime
> knowing anything about it. So we could get a QEvent in
an event
> handler that was allocated by the Qt runtime in C++
with address
> 0xfoobar, keep a mapping to the corresponding C# QEvent
instance with
> address 0xfoobar. But in the C++ world the QEvent could
be deleted,
> and a QBrush allocated on the heap with the same
address as the former
> QEvent. Subsequently, when we call a method in C# that
returns a
> QBrush with a C++ address 0xfoobar, we look it up in
the pointerMap,
> and still think it is a QEvent and return it as a C#
QEvent instance.
Ok, I have tried it out. That's my code so far (only the
relevant part):

// the instance doesn't exist anymore, the method is not
static and it isn't a
// constructor -> skip call
if (!_current_object && !(_tmp.flags &
Smoke::mf_static) && !_ctor)
	_called = true;
// it is a destructor but the instance wasn't created in C#
-> skip call
if (_dtor && !o->allocated)
	_called = true;
if (_dtor) {
	o->ptr = 0;
}

That works nicely and well with t1 and the pingpong example,
no problems here. 
But with t14 the whole thing still crashes when quitting the
app. After some 
debugging code I found out that a certain QLabel-destructor
is called two 
times, the pointer is exactly the same. Only difference:
'allocated' is one 
time 'false', the other time it is 'true'. Output from my
debugging:

class name: QLabel, method name: ~QLabel, allocated: 0,
_current_object: 
140796736
class name: QLabel, method name: ~QLabel, allocated: 1,
_current_object: 
140796736

Normally _current_object should be 0 in the second call, but
it isn't. And I 
have no clue why allocated is false first time, and true
second time.
Any ideas?

-- 
Arno Rehn
arnoarnorehn.de
_______________________________________________
Kde-bindings mailing list
Kde-bindingskde.org
ht
tps://mail.kde.org/mailman/listinfo/kde-bindings

Re: Problem condition in Qyoto MethodCall
country flaguser name
Germany
2007-02-10 18:19:41
Am Samstag, 10. Februar 2007 schrieb Arno Rehn:
> Am Samstag, 10. Februar 2007 schrieb Richard Dale:
> > On Saturday 10 February 2007, Arno Rehn wrote:
> > > Am Samstag, 10. Februar 2007 schrieb Richard
Dale:
> > > > On Saturday 10 February 2007, Arno Rehn
wrote:
> > > > > Am Samstag, 10. Februar 2007
schrieb Arno Rehn:
> > > > > > Am Samstag, 10. Februar 2007
schrieb Richard Dale:
> > > > > > > This is wrong, but I
still haven't worked out what the correct
> > > > > > > version should be:
> > > > > > >
> > > > > > > // We have to check here,
if our target does still exists.
> > > > > > > // If there is no entry
in the weakRef Dictionary, the instance
> > > > > > > doesn't exist anymore.
> > > > > > > // There's also no entry,
if the method is a constructor or the
> > > > > > > method is static.
> > > > > > > // If the target doesn't
exist anymore, set _called to true so
> > > > > > > the method won't be
invoked.
> > > > > > > // The other possibility
is that the qApp was just destroyed
> > > > > > > and we want to call a
destructor.
> > > > > > > // This could lead to a
crash when we interfere with the
> > > > > > > destroying mechanism of
Q(Core)Application.
> > > > > > > if (
((getPointerObject(_current_object) == 0) && !_ctor
&&
> > > > > > > !(_tmp.flags &
Smoke::mf_static))
> > > > > > >
> > > > > > >         || ((_tmp.flags
& Smoke::mf_dtor) && (qApp == 0)) )
> > > > > > >
> > > > > > >         _called = true;
> > > > > > >
> > > > > > > Not every instance has an
entry in the weak reference map. For
> > > > > > > example, I had a QVariant
which was created in C++ code and it
> > > > > > > failed the condition and
'_called' was set to true. Try the
> > > > > > > qdbus/pingpong example -
it crashes when trying to access to
> > > > > > > QVariant returned.
> > > > > >
> > > > > > Oops, didn't know that not
every instance is in the weakRef map.
> > > > > >
> > > > > > > We should only be looking
at the 'o' and 'o->ptr' values and
> > > > > > > not call the method if
they are zero and it's not a static
> > > > > > > method or constructor. I
don't think we need to test for
> > > > > > > destructors at all
because 'o->ptr' is set to 0 once something
> > > > > > > has been deleted (or it
should be anyway).
> > > > > >
> > > > > > Uhm, actually if we just test
for o->ptr == 0 and the method not
> > > > > > being a constructor it doesn't
work. My code:
> > > > > > 		if ((_current_object == 0)
&& !_ctor)
> > > > > > 			_called = true;
> > > > > > Result:
> > > > > > *** glibc detected *** mono:
free(): invalid pointer: 0xb6b94c9c
> > > > > > *** at startup.
> > > > > > As the problem with
destructors just happens when the qApp is
> > > > > > about to quit I think we
shouldn't test for something being null
> > > > > > at all, just if it is a
destructor and if the qApp is about to
> > > > > > quit. If so, don't call the
destructor. If it still crashes
> > > > > > somewhen else because the
underlying C++ instance doesn't exist
> > > > > > anymore, the problem will
probably have another cause.
> > > > >
> > > > > Ok, that won't work, I didn't think
about that it is possible to
> > > > > not have called
QCoreApplication::exec and still can do something
> > > > > with Qt. But just checking for
o->ptr being 0 won't work either, as
> > > > > I've already stated.
> > > >
> > > > Ah, ok. This is the thing I love about
systems programming - you can
> > > > spend about two weeks thinking about the
correct version of a single
> > > > line of code. I think o->ptr is only
set to zero for something which
> > > > was created in the C# side, but for an
instance created in the C++
> > > > side I think we need to not call the
delete method when the
> > > > destructor is called, and we do need to
set o->ptr to zero.
> > >
> > > Ok, but how do we check whether it was
created in C++ or in C#? Should
> > > we add another field to the smokeqyoto_object
struct? What purpose does
> > > the "allocated" field in that
structure have?
> >
> > It indicates whether the instance was constructed
in the C++ world, or
> > in the C# world, when 'allocated' is true it means
the instance was
> > created via a Qyoto constructor. We don't want to
call the destructor
> > on any instances which have been constructed in
the C++ world. Also we
> > want to call destructors for instances constructed
in the C# world
> > only once, and so we must set the o->ptr to 0
once an instance has
> > been deleted.
> >
> > The reason that we don't want to keep C++ instance
to C# instance
> > mappings for instances in the weak reference
pointer map that were
> > allocated in the C++ world, is that C++ can delete
an instance and
> > reallocate another one with the same address
without the Qyoto runtime
> > knowing anything about it. So we could get a
QEvent in an event
> > handler that was allocated by the Qt runtime in
C++ with address
> > 0xfoobar, keep a mapping to the corresponding C#
QEvent instance with
> > address 0xfoobar. But in the C++ world the QEvent
could be deleted,
> > and a QBrush allocated on the heap with the same
address as the former
> > QEvent. Subsequently, when we call a method in C#
that returns a
> > QBrush with a C++ address 0xfoobar, we look it up
in the pointerMap,
> > and still think it is a QEvent and return it as a
C# QEvent instance.
>
> Ok, I have tried it out. That's my code so far (only
the relevant part):
>
> // the instance doesn't exist anymore, the method is
not static and it
> isn't a // constructor -> skip call
> if (!_current_object && !(_tmp.flags &
Smoke::mf_static) && !_ctor)
> 	_called = true;
> // it is a destructor but the instance wasn't created
in C# -> skip call
> if (_dtor && !o->allocated)
> 	_called = true;
> if (_dtor) {
> 	o->ptr = 0;
> }
>
> That works nicely and well with t1 and the pingpong
example, no problems
> here. But with t14 the whole thing still crashes when
quitting the app.
> After some debugging code I found out that a certain
QLabel-destructor is
> called two times, the pointer is exactly the same. Only
difference:
> 'allocated' is one time 'false', the other time it is
'true'. Output from
> my debugging:
>
> class name: QLabel, method name: ~QLabel, allocated: 0,
_current_object:
> 140796736
> class name: QLabel, method name: ~QLabel, allocated: 1,
_current_object:
> 140796736
>
> Normally _current_object should be 0 in the second
call, but it isn't. And
> I have no clue why allocated is false first time, and
true second time. Any
> ideas?
Hmmm, funny. Same goes for t1, but that doesn't crash. I did
some tests and 
the object really does still exist, so why can't we
successfully call the 
destructor (when the app is exiting, otherwise it should
work fine) ?

-- 
Arno Rehn
arnoarnorehn.de
_______________________________________________
Kde-bindings mailing list
Kde-bindingskde.org
ht
tps://mail.kde.org/mailman/listinfo/kde-bindings

Re: Problem condition in Qyoto MethodCall
country flaguser name
Spain
2007-02-10 22:05:02
On Saturday 10 February 2007, Arno Rehn wrote:
> Am Samstag, 10. Februar 2007 schrieb Richard Dale:
> > On Saturday 10 February 2007, Arno Rehn wrote:
> > > Am Samstag, 10. Februar 2007 schrieb Richard
Dale:
> > > > On Saturday 10 February 2007, Arno Rehn
wrote:
> > > > > Am Samstag, 10. Februar 2007
schrieb Arno Rehn:
> > > > > > Am Samstag, 10. Februar 2007
schrieb Richard Dale:
> > > > > > > This is wrong, but I
still haven't worked out what the correct
> > > > > > > version should be:
> > > > > > >
> > > > > > > // We have to check here,
if our target does still exists.
> > > > > > > // If there is no entry
in the weakRef Dictionary, the instance
> > > > > > > doesn't exist anymore.
> > > > > > > // There's also no entry,
if the method is a constructor or the
> > > > > > > method is static.
> > > > > > > // If the target doesn't
exist anymore, set _called to true so
> > > > > > > the method won't be
invoked.
> > > > > > > // The other possibility
is that the qApp was just destroyed
> > > > > > > and we want to call a
destructor.
> > > > > > > // This could lead to a
crash when we interfere with the
> > > > > > > destroying mechanism of
Q(Core)Application.
> > > > > > > if (
((getPointerObject(_current_object) == 0) && !_ctor
&&
> > > > > > > !(_tmp.flags &
Smoke::mf_static))
> > > > > > >
> > > > > > >         || ((_tmp.flags
& Smoke::mf_dtor) && (qApp == 0)) )
> > > > > > >
> > > > > > >         _called = true;
> > > > > > >
> > > > > > > Not every instance has an
entry in the weak reference map. For
> > > > > > > example, I had a QVariant
which was created in C++ code and it
> > > > > > > failed the condition and
'_called' was set to true. Try the
> > > > > > > qdbus/pingpong example -
it crashes when trying to access to
> > > > > > > QVariant returned.
> > > > > >
> > > > > > Oops, didn't know that not
every instance is in the weakRef map.
> > > > > >
> > > > > > > We should only be looking
at the 'o' and 'o->ptr' values and
> > > > > > > not call the method if
they are zero and it's not a static
> > > > > > > method or constructor. I
don't think we need to test for
> > > > > > > destructors at all
because 'o->ptr' is set to 0 once something
> > > > > > > has been deleted (or it
should be anyway).
> > > > > >
> > > > > > Uhm, actually if we just test
for o->ptr == 0 and the method not
> > > > > > being a constructor it doesn't
work. My code:
> > > > > > 		if ((_current_object == 0)
&& !_ctor)
> > > > > > 			_called = true;
> > > > > > Result:
> > > > > > *** glibc detected *** mono:
free(): invalid pointer: 0xb6b94c9c
> > > > > > *** at startup.
> > > > > > As the problem with
destructors just happens when the qApp is
> > > > > > about to quit I think we
shouldn't test for something being null
> > > > > > at all, just if it is a
destructor and if the qApp is about to
> > > > > > quit. If so, don't call the
destructor. If it still crashes
> > > > > > somewhen else because the
underlying C++ instance doesn't exist
> > > > > > anymore, the problem will
probably have another cause.
> > > > >
> > > > > Ok, that won't work, I didn't think
about that it is possible to
> > > > > not have called
QCoreApplication::exec and still can do something
> > > > > with Qt. But just checking for
o->ptr being 0 won't work either, as
> > > > > I've already stated.
> > > >
> > > > Ah, ok. This is the thing I love about
systems programming - you can
> > > > spend about two weeks thinking about the
correct version of a single
> > > > line of code. I think o->ptr is only
set to zero for something which
> > > > was created in the C# side, but for an
instance created in the C++
> > > > side I think we need to not call the
delete method when the
> > > > destructor is called, and we do need to
set o->ptr to zero.
> > >
> > > Ok, but how do we check whether it was
created in C++ or in C#? Should
> > > we add another field to the smokeqyoto_object
struct? What purpose does
> > > the "allocated" field in that
structure have?
> >
> > It indicates whether the instance was constructed
in the C++ world, or
> > in the C# world, when 'allocated' is true it means
the instance was
> > created via a Qyoto constructor. We don't want to
call the destructor
> > on any instances which have been constructed in
the C++ world. Also we
> > want to call destructors for instances constructed
in the C# world
> > only once, and so we must set the o->ptr to 0
once an instance has
> > been deleted.
> >
> > The reason that we don't want to keep C++ instance
to C# instance
> > mappings for instances in the weak reference
pointer map that were
> > allocated in the C++ world, is that C++ can delete
an instance and
> > reallocate another one with the same address
without the Qyoto runtime
> > knowing anything about it. So we could get a
QEvent in an event
> > handler that was allocated by the Qt runtime in
C++ with address
> > 0xfoobar, keep a mapping to the corresponding C#
QEvent instance with
> > address 0xfoobar. But in the C++ world the QEvent
could be deleted,
> > and a QBrush allocated on the heap with the same
address as the former
> > QEvent. Subsequently, when we call a method in C#
that returns a
> > QBrush with a C++ address 0xfoobar, we look it up
in the pointerMap,
> > and still think it is a QEvent and return it as a
C# QEvent instance.
>
> Ok, I have tried it out. That's my code so far (only
the relevant part):
>
> // the instance doesn't exist anymore, the method is
not static and it
> isn't a // constructor -> skip call
> if (!_current_object && !(_tmp.flags &
Smoke::mf_static) && !_ctor)
> 	_called = true;
> // it is a destructor but the instance wasn't created
in C# -> skip call
> if (_dtor && !o->allocated)
> 	_called = true;
> if (_dtor) {
> 	o->ptr = 0;
> }
I've just changed it to this:

		if (_target != 0) {
	    	_o = value_obj_info(_target);
			if (_o != 0 && _o->ptr != 0) {
				if (!_o->allocated && isDestructor()) {
					_called = true;
				}
			} else if (!isConstructor() && !isStatic()) {
				_called = true;
			}
		}

Then, once the method has been called:

		// A constructor
		if (isConstructor()) {
			_o = alloc_smokeqyoto_object(true, _smoke,
method().classId, 
_stack[0].s_voidp);
			(*SetSmokeObject)(_target, _o);
		    mapPointer(_target, _o, _o->classId, 0);
			
			// create a signal spy to catch the
"aboutToQuit()" signal
			if (strcmp("QApplication",
_smoke->className(method().classId)) == 0
				|| strcmp("QCoreApplication",
_smoke->className(method().classId)) == 0) {
				
				qapp_spy = new QSignalSpy(qApp, SIGNAL(aboutToQuit()));
			}
		} else if (isDestructor()) {
			_o->ptr = 0;
			_o->allocated = false;
		}



> That works nicely and well with t1 and the pingpong
example, no problems
> here. But with t14 the whole thing still crashes when
quitting the app.
> After some debugging code I found out that a certain
QLabel-destructor is
> called two times, the pointer is exactly the same. Only
difference:
> 'allocated' is one time 'false', the other time it is
'true'. Output from
> my debugging:
>
> class name: QLabel, method name: ~QLabel, allocated: 0,
_current_object:
> 140796736
> class name: QLabel, method name: ~QLabel, allocated: 1,
_current_object:
> 140796736
>
> Normally _current_object should be 0 in the second
call, but it isn't. And
> I have no clue why allocated is false first time, and
true second time. Any
> ideas?
I don't know if my latest changes have fixed this, but it
seems strange to go 
from 'allocated == false' to 'allocated == true' rather than
the other way 
round.

-- Richard

_______________________________________________
Kde-bindings mailing list
Kde-bindingskde.org
ht
tps://mail.kde.org/mailman/listinfo/kde-bindings

Re: Problem condition in Qyoto MethodCall
country flaguser name
Germany
2007-02-12 09:21:26
> [ ... 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...

-- 
Arno Rehn
arnoarnorehn.de

_______________________________________________
Kde-bindings mailing list
Kde-bindingskde.org
ht
tps://mail.kde.org/mailman/listinfo/kde-bindings

  
Re: Problem condition in Qyoto MethodCall
country flaguser name
Spain
2007-02-12 09:53:46
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. What 
problem does it solve that the current scheme with the
IsContainedInstance() 
function doesn't do? 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.

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.

Qyoto seems a bit slow to me - I expected it to be faster
than QtRuby, but 
it's actually slower at the moment. I tried running mono
with the '--profile' 
option and there doesn't seem to be any obvious method that
is hogging the 
time. The methodId caching scheme where the methodId was put
inside the 
SmokeMethod didn't work, and so there seems to be something
strange about how 
Attributes work. Now I've added caching of methodIds again,
it didn't seem to 
make much difference to the speed.

-- Richard
_______________________________________________
Kde-bindings mailing list
Kde-bindingskde.org
ht
tps://mail.kde.org/mailman/listinfo/kde-bindings

Re: Problem condition in Qyoto MethodCall
country flaguser name
Germany
2007-02-12 11:13:17
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.

> 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...

> Qyoto seems a bit slow to me - I expected it to be
faster than QtRuby, but
> it's actually slower at the moment. I tried running
mono with the
> '--profile' option and there doesn't seem to be any
obvious method that is
> hogging the time. The methodId caching scheme where the
methodId was put
> inside the SmokeMethod didn't work, and so there seems
to be something
> strange about how Attributes work. Now I've added
caching of methodIds
> again, it didn't seem to make much difference to the
speed.
I think all the marshalling functions make Qyoto so slow,
because for a simple 
marshalling a whole bunch of C# methods is called from C++
and vice versa. 
But I only recognize a slowdown when I start an application
up. The mono 
runtime itself needs some time to start and then then Qyoto
runtime needs 
some little time. But when it finally runs it's quite fast
from what I've 
seen so far.

-- 
Arno Rehn
arnoarnorehn.de
_______________________________________________
Kde-bindings mailing list
Kde-bindingskde.org
ht
tps://mail.kde.org/mailman/listinfo/kde-bindings

Re: Problem condition in Qyoto MethodCall
user name
2007-02-12 11:47:45
On Monday 12 February 2007 5:13 pm, 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.

I don't think so. Whether an instance is currently
'contained' has little to 
do with whether it was created by a C# ctor. An instance can
be contained or 
not contained at different times depending on how it is
used. You only call 
the dtor if it is not contained. You must correctly maintain
the state of 
whether an instance is currently contained. If you don't you
will either get 
crashes (when there are multiple calls to the dtor) or
memory leaks (when 
there are no calls to the dtor). This is why automated
bindings generators 
only get you so far. If you want rock-solid bindings you
have to look at 
every API call yourself.

> > 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.
>
> > 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...

The different Transfer annotations are the means by which
PyQt knows that an 
instance's 'contained' state has changed. For example...

    QLabel(QWidget *parent /TransferThis/ = 0,
Qt::WindowFlags f = 0);

...means that the QLabel instance is contained if parent is
non-zero, 
otherwise it is not contained. "Transfer" is short
for "transfer 
responsibility for calling the dtor".

Phil
_______________________________________________
Kde-bindings mailing list
Kde-bindingskde.org
ht
tps://mail.kde.org/mailman/listinfo/kde-bindings

Re: Problem condition in Qyoto MethodCall
country flaguser name
Germany
2007-02-12 12:04:11
Am Montag, 12. Februar 2007 schrieb Phil Thompson:
> On Monday 12 February 2007 5:13 pm, 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.
>
> I don't think so. Whether an instance is currently
'contained' has little
> to do with whether it was created by a C# ctor. An
instance can be
> contained or not contained at different times depending
on how it is used.
> You only call the dtor if it is not contained. You must
correctly maintain
> the state of whether an instance is currently
contained. If you don't you
> will either get crashes (when there are multiple calls
to the dtor) or
> memory leaks (when there are no calls to the dtor).
This is why automated
> bindings generators only get you so far. If you want
rock-solid bindings
> you have to look at every API call yourself.
Indeed, I've just come across this. It's better to keep the
"contained" field 
in smokeqyoto_object. First off it's easier to understand
and second you may 
want to do something else with the value of
"allocated", and then it has to 
have the right 'meaning'.

Another problem I encountered was that the 'deleted' method
in 
QyotoSmokeBinding seems to be only called for classes
derived from 'QObject', 
e.g. when a QRect is destroyed the method is not invoked.
That makes it more 
difficult to handle the weakRef map correctly.

> > > 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.
> >
> > > 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...
>
> The different Transfer annotations are the means by
which PyQt knows that
> an instance's 'contained' state has changed. For
example...
>
>     QLabel(QWidget *parent /TransferThis/ = 0,
Qt::WindowFlags f = 0);
>
> ...means that the QLabel instance is contained if
parent is non-zero,
> otherwise it is not contained. "Transfer" is
short for "transfer
> responsibility for calling the dtor".
I see, but I don't think it can be implemented with
attributes in C#. If we 
want to do it in C# we would have to catch the calls in 
SmokeInvocation.Invoke() and then decide whether to set
'contained' to true 
or not. Though I think it's better to keep this whole thing
in C++, otherwise 
it would require more and more calls from C# to C++ and thus
slow down the 
whole thing.


-- 
Arno Rehn
arnoarnorehn.de
_______________________________________________
Kde-bindings mailing list
Kde-bindingskde.org
ht
tps://mail.kde.org/mailman/listinfo/kde-bindings

Re: Problem condition in Qyoto MethodCall
country flaguser name
Spain
2007-02-12 11:25:07
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?

> > 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.

> > Qyoto seems a bit slow to me - I expected it to be
faster than QtRuby,
> > but it's actually slower at the moment. I tried
running mono with the
> > '--profile' option and there doesn't seem to be
any obvious method that
> > is hogging the time. The methodId caching scheme
where the methodId was
> > put inside the SmokeMethod didn't work, and so
there seems to be
> > something strange about how Attributes work. Now
I've added caching of
> > methodIds again, it didn't seem to make much
difference to the speed.
>
> I think all the marshalling functions make Qyoto so
slow, because for a
> simple marshalling a whole bunch of C# methods is
called from C++ and vice
> versa. But I only recognize a slowdown when I start an
application up. The
> mono runtime itself needs some time to start and then
then Qyoto runtime
> needs some little time. But when it finally runs it's
quite fast from what
> I've seen so far.
Yes, that might be true. The marshalling a strings <->
QStrings could 
certainly be speeded up a think, as it makes more round
trips between C++ and 
C# than it needs to. I haven't tried profiling the C/C++
side yet, maybe that 
might give some more info. It might be a matter of writing
test programs to 
find out what is slow. I think it's 'good enough' for now
anyway, and it's 
more important to be feature complete and correct than fast
at the moment.

-- Richard

_______________________________________________
Kde-bindings mailing list
Kde-bindingskde.org
ht
tps://mail.kde.org/mailman/listinfo/kde-bindings

[1-10] [11-12]

about | contact  Other archives ( Real Estate discussion Medical topics )