package jetbrains.mps.debugger.java.runtime.engine.concurrent; /*Generated by MPS */ import org.apache.log4j.Logger; import org.apache.log4j.LogManager; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.CountDownLatch; import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes; import java.util.List; import jetbrains.mps.internal.collections.runtime.ListSequence; import java.util.ArrayList; import org.apache.log4j.Level; public class ManagerThread { private static final Logger LOG = LogManager.getLogger(ManagerThread.class); private final BlockingQueue<IManagerCommand> myCommandQueue = new LinkedBlockingQueue<IManagerCommand>(); private final ManagerThread.WorkerThread myThread = new ManagerThread.WorkerThread(); private volatile boolean myClosed = false; public ManagerThread() { myThread.start(); } public void invoke(IManagerCommand command) { if (isManagerThread()) { myThread.processCommand(command); } else { schedule(command); } } public void invokeAndWait(final IManagerCommand command) { if (isManagerThread()) { myThread.processCommand(command); } else { final CountDownLatch countDown = new CountDownLatch(1); schedule(Commands.fromClosure(new _FunctionTypes._void_P0_E0() { public void invoke() { try { command.invoke(); } finally { countDown.countDown(); } } }, new _FunctionTypes._void_P0_E0() { public void invoke() { try { command.cancel(); } finally { countDown.countDown(); } } })); try { countDown.await(); } catch (InterruptedException ignore) { } } } public void schedule(IManagerCommand command) { if (myClosed) { command.cancel(); } else { myCommandQueue.offer(command); } } public void close() { myClosed = true; } public static boolean isManagerThread() { return Thread.currentThread() instanceof ManagerThread.WorkerThread; } public static void assertIsMangerThread() { assert isManagerThread(); } private class WorkerThread extends Thread { public WorkerThread() { } @Override public void run() { try { while (true) { if (isInterrupted() || myClosed) { break; } processCommand(myCommandQueue.take()); } if (myClosed) { List<IManagerCommand> unprocessed = ListSequence.fromList(new ArrayList<IManagerCommand>()); myCommandQueue.drainTo(unprocessed); for (IManagerCommand command : ListSequence.fromList(unprocessed)) { try { command.cancel(); } catch (Throwable t) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("Command " + command + " threw an exception.", t); } } } } } catch (InterruptedException ignore) { // do what? } if (LOG.isDebugEnabled()) { LOG.debug("Thread " + this + " finished working."); } } private void processCommand(IManagerCommand command) { try { if (myClosed) { command.cancel(); } else { command.invoke(); } } catch (Throwable t) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("Command " + command + " threw an exception.", t); } } } } }