mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-04 23:39:07 +07:00
IDEA-336005 unload services by module descriptor instead of plugin id
What happened: 1. plugin X was unloaded. 2. a module U of another plugin Y was unloaded as well because it depends on module from X. 3. still loaded module L of Y was requesting the services which is a part of L. Before the change: - L services were unloaded together with U services on a step 2 because of `PluginId` as the key. After the change: - L services are intact, step 2 only unloads services of unloaded module U. GitOrigin-RevId: 455fca458a8622ef3efb8b250a5e56ac516f4084
This commit is contained in:
committed by
intellij-monorepo-bot
parent
a4f53413fd
commit
01b9d2dbc0
@@ -702,6 +702,9 @@ object DynamicPlugins {
|
||||
val app = ApplicationManager.getApplication() as ApplicationImpl
|
||||
(ActionManager.getInstance() as ActionManagerImpl).unloadActions(module)
|
||||
|
||||
if (module.pluginId.idString == "com.intellij.jsp") {
|
||||
println("Unloading")
|
||||
}
|
||||
val openedProjects = ProjectUtil.getOpenProjects().asList()
|
||||
val appExtensionArea = app.extensionArea
|
||||
val priorityUnloadListeners = mutableListOf<Runnable>()
|
||||
@@ -738,20 +741,19 @@ object DynamicPlugins {
|
||||
area.unregisterExtensionPoints(points, module)
|
||||
}
|
||||
|
||||
val pluginId = module.pluginId
|
||||
app.unloadServices(module.appContainerDescriptor.services, pluginId)
|
||||
app.unloadServices(module, module.appContainerDescriptor.services)
|
||||
val appMessageBus = app.messageBus as MessageBusEx
|
||||
module.appContainerDescriptor.listeners?.let { appMessageBus.unsubscribeLazyListeners(module, it) }
|
||||
|
||||
for (project in openedProjects) {
|
||||
(project as ComponentManagerImpl).unloadServices(module.projectContainerDescriptor.services, pluginId)
|
||||
(project as ComponentManagerImpl).unloadServices(module, module.projectContainerDescriptor.services)
|
||||
module.projectContainerDescriptor.listeners?.let {
|
||||
((project as ComponentManagerImpl).messageBus as MessageBusEx).unsubscribeLazyListeners(module, it)
|
||||
}
|
||||
|
||||
val moduleServices = module.moduleContainerDescriptor.services
|
||||
for (ideaModule in ModuleManager.getInstance(project).modules) {
|
||||
(ideaModule as ComponentManagerImpl).unloadServices(moduleServices, pluginId)
|
||||
(ideaModule as ComponentManagerImpl).unloadServices(module, moduleServices)
|
||||
createDisposeTreePredicate(module)?.let { Disposer.disposeChildren(ideaModule, it) }
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
package com.intellij.openapi.client
|
||||
|
||||
import com.intellij.codeWithMe.ClientId
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptorImpl
|
||||
import com.intellij.openapi.application.Application
|
||||
import com.intellij.openapi.components.ServiceDescriptor
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.extensions.PluginId
|
||||
import com.intellij.serviceContainer.ComponentManagerImpl
|
||||
import com.intellij.serviceContainer.PrecomputedExtensionModel
|
||||
import com.intellij.serviceContainer.throwAlreadyDisposedError
|
||||
@@ -69,12 +69,12 @@ abstract class ClientAwareComponentManager: ComponentManagerImpl {
|
||||
}
|
||||
}
|
||||
|
||||
override fun unloadServices(services: List<ServiceDescriptor>, pluginId: PluginId) {
|
||||
super.unloadServices(services, pluginId)
|
||||
override fun unloadServices(module: IdeaPluginDescriptor, services: List<ServiceDescriptor>) {
|
||||
super.unloadServices(module, services)
|
||||
|
||||
val sessionsManager = super.getService(ClientSessionsManager::class.java)!!
|
||||
for (session in sessionsManager.getSessions(ClientKind.ALL)) {
|
||||
(session as? ClientSessionImpl)?.unloadServices(services, pluginId)
|
||||
(session as? ClientSessionImpl)?.unloadServices(module, services)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,10 +17,7 @@ import com.intellij.openapi.application.*
|
||||
import com.intellij.openapi.components.*
|
||||
import com.intellij.openapi.components.ServiceDescriptor.PreloadMode
|
||||
import com.intellij.openapi.components.impl.stores.IComponentStore
|
||||
import com.intellij.openapi.diagnostic.Attachment
|
||||
import com.intellij.openapi.diagnostic.ControlFlowException
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.diagnostic.*
|
||||
import com.intellij.openapi.extensions.*
|
||||
import com.intellij.openapi.extensions.impl.ExtensionPointImpl
|
||||
import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl
|
||||
@@ -219,7 +216,7 @@ abstract class ComponentManagerImpl(
|
||||
ordered = true,
|
||||
)
|
||||
|
||||
private val pluginServices = ConcurrentHashMap<PluginId, UnregisterHandle>()
|
||||
private val pluginServices = ConcurrentHashMap<IdeaPluginDescriptor, UnregisterHandle>()
|
||||
|
||||
@Suppress("LeakingThis")
|
||||
internal val dependencyResolver = ComponentManagerResolver(this)
|
||||
@@ -914,8 +911,7 @@ abstract class ComponentManagerImpl(
|
||||
}
|
||||
val handle: UnregisterHandle? = registrar.complete()
|
||||
if (handle != null) {
|
||||
val pluginId = pluginDescriptor.pluginId
|
||||
pluginServices.put(pluginId, handle)
|
||||
pluginServices.put(pluginDescriptor, handle)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1465,9 +1461,9 @@ abstract class ComponentManagerImpl(
|
||||
return PluginException(message, error, pluginId, attachments?.map { Attachment(it.key, it.value) } ?: emptyList())
|
||||
}
|
||||
|
||||
open fun unloadServices(services: List<ServiceDescriptor>, pluginId: PluginId) {
|
||||
open fun unloadServices(module: IdeaPluginDescriptor, services: List<ServiceDescriptor>) {
|
||||
if (useInstanceContainer) {
|
||||
unloadServices2(pluginId)
|
||||
unloadServices2(module)
|
||||
return
|
||||
}
|
||||
checkState()
|
||||
@@ -1497,7 +1493,7 @@ abstract class ComponentManagerImpl(
|
||||
val iterator = componentKeyToAdapter.values.iterator()
|
||||
while (iterator.hasNext()) {
|
||||
val adapter = iterator.next() as? LightServiceComponentAdapter ?: continue
|
||||
if (adapter.pluginId == pluginId) {
|
||||
if (adapter.pluginId == module.pluginId) {
|
||||
adapter.getInitializedInstance()?.let { instance ->
|
||||
if (instance is Disposable) {
|
||||
Disposer.dispose(instance)
|
||||
@@ -1510,17 +1506,17 @@ abstract class ComponentManagerImpl(
|
||||
}
|
||||
}
|
||||
|
||||
private fun unloadServices2(pluginId: PluginId) {
|
||||
private fun unloadServices2(module: IdeaPluginDescriptor) {
|
||||
val debugString = debugString(true)
|
||||
val handle = pluginServices.get(pluginId)
|
||||
val handle = pluginServices.get(module)
|
||||
if (handle == null) {
|
||||
LOG.debug("$debugString : nothing to unload $pluginId")
|
||||
LOG.debug { "$debugString : nothing to unload ${module.pluginId}:${module.descriptorPath}" }
|
||||
return
|
||||
}
|
||||
val holders = handle.unregister()
|
||||
if (holders.isEmpty()) {
|
||||
// warn because the handle should not be in the map in the first place
|
||||
LOG.warn("$debugString : nothing unloaded for $pluginId")
|
||||
LOG.warn("$debugString : nothing unloaded for ${module.pluginId}:${module.descriptorPath}")
|
||||
return
|
||||
}
|
||||
val store = componentStore
|
||||
|
||||
Reference in New Issue
Block a user