mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-26 04:35:36 +00:00
Fixed: Cannot properly cancel script searching
This commit is contained in:
@@ -62,6 +62,7 @@ import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
@@ -255,14 +256,22 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
logger.log(Level.SEVERE, "Decompilation timeout", ex);
|
||||
Helper.appendTimeoutCommentAs3(writer, timeout, 0);
|
||||
return;
|
||||
} catch (CancellationException ex) {
|
||||
throw new InterruptedException();
|
||||
} catch (ExecutionException ex) {
|
||||
writer.continueMeasure();
|
||||
Exception convertException = ex;
|
||||
Throwable cause = ex.getCause();
|
||||
if (ex instanceof ExecutionException && cause instanceof Exception) {
|
||||
if (cause instanceof Exception) {
|
||||
convertException = (Exception) cause;
|
||||
}
|
||||
|
||||
if (convertException instanceof CancellationException) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
if (convertException instanceof InterruptedException) {
|
||||
throw (InterruptedException) convertException;
|
||||
}
|
||||
logger.log(Level.SEVERE, "Decompilation error", convertException);
|
||||
Helper.appendErrorComment(writer, convertException);
|
||||
return;
|
||||
|
||||
@@ -52,6 +52,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
@@ -326,9 +327,10 @@ public final class MethodBody implements Cloneable {
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
throw ex;
|
||||
} catch (CancellationException ex) {
|
||||
throw new InterruptedException();
|
||||
} catch (Exception | OutOfMemoryError | StackOverflowError ex) {
|
||||
convertException = ex;
|
||||
ex.printStackTrace();
|
||||
Throwable cause = ex.getCause();
|
||||
if (ex instanceof ExecutionException && cause instanceof Exception) {
|
||||
convertException = (Exception) cause;
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.search;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
@@ -26,8 +27,10 @@ import com.jpexs.decompiler.flash.helpers.HighlightedText;
|
||||
import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.logging.Level;
|
||||
@@ -114,7 +117,7 @@ public class ActionScriptSearch {
|
||||
swf.getFlexMainClass(ignoredClasses, ignoredNss);
|
||||
}
|
||||
|
||||
|
||||
final List<ABCSearchResult> found = Collections.synchronizedList(new ArrayList<>());
|
||||
List<ScriptPack> allpacks = swf.getAS3Packs();
|
||||
final Pattern pat = regexp
|
||||
? Pattern.compile(txt, ignoreCase ? (Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE) : 0)
|
||||
@@ -168,6 +171,9 @@ public class ActionScriptSearch {
|
||||
Future<HighlightedText> text = SWF.getCachedFuture(pack, new ScriptDecompiledListener<HighlightedText>() {
|
||||
@Override
|
||||
public void onStart() {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
return;
|
||||
}
|
||||
if (listener != null) {
|
||||
listener.onDecompile(fpos, allpacks.size(), pack.getClassPath().toString());
|
||||
}
|
||||
@@ -175,8 +181,11 @@ public class ActionScriptSearch {
|
||||
|
||||
@Override
|
||||
public void onComplete(HighlightedText result) {
|
||||
public void onComplete(HighlightedText result) {
|
||||
if (listener != null) {
|
||||
|
||||
if (!Thread.currentThread().isInterrupted()) {
|
||||
if (listener != null) {
|
||||
listener.onSearch(fpos, allpacks.size(), pack.getClassPath().toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (pat.matcher(result.text).find()) {
|
||||
@@ -193,6 +202,8 @@ public class ActionScriptSearch {
|
||||
for (Future<HighlightedText> future : futures) {
|
||||
try {
|
||||
future.get();
|
||||
} catch (CancellationException ex) {
|
||||
throw new InterruptedException();
|
||||
} catch (ExecutionException ex) {
|
||||
Logger.getLogger(ActionScriptSearch.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
@@ -205,7 +216,6 @@ public class ActionScriptSearch {
|
||||
|
||||
return found;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,12 +12,15 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.helpers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@@ -42,11 +45,16 @@ public abstract class CancellableWorker<T> implements RunnableFuture<T> {
|
||||
|
||||
private final FutureTask<T> future;
|
||||
|
||||
private static final Map<Thread, CancellableWorker> threadWorkers = Collections.synchronizedMap(new WeakHashMap<>());
|
||||
|
||||
private List<CancellableWorker> subWorkers = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
public CancellableWorker() {
|
||||
super();
|
||||
Callable<T> callable = new Callable<T>() {
|
||||
@Override
|
||||
public T call() throws Exception {
|
||||
threadWorkers.put(Thread.currentThread(), CancellableWorker.this);
|
||||
return doInBackground();
|
||||
}
|
||||
};
|
||||
@@ -73,13 +81,22 @@ public abstract class CancellableWorker<T> implements RunnableFuture<T> {
|
||||
protected void done() {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public final void execute() {
|
||||
Thread t = Thread.currentThread();
|
||||
if (threadWorkers.containsKey(t)) {
|
||||
threadWorkers.get(t).subWorkers.add(this);
|
||||
}
|
||||
onStart();
|
||||
THREAD_POOL.execute(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean cancel(boolean mayInterruptIfRunning) {
|
||||
List<CancellableWorker> sw = new ArrayList<>(subWorkers);
|
||||
for (CancellableWorker w : sw) {
|
||||
w.cancel(mayInterruptIfRunning);
|
||||
}
|
||||
boolean r = future.cancel(mayInterruptIfRunning);
|
||||
if (r) {
|
||||
workerCancelled();
|
||||
@@ -118,6 +135,10 @@ public abstract class CancellableWorker<T> implements RunnableFuture<T> {
|
||||
}
|
||||
|
||||
public static <T> T call(final Callable<T> c, long timeout, TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException {
|
||||
Thread t = Thread.currentThread();
|
||||
if (t.isInterrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
CancellableWorker<T> worker = new CancellableWorker<T>() {
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user