Skip to content

Commit

Permalink
Use a custom ForkJoinWorkerThreadFactory in AsyncCompletionProposalPo…
Browse files Browse the repository at this point in the history
…pup (eclipse-platform#185)

* Use a custom ForkJoinWorkerThreadFactory in AsyncCompletionProposalPopup

CompletableFuture.supplyAsync() is using the defaultForkJoinWorkerThreadFactory. In case a SecurityManager is installed, using the defaultForkJoinWorkerThreadFactory would result in worker threads with no permissions, which leads to not content assist in the java editor.

Use a custom ForkJoinWorkerThreadFactory implementation to work around this.

See also:
eclipse-platform/eclipse.platform#294
eclipse-platform/eclipse.platform#295

* Improve comment
  • Loading branch information
Christopher-Hermann authored May 3, 2023
1 parent 4a4bc0a commit 783721b
Showing 1 changed file with 33 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
Expand All @@ -42,6 +44,7 @@
import org.eclipse.core.runtime.SafeRunner;

import org.eclipse.jface.contentassist.IContentAssistSubjectControl;
import org.eclipse.jface.util.SafeRunnable;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentEvent;
Expand Down Expand Up @@ -372,28 +375,40 @@ protected List<CompletableFuture<List<ICompletionProposal>>> buildCompletionFutu
}
List<CompletableFuture<List<ICompletionProposal>>> futures = new ArrayList<>(processors.size());
for (IContentAssistProcessor processor : processors) {
futures.add(CompletableFuture.supplyAsync(() -> {
AtomicReference<List<ICompletionProposal>> result= new AtomicReference<>();
SafeRunner.run(() -> {
ICompletionProposal[] proposals= processor.computeCompletionProposals(fViewer, invocationOffset);
if (proposals == null) {
result.set(Collections.emptyList());
} else {
result.set(Arrays.asList(proposals));
}
});
List<ICompletionProposal> proposals= result.get();
if (proposals == null) { // an error occurred during computeCompletionProposal,
// possible improvement: give user feedback by returning an error "proposal" shown
// in completion popup and providing details
return Collections.emptyList();
}
return proposals;
}));
// Use a custom ForkJoinWorkerThreadFactory, to prevent issues with a
// potential SecurityManager. Threads created by ForkJoinPool.commonPool(),
// which is used in CompletableFuture.supplyAsync(), get no permissions.
ForkJoinPool commonPool= new ForkJoinPool(ForkJoinPool.getCommonPoolParallelism(),
pool -> new ForkJoinWorkerThread(pool) {
// anonymous subclass to access protected constructor
}, null, false);
futures.add(CompletableFuture.supplyAsync(() -> this.getCompletionProposals(processor, invocationOffset), commonPool));
}
return futures;
}

private List<ICompletionProposal> getCompletionProposals(IContentAssistProcessor processor, int invocationOffset) {
AtomicReference<List<ICompletionProposal>> result= new AtomicReference<>();
SafeRunner.run(new SafeRunnable() {
@Override
public void run() throws Exception {
ICompletionProposal[] proposals= processor.computeCompletionProposals(fViewer, invocationOffset);
if (proposals == null) {
result.set(Collections.emptyList());
} else {
result.set(Arrays.asList(proposals));
}
}
});
List<ICompletionProposal> proposals= result.get();
if (proposals == null) { // an error occurred during computeCompletionProposal,
// possible improvement: give user feedback by returning an error "proposal" shown
// in completion popup and providing details
return Collections.emptyList();
}
return proposals;
}

private String getTokenContentType(int invocationOffset) throws BadLocationException {
if (fContentAssistSubjectControl != null) {
IDocument document= fContentAssistSubjectControl.getDocument();
Expand Down

0 comments on commit 783721b

Please sign in to comment.