1.1 --- a/vcscore/src/org/netbeans/modules/vcscore/cmdline/UserCommandTask.java Thu Jan 16 16:35:57 2003 +0000
1.2 +++ b/vcscore/src/org/netbeans/modules/vcscore/cmdline/UserCommandTask.java Thu Jan 16 16:59:49 2003 +0000
1.3 @@ -20,6 +20,8 @@
1.4 import java.util.HashSet;
1.5 import java.util.Hashtable;
1.6 import java.util.Iterator;
1.7 +import java.util.LinkedList;
1.8 +import java.util.List;
1.9 import java.util.Map;
1.10 import java.util.Set;
1.11
1.12 @@ -80,6 +82,12 @@
1.13 */
1.14 private static Set runningTasks = new HashSet();
1.15
1.16 + /**
1.17 + * The list of pending tasks, preserving the order in which they were scheduled.
1.18 + * This list is necessary for tasks synchronization.
1.19 + */
1.20 + private static List pendingTasks = new LinkedList();
1.21 +
1.22 /** Creates a new instance of UserCommandTask */
1.23 public UserCommandTask(UserCommandSupport cmdSupport, VcsDescribedCommand cmd) {//, VcsCommandExecutor executor) {
1.24 super(cmdSupport, cmd);
1.25 @@ -309,10 +317,15 @@
1.26 protected int execute() {
1.27 int status = STATUS_SUCCEEDED;
1.28 try {
1.29 - runningTasks.add(this);//, Thread.currentThread());
1.30 + //runningTasks.add(this);//, Thread.currentThread());
1.31 + // Task is added as running when canRun() returns true. It's too late to do it here!
1.32 + // canRun() can be called quickly one after another and excute() in a lazy thread later.
1.33 status = super.execute();
1.34 } finally {
1.35 - runningTasks.remove(this);
1.36 + synchronized (runningTasks) {
1.37 + runningTasks.remove(this);
1.38 + //System.out.println("RUNNING TASK REMOVED: "+this);
1.39 + }
1.40 if (visualizer != null) {
1.41 visualizer.setExitStatus(executor.getExitStatus());
1.42 }
1.43 @@ -466,6 +479,10 @@
1.44 * @return true if the command can be run in the current monitor lock, false otherwise.
1.45 */
1.46 private boolean canRun(UserCommandTask task) {
1.47 + if (!pendingTasks.contains(task)) {
1.48 + pendingTasks.add(task);
1.49 + //System.out.println("PENDING TASK ADDED: "+task);
1.50 + }
1.51 VcsCommandExecutor vce = task.getExecutor();
1.52 VcsCommand cmd = vce.getCommand();
1.53 //System.out.println("canRun("+cmd.getName()+")");
1.54 @@ -475,82 +492,106 @@
1.55 VcsCommand.PROPERTY_CONCURRENT_EXECUTION);
1.56 String concurrencyWith = (String) cmd.getProperty(VcsCommand.PROPERTY_CONCURRENT_EXECUTION_WITH);
1.57 //System.out.println(" concurrency = "+concurrency+", concurrencyWith = "+concurrencyWith);
1.58 - if ((concurrency == VcsCommand.EXEC_CONCURRENT_ALL
1.59 - && concurrencyWith == null)
1.60 - || concurrency == VcsCommand.EXEC_SERIAL_INERT) return true;
1.61 - HashMap concurrencyMap = createConcurrencyMap(concurrencyWith);
1.62 - String name = cmd.getName();
1.63 boolean haveToWait = false;
1.64 - boolean serialOnFile = (concurrency & VcsCommand.EXEC_SERIAL_ON_FILE) != 0;
1.65 - boolean serialOnPackage = (concurrency & VcsCommand.EXEC_SERIAL_ON_PACKAGE) != 0;
1.66 - boolean serialWithParent = (concurrency & VcsCommand.EXEC_SERIAL_WITH_PARENT) != 0;
1.67 - boolean serialOfCommand = (concurrency & VcsCommand.EXEC_SERIAL_OF_COMMAND) != 0;
1.68 - boolean serialOfAll = (concurrency & VcsCommand.EXEC_SERIAL_ALL) != 0;
1.69 - boolean matchOnFile = false;
1.70 - boolean matchOnPackage = false;
1.71 - boolean matchWithParent = false;
1.72 - boolean matchOfCommand = false;
1.73 - //System.out.println(" serialOnFile = "+serialOnFile);
1.74 - //System.out.println(" serialOnPackage = "+serialOnPackage);
1.75 - //System.out.println(" serialWithParent = "+serialWithParent);
1.76 - //System.out.println(" serialOfCommand = "+serialOfCommand);
1.77 - //System.out.println(" serialOfAll = "+serialOfAll);
1.78 - //System.out.println(" commandsToTestAgainst = "+commandsToTestAgainst);
1.79 - //if (serialOfAll && commandsToTestAgainst.size() > 0) return false;
1.80 - //commandsToTestAgainst.addAll(commandsToRun);
1.81 - //commandsToTestAgainst.addAll(commandsWaitQueue);
1.82 - //commandsToTestAgainst.remove(vce);
1.83 - for(Iterator iter = runningTasks.iterator(); iter.hasNext(); ) {
1.84 - UserCommandTask cwTest = (UserCommandTask) iter.next();
1.85 - VcsCommandExecutor ec = cwTest.getExecutor();
1.86 - Collection cmdFiles = ec.getFiles();
1.87 - VcsCommand uc = ec.getCommand();
1.88 - //System.out.println(" testing with cmd = "+uc.getName());
1.89 - int cmdConcurrency = VcsCommandIO.getIntegerPropertyAssumeZero(uc, VcsCommand.PROPERTY_CONCURRENT_EXECUTION);
1.90 - //System.out.println(" cmdConcurrency = "+cmdConcurrency);
1.91 - if (VcsCommand.EXEC_SERIAL_INERT == cmdConcurrency) continue;
1.92 - if (serialOfAll) {
1.93 - haveToWait = true;
1.94 - break;
1.95 + if ((concurrency != VcsCommand.EXEC_CONCURRENT_ALL || concurrencyWith != null)
1.96 + && concurrency != VcsCommand.EXEC_SERIAL_INERT) {
1.97 +
1.98 + HashMap concurrencyMap = createConcurrencyMap(concurrencyWith);
1.99 + String name = cmd.getName();
1.100 + boolean serialOnFile = (concurrency & VcsCommand.EXEC_SERIAL_ON_FILE) != 0;
1.101 + boolean serialOnPackage = (concurrency & VcsCommand.EXEC_SERIAL_ON_PACKAGE) != 0;
1.102 + boolean serialWithParent = (concurrency & VcsCommand.EXEC_SERIAL_WITH_PARENT) != 0;
1.103 + boolean serialOfCommand = (concurrency & VcsCommand.EXEC_SERIAL_OF_COMMAND) != 0;
1.104 + boolean serialOfAll = (concurrency & VcsCommand.EXEC_SERIAL_ALL) != 0;
1.105 + boolean matchOnFile = false;
1.106 + boolean matchOnPackage = false;
1.107 + boolean matchWithParent = false;
1.108 + boolean matchOfCommand = false;
1.109 + //System.out.println(" serialOnFile = "+serialOnFile);
1.110 + //System.out.println(" serialOnPackage = "+serialOnPackage);
1.111 + //System.out.println(" serialWithParent = "+serialWithParent);
1.112 + //System.out.println(" serialOfCommand = "+serialOfCommand);
1.113 + //System.out.println(" serialOfAll = "+serialOfAll);
1.114 + //System.out.println(" commandsToTestAgainst = "+commandsToTestAgainst);
1.115 + //if (serialOfAll && commandsToTestAgainst.size() > 0) return false;
1.116 + //commandsToTestAgainst.addAll(commandsToRun);
1.117 + //commandsToTestAgainst.addAll(commandsWaitQueue);
1.118 + //commandsToTestAgainst.remove(vce);
1.119 + Set tasksToTest;
1.120 + synchronized (runningTasks) {
1.121 + tasksToTest = new HashSet(runningTasks);
1.122 }
1.123 - String cmdName = uc.getName();
1.124 - if (serialOnFile) {
1.125 - for(Iterator it = files.iterator(); it.hasNext(); ) {
1.126 - String file = (String) it.next();
1.127 - if (cmdFiles.contains(file)) {
1.128 - matchOnFile = true;
1.129 + if ((concurrency & VcsCommand.EXEC_SERIAL_WITH_PENDING) != 0) {
1.130 + //tasksToTest = new HashSet(runningTasks);
1.131 + for (Iterator pendingIt = pendingTasks.iterator(); pendingIt.hasNext(); ) {
1.132 + UserCommandTask pendingTask = (UserCommandTask) pendingIt.next();
1.133 + if (pendingTask != task) {
1.134 + tasksToTest.add(pendingTask);
1.135 + } else {
1.136 break;
1.137 }
1.138 }
1.139 }
1.140 - if (serialOnPackage) {
1.141 - if (areFilesInSamePackage(files, cmdFiles)) {
1.142 - matchOnPackage = true;
1.143 - }
1.144 - }
1.145 - if (serialWithParent) {
1.146 - if (isParentFolder(files, cmdFiles)) {
1.147 - matchWithParent = true;
1.148 - }
1.149 - }
1.150 - if (serialOfCommand) {
1.151 - matchOfCommand = name.equals(cmdName);
1.152 - }
1.153 - // if (serialOfCommand && !matchOfCommand) do not wait
1.154 - if ((!serialOfCommand || matchOfCommand) && (matchOnFile || matchOnPackage || matchWithParent || matchOfCommand)) {
1.155 - //System.out.println(" matchOnFile = "+matchOnFile+", matchOnPackage = "+matchOnPackage+", matchWithParent = "+matchWithParent+", matchOfCommand = "+matchOfCommand);
1.156 - haveToWait = true;
1.157 - break;
1.158 - }
1.159 - Integer concurrencyWithNum = (Integer) concurrencyMap.get(cmdName);
1.160 - if (concurrencyWithNum != null) {
1.161 - if (haveToWaitFor(files, cmdFiles, concurrencyWithNum.intValue())) {
1.162 + for(Iterator iter = tasksToTest.iterator(); iter.hasNext(); ) {
1.163 + UserCommandTask cwTest = (UserCommandTask) iter.next();
1.164 + VcsCommandExecutor ec = cwTest.getExecutor();
1.165 + Collection cmdFiles = ec.getFiles();
1.166 + VcsCommand uc = ec.getCommand();
1.167 + //System.out.println(" testing with cmd = "+uc.getName()+", cmdFiles = "+cmdFiles+", TASK = "+cwTest);
1.168 + int cmdConcurrency = VcsCommandIO.getIntegerPropertyAssumeZero(uc, VcsCommand.PROPERTY_CONCURRENT_EXECUTION);
1.169 + //System.out.println(" cmdConcurrency = "+cmdConcurrency);
1.170 + if (VcsCommand.EXEC_SERIAL_INERT == cmdConcurrency) continue;
1.171 + if (serialOfAll) {
1.172 haveToWait = true;
1.173 break;
1.174 }
1.175 + String cmdName = uc.getName();
1.176 + if (serialOnFile) {
1.177 + for(Iterator it = files.iterator(); it.hasNext(); ) {
1.178 + String file = (String) it.next();
1.179 + if (cmdFiles.contains(file)) {
1.180 + matchOnFile = true;
1.181 + break;
1.182 + }
1.183 + }
1.184 + }
1.185 + if (serialOnPackage) {
1.186 + if (areFilesInSamePackage(files, cmdFiles)) {
1.187 + matchOnPackage = true;
1.188 + }
1.189 + }
1.190 + if (serialWithParent) {
1.191 + if (isParentFolder(files, cmdFiles)) {
1.192 + matchWithParent = true;
1.193 + }
1.194 + }
1.195 + if (serialOfCommand) {
1.196 + matchOfCommand = name.equals(cmdName);
1.197 + }
1.198 + // if (serialOfCommand && !matchOfCommand) do not wait
1.199 + if ((!serialOfCommand || matchOfCommand) && (matchOnFile || matchOnPackage || matchWithParent || matchOfCommand)) {
1.200 + //System.out.println(" matchOnFile = "+matchOnFile+", matchOnPackage = "+matchOnPackage+", matchWithParent = "+matchWithParent+", matchOfCommand = "+matchOfCommand);
1.201 + haveToWait = true;
1.202 + break;
1.203 + }
1.204 + Integer concurrencyWithNum = (Integer) concurrencyMap.get(cmdName);
1.205 + if (concurrencyWithNum != null) {
1.206 + if (haveToWaitFor(files, cmdFiles, concurrencyWithNum.intValue())) {
1.207 + haveToWait = true;
1.208 + break;
1.209 + }
1.210 + }
1.211 }
1.212 }
1.213 //System.out.println("haveToWait = "+haveToWait);
1.214 + if (!haveToWait) {
1.215 + synchronized (runningTasks) {
1.216 + runningTasks.add(task);
1.217 + //System.out.println("RUNNING TASK ADDED: "+task);
1.218 + }
1.219 + pendingTasks.remove(task);
1.220 + //System.out.println("PENDING TASK REMOVED: "+task);
1.221 + }
1.222 return !haveToWait;
1.223 }
1.224
2.1 --- a/vcscore/src/org/netbeans/modules/vcscore/commands/VcsCommand.java Thu Jan 16 16:35:57 2003 +0000
2.2 +++ b/vcscore/src/org/netbeans/modules/vcscore/commands/VcsCommand.java Thu Jan 16 16:59:49 2003 +0000
2.3 @@ -383,6 +383,12 @@
2.4 * command is already running.
2.5 */
2.6 public static final int EXEC_SERIAL_ALL = 16;
2.7 + /** Serial execution even with respect to the pending commands, that are waiting
2.8 + * for the actual execution. This flag cause, that all pending commands are
2.9 + * considered in addition to the already running commands when evaluating
2.10 + * of whether the command can be executed or not.
2.11 + */
2.12 + public static final int EXEC_SERIAL_WITH_PENDING = 32;
2.13 /** This command is inert with all other commands. When other commands are
2.14 * considered whether they can be executed, commands with inert concurrent
2.15 * execution property are ignored. This can be used for meta commands,