Lines 111-117
Link Here
|
111 |
import org.openide.filesystems.FileEvent; |
111 |
import org.openide.filesystems.FileEvent; |
112 |
import org.openide.filesystems.FileObject; |
112 |
import org.openide.filesystems.FileObject; |
113 |
import org.openide.filesystems.FileRenameEvent; |
113 |
import org.openide.filesystems.FileRenameEvent; |
114 |
import org.openide.filesystems.FileStateInvalidException; |
|
|
115 |
import org.openide.filesystems.FileUtil; |
114 |
import org.openide.filesystems.FileUtil; |
116 |
import org.openide.filesystems.FileUtil; |
115 |
import org.openide.filesystems.FileUtil; |
117 |
import org.openide.loaders.DataObject; |
116 |
import org.openide.loaders.DataObject; |
Lines 230-235
Link Here
|
230 |
private final static SingleThreadFactory factory = new SingleThreadFactory (); |
229 |
private final static SingleThreadFactory factory = new SingleThreadFactory (); |
231 |
private final static CurrentRequestReference currentRequest = new CurrentRequestReference (); |
230 |
private final static CurrentRequestReference currentRequest = new CurrentRequestReference (); |
232 |
private final static EditorRegistryListener editorRegistryListener = new EditorRegistryListener (); |
231 |
private final static EditorRegistryListener editorRegistryListener = new EditorRegistryListener (); |
|
|
232 |
private final static List<Request> todo = Collections.synchronizedList(new LinkedList<Request>()); |
233 |
//Only single thread can operate on the single javac |
233 |
//Only single thread can operate on the single javac |
234 |
private final static ReentrantLock javacLock = new ReentrantLock (true); |
234 |
private final static ReentrantLock javacLock = new ReentrantLock (true); |
235 |
|
235 |
|
Lines 540-545
Link Here
|
540 |
} |
540 |
} |
541 |
} |
541 |
} |
542 |
} |
542 |
} |
|
|
543 |
|
544 |
|
545 |
/** |
546 |
* Performs the given task when the scan finished. When no background scan is running |
547 |
* it performs the given task synchronously. When the background scan is active it queues |
548 |
* the given task and returns, the task is performed when the background scan completes by |
549 |
* the thread doing the background scan. |
550 |
* @param task to be performed |
551 |
* @param shared if true the java compiler may be reused by other {@link org.netbeans.api.java.source.CancellableTasks}, |
552 |
* the value false may have negative impact on the IDE performance. |
553 |
* @since 0.12 |
554 |
*/ |
555 |
public void runWhenScanFinished (final CancellableTask<CompilationController> task, final boolean shared) throws IOException { |
556 |
assert task != null; |
557 |
final Request r = new Request (task,this,null,null,shared); |
558 |
//0) Add speculatively task to be performed at the end of background scan |
559 |
todo.add (r); |
560 |
//1) Try to aquire javac lock, if successfull no task is running |
561 |
// perform the given taks synchronously if it wasn't already performed |
562 |
// by background scan. |
563 |
final boolean locked = javacLock.tryLock(); |
564 |
if (locked) { |
565 |
try { |
566 |
if (todo.remove(r)) { |
567 |
runUserActionTask(task, shared); |
568 |
} |
569 |
} finally { |
570 |
javacLock.unlock(); |
571 |
} |
572 |
} |
573 |
else { |
574 |
//Otherwise interrupt currently running task and try to aquire lock |
575 |
do { |
576 |
final JavaSource.Request[] request = new JavaSource.Request[1]; |
577 |
boolean isScanner = false; |
578 |
if (request[0] == null) { |
579 |
isScanner = currentRequest.getUserTaskToCancel(request); |
580 |
} |
581 |
try { |
582 |
if (isScanner) { |
583 |
return; |
584 |
} |
585 |
if (request[0] != null) { |
586 |
request[0].task.cancel(); |
587 |
} |
588 |
if (javacLock.tryLock()) { |
589 |
try { |
590 |
if (todo.remove(r)) { |
591 |
runUserActionTask(task, shared); |
592 |
} |
593 |
} finally { |
594 |
javacLock.unlock(); |
595 |
} |
596 |
} |
597 |
} finally { |
598 |
currentRequest.cancelCompleted(request[0]); |
599 |
} |
600 |
} while (true); |
601 |
} |
602 |
} |
543 |
|
603 |
|
544 |
/** Runs a task which permits for modifying the sources. |
604 |
/** Runs a task which permits for modifying the sources. |
545 |
* Call to this method will cancel processig of all the phase completion tasks until |
605 |
* Call to this method will cancel processig of all the phase completion tasks until |
Lines 1126-1132
Link Here
|
1126 |
Request otherRequest = (Request) other; |
1186 |
Request otherRequest = (Request) other; |
1127 |
return priority == otherRequest.priority |
1187 |
return priority == otherRequest.priority |
1128 |
&& reschedule == otherRequest.reschedule |
1188 |
&& reschedule == otherRequest.reschedule |
1129 |
&& phase.equals (otherRequest.phase) |
1189 |
&& phase == null ? otherRequest.phase == null : phase.equals (otherRequest.phase) |
1130 |
&& task.equals(otherRequest.task); |
1190 |
&& task.equals(otherRequest.task); |
1131 |
} |
1191 |
} |
1132 |
else { |
1192 |
else { |
Lines 1176-1182
Link Here
|
1176 |
assert r.reschedule == false; |
1236 |
assert r.reschedule == false; |
1177 |
javacLock.lock (); |
1237 |
javacLock.lock (); |
1178 |
try { |
1238 |
try { |
1179 |
r.task.run (null); |
1239 |
try { |
|
|
1240 |
r.task.run (null); |
1241 |
} finally { |
1242 |
boolean cancelled = requests.contains(r); |
1243 |
if (!cancelled) { |
1244 |
Request[] _todo; |
1245 |
synchronized (todo) { |
1246 |
_todo = todo.toArray(new Request[todo.size()]); |
1247 |
todo.clear(); |
1248 |
} |
1249 |
for (Request rq : _todo) { |
1250 |
rq.javaSource.runUserActionTask((CancellableTask<CompilationController>)rq.task, rq.reschedule); |
1251 |
} |
1252 |
} |
1253 |
} |
1180 |
} catch (RuntimeException re) { |
1254 |
} catch (RuntimeException re) { |
1181 |
Exceptions.printStackTrace(re); |
1255 |
Exceptions.printStackTrace(re); |
1182 |
} |
1256 |
} |
Lines 1660-1665
Link Here
|
1660 |
} |
1734 |
} |
1661 |
} |
1735 |
} |
1662 |
return request; |
1736 |
return request; |
|
|
1737 |
} |
1738 |
|
1739 |
/** |
1740 |
* Called by {@link JavaSource#runWhenScanFinished} to find out which |
1741 |
* task is currently running. Returns true when the running task in backgroud |
1742 |
* scan otherwise returns false. The caller is expected not to call cancel on |
1743 |
* the background scanner, so this method do not reset reference and do not set |
1744 |
* cancelled flag when running task is background scan. But it sets the canceledReference |
1745 |
* to prevent java source thread to dispatch next queued task. |
1746 |
* @param request is filled by currently running task or null when there is no running task. |
1747 |
* @return true when running task is background scan |
1748 |
*/ |
1749 |
public boolean getUserTaskToCancel (JavaSource.Request[] request) { |
1750 |
assert request != null; |
1751 |
assert request.length == 1; |
1752 |
boolean result = false; |
1753 |
if (!factory.isDispatchThread(Thread.currentThread())) { |
1754 |
synchronized (this) { |
1755 |
request[0] = this.reference; |
1756 |
if (request[0] != null) { |
1757 |
result = request[0].phase == null; |
1758 |
assert this.canceledReference == null || result; |
1759 |
this.canceledReference = request[0]; |
1760 |
if (!result) { |
1761 |
this.reference = null; |
1762 |
} |
1763 |
this.canceled = result; |
1764 |
if (reportSlowTasks) { |
1765 |
cancelTime = System.currentTimeMillis(); |
1766 |
} |
1767 |
} |
1768 |
} |
1769 |
} |
1770 |
return result; |
1663 |
} |
1771 |
} |
1664 |
|
1772 |
|
1665 |
public synchronized boolean isCanceled () { |
1773 |
public synchronized boolean isCanceled () { |