package jetbrains.mps.core.tool.environment.classloading; /*Generated by MPS */ import org.apache.log4j.Logger; import java.util.Map; import java.util.Collections; import java.util.WeakHashMap; import java.util.concurrent.ScheduledExecutorService; import jetbrains.mps.core.tool.environment.common.ConcurrencyUtil; import java.util.concurrent.TimeUnit; /** * * @author mike */ @SuppressWarnings(value = {"NonPrivateFieldAccessedInSynchronizedContext"}) /*package*/ abstract class Timed<T> { private static final Logger LOG = Logger.getLogger("#com.intellij.util.Timed"); private static final Map<Timed, Boolean> ourReferences = Collections.synchronizedMap(new WeakHashMap<Timed, Boolean>()); /*package*/ int myLastCheckedAccessCount; /*package*/ int myAccessCount; protected T myT; /*package*/ boolean myPolled; public Timed() { } public void dispose() { final Object t = myT; myT = null; remove(); } protected final void poll() { if (!(myPolled)) { Timed.ourReferences.put(this, Boolean.TRUE); myPolled = true; } } protected final void remove() { Timed.ourReferences.remove(this); myPolled = false; } protected boolean isLocked() { return false; } /*package*/ static void disposeTimed() { final Timed[] references = Timed.ourReferences.keySet().toArray(new Timed[Timed.ourReferences.size()]); for (Timed timed : references) { if (timed == null) { continue; } synchronized (timed) { if (timed.myLastCheckedAccessCount == timed.myAccessCount && !(timed.isLocked())) { timed.dispose(); } else { timed.myLastCheckedAccessCount = timed.myAccessCount; } } } } static { ScheduledExecutorService service = ConcurrencyUtil.newSingleScheduledThreadExecutor("timed reference disposer", Thread.MIN_PRIORITY + 1); service.scheduleWithFixedDelay(new Runnable() { @Override public void run() { try { Timed.disposeTimed(); } catch (Throwable e) { Timed.LOG.error(null, e); } } }, 60, 60, TimeUnit.SECONDS); } }