From 575f3002ccb6091014ff9959a9eb54b53b501351 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Tue, 6 Sep 2011 07:16:49 +0200 Subject: X11Util/Display Lifecycle: Reuse pending (unclosable) Display connections See commit 9ed513e9a9616f6028084df4c650c8caf31ea49d (bug 502) Since we cannot close Display connections (X11/AMD), at least we reuse them to not bloat the memory for long term applications --- .../classes/jogamp/nativewindow/x11/X11Util.java | 129 +++++++++++++-------- 1 file changed, 83 insertions(+), 46 deletions(-) (limited to 'src/nativewindow') diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java index b81db2538..ec4602836 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java +++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java @@ -172,13 +172,14 @@ public class X11Util { // not exactly thread safe, but good enough for our purpose, // which is to tag a NamedDisplay uncloseable after creation. private static Object globalLock = new Object(); - private static LongObjectHashMap globalNamedDisplayMap = new LongObjectHashMap(); + private static LongObjectHashMap openDisplayMap = new LongObjectHashMap(); // handle -> name private static List openDisplayList = new ArrayList(); private static List pendingDisplayList = new ArrayList(); public static class NamedDisplay { - String name; - long handle; + final String name; + final long handle; + final int hash32; int refCount; boolean unCloseable; Throwable creationStack; @@ -186,8 +187,14 @@ public class X11Util { protected NamedDisplay(String name, long handle) { this.name=name; this.handle=handle; - this.refCount=1; + this.refCount=0; this.unCloseable=false; + { + int h32; + h32 = 31 + (int) handle ; // lo + h32 = ((h32 << 5) - h32) + (int) ( handle >>> 32 ) ; // hi + hash32 = h32; + } if(DEBUG) { this.creationStack=new Throwable("NamedDisplay Created at:"); } else { @@ -195,6 +202,22 @@ public class X11Util { } } + public final int hashCode() { + return hash32; + } + + public final boolean equals(Object obj) { + if(this == obj) { return true; } + if(obj instanceof NamedDisplay) { + NamedDisplay n = (NamedDisplay) obj; + return handle == n.handle; + } + return false; + } + + public final void addRef() { refCount++; } + public final void removeRef() { refCount--; } + public final String getName() { return name; } public final long getHandle() { return handle; } public final int getRefCount() { return refCount; } @@ -222,8 +245,8 @@ public class X11Util { int num=0; if(DEBUG||verbose||pendingDisplayList.size() > 0) { String msg = "X11Util.Display: Shutdown (close open / pending Displays: "+realXCloseOpenAndPendingDisplays+ - ", open (no close attempt): "+globalNamedDisplayMap.size()+"/"+openDisplayList.size()+ - ", open (no close attempt and uncloseable): "+pendingDisplayList.size()+")" ; + ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+ + ", pending (not closed, marked uncloseable): "+pendingDisplayList.size()+")" ; if(DEBUG) { Exception e = new Exception(msg); e.printStackTrace(); @@ -244,7 +267,7 @@ public class X11Util { } openDisplayList.clear(); pendingDisplayList.clear(); - globalNamedDisplayMap.clear(); + openDisplayMap.clear(); } return num; } @@ -319,7 +342,7 @@ public class X11Util { public static boolean markDisplayUncloseable(long handle) { NamedDisplay ndpy; synchronized(globalLock) { - ndpy = (NamedDisplay) globalNamedDisplayMap.get(handle); + ndpy = (NamedDisplay) openDisplayMap.get(handle); } if( null != ndpy ) { ndpy.setUncloseable(true); @@ -328,26 +351,40 @@ public class X11Util { return false; } - /** Returns this created named display. */ + /** Returns a created or reused named display. */ public static long openDisplay(String name) { + long dpy = 0; + NamedDisplay namedDpy = null; name = validateDisplayName(name); - long dpy = XOpenDisplay(name); - if(0==dpy) { - throw new NativeWindowException("X11Util.Display: Unable to create a display("+name+") connection. Thread "+Thread.currentThread().getName()); - } - // if you like to debug and synchronize X11 commands .. - // setSynchronizeDisplay(dpy, true); - NamedDisplay namedDpy = new NamedDisplay(name, dpy); - synchronized(globalLock) { - globalNamedDisplayMap.put(dpy, namedDpy); + boolean reused = false; + + synchronized(globalLock) { + for(int i=0; i