aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-04-21 21:11:35 +0200
committerSven Gothel <[email protected]>2012-04-21 21:11:35 +0200
commit6bcfe5e3b60782c4bb047117c12579ff15c961a1 (patch)
tree667e51830a2d622b23769a9eb0f4c5f257beadc2 /src
parent89304ecb034b2c2778f09423cb6d66d084074e11 (diff)
Newt/OSX(native): close0() shall not release NewtMacWindow (NSWindow) in case it's already in destruction (destroyNotifySend via windowWillClose())
This fixes the double release crash of the NSWindow, at the end of an application. Tested on OSX 10.6.8 and 10.7.3.
Diffstat (limited to 'src')
-rw-r--r--src/newt/native/MacWindow.m34
-rw-r--r--src/newt/native/NewtMacWindow.h3
-rw-r--r--src/newt/native/NewtMacWindow.m36
3 files changed, 53 insertions, 20 deletions
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index 6d7978895..5a35973cd 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -700,17 +700,17 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_close0
NewtMacWindow* mWin = (NewtMacWindow*) ((intptr_t) window);
NewtView* mView = (NewtView *)[mWin contentView];
NSWindow* pWin = [mWin parentWindow];
- DBG_PRINT( "windowClose.0 - %p,%d view %p,%d, parent %p\n",
- mWin, getRetainCount(mWin), mView, getRetainCount(mView), pWin);
+ BOOL destroyNotifySent = (NULL != mView) ? [mView getDestroyNotifySent] : false;
+
+ DBG_PRINT( "windowClose.0 - %p,%d, destroyNotifySent %d, view %p,%d, parent %p\n",
+ mWin, getRetainCount(mWin), destroyNotifySent, mView, getRetainCount(mView), pWin);
if(NULL!=mView) {
+ // cleanup view
jobject javaWindowObject = [mView getJavaWindowObject];
- if( false == [mView getDestroyNotifySent] ) {
- [mView setDestroyNotifySent: true];
- } else if(NULL!=javaWindowObject) {
- DBG_PRINT( "windowClose.Error: javaWindowObject not NULL (%p), destroyNotifySent==true\n", javaWindowObject);
- }
+ [mView setDestroyNotifySent: true];
if(NULL!=javaWindowObject) {
+ DBG_PRINT( "windowClose.0: Clear global javaWindowObject reference (%p)\n", javaWindowObject);
(*env)->DeleteGlobalRef(env, javaWindowObject);
[mView setJavaWindowObject: NULL];
}
@@ -737,15 +737,19 @@ NS_ENDHANDLER
DBG_PRINT( "windowClose.1 - %p,%d view %p,%d, parent %p\n",
mWin, getRetainCount(mWin), mView, getRetainCount(mView), pWin);
- // '[mWin close]' causes a crash at exit.
- // This probably happens b/c it sends events to the main loop
- // but our resources are gone ?!
- // However, issuing a simple release seems to work quite well.
- // [mWin release];
- [mWin performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];
+ // Only release window, if release is not yet in process.
+ // E.g. destroyNotifySent:=true set by NewtMacWindow::windowWillClose(), i.e. window-close was clicked.
+ if(!destroyNotifySent) {
+ // '[mWin close]' causes a crash at exit.
+ // This probably happens b/c it sends events to the main loop
+ // but our resources are gone ?!
+ // However, issuing a simple release seems to work quite well.
+ // [mWin release];
+ [mWin performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];
+ }
- DBG_PRINT( "windowClose.X - %p,%d view %p,%d, parent %p\n",
- mWin, getRetainCount(mWin), mView, getRetainCount(mView), pWin);
+ DBG_PRINT( "windowClose.X - %p,%d, released %d, view %p,%d, parent %p\n",
+ mWin, getRetainCount(mWin), !destroyNotifySent, mView, getRetainCount(mView), pWin);
[pool release];
}
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index f576f75f7..aa460ea88 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -65,6 +65,7 @@
}
- (id)initWithFrame:(NSRect)frameRect;
+- (void) release;
- (void) dealloc;
/* Set during event dispatching cycle */
@@ -122,6 +123,8 @@
defer: (BOOL) deferCreation
screen:(NSScreen *)screen
isFullscreenWindow:(BOOL)isfs;
+- (void) release;
+- (void) dealloc;
- (void) updateInsets: (JNIEnv*) env;
- (void) attachToParent: (NSWindow*) parent;
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index 402389e71..187aec7fb 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -119,12 +119,25 @@ static jmethodID windowRepaintID = NULL;
return [super initWithFrame:frameRect];
}
+- (void) release
+{
+#ifdef VERBOSE_ON
+ NSLog(@"NewtView::release\n");
+ NSLog(@"%@",[NSThread callStackSymbols]);
+#endif
+ [super release];
+}
+
- (void) dealloc
{
if(softLocked) {
NSLog(@"NewtView::dealloc: softLock still hold @ dealloc!\n");
}
pthread_mutex_destroy(&softLockSync);
+#ifdef VERBOSE_ON
+ NSLog(@"NewtView::dealloc\n");
+ NSLog(@"%@",[NSThread callStackSymbols]);
+#endif
[super dealloc];
}
@@ -362,6 +375,24 @@ static jmethodID windowRepaintID = NULL;
return res;
}
+- (void) release
+{
+#ifdef VERBOSE_ON
+ NSLog(@"NewtWindow::release\n");
+ NSLog(@"%@",[NSThread callStackSymbols]);
+#endif
+ [super release];
+}
+
+- (void) dealloc
+{
+#ifdef VERBOSE_ON
+ NSLog(@"NewtWindow::dealloc\n");
+ NSLog(@"%@",[NSThread callStackSymbols]);
+#endif
+ [super dealloc];
+}
+
- (void) updateInsets: (JNIEnv*) env
{
NSView* nsview = [self contentView];
@@ -940,11 +971,6 @@ static jint mods2JavaMods(NSUInteger mods)
[view setDestroyNotifySent: true];
(*env)->CallVoidMethod(env, javaWindowObject, windowDestroyNotifyID);
- // Can't issue call here - locked window state, done from Java method
-
- // EOL ..
- (*env)->DeleteGlobalRef(env, javaWindowObject);
- [view setJavaWindowObject: NULL];
if (shallBeDetached) {
(*jvmHandle)->DetachCurrentThread(jvmHandle);