diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SynchronizedTask.java b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SynchronizedTask.java deleted file mode 100644 index a77454616..000000000 --- a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SynchronizedTask.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * This file is part of AndroidIDE. - * - * AndroidIDE is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AndroidIDE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with AndroidIDE. If not, see . - */ - -/* - * This file is part of AndroidIDE. - * - * AndroidIDE is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AndroidIDE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with AndroidIDE. If not, see . - */ - -package com.itsaky.androidide.lsp.java.compiler; - -import androidx.annotation.NonNull; - -import com.itsaky.androidide.lsp.java.CompilationCancellationException; -import com.itsaky.androidide.lsp.java.utils.CancelChecker; -import com.itsaky.androidide.utils.ILogger; - -import java.util.concurrent.Semaphore; -import java.util.function.Consumer; - -import kotlin.jvm.functions.Function1; - -public class SynchronizedTask { - - private static final ILogger LOG = ILogger.newInstance("SynchronizedTask"); - private volatile boolean isCompiling = false; - private final Semaphore semaphore = new Semaphore(1); - private CompileTask task; - - public void run(@NonNull Consumer taskConsumer) { - try { - semaphore.acquire(); - } catch (InterruptedException e) { - throw new CompilationCancellationException(e); - } - try { - taskConsumer.accept(this.task); - } catch (Throwable err) { - if (!CancelChecker.isCancelled(err)) { - LOG.error("An error occurred while working with compilation task", err); - } - throw err; - } finally { - semaphore.release(); - } - } - - public T get(@NonNull Function1 function) { - try { - semaphore.acquire(); - } catch (InterruptedException e) { - throw new CompilationCancellationException(e); - } - - try { - return function.invoke(this.task); - } catch (Throwable err) { - if (!CancelChecker.isCancelled(err)) { - LOG.error("An error occurred while working with compilation task", err); - } - throw err; - } finally { - semaphore.release(); - } - } - - void post(@NonNull Runnable run) { - try { - semaphore.acquire(); - } catch (InterruptedException e) { - throw new CompilationCancellationException(e); - } - - isCompiling = true; - - try { - if (this.task != null) { - this.task.close(); - } - run.run(); - } catch (Throwable err) { - if (!CancelChecker.isCancelled(err)) { - LOG.error("An error occurred", err); - } - throw err; - } finally { - semaphore.release(); - isCompiling = false; - } - } - - void setTask(CompileTask task) { - this.task = task; - } - - public synchronized boolean isBusy() { - return isCompiling || semaphore.availablePermits() == 0; - } - - /** - * FOR INTERNAL USE ONLY! - */ - public void logStats() { - LOG.warn("[SynchronizedTask] isCompiling =", isCompiling); - LOG.warn("[SynchronizedTask] queuedLength =", semaphore.getQueueLength()); - } -} diff --git a/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SynchronizedTask.kt b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SynchronizedTask.kt new file mode 100644 index 000000000..120b73c7a --- /dev/null +++ b/lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/SynchronizedTask.kt @@ -0,0 +1,135 @@ +/* + * This file is part of AndroidIDE. + * + * AndroidIDE is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AndroidIDE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with AndroidIDE. If not, see . + */ +/* + * This file is part of AndroidIDE. + * + * AndroidIDE is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AndroidIDE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with AndroidIDE. If not, see . + */ +package com.itsaky.androidide.lsp.java.compiler + +import com.itsaky.androidide.lsp.java.CompilationCancellationException +import com.itsaky.androidide.lsp.java.utils.CancelChecker.Companion.isCancelled +import com.itsaky.androidide.utils.ILogger +import java.util.concurrent.Semaphore + +class SynchronizedTask { + + @Volatile + @PublishedApi + internal var isCompiling = false + + @PublishedApi + internal val semaphore = Semaphore(1) + + @PublishedApi + internal var task: CompileTask? = null + private set + + inline fun run(crossinline taskConsumer: (CompileTask) -> Unit) { + try { + semaphore.acquire() + } catch (e: InterruptedException) { + throw CompilationCancellationException(e) + } + try { + taskConsumer(task!!) + } catch (err: Throwable) { + if (!isCancelled(err)) { + log.error("An error occurred while working with compilation task", err) + } + throw err + } finally { + semaphore.release() + } + } + + inline fun get(crossinline action: (CompileTask) -> T): T { + try { + semaphore.acquire() + } catch (e: InterruptedException) { + throw CompilationCancellationException(e) + } + return try { + action(task!!) + } catch (err: Throwable) { + if (!isCancelled(err)) { + log.error("An error occurred while working with compilation task", err) + } + throw err + } finally { + semaphore.release() + } + } + + fun post(action: Runnable) = post { action.run() } + + inline fun post(action: () -> Unit) { + try { + semaphore.acquire() + } catch (e: InterruptedException) { + throw CompilationCancellationException(e) + } + isCompiling = true + try { + if (task != null) { + task!!.close() + } + action() + } catch (err: Throwable) { + if (!isCancelled(err)) { + log.error("An error occurred", err) + } + throw err + } finally { + semaphore.release() + isCompiling = false + } + } + + fun setTask(task: CompileTask?) { + this.task = task + } + + @get:Synchronized + val isBusy: Boolean + get() = isCompiling || semaphore.availablePermits() == 0 + + /** + * **FOR INTERNAL USE ONLY!** + */ + fun logStats() { + log.warn("[SynchronizedTask] isCompiling =", isCompiling) + log.warn("[SynchronizedTask] queuedLength =", semaphore.queueLength) + } + + companion object { + + @PublishedApi + internal val log: ILogger = ILogger.newInstance("SynchronizedTask") + } +} \ No newline at end of file