execute "mac app init" in parallel to appStarter, don't execute preloading activity as part of app initialized callback

GitOrigin-RevId: 15220b09d4226062df111b35ee034f80eb1bc62c
This commit is contained in:
Vladimir Krivosheev
2021-04-06 19:13:30 +00:00
committed by intellij-monorepo-bot
parent cb9b4388ab
commit 08b6e26a77
14 changed files with 246 additions and 236 deletions
@@ -1,11 +1,11 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.progress.util;
import com.intellij.openapi.progress.StandardProgressIndicator;
public class ProgressIndicatorBase extends AbstractProgressIndicatorExBase implements StandardProgressIndicator {
public ProgressIndicatorBase() {
this(false);
super();
}
public ProgressIndicatorBase(boolean reusable) {
@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.progress.util;
import com.intellij.openapi.Disposable;
@@ -16,12 +16,10 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.NlsContexts;
import com.intellij.openapi.util.SystemInfoRt;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.CoreAwareIconManager;
import com.intellij.ui.IconManager;
import com.intellij.util.DeprecatedMethodException;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Stack;
import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
import org.jetbrains.annotations.NonNls;
@@ -29,8 +27,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class AbstractProgressIndicatorBase extends UserDataHolderBase implements ProgressIndicator {
private static final Logger LOG = Logger.getInstance(AbstractProgressIndicatorBase.class);
@@ -43,10 +43,10 @@ public class AbstractProgressIndicatorBase extends UserDataHolderBase implements
private volatile boolean myRunning;
private volatile boolean myStopped;
private volatile boolean myIndeterminate = Registry.is("ide.progress.indeterminate.by.default", true);
private volatile boolean myIndeterminate = Boolean.parseBoolean(System.getProperty("ide.progress.indeterminate.by.default", "true"));
private volatile Runnable myMacActivity;
// false by default - do not attempt to use such a relatively heavy code on start-up
private volatile boolean myShouldStartActivity = SystemInfoRt.isMac && Registry.is("idea.mac.prevent.app.nap", false);
private volatile boolean myShouldStartActivity = SystemInfoRt.isMac && Boolean.parseBoolean(System.getProperty("idea.mac.prevent.app.nap", "true"));
private Stack<@NlsContexts.ProgressText String> myTextStack; // guarded by this
private DoubleArrayList myFractionStack; // guarded by this
@@ -88,7 +88,8 @@ public class AbstractProgressIndicatorBase extends UserDataHolderBase implements
}
}
private static final Set<Class<?>> ourReportedReuseExceptions = ContainerUtil.newConcurrentSet();
@SuppressWarnings("SSBasedInspection")
private static final Set<Class<?>> ourReportedReuseExceptions = Collections.newSetFromMap(new ConcurrentHashMap<>());
protected boolean isReuseable() {
return false;
+4
View File
@@ -1,3 +1,7 @@
# 31
* Rename `add registry keys` to `registry keys adding`.
# 30
* Add `preloading activity executing`.
@@ -38,7 +38,7 @@ class StartUpPerformanceReporter : StartupActivity, StartUpPerformanceService {
companion object {
internal val LOG = logger<StartUpMeasurer>()
internal const val VERSION = "30"
internal const val VERSION = "31"
internal fun sortItems(items: MutableList<ActivityImpl>) {
items.sortWith(Comparator { o1, o2 ->
@@ -1,4 +1,4 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.wm;
import com.intellij.util.containers.WeakList;
@@ -12,20 +12,19 @@ import java.awt.event.FocusEvent;
import java.util.List;
public final class WeakFocusStackManager {
private static final WeakFocusStackManager INSTANCE = new WeakFocusStackManager();
private final WeakList<Component> focusOwners = new WeakList<>();
private static final WeakFocusStackManager instance = new WeakFocusStackManager();
@NotNull
public static WeakFocusStackManager getInstance() {
return instance;
public static @NotNull WeakFocusStackManager getInstance() {
return INSTANCE;
}
private WeakFocusStackManager() {
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
@Override
public void eventDispatched(AWTEvent event) {
// We are interested only in FOCUS_GAINED events
// we are interested only in FOCUS_GAINED events
if (event.getID() == FocusEvent.FOCUS_GAINED) {
focusOwners.add((Component)event.getSource());
}
@@ -33,8 +32,7 @@ public final class WeakFocusStackManager {
}, AWTEvent.FOCUS_EVENT_MASK);
}
@Nullable
public Component getLastFocusedOutside(Container container) {
public @Nullable Component getLastFocusedOutside(Container container) {
List<Component> components = focusOwners.toStrongList();
for (int i = components.size() - 1; i >= 0; i--) {
if (!SwingUtilities.isDescendingFrom(components.get(i), container)) {
@@ -492,8 +492,10 @@ open class RecentProjectsManagerBase : RecentProjectsManager(), PersistentStateC
projectManager.openProject(entry.first, entry.second)
}
catch (e: Exception) {
@Suppress("SSBasedInspection")
(entry.second.frameManager as MyProjectUiFrameManager?)?.dispose()
while (iterator.hasNext()) {
@Suppress("SSBasedInspection")
(iterator.next().second.frameManager as MyProjectUiFrameManager?)?.dispose()
}
@@ -17,24 +17,19 @@ import com.intellij.openapi.components.stateStore
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.extensions.ExtensionNotApplicableException
import com.intellij.openapi.extensions.PluginDescriptor
import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl
import com.intellij.openapi.progress.EmptyProgressIndicator
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.progress.util.AbstractProgressIndicatorBase
import com.intellij.openapi.progress.util.ProgressIndicatorBase
import com.intellij.openapi.ui.DialogEarthquakeShaker
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.IconLoader
import com.intellij.openapi.util.SystemInfoRt
import com.intellij.openapi.util.SystemPropertyBean
import com.intellij.openapi.util.registry.RegistryKeyBean
import com.intellij.openapi.wm.WeakFocusStackManager
import com.intellij.openapi.wm.WindowManager
import com.intellij.serviceContainer.ComponentManagerImpl
import com.intellij.ui.AnimatedIcon
import com.intellij.ui.AppIcon
import com.intellij.ui.mac.MacOSApplicationProvider
import com.intellij.ui.mac.foundation.Foundation
import com.intellij.ui.mac.touchbar.TouchBarsManager
import com.intellij.util.TimeoutUtil
@@ -151,69 +146,89 @@ private fun startApp(app: ApplicationImpl,
plugins
}
val preloadSyncServiceFuture = initStoreFuture.thenAccept {
preloadServices(it, app, activityPrefix = "")
val appInitializedFuture = initStoreFuture.thenCompose {
val preloadSyncServiceFuture = preloadServices(it, app, activityPrefix = "")
val placeOnEventQueueActivity = initAppActivity.startChild(Activities.PLACE_ON_EVENT_QUEUE)
val loadComponentInEdtFuture = CompletableFuture.runAsync({
placeOnEventQueueActivity.end()
val indicator = if (SplashManager.SPLASH_WINDOW == null) {
null
}
else object : EmptyProgressIndicator() {
override fun setFraction(fraction: Double) {
SplashManager.SPLASH_WINDOW.showProgress(fraction)
}
}
app.loadComponents(indicator)
}, Executor(app::invokeLater))
CompletableFuture.allOf(loadComponentInEdtFuture, preloadSyncServiceFuture, StartupUtil.getServerFuture())
}
initStoreFuture.thenRunAsync({
runActivity("add registry keys") {
runActivity("registry keys adding") {
RegistryKeyBean.addKeysFromPlugins()
}
}, ForkJoinPool.commonPool())
if (!app.isHeadlessEnvironment) {
if (SystemInfoRt.isMac) {
runActivity("mac app init") {
MacOSApplicationProvider.initApplication()
}
initStoreFuture.thenRunAsync(Runnable {
// ensure that TouchBarsManager is loaded before WelcomeFrame/project
// do not wait completion - it is thread safe and not required for application start
runActivity("mac touchbar") {
if (app.isDisposed) {
return@Runnable
}
Foundation.init()
if (app.isDisposed) {
return@Runnable
}
TouchBarsManager.initialize()
if (!app.isHeadlessEnvironment && SystemInfoRt.isMac) {
initStoreFuture.thenRunAsync(Runnable {
// ensure that TouchBarsManager is loaded before WelcomeFrame/project
// do not wait completion - it is thread safe and not required for application start
runActivity("mac touchbar") {
if (app.isDisposed) {
return@Runnable
}
}, ForkJoinPool.commonPool())
}
WeakFocusStackManager.getInstance()
Foundation.init()
if (app.isDisposed) {
return@Runnable
}
TouchBarsManager.initialize()
}
}, ForkJoinPool.commonPool())
}
initStoreFuture
.thenCompose {
val placeOnEventQueueActivity = initAppActivity.startChild(Activities.PLACE_ON_EVENT_QUEUE)
val loadComponentInEdtFuture = CompletableFuture.runAsync({
placeOnEventQueueActivity.end()
appInitializedFuture
.thenComposeAsync({
val pool = ForkJoinPool.commonPool()
val indicator = if (SplashManager.SPLASH_WINDOW == null) {
null
val future = CompletableFuture.runAsync({
initAppActivity.runChild("app initialized callback") {
ForkJoinTask.invokeAll(callAppInitialized(app))
}
else object : EmptyProgressIndicator() {
override fun setFraction(fraction: Double) {
SplashManager.SPLASH_WINDOW.showProgress(fraction)
}, pool)
if (!app.isUnitTestMode && !app.isHeadlessEnvironment &&
java.lang.Boolean.parseBoolean(System.getProperty("enable.activity.preloading", "true"))) {
pool.execute { executePreloadActivities(app) }
}
pool.execute {
runActivity("create locator file") {
val locatorFile = Path.of(PathManager.getSystemPath(), ApplicationEx.LOCATOR_FILE_NAME)
try {
locatorFile.parent?.createDirectories()
Files.writeString(locatorFile, PathManager.getHomePath(), StandardCharsets.UTF_8)
}
catch (e: IOException) {
LOG.warn("Can't store a location in '$locatorFile'", e)
}
}
app.loadComponents(indicator)
}, Executor { ApplicationManager.getApplication().invokeLater(it) })
}
CompletableFuture.allOf(loadComponentInEdtFuture, preloadSyncServiceFuture, StartupUtil.getServerFuture())
}
.thenRunAsync({
initAppActivity.runChild("app initialized callback") {
ForkJoinTask.invokeAll(callAppInitialized(app))
if (!Main.isLightEdit()) {
// this functionality should be used only by plugin functionality that is used after start-up
pool.execute {
runActivity("system properties setting") {
SystemPropertyBean.initSystemProperties()
}
}
}
if (!app.isHeadlessEnvironment) {
addActivateAndWindowsCliListeners()
}
initAppActivity.end()
future
}, Executor {
// if `loadComponentInEdtFuture` is completed after `preloadSyncServiceFuture`,
// then this task will be executed in EDT, so force execution out of EDT
@@ -225,6 +240,11 @@ private fun startApp(app: ApplicationImpl,
}
})
.thenRun {
if (!app.isHeadlessEnvironment) {
addActivateAndWindowsCliListeners()
}
initAppActivity.end()
if (starter.requiredModality == ApplicationStarter.NOT_IN_EDT) {
starter.main(args)
// no need to use pool once plugins are loaded
@@ -261,8 +281,8 @@ fun preloadServices(plugins: List<IdeaPluginDescriptorImpl>,
}
}
logError(result.asyncPreloadedServices)
return logError(result.syncPreloadedServices)
logError(result.first)
return logError(result.second)
}
private fun addActivateAndWindowsCliListeners() {
@@ -398,139 +418,117 @@ private fun processProgramArguments(args: List<String>): List<String> {
return arguments
}
fun callAppInitialized(app: Application): List<RecursiveAction> {
val extensionArea = app.extensionArea as ExtensionsAreaImpl
fun callAppInitialized(app: ApplicationImpl): List<ForkJoinTask<*>> {
val extensionArea = app.extensionArea
val extensionPoint = extensionArea.getExtensionPoint<ApplicationInitializedListener>("com.intellij.applicationInitializedListener")
val result = ArrayList<RecursiveAction>(extensionPoint.size())
val result = ArrayList<ForkJoinTask<*>>(extensionPoint.size())
extensionPoint.processImplementations(/* shouldBeSorted = */ false) { supplier, _ ->
result.add(object : RecursiveAction() {
override fun compute() {
try {
supplier.get().componentsInitialized()
}
catch (ignore: ExtensionNotApplicableException) {
}
catch (e: Throwable) {
LOG.error(e)
}
result.add(ForkJoinTask.adapt {
try {
supplier.get().componentsInitialized()
}
catch (ignore: ExtensionNotApplicableException) {
}
catch (e: Throwable) {
LOG.error(e)
}
})
}
extensionPoint.reset()
if (!app.isUnitTestMode && !app.isHeadlessEnvironment &&
java.lang.Boolean.parseBoolean(System.getProperty("enable.activity.preloading", "true"))) {
result.add(Preloader(extensionArea))
}
// should be after scheduling all app initialized listeners (because this activity is not important)
result.add(object : RecursiveAction() {
override fun compute() {
val pool = ForkJoinPool.commonPool()
pool.execute {
runActivity("create locator file") {
val locatorFile = Path.of(PathManager.getSystemPath(), ApplicationEx.LOCATOR_FILE_NAME)
try {
locatorFile.parent?.createDirectories()
Files.writeString(locatorFile, PathManager.getHomePath(), StandardCharsets.UTF_8)
}
catch (e: IOException) {
LOG.warn("Can't store a location in '$locatorFile'", e)
}
}
}
if (!Main.isLightEdit()) {
// this functionality should be used only by plugin functionality that is used after start-up
pool.execute {
runActivity("system properties setting") {
SystemPropertyBean.initSystemProperties()
}
}
}
}
})
return result
}
private class Preloader(private val extensionArea: ExtensionsAreaImpl) : RecursiveAction() {
companion object {
@JvmStatic
private fun checkHeavyProcessRunning() {
if (HeavyProcessLatch.INSTANCE.isRunning) {
TimeoutUtil.sleep(1)
}
private fun checkHeavyProcessRunning() {
if (HeavyProcessLatch.INSTANCE.isRunning) {
TimeoutUtil.sleep(1)
}
}
private fun executePreloadActivity(activity: PreloadingActivity, descriptor: PluginDescriptor?, app: ApplicationImpl) {
checkHeavyProcessRunning()
val indicator = AbstractProgressIndicatorBase()
if (app.isDisposed) {
return
}
val isDebugEnabled = LOG.isDebugEnabled
ProgressManager.getInstance().executeProcessUnderProgress({
val measureActivity = if (descriptor == null) {
null
}
else {
StartUpMeasurer.startActivity(activity.javaClass.name, ActivityCategory.PRELOAD_ACTIVITY, descriptor.pluginId.idString)
}
@JvmStatic
private fun preload(activity: PreloadingActivity, descriptor: PluginDescriptor?) {
val indicator = ProgressIndicatorBase()
Disposer.register(ApplicationManager.getApplication()) { indicator.cancel() }
val wrappingIndicator = object : AbstractProgressIndicatorBase() {
try {
indicator.start()
activity.preload(object : AbstractProgressIndicatorBase() {
override fun checkCanceled() {
checkHeavyProcessRunning()
indicator.checkCanceled()
}
override fun isCanceled() = indicator.isCanceled
override fun isCanceled() = indicator.isCanceled || app.isDisposed
})
if (isDebugEnabled) {
LOG.debug("${activity.javaClass.name} finished")
}
}
catch (ignore: ProcessCanceledException) {
return@executeProcessUnderProgress
}
finally {
measureActivity?.end()
if (indicator.isRunning) {
indicator.stop()
}
}
}, indicator)
}
if (indicator.isCanceled) {
return
}
checkHeavyProcessRunning()
if (indicator.isCanceled) {
private fun executePreloadActivities(app: ApplicationImpl) {
val activity = StartUpMeasurer.startActivity("preloading activity executing", ActivityCategory.APP_INIT)
val list = mutableListOf<Pair<PreloadingActivity, PluginDescriptor>>()
val extensionPoint = app.extensionArea.getExtensionPoint<PreloadingActivity>("com.intellij.preloadingActivity")
extensionPoint.processImplementations(/* shouldBeSorted = */ false) { supplier, pluginDescriptor ->
val preloadingActivity: PreloadingActivity
try {
preloadingActivity = supplier.get()
}
catch (ignore: ExtensionNotApplicableException) {
return@processImplementations
}
catch (e: Throwable) {
LOG.error(e)
return@processImplementations
}
list.add(Pair(preloadingActivity, pluginDescriptor))
}
extensionPoint.reset()
if (list.isEmpty()) {
return
}
// don't execute as one long task, make sure that other more important tasks maybe executed in between
ForkJoinPool.commonPool().execute(object : Runnable {
private var index = 0
override fun run() {
if (app.isDisposed) {
return
}
val isDebugEnabled = LOG.isDebugEnabled
ProgressManager.getInstance().runProcess({
val measureActivity = if (descriptor == null) {
null
}
else {
StartUpMeasurer.startActivity(activity.javaClass.name,
ActivityCategory.PRELOAD_ACTIVITY,
descriptor.pluginId.idString)
}
try {
activity.preload(wrappingIndicator)
}
catch (ignore: ProcessCanceledException) {
return@runProcess
}
finally {
measureActivity?.end()
}
if (isDebugEnabled) {
LOG.debug("${activity.javaClass.name} finished")
}
}, indicator)
}
}
override fun compute() {
runActivity("preloading activity executing") {
val extensionPoint = extensionArea.getExtensionPoint<PreloadingActivity>("com.intellij.preloadingActivity")
extensionPoint.processImplementations(/* shouldBeSorted = */ false) { supplier, pluginDescriptor ->
val activity: PreloadingActivity
try {
activity = supplier.get()
}
catch (ignore: ExtensionNotApplicableException) {
return@processImplementations
}
catch (e: Throwable) {
LOG.error(e)
return@processImplementations
}
preload(activity, pluginDescriptor)
val item = list.get(index++)
executePreloadActivity(item.first, item.second, app)
if (index == list.size || app.isDisposed) {
activity.end()
}
else {
ForkJoinPool.commonPool().execute(this)
}
extensionPoint.reset()
}
}
})
}
@@ -40,11 +40,14 @@ import com.intellij.util.ui.accessibility.ScreenReader
import java.awt.EventQueue
import java.beans.PropertyChangeListener
import java.nio.file.Path
import java.util.concurrent.ForkJoinPool
import javax.swing.JOptionPane
open class IdeStarter : ApplicationStarter {
companion object {
@JvmStatic
private var filesToLoad: List<Path> = emptyList()
@JvmStatic
private var wizardStepProvider: CustomizeIDEWizardStepsProvider? = null
@JvmStatic
@@ -79,15 +82,9 @@ open class IdeStarter : ApplicationStarter {
val frameInitActivity = StartUpMeasurer.startMainActivity("frame initialization")
// Event queue should not be changed during initialization of application components.
// It also cannot be changed before initialization of application components because IdeEventQueue uses other
// application components. So it is proper to perform replacement only here.
// out of EDT
val windowManager = WindowManagerEx.getInstanceEx()
app.invokeLater {
runMainActivity("IdeEventQueue informing about WindowManager") {
IdeEventQueue.getInstance().setWindowManager(windowManager)
}
runMainActivity("IdeEventQueue informing about WindowManager") {
IdeEventQueue.getInstance().setWindowManager(windowManager)
}
val lifecyclePublisher = app.messageBus.syncPublisher(AppLifecycleListener.TOPIC)
@@ -222,7 +219,7 @@ private fun loadProjectFromExternalCommandLine(commandLineArgs: List<String>): P
private fun postOpenUiTasks(app: Application) {
if (SystemInfoRt.isMac) {
NonUrgentExecutor.getInstance().execute {
ForkJoinPool.commonPool().execute {
runActivity("mac touchbar on app init") {
TouchBarsManager.onApplicationInitialized()
if (TouchBarsManager.isTouchBarAvailable()) {
@@ -232,7 +229,7 @@ private fun postOpenUiTasks(app: Application) {
}
}
else if (SystemInfoRt.isXWindow && SystemInfo.isJetBrainsJvm) {
NonUrgentExecutor.getInstance().execute {
ForkJoinPool.commonPool().execute {
runActivity("input method disabling on Linux") {
disableInputMethodsIfPossible()
}
@@ -32,10 +32,12 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.ShutDownTracker;
import com.intellij.openapi.util.SystemInfoRt;
import com.intellij.openapi.util.io.win32.IdeaWin32;
import com.intellij.openapi.wm.WeakFocusStackManager;
import com.intellij.openapi.wm.impl.X11UiUtil;
import com.intellij.ui.AppUIUtil;
import com.intellij.ui.CoreIconManager;
import com.intellij.ui.IconManager;
import com.intellij.ui.mac.MacOSApplicationProvider;
import com.intellij.ui.scale.JBUIScale;
import com.intellij.util.EnvironmentUtil;
import com.intellij.util.lang.ZipFilePool;
@@ -86,7 +88,8 @@ public final class StartupUtil {
public static BiFunction<String, String[], Integer> LISTENER = (integer, s) -> Main.ACTIVATE_NOT_INITIALIZED;
private static final String IDEA_CLASS_BEFORE_APPLICATION_PROPERTY = "idea.class.before.app";
private static final String USE_SEPARATE_WRITE_THREAD_PROPERTY = "idea.use.separate.write.thread"; // see `ApplicationImpl#USE_SEPARATE_WRITE_THREAD`
// see `ApplicationImpl#USE_SEPARATE_WRITE_THREAD`
private static final String USE_SEPARATE_WRITE_THREAD_PROPERTY = "idea.use.separate.write.thread";
private static final String MAGIC_MAC_PATH = "/AppTranslocation/";
@@ -312,7 +315,22 @@ public final class StartupUtil {
}
prepareUiFuture.complete(null);
if (!Main.isHeadless()) {
// not important
EventQueue.invokeLater(() -> {
//noinspection ResultOfMethodCallIgnored
WeakFocusStackManager.getInstance();
});
}
});
if (!Main.isHeadless() && SystemInfoRt.isMac) {
ForkJoinPool.commonPool().execute(() -> {
Activity subActivity = StartUpMeasurer.startActivity("mac app init", ActivityCategory.APP_INIT);
MacOSApplicationProvider.initApplication();
subActivity.end();
});
}
});
startApp(Arrays.asList(args), prepareUiFuture, log, configImportNeeded, appStarterFuture, euaDocument);
}
@@ -359,7 +359,7 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
List<IdeaPluginDescriptorImpl> plugins = PluginManagerCore.getLoadedPlugins(null);
registerComponents(plugins, this, null);
ApplicationLoader.initConfigurationStore(this);
preloadServices(plugins, "", false).getSyncPreloadedServices().join();
preloadServices(plugins, "", false).getSecond().join();
loadComponents(null);
ForkJoinTask.invokeAll(ApplicationLoader.callAppInitialized(this));
}
@@ -1,10 +1,10 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.wm.impl;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.SystemInfoRt;
import com.intellij.ui.mac.MacDockDelegate;
import com.intellij.ui.win.WinDockDelegate;
import org.jetbrains.annotations.Nullable;
@@ -18,35 +18,32 @@ public final class SystemDock {
void updateRecentProjectsMenu();
}
synchronized public static void updateMenu() {
try {
if (ourDelegate != null) {
ourDelegate.updateRecentProjectsMenu();
}
}
catch (Throwable err) {
log.error(err);
}
}
private static final Logger log = Logger.getInstance(SystemDock.class);
private static final @Nullable Delegate ourDelegate;
private static final @Nullable Delegate impl;
static {
SystemDock.Delegate delegate = null;
final Application app = ApplicationManager.getApplication();
Application app = ApplicationManager.getApplication();
if (app != null && !app.isUnitTestMode()) {
if (SystemInfo.isMac) {
if (SystemInfoRt.isMac) {
delegate = MacDockDelegate.getInstance();
}
else if (SystemInfo.isWindows) {
else if (SystemInfoRt.isWindows) {
delegate = WinDockDelegate.getInstance();
}
}
ourDelegate = delegate;
impl = delegate;
}
public synchronized static void updateMenu() {
try {
if (impl != null) {
impl.updateRecentProjectsMenu();
}
}
catch (Throwable err) {
Logger.getInstance(SystemDock.class).error(err);
}
}
}
@@ -822,8 +822,8 @@ abstract class ComponentManagerImpl @JvmOverloads constructor(internal val paren
final override fun createError(error: Throwable, pluginId: PluginId): RuntimeException {
return when (val effectiveError: Throwable = if (error is InvocationTargetException) error.targetException else error) {
is ProcessCanceledException, is ExtensionNotApplicableException -> effectiveError as RuntimeException
else -> createPluginExceptionIfNeeded(effectiveError, pluginId)
is ProcessCanceledException, is ExtensionNotApplicableException, is PluginException -> effectiveError as RuntimeException
else -> PluginException(effectiveError, pluginId)
}
}
@@ -871,13 +871,10 @@ abstract class ComponentManagerImpl @JvmOverloads constructor(internal val paren
@Internal
open fun activityNamePrefix(): String? = null
data class ServicePreloadingResult(val asyncPreloadedServices: CompletableFuture<Void?>,
val syncPreloadedServices: CompletableFuture<Void?>)
@ApiStatus.Internal
fun preloadServices(plugins: List<IdeaPluginDescriptorImpl>,
activityPrefix: String,
onlyIfAwait: Boolean = false): ServicePreloadingResult {
onlyIfAwait: Boolean = false): Pair<CompletableFuture<Void?>, CompletableFuture<Void?>> {
val asyncPreloadedServices = mutableListOf<RecursiveAction>()
val syncPreloadedServices = mutableListOf<RecursiveAction>()
for (plugin in plugins) {
@@ -934,13 +931,13 @@ abstract class ComponentManagerImpl @JvmOverloads constructor(internal val paren
}
}
return ServicePreloadingResult(
asyncPreloadedServices = CompletableFuture.runAsync({
return Pair(
CompletableFuture.runAsync({
runActivity("${activityPrefix}service async preloading") {
ForkJoinTask.invokeAll(asyncPreloadedServices)
}
}, ForkJoinPool.commonPool()),
syncPreloadedServices = CompletableFuture.runAsync({
CompletableFuture.runAsync({
runActivity("${activityPrefix}service sync preloading") {
ForkJoinTask.invokeAll(syncPreloadedServices)
}
@@ -170,9 +170,6 @@ ide.hide.excluded.files.description=Do not show excluded files in Project View a
use.tty.for.external.tools=false
use.tty.for.external.tools.description=Use command line with TTY support to run 'External Tools'
idea.mac.prevent.app.nap=true
idea.mac.prevent.app.nap.description=Prevent app nap during indexing and inspection
ide.appIcon.badge=true
ide.appIcon.requestAttention=true
ide.appIcon.requestAttention.after.indexing=false
@@ -1077,7 +1074,6 @@ project.tree.structure.show.url.description=Show URL in the ProjectView nodes fo
ide.show.progress.without.status.bar=true
ide.show.progress.without.status.bar.description=Disables transparent progress indicator when status bar is switched off
ide.progress.indeterminate.by.default=true
editor.injected.highlighting.enabled=true
editor.injected.highlighting.enabled.description=Disables injected fragments highlighting (requires project reopening)
@@ -1,11 +1,10 @@
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.util.containers;
import com.intellij.reference.SoftReference;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.*;
@@ -49,10 +48,11 @@ public class UnsafeWeakList<T> extends AbstractCollection<T> {
boolean processQueue() {
boolean processed = false;
MyReference<T> reference;
//noinspection unchecked
while ((reference = (MyReference<T>)myQueue.poll()) != null) {
int index = reference.index;
if (index < myList.size() && reference == myList.get(index)) { // list may have changed while the reference was dangling in queue
// list may have changed while the reference was dangling in queue
if (index < myList.size() && reference == myList.get(index)) {
nullizeAt(index);
}
processed = true;
@@ -151,7 +151,8 @@ public class UnsafeWeakList<T> extends AbstractCollection<T> {
nextElement = null;
nextIndex = -1;
for (int i= curIndex +1; i<myList.size();i++) {
T t = SoftReference.dereference(myList.get(i));
Reference<T> ref = myList.get(i);
T t = ref == null ? null : ref.get();
if (t != null) {
nextElement = t;
nextIndex = i;
@@ -188,7 +189,8 @@ public class UnsafeWeakList<T> extends AbstractCollection<T> {
public boolean remove(@NotNull Object o) {
processQueue();
for (int i = 0; i < myList.size(); i++) {
T t = SoftReference.dereference(myList.get(i));
Reference<T> ref = myList.get(i);
T t = ref == null ? null : ref.get();
if (t != null && t.equals(o)) {
nullizeAt(i);
modCount++;
@@ -238,7 +240,7 @@ public class UnsafeWeakList<T> extends AbstractCollection<T> {
}
private static void throwNotAllowedException() {
throw new IncorrectOperationException("index/size-based operations in UnsafeWeakList are not supported because they don't make sense in the presence of weak references. Use .iterator() (which retains its elements to avoid sudden GC) instead.");
throw new UnsupportedOperationException("index/size-based operations in UnsafeWeakList are not supported because they don't make sense in the presence of weak references. Use .iterator() (which retains its elements to avoid sudden GC) instead.");
}
@Override