Bug 893

Summary: NewtCanvasAWT Lifecycle Race Condition (NPE on shutdown periodically)
Product: [JogAmp] Newt Reporter: Jesse <narf_bro>
Component: windowsAssignee: Sven Gothel <sgothel>
Status: RESOLVED FIXED    
Severity: critical CC: narf_bro
Priority: P1    
Version: 1   
Hardware: pc_x86_64   
OS: windows   
Type: --- SCM Refs:
d8f7418f170aba4703df2b11d5ae11598f71a796
Workaround: ---

Description Jesse 2013-11-06 15:17:19 CET
Sometimes when I shutdown by pressing the X button in the top right corner, I get a null pointer on the jawtWindow inside attachNewtChild. Call stack is below. 

All IsoCanvas.paint does is call super.paint().

Problem is a simple race condition - destroyImpl sets jawtWindow to null while paint is in progress. Null check at top of attachNewtChild() gets bypassed but by the time it hits jawtWindow.isOffscreenLayerSurfaceEnabled, jawtWindow is null.

Either need synchronization around destroy / paint or destroy needs to be called from the same EDT that's running the paint so it's sequential.

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
		at com.jogamp.newt.awt.NewtCanvasAWT.attachNewtChild(NewtCanvasAWT.java:745)
		at com.jogamp.newt.awt.NewtCanvasAWT.validateComponent(NewtCanvasAWT.java:660)
		at com.jogamp.newt.awt.NewtCanvasAWT.paint(NewtCanvasAWT.java:461)
		at Iso3d.IsoCanvas.paint(IsoCanvas.java:103)
		at sun.awt.RepaintArea.paintComponent(RepaintArea.java:264)
		at sun.awt.RepaintArea.paint(RepaintArea.java:240)
		at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:347)
		at java.awt.Component.dispatchEventImpl(Component.java:4937)
		at java.awt.Component.dispatchEvent(Component.java:4687)
		at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:729)
		at java.awt.EventQueue.access$200(EventQueue.java:103)
		at java.awt.EventQueue$3.run(EventQueue.java:688)
		at java.awt.EventQueue$3.run(EventQueue.java:686)
		at java.security.AccessController.doPrivileged(Native Method)
		at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
		at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
		at java.awt.EventQueue$4.run(EventQueue.java:702)
		at java.awt.EventQueue$4.run(EventQueue.java:700)
		at java.security.AccessController.doPrivileged(Native Method)
		at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
		at java.awt.EventQueue.dispatchEvent(EventQueue.java:699)
		at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
		at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
		at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
		at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
		at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
Comment 1 Sven Gothel 2013-11-18 16:13:35 CET
d8f7418f170aba4703df2b11d5ae11598f71a796
 As suggested: Employ synchronization on lifecycle actions _and_ 
 perform destroyImpl(..) always on AWT-EDT to avoid a deadlock.