summaryrefslogtreecommitdiffstats
path: root/src/java/com/sun/gluegen
diff options
context:
space:
mode:
authorKenneth Russel <[email protected]>2006-08-27 03:52:07 +0000
committerKenneth Russel <[email protected]>2006-08-27 03:52:07 +0000
commit295c0331e911c9cd75c2c03597ce9a20ec995bd6 (patch)
tree0e1ec9b6561a94581e861a2301b8ae3db54dfd94 /src/java/com/sun/gluegen
parentd289b0d2b3e36a87112a2c843e7e91700078c160 (diff)
Changed NativeLibrary.open() to accept boolean argument indicating
whether to search the system path first; perhaps useful if applications ship only a backup version of native libraries associated with a particular Java binding. In the case of JOAL we plan to ship a recent OpenAL implementation so we will not need to search the system path first. Changed ForceProcAddressGen directive to force call-through-function-pointer semantics for the targeted function. Changed JOAL to not link directly against the OpenAL library at all, but instead to look up all entry points using the GlueGen NativeLibrary class (instead of the custom dlsym code, now removed) in particular to solve DSO versioning problems on Linux. Updated EAX binding to work with dynamically loading OpenAL. Tested on Windows so far; more testing needed on Linux in Java Web Start scenarios. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/../svn-server-sync/gluegen/trunk@42 a78bb65f-1512-4460-ba86-f6dc96a7bf27
Diffstat (limited to 'src/java/com/sun/gluegen')
-rwxr-xr-xsrc/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java19
-rwxr-xr-xsrc/java/com/sun/gluegen/procaddress/ProcAddressConfiguration.java5
-rwxr-xr-xsrc/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java17
-rwxr-xr-xsrc/java/com/sun/gluegen/runtime/MacOSXDynamicLinkerImpl.java2
-rwxr-xr-xsrc/java/com/sun/gluegen/runtime/NativeLibrary.java61
-rwxr-xr-xsrc/java/com/sun/gluegen/runtime/UnixDynamicLinkerImpl.java2
6 files changed, 91 insertions, 15 deletions
diff --git a/src/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java b/src/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java
index 423f009..8dc46ee 100755
--- a/src/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java
+++ b/src/java/com/sun/gluegen/procaddress/ProcAddressCMethodBindingEmitter.java
@@ -46,12 +46,14 @@ import com.sun.gluegen.cgram.types.*;
public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter {
private boolean callThroughProcAddress;
+ private boolean needsLocalTypedef;
private static String procAddressJavaTypeName =
JavaType.createForClass(Long.TYPE).jniTypeName();
private ProcAddressEmitter emitter;
public ProcAddressCMethodBindingEmitter(CMethodBindingEmitter methodToWrap,
final boolean callThroughProcAddress,
+ boolean needsLocalTypedef,
ProcAddressEmitter emitter) {
super(
new MethodBinding(methodToWrap.getBinding()) {
@@ -91,6 +93,7 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter {
setCommentEmitter(defaultCommentEmitter);
this.callThroughProcAddress = callThroughProcAddress;
+ this.needsLocalTypedef = needsLocalTypedef;
this.emitter = emitter;
}
@@ -112,10 +115,24 @@ public class ProcAddressCMethodBindingEmitter extends CMethodBindingEmitter {
protected void emitBodyVariableDeclarations(PrintWriter writer) {
if (callThroughProcAddress) {
// create variable for the function pointer with the right type, and set
- // it to the value of the passed-in glProcAddress
+ // it to the value of the passed-in proc address
FunctionSymbol cSym = getBinding().getCSymbol();
String funcPointerTypedefName =
emitter.getFunctionPointerTypedefName(cSym);
+
+ if (needsLocalTypedef) {
+ // We (probably) didn't get a typedef for this function
+ // pointer type in the header file; the user requested that we
+ // forcibly generate one. Here we force the emission of one.
+ PointerType funcPtrType = new PointerType(null, cSym.getType(), 0);
+ // Just for safety, emit this name slightly differently than
+ // the mangling would otherwise produce
+ funcPointerTypedefName = "_local_" + funcPointerTypedefName;
+
+ writer.print(" typedef ");
+ writer.print(funcPtrType.toString(funcPointerTypedefName));
+ writer.println(";");
+ }
writer.print(" ");
writer.print(funcPointerTypedefName);
diff --git a/src/java/com/sun/gluegen/procaddress/ProcAddressConfiguration.java b/src/java/com/sun/gluegen/procaddress/ProcAddressConfiguration.java
index 54dd2cb..e5edd0d 100755
--- a/src/java/com/sun/gluegen/procaddress/ProcAddressConfiguration.java
+++ b/src/java/com/sun/gluegen/procaddress/ProcAddressConfiguration.java
@@ -52,6 +52,7 @@ public class ProcAddressConfiguration extends JavaConfiguration
private String tableClassName = "ProcAddressTable";
private Set/*<String>*/ skipProcAddressGen = new HashSet();
private List/*<String>*/ forceProcAddressGen = new ArrayList();
+ private Set/*<String>*/ forceProcAddressGenSet = new HashSet();
private String getProcAddressTableExpr;
private ConvNode procAddressNameConverter;
@@ -78,6 +79,7 @@ public class ProcAddressConfiguration extends JavaConfiguration
{
String sym = readString("ForceProcAddressGen", tok, filename, lineNo);
forceProcAddressGen.add(sym);
+ forceProcAddressGenSet.add(sym);
}
else if (cmd.equalsIgnoreCase("GetProcAddressTableExpr"))
{
@@ -253,4 +255,7 @@ public class ProcAddressConfiguration extends JavaConfiguration
return procAddressNameConverter.convert(funcName);
}
+ public boolean forceProcAddressGen(String funcName) {
+ return forceProcAddressGenSet.contains(funcName);
+ }
}
diff --git a/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java b/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java
index 75fb59c..19d4fe3 100755
--- a/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java
+++ b/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java
@@ -58,6 +58,7 @@ public class ProcAddressEmitter extends JavaEmitter
protected static final String WRAP_PREFIX = "dispatch_";
private TypeDictionary typedefDictionary;
private PrintWriter tableWriter;
+ private Set emittedTableEntries;
private String tableClassPackage;
private String tableClassName;
@@ -219,6 +220,7 @@ public class ProcAddressEmitter extends JavaEmitter
{
// See whether we need a proc address entry for this one
boolean callThroughProcAddress = needsProcAddressWrapper(baseCEmitter.getBinding().getCSymbol());
+ boolean forceProcAddress = getProcAddressConfig().forceProcAddressGen(baseCEmitter.getBinding().getCSymbol().getName());
// Note that we don't care much about the naming of the C argument
// variables so to keep things simple we ignore the buffer object
// property for the binding
@@ -226,7 +228,10 @@ public class ProcAddressEmitter extends JavaEmitter
// The C-side JNI binding for this particular function will have an
// extra final argument, which is the address (the OpenGL procedure
// address) of the function it needs to call
- ProcAddressCMethodBindingEmitter res = new ProcAddressCMethodBindingEmitter(baseCEmitter, callThroughProcAddress, this);
+ ProcAddressCMethodBindingEmitter res = new ProcAddressCMethodBindingEmitter(baseCEmitter,
+ callThroughProcAddress,
+ forceProcAddress,
+ this);
MessageFormat exp = baseCEmitter.getReturnValueCapacityExpression();
if (exp != null) {
res.setReturnValueCapacityExpression(exp);
@@ -250,6 +255,10 @@ public class ProcAddressEmitter extends JavaEmitter
shouldWrap = false;
}
+ if (config.forceProcAddressGen(symName)) {
+ shouldWrap = true;
+ }
+
if (shouldWrap)
{
// Hoist argument names from function pointer if not supplied in prototype
@@ -281,6 +290,7 @@ public class ProcAddressEmitter extends JavaEmitter
CodeGenUtils.packageAsPath(implPackageName);
tableWriter = openFile(jImplRoot + File.separator + tableClassName + ".java");
+ emittedTableEntries = new HashSet();
CodeGenUtils.emitAutogeneratedWarning(tableWriter, this);
@@ -358,6 +368,11 @@ public class ProcAddressEmitter extends JavaEmitter
protected void emitProcAddressTableEntryForString(String str)
{
+ // Deal gracefully with forced proc address generation in the face
+ // of having the function pointer typedef in the header file too
+ if (emittedTableEntries.contains(str))
+ return;
+ emittedTableEntries.add(str);
tableWriter.print(" public long ");
tableWriter.print(PROCADDRESS_VAR_PREFIX);
tableWriter.print(str);
diff --git a/src/java/com/sun/gluegen/runtime/MacOSXDynamicLinkerImpl.java b/src/java/com/sun/gluegen/runtime/MacOSXDynamicLinkerImpl.java
index 37e3cd0..f998d07 100755
--- a/src/java/com/sun/gluegen/runtime/MacOSXDynamicLinkerImpl.java
+++ b/src/java/com/sun/gluegen/runtime/MacOSXDynamicLinkerImpl.java
@@ -34,7 +34,7 @@ public class MacOSXDynamicLinkerImpl implements DynamicLinker
// other words, one can actually link against the library instead of
// having to dlsym all entry points. System.loadLibrary() uses
// RTLD_LOCAL visibility so can't be used for this purpose.
- return dlopen(pathname, RTLD_GLOBAL);
+ return dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL);
}
public long lookupSymbol(long libraryHandle, String symbolName) {
diff --git a/src/java/com/sun/gluegen/runtime/NativeLibrary.java b/src/java/com/sun/gluegen/runtime/NativeLibrary.java
index f61afb6..01148b1 100755
--- a/src/java/com/sun/gluegen/runtime/NativeLibrary.java
+++ b/src/java/com/sun/gluegen/runtime/NativeLibrary.java
@@ -61,6 +61,7 @@ public class NativeLibrary {
private static final int WINDOWS = 1;
private static final int UNIX = 2;
private static final int MACOSX = 3;
+ private static boolean DEBUG;
private static int platform;
private static DynamicLinker dynLink;
private static String prefix;
@@ -78,6 +79,9 @@ public class NativeLibrary {
} else {
platform = UNIX;
}
+
+ DEBUG = (System.getProperty("gluegen.debug.NativeLibrary") != null);
+
return null;
}
});
@@ -118,35 +122,58 @@ public class NativeLibrary {
}
/** Opens the given native library, assuming it has the same base
- name on all platforms, in the context of the specified
- ClassLoader, which is used to help find the library in the case
- of e.g. Java Web Start. */
+ name on all platforms, looking first in the system's search
+ path, and in the context of the specified ClassLoader, which is
+ used to help find the library in the case of e.g. Java Web Start. */
public static NativeLibrary open(String libName, ClassLoader loader) {
- return open(libName, libName, libName, loader);
+ return open(libName, libName, libName, true, loader);
}
/** Opens the given native library, assuming it has the given base
names (no "lib" prefix or ".dll/.so/.dylib" suffix) on the
Windows, Unix and Mac OS X platforms, respectively, and in the
context of the specified ClassLoader, which is used to help find
- the library in the case of e.g. Java Web Start. */
+ the library in the case of e.g. Java Web Start. The
+ searchSystemPathFirst argument changes the behavior to first
+ search the default system path rather than searching it last.
+ Note that we do not currently handle DSO versioning on Unix.
+ Experience with JOAL and OpenAL has shown that it is extremely
+ problematic to rely on a specific .so version (for one thing,
+ ClassLoader.findLibrary on Unix doesn't work with files not
+ ending in .so, for example .so.0), and in general if this
+ dynamic loading facility is used correctly the version number
+ will be irrelevant.
+ */
public static NativeLibrary open(String windowsLibName,
String unixLibName,
String macOSXLibName,
+ boolean searchSystemPathFirst,
ClassLoader loader) {
List possiblePaths = enumerateLibraryPaths(windowsLibName,
unixLibName,
macOSXLibName,
+ searchSystemPathFirst,
loader);
// Iterate down these and see which one if any we can actually find.
for (Iterator iter = possiblePaths.iterator(); iter.hasNext(); ) {
String path = (String) iter.next();
+ if (DEBUG) {
+ System.out.println("Trying to load " + path);
+ }
ensureNativeLibLoaded();
long res = dynLink.openLibrary(path);
if (res != 0) {
+ if (DEBUG) {
+ System.out.println("Successfully loaded " + path + ": res = 0x" + Long.toHexString(res));
+ }
return new NativeLibrary(res, path);
}
}
+
+ if (DEBUG) {
+ System.out.println("Did not succeed in loading (" + windowsLibName + ", " + unixLibName + ", " + macOSXLibName + ")");
+ }
+
// For now, just return null to indicate the open operation didn't
// succeed (could also throw an exception if we could tell which
// of the openLibrary operations actually failed)
@@ -188,18 +215,28 @@ public class NativeLibrary {
private static List enumerateLibraryPaths(String windowsLibName,
String unixLibName,
String macOSXLibName,
+ boolean searchSystemPathFirst,
ClassLoader loader) {
+ List paths = new ArrayList();
String libName = selectName(windowsLibName, unixLibName, macOSXLibName);
+ if (libName == null)
+ return paths;
String[] baseNames = buildNames(libName);
- List paths = new ArrayList();
+ if (searchSystemPathFirst) {
+ // Add just the library names to use the OS's search algorithm
+ for (int i = 0; i < baseNames.length; i++) {
+ paths.add(baseNames[i]);
+ }
+ }
// The idea to ask the ClassLoader to find the library is borrowed
// from the LWJGL library
String clPath = getPathFromClassLoader(libName, loader);
- if (clPath != null)
+ if (clPath != null) {
paths.add(clPath);
-
+ }
+
// Add entries from java.library.path
String javaLibraryPath =
(String) AccessController.doPrivileged(new PrivilegedAction() {
@@ -223,9 +260,11 @@ public class NativeLibrary {
});
addPaths(userDir, baseNames, paths);
- // Add just the library names to use the OS's search algorithm
- for (int i = 0; i < baseNames.length; i++) {
- paths.add(baseNames[i]);
+ if (!searchSystemPathFirst) {
+ // Add just the library names to use the OS's search algorithm
+ for (int i = 0; i < baseNames.length; i++) {
+ paths.add(baseNames[i]);
+ }
}
return paths;
diff --git a/src/java/com/sun/gluegen/runtime/UnixDynamicLinkerImpl.java b/src/java/com/sun/gluegen/runtime/UnixDynamicLinkerImpl.java
index 006f90d..b6a79be 100755
--- a/src/java/com/sun/gluegen/runtime/UnixDynamicLinkerImpl.java
+++ b/src/java/com/sun/gluegen/runtime/UnixDynamicLinkerImpl.java
@@ -40,7 +40,7 @@ public class UnixDynamicLinkerImpl implements DynamicLinker
// other words, one can actually link against the library instead of
// having to dlsym all entry points. System.loadLibrary() uses
// RTLD_LOCAL visibility so can't be used for this purpose.
- return dlopen(pathname, RTLD_GLOBAL);
+ return dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL);
}
public long lookupSymbol(long libraryHandle, String symbolName) {