LfsPluginServlet#reload: Fix plugin reload

Issue: when plugin gets unloaded it unconditionally cleans up current
reference to the Guice filter chain. Additionally, the access to
LfsPluginServlet.filter was not thread safe.

Use AtomicReference to make LfsPluginServlet.filter thread safe.

When unloading, set LfsPluginServlet.filter to null only if its value
didn't change since the time this plugin version was loaded.

Change-Id: I3287706107bd327af04c563eb46bf398aabda686
Signed-off-by: Jacek Centkowski <geminica.programs@gmail.com>
Also-by: Saša Živkov <zivkov@gmail.com>
This commit is contained in:
Jacek Centkowski
2016-07-11 12:20:34 +02:00
parent 37b341450e
commit e1ab7e9442

View File

@@ -34,6 +34,7 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import javax.servlet.FilterChain;
import javax.servlet.ServletConfig;
@@ -58,7 +59,7 @@ public class LfsPluginServlet extends HttpServlet
private List<Plugin> pending = new ArrayList<>();
private final String pluginName;
private final FilterChain chain;
private GuiceFilter filter;
private AtomicReference<GuiceFilter> filter;
@Inject
LfsPluginServlet(@GerritServerConfig Config cfg) {
@@ -71,17 +72,18 @@ public class LfsPluginServlet extends HttpServlet
(HttpServletRequest) req, (HttpServletResponse) res);
}
};
this.filter = new AtomicReference<>();
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
if (filter == null) {
if (filter.get() == null) {
CacheHeaders.setNotCacheable(res);
res.sendError(SC_NOT_IMPLEMENTED);
return;
}
filter.doFilter(req, res, chain);
filter.get().doFilter(req, res, chain);
}
@Override
@@ -112,13 +114,14 @@ public class LfsPluginServlet extends HttpServlet
if (!plugin.getName().equals(pluginName)) {
return;
}
filter = load(plugin);
final GuiceFilter guiceFilter = load(plugin);
plugin.add(new RegistrationHandle() {
@Override
public void remove() {
filter = null;
filter.compareAndSet(guiceFilter, null);
}
});
filter.set(guiceFilter);
}
private GuiceFilter load(Plugin plugin) {