I've been looking at the resource management of NEWT and I'm having trouble understanding how the management of resources is supposed to occur. I can see how simple cases are handled, but once you start to have multiple windows with distinct lifecycles then resource management (e.g. threads) start to be a problem.
I've been looking at this problem, so I'd like to start some discussion of an appropriate solution. The following is my understanding of the current code base.
There is an object hierarchy with each level having potentially several children:
- Each display may have multiple screens
- Each screen may have multiple windows
Each object has a destroy mechanism, although the concept seems to be applied inconsistently.
- Display has a destroy() method, but it decrements a reference counter of associated screens. Thus calling display.destroy() may or may not actually destroy the Display. The internal reference count represents the number of associated screens. Since display.destroy() is public, it is possible to destroy the display directly, making the reference count incorrect.
- Screen has a destroy() method, but it doesn't actually call display.destroy(). Calling screen.destroy() will null out the screen instance's reference to the Display, but doesn't decrement the reference count.
- Window has a destroy() method, but it doesn't release screens by default. Calling window.destroy(true), indicating a deep destroy, will call both screen.destroy() and the screen's display.destroy(), but this means that destroying a single display takes out both the screen (which may be shared with other displays) and the screen's display (which may be shared with other screens).
None of the classes have a finalizer, so garbage collection isn't used to take care of cleaning up resources. I don't think garbage collection would be a particularly good solution to count on. Garbage collection could be a fall back.
NewtCanvasAWT tends to reparent NEWT child window, meaning that multiple NewtCanvasAWT instances results in a shared Display. This makes it very difficult to manage multiple NEWT windows independently.
It seems like extending reference counting into Screen and making destroy more consistent might be the right approach. Does anyone have any other ideas?
TestParenting01cAWT.java is a modified version of one of the unit tests. Although glWindow1.destroy(true) is called, a 2nd screen associated with the same display instance is created by NewtCanvasAWT. This means that edt1.waitUntilStopped() will never return.
The use of a ThreadLocal map for tracking displays doesn't handle destroy correctly. When a display is created it is put into a map held within a ThreadLocal instance. The destroy() method is called on the Display's EDT thread, meaning it isn't called on the same thread.
If the Display can be created and destroyed on different threads, then why is the TheadLocal used?