Found in the review of #132; the race predates that PR.
What happens
ScriptedConfiguration.getGroovyScriptEngine() reads the groovyScriptEngine field twice outside the lock: once for the null check on the fast path (ScriptedConfiguration.java:786) and once for the return (:804). release() sets the field to null (:668) inside synchronized (this), a lock the fast path does not take.
If release() runs between the two reads, getGroovyScriptEngine() returns null, and evaluate throws an NPE at getGroovyScriptEngine().createScript(...) (:744). loadScript (:760) has the same exposure. release() is called from OperationalContext.dispose() when the connector's pooled configuration is disposed, for example on connector-server shutdown. ConnectionListener.shutdown does not wait for in-flight requests, so a script evaluation that is still running can hit the race. The window is small.
Expected
getGroovyScriptEngine() never returns null. The usual way to write double-checked locking with a volatile field is to read the field once into a local variable.
Found in the review of #132; the race predates that PR.
What happens
ScriptedConfiguration.getGroovyScriptEngine()reads thegroovyScriptEnginefield twice outside the lock: once for the null check on the fast path (ScriptedConfiguration.java:786) and once for thereturn(:804).release()sets the field tonull(:668) insidesynchronized (this), a lock the fast path does not take.If
release()runs between the two reads,getGroovyScriptEngine()returnsnull, andevaluatethrows an NPE atgetGroovyScriptEngine().createScript(...)(:744).loadScript(:760) has the same exposure.release()is called fromOperationalContext.dispose()when the connector's pooled configuration is disposed, for example on connector-server shutdown.ConnectionListener.shutdowndoes not wait for in-flight requests, so a script evaluation that is still running can hit the race. The window is small.Expected
getGroovyScriptEngine()never returnsnull. The usual way to write double-checked locking with avolatilefield is to read the field once into a local variable.