From d54b932d36ff93c26cbb07f5b0038ad1a991ace0 Mon Sep 17 00:00:00 2001 From: Dmitry Lomov Date: Wed, 28 Nov 2012 16:24:25 +0100 Subject: [PATCH] Stack overflow for DoWhile fixed --- .../src/com/intellij/concurrency/DoWhile.java | 6 ++- .../SameThreadExecutorWithTrampoline.java | 51 +++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 platform/core-api/src/com/intellij/concurrency/SameThreadExecutorWithTrampoline.java diff --git a/platform/core-api/src/com/intellij/concurrency/DoWhile.java b/platform/core-api/src/com/intellij/concurrency/DoWhile.java index 15560b0c87ca..ea6f3755c408 100644 --- a/platform/core-api/src/com/intellij/concurrency/DoWhile.java +++ b/platform/core-api/src/com/intellij/concurrency/DoWhile.java @@ -20,14 +20,16 @@ package com.intellij.concurrency; */ public abstract class DoWhile { private AsyncFutureResult myResult; + private SameThreadExecutorWithTrampoline myExecutor; public DoWhile() { } public AsyncFutureResult getResult() { if (myResult == null) { + myExecutor = new SameThreadExecutorWithTrampoline(); myResult = AsyncFutureFactory.getInstance().createAsyncFutureResult(); - body().addConsumer(SameThreadExecutor.INSTANCE, new MyConsumer()); + body().addConsumer(myExecutor, new MyConsumer()); } return myResult; } @@ -50,7 +52,7 @@ public abstract class DoWhile { myResult.set(true); } else { - body().addConsumer(SameThreadExecutor.INSTANCE, this); + body().addConsumer(myExecutor, this); } } } diff --git a/platform/core-api/src/com/intellij/concurrency/SameThreadExecutorWithTrampoline.java b/platform/core-api/src/com/intellij/concurrency/SameThreadExecutorWithTrampoline.java new file mode 100644 index 000000000000..e0ca2c7b28cb --- /dev/null +++ b/platform/core-api/src/com/intellij/concurrency/SameThreadExecutorWithTrampoline.java @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.concurrency; + +import com.intellij.util.containers.Queue; +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.Executor; + +/** + * Author: dmitrylomov + */ +public class SameThreadExecutorWithTrampoline implements Executor { + + private ThreadLocal> myExecutionTrampoline = new ThreadLocal>(); + + public SameThreadExecutorWithTrampoline() {} + + + @Override + public void execute(@NotNull Runnable command) { + if (myExecutionTrampoline.get() != null) { + myExecutionTrampoline.get().addLast(command); + return; + } + try { + final Queue queue = new Queue(2); + myExecutionTrampoline.set(queue); + queue.addLast(command); + while(!queue.isEmpty()) { + final Runnable runnable = queue.pullFirst(); + runnable.run(); + } + } finally { + myExecutionTrampoline.set(null); + } + } +}