diff options
author | Sven Gothel <[email protected]> | 2023-07-01 11:45:31 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2023-07-01 11:45:31 +0200 |
commit | 6200b9122a90ef8c2af8b9205b4b1c90b1aa5074 (patch) | |
tree | 0b23f16f49ed43d66461b7e7c6ee7e304ad10c7b | |
parent | dd5829a4fed25fbad766361b87c65076ef596ded (diff) |
GlueGen JavaCallback: Release the associated data (natively) only after the actual toolkit setCallback call
.. to avoid a potential race condition
-rw-r--r-- | src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java index 2bc453d..977596f 100644 --- a/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java +++ b/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java @@ -620,10 +620,13 @@ public class JavaMethodBindingEmitter extends FunctionEmitter { unit.emitln(" }"); unit.emitln(" private final void add"+capIfaceName+"Map("+binding.getJavaSelectParameter(new StringBuilder(), javaCallback.setFuncKeyIndices, true).toString()+UsrParamClassName+" value) {"); unit.emitln(" final "+KeyClassName+" key = new "+KeyClassName+"("+binding.getJavaCallSelectArguments(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+");"); - unit.emitln(" "+usrMapInstanceName+".put(key, value);"); + unit.emitln(" final "+UsrParamClassName+" old = "+usrMapInstanceName+".put(key, value);"); if( DEBUG_JAVACALLBACK ) { unit.emitln(" System.err.println(\"ZZZ Map \"+key+\" -> value.nativeParam 0x\"+Long.toHexString(null!=value?value.nativeParam:0));"); } + unit.emitln(" if( null != old ) {"); + unit.emitln(" release"+capIfaceName+"MapImpl(old.nativeParam);"); + unit.emitln(" }"); unit.emitln(" }"); unit.emitln(" private final void release"+capIfaceName+"Map("+binding.getJavaSelectParameter(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+") {"); unit.emitln(" final "+KeyClassName+" key = new "+KeyClassName+"("+binding.getJavaCallSelectArguments(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+");"); @@ -768,7 +771,6 @@ public class JavaMethodBindingEmitter extends FunctionEmitter { final String usrMapInstanceName = lowIfaceName+"UsrMap"; unit.emitln(" synchronized( "+usrMapInstanceName+" ) {"); unit.emitln(" final long[] nativeUserParam = { 0 };"); - unit.emitln(" release"+capIfaceName+"Map("+binding.getJavaCallSelectArguments(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+"); // Ensure a previously mapped instance is released"); unit.emitln(); } if (!returnType.isVoid()) { @@ -810,8 +812,12 @@ public class JavaMethodBindingEmitter extends FunctionEmitter { } unit.emitln(); unit.emitln(" if( 0 != nativeUserParam[0] ) {"); + unit.emitln(" // callback registrated -> add will release a previously mapped instance "); unit.emitln(" add"+capIfaceName+"Map("+binding.getJavaCallSelectArguments(new StringBuilder(), javaCallback.setFuncKeyIndices, true).toString()+ "new "+UsrParamClassName+"("+funcArgName+", "+userParamArgName+", nativeUserParam[0]));"); + unit.emitln(" } else {"); + unit.emitln(" // callback released (null func) -> release a previously mapped instance "); + unit.emitln(" release"+capIfaceName+"Map("+binding.getJavaCallSelectArguments(new StringBuilder(), javaCallback.setFuncKeyIndices, false).toString()+");"); unit.emitln(" }"); unit.emitln(" } // synchronized "); } |