[Kde-bindings] KDE/kdebindings
Arno Rehn
kde at arnorehn.de
Tue Mar 10 16:34:16 UTC 2009
SVN commit 937860 by arnorehn:
* Get rid of application_terminated checks in methodcall.cpp and make the
application cleanup properly. The problem was WeakReference.IsValid being
false when the application was in the process of shutting down, even though
the target object was still there. When shutting down, convert weak refs to
strong refs and check for objects in the global reference map.
Only thing that doesn't work correctly is QCoreApplication and subclasses.
It's expected to be deleted as the last Qt object and a bug in QApplication
is preventing its deletion in an atexit() function. Work around that by not
calling it's destructor for now.
CCMAIL: kde-bindings at kde.org
M +11 -0 csharp/qyoto/ChangeLog
M +1 -1 csharp/qyoto/core/QCoreApplication.cs
M +4 -1 csharp/qyoto/gui/QApplication.cs
M +5 -0 csharp/qyoto/src/Qyoto.cs
M +30 -1 csharp/qyoto/src/SmokeMarshallers.cs
M +5 -5 csharp/qyoto/src/handlers.cpp
M +8 -5 csharp/qyoto/src/methodcall.cpp
M +3 -0 csharp/qyoto/src/qyoto.cpp
M +1 -1 kalyptus/kalyptusCxxToKimono.pm
--- trunk/KDE/kdebindings/csharp/qyoto/ChangeLog #937859:937860
@@ -1,3 +1,14 @@
+2009-02-10 Arno Rehn <arno at arnorehn.de>
+ * Get rid of application_terminated checks in methodcall.cpp and make the
+ application cleanup properly. The problem was WeakReference.IsValid being
+ false when the application was in the process of shutting down, even though
+ the target object was still there. When shutting down, convert weak refs to
+ strong refs and check for objects in the global reference map.
+ Only thing that doesn't work correctly is QCoreApplication and subclasses.
+ It's expected to be deleted as the last Qt object and a bug in QApplication
+ is preventing its deletion in an atexit() function. Work around that by not
+ calling it's destructor for now.
+
2009-02-23 Arno Rehn <arno at arnorehn.de>
* Apply a patch from Eric Butler: Fix Qyoto.GetCPPEnumValue() to return the
correct value.
--- trunk/KDE/kdebindings/csharp/qyoto/core/QCoreApplication.cs #937859:937860
@@ -79,7 +79,7 @@
}
public static int Exec() {
int result = (int) staticInterceptor.Invoke("exec", "exec()", typeof(int));
- Qyoto.SetApplicationTerminated();
+ Qyoto.Cleanup();
return result;
}
public static void ProcessEvents(uint flags) {
--- trunk/KDE/kdebindings/csharp/qyoto/gui/QApplication.cs #937859:937860
@@ -145,6 +145,9 @@
public static void SetColorSpec(int arg1) {
staticInterceptor.Invoke("setColorSpec$", "setColorSpec(int)", typeof(void), typeof(int), arg1);
}
+ public static void SetGraphicsSystem(string arg1) {
+ staticInterceptor.Invoke("setGraphicsSystem$", "setGraphicsSystem(const QString&)", typeof(void), typeof(string), arg1);
+ }
public static QCursor OverrideCursor() {
return (QCursor) staticInterceptor.Invoke("overrideCursor", "overrideCursor()", typeof(QCursor));
}
@@ -276,7 +279,7 @@
}
public static new int Exec() {
int result = (int) staticInterceptor.Invoke("exec", "exec()", typeof(int));
- Qyoto.SetApplicationTerminated();
+ Qyoto.Cleanup();
return result;
}
public static void CloseAllWindows() {
--- trunk/KDE/kdebindings/csharp/qyoto/src/Qyoto.cs #937859:937860
@@ -285,6 +285,11 @@
/// This hashtable has the class types as keys, and QMetaObjects as values
static Dictionary<Type, QMetaObject> metaObjects = new Dictionary<Type, QMetaObject> ();
+ public static void Cleanup() {
+ SmokeMarshallers.ConvertRefs();
+ SetApplicationTerminated();
+ }
+
public static uint GetCPPEnumValue(string c, string value) {
Type t = Type.GetType("Qyoto." + c, false);
if (t == null) {
--- trunk/KDE/kdebindings/csharp/qyoto/src/SmokeMarshallers.cs #937859:937860
@@ -363,7 +363,7 @@
public static void MapPointer(IntPtr ptr, IntPtr instancePtr, bool createGlobalReference) {
lock (pointerMap) {
Object instance = ((GCHandle) instancePtr).Target;
- WeakReference weakRef = new WeakReference(instance);
+ WeakReference weakRef = new WeakReference(instance, true);
pointerMap[ptr] = weakRef;
#if DEBUG
if ((QDebug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0) {
@@ -411,6 +411,7 @@
// of a Qyoto class and therefore could have custom slots or overriden methods
public static IntPtr GetInstance(IntPtr ptr, bool allInstances) {
WeakReference weakRef;
+ object strongRef;
if (!pointerMap.TryGetValue(ptr, out weakRef)) {
#if DEBUG
if ( (QDebug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0
@@ -440,6 +441,24 @@
GCHandle instanceHandle = GCHandle.Alloc(weakRef.Target);
#endif
return (IntPtr) instanceHandle;
+ } else if (Environment.HasShutdownStarted && globalReferenceMap.TryGetValue(ptr, out strongRef)) {
+#if DEBUG
+ if ( (QDebug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0
+ && QDebug.debugLevel >= DebugLevel.Extensive )
+ {
+ Console.WriteLine("GetInstance() strongRef 0x{0:x8} -> {1}", (int) ptr, strongRef);
+ }
+#endif
+ if (!allInstances && IsSmokeClass(strongRef.GetType())) {
+ return IntPtr.Zero;
+ }
+
+#if DEBUG
+ GCHandle instanceHandle = DebugGCHandle.Alloc(strongRef);
+#else
+ GCHandle instanceHandle = GCHandle.Alloc(strongRef);
+#endif
+ return (IntPtr) instanceHandle;
} else {
#if DEBUG
if ( (QDebug.DebugChannel() & QtDebugChannel.QTDB_GC) != 0
@@ -453,6 +472,16 @@
}
}
+ // converts weak references to strong references so they are still available
+ // when the application is shutting down.
+ public static void ConvertRefs() {
+ foreach (KeyValuePair<IntPtr, WeakReference> pair in pointerMap) {
+ if (!pair.Value.IsAlive)
+ continue;
+ globalReferenceMap[pair.Key] = pair.Value.Target;
+ }
+ }
+
private class SmokeClassData {
public string className;
public ConstructorInfo constructorInfo;
--- trunk/KDE/kdebindings/csharp/qyoto/src/handlers.cpp #937859:937860
@@ -1043,10 +1043,10 @@
}
if(m->type().isStack()) {
-// o->allocated = true;
- // Keep a mapping of the pointer so that it is only wrapped once
- mapPointer(obj, o, o->classId, 0);
+ o->allocated = true;
}
+ // Keep a mapping of the pointer so that it is only wrapped once
+ mapPointer(obj, o, o->classId, 0);
m->var().s_class = obj;
}
@@ -1455,9 +1455,9 @@
if (m->type().isStack()) {
o->allocated = true;
- // Keep a mapping of the pointer so that it is only wrapped once
- mapPointer(obj, o, o->classId, 0);
}
+ // Keep a mapping of the pointer so that it is only wrapped once
+ mapPointer(obj, o, o->classId, 0);
m->var().s_class = obj;
}
--- trunk/KDE/kdebindings/csharp/qyoto/src/methodcall.cpp #937859:937860
@@ -26,10 +26,10 @@
_o = (smokeqyoto_object*) (*GetSmokeObject)(_target);
if (_o != 0 && _o->ptr != 0) {
if ( isDestructor()
- && (!_o->allocated || IsContainedInstance(_o) || application_terminated) )
+ && (!_o->allocated || IsContainedInstance(_o)
+ || smoke->isDerivedFromByName(smoke->className(_o->classId), "QCoreApplication")) )
{
_called = true;
-// _o->allocated = false;
}
} else {
// not a constructor, not static, pointer invalid -> object already destroyed
@@ -96,9 +96,12 @@
(*SetSmokeObject)(_target, _o);
mapPointer(_target, _o, _o->classId, 0);
} else if (isDestructor()) {
- unmapPointer(_o, _o->classId, 0);
- (*SetSmokeObject)(_target, 0);
- free_smokeqyoto_object(_o);
+ void *check = (*GetSmokeObject)(_target);
+ if (check) {
+ unmapPointer(_o, _o->classId, 0);
+ (*SetSmokeObject)(_target, 0);
+ free_smokeqyoto_object(_o);
+ }
} else {
Qyoto::MethodReturnValue r(_smoke, _method, _stack, _retval);
}
--- trunk/KDE/kdebindings/csharp/qyoto/src/qyoto.cpp #937859:937860
@@ -93,11 +93,14 @@
QChildEvent *e = static_cast<QChildEvent *>(event);
void * childObj = (*GetInstance)(e->child(), true);
if (childObj != 0) {
+ smokeqyoto_object *o = (smokeqyoto_object*) (*GetSmokeObject)(childObj);
// Maybe add a check whether the childObj is still a QObject here
if (e->added()) {
(*AddGlobalRef)(childObj, e->child());
+ o->allocated = false; // we don't need to care about deleting stuff anymore
} else {
(*RemoveGlobalRef)(childObj, e->child());
+ o->allocated = true; // now we need to care about deletion again
}
(*FreeGCHandle)(childObj);
--- trunk/KDE/kdebindings/kalyptus/kalyptusCxxToKimono.pm #937859:937860
@@ -2683,7 +2683,7 @@
$staticMethodCode .= $csharpReturnType;
$staticMethodCode .= " $name($csharpparams) \{\n";
$staticMethodCode .= " int result = (int) staticInterceptor.Invoke(\"exec\", \"exec()\", typeof(int));\n";
- $staticMethodCode .= " Qyoto.SetApplicationTerminated();\n";
+ $staticMethodCode .= " Qyoto.Cleanup();\n";
$staticMethodCode .= " return result;\n";
$staticMethodCode .= " }\n";
} elsif ($isStatic or $classNode->{NodeType} eq 'namespace') {
More information about the Kde-bindings
mailing list