Fix deadlock when removing ScriptEngine (#2785)
Signed-off-by: Jan N. Klug <github@klug.nrw>pull/2804/head
parent
013e317b6b
commit
0ba4de3594
|
@ -20,6 +20,8 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.script.Invocable;
|
import javax.script.Invocable;
|
||||||
import javax.script.ScriptContext;
|
import javax.script.ScriptContext;
|
||||||
|
@ -34,6 +36,7 @@ import org.openhab.core.automation.module.script.ScriptEngineContainer;
|
||||||
import org.openhab.core.automation.module.script.ScriptEngineFactory;
|
import org.openhab.core.automation.module.script.ScriptEngineFactory;
|
||||||
import org.openhab.core.automation.module.script.ScriptEngineManager;
|
import org.openhab.core.automation.module.script.ScriptEngineManager;
|
||||||
import org.openhab.core.automation.module.script.ScriptExtensionManagerWrapper;
|
import org.openhab.core.automation.module.script.ScriptExtensionManagerWrapper;
|
||||||
|
import org.openhab.core.common.ThreadPoolManager;
|
||||||
import org.osgi.service.component.annotations.Activate;
|
import org.osgi.service.component.annotations.Activate;
|
||||||
import org.osgi.service.component.annotations.Component;
|
import org.osgi.service.component.annotations.Component;
|
||||||
import org.osgi.service.component.annotations.Reference;
|
import org.osgi.service.component.annotations.Reference;
|
||||||
|
@ -52,6 +55,9 @@ import org.slf4j.LoggerFactory;
|
||||||
@Component(service = ScriptEngineManager.class)
|
@Component(service = ScriptEngineManager.class)
|
||||||
public class ScriptEngineManagerImpl implements ScriptEngineManager {
|
public class ScriptEngineManagerImpl implements ScriptEngineManager {
|
||||||
|
|
||||||
|
private final ScheduledExecutorService scheduler = ThreadPoolManager
|
||||||
|
.getScheduledPool(ThreadPoolManager.THREAD_POOL_NAME_COMMON);
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(ScriptEngineManagerImpl.class);
|
private final Logger logger = LoggerFactory.getLogger(ScriptEngineManagerImpl.class);
|
||||||
private final Map<String, ScriptEngineContainer> loadedScriptEngineInstances = new HashMap<>();
|
private final Map<String, ScriptEngineContainer> loadedScriptEngineInstances = new HashMap<>();
|
||||||
private final Map<String, ScriptEngineFactory> customSupport = new HashMap<>();
|
private final Map<String, ScriptEngineFactory> customSupport = new HashMap<>();
|
||||||
|
@ -216,12 +222,17 @@ public class ScriptEngineManagerImpl implements ScriptEngineManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scriptEngine instanceof AutoCloseable) {
|
if (scriptEngine instanceof AutoCloseable) {
|
||||||
AutoCloseable closeable = (AutoCloseable) scriptEngine;
|
// we cannot not use ScheduledExecutorService.execute here as it might execute the task in the calling
|
||||||
try {
|
// thread (calling ScriptEngine.close in the same thread may result in a deadlock if the ScriptEngine
|
||||||
closeable.close();
|
// tries to Thread.join)
|
||||||
} catch (Exception e) {
|
scheduler.schedule(() -> {
|
||||||
logger.error("Error while closing script engine", e);
|
AutoCloseable closeable = (AutoCloseable) scriptEngine;
|
||||||
}
|
try {
|
||||||
|
closeable.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Error while closing script engine", e);
|
||||||
|
}
|
||||||
|
}, 0, TimeUnit.SECONDS);
|
||||||
} else {
|
} else {
|
||||||
logger.trace("ScriptEngine does not support AutoCloseable interface");
|
logger.trace("ScriptEngine does not support AutoCloseable interface");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue