/** * Copyright (c) 2012 by JP Moresmau * This code is made available under the terms of the Eclipse Public License, * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html */ package net.sf.eclipsefp.haskell.buildwrapper.usage; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import net.sf.eclipsefp.haskell.buildwrapper.BWFacade; import net.sf.eclipsefp.haskell.buildwrapper.BuildWrapperPlugin; import net.sf.eclipsefp.haskell.buildwrapper.types.Component; import org.eclipse.core.resources.IProject; /** * This thread calls the BuildWrapper executable and populates the database when needed * All requests to update a project are queued here * @author JP Moresmau * */ public class UsageThread extends Thread { private boolean shouldStop=false; private LinkedHashSet<IProject> ps=new LinkedHashSet<>(); /** * are we currently working? */ private AtomicBoolean working=new AtomicBoolean(false); public UsageThread() { super("UsageThread"); setDaemon(true); } @Override public void run(){ /** * create the API in a thread, since new UsageAPI does a new UsageDB, which loads the SQLite library, etc * This can hang on MacOS, so let's no hand the UI thread */ final UsageAPI api=new UsageAPI(); BuildWrapperPlugin.getDefault().setUsageAPI(api); while (!shouldStop){ synchronized (ps) { try{ ps.wait(); } catch (InterruptedException ie){ // noop } } if (!shouldStop){ working.set(true); IProject p=getNext(); while (p!=null && !shouldStop){ boolean retAll=!api.knowsProject(p); BWFacade f=BuildWrapperPlugin.getFacade(p); if (f!=null){ List<Component> cs=f.getComponents(); for (Component c:cs){ if (c.isBuildable()){ f.generateUsage(c,retAll); } } } p=getNext(); } } working.set(false); } } public boolean isWorking(){ return working.get(); } private IProject getNext(){ synchronized (ps) { if (!ps.isEmpty()){ Iterator<IProject> it=ps.iterator(); IProject p=it.next(); it.remove(); return p; } } return null; } public void addProject(IProject p){ synchronized (ps) { ps.add(p); ps.notifyAll(); } } public void setShouldStop() { synchronized (ps) { this.shouldStop = true; ps.notifyAll(); } } }