Bug 893 - NewtCanvasAWT Lifecycle Race Condition (NPE on shutdown periodically)
Summary: NewtCanvasAWT Lifecycle Race Condition (NPE on shutdown periodically)
Status: RESOLVED FIXED
Alias: None
Product: Newt
Classification: JogAmp
Component: windows (show other bugs)
Version: 1
Hardware: pc_x86_64 windows
: P1 critical
Assignee: Sven Gothel
URL:
Depends on:
Blocks:
 
Reported: 2013-11-06 15:17 CET by Jesse
Modified: 2013-11-18 16:13 CET (History)
1 user (show)

See Also:
Type: ---
SCM Refs:
d8f7418f170aba4703df2b11d5ae11598f71a796
Workaround: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
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.