Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Deadlock during injector initialization
Deadlock during injector initialization [message #1679046] Mon, 16 March 2015 12:50 Go to next message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1853
Registered: July 2009
Senior Member
Hi,

I'm observing a deadlock during injector initialization, which seems to
be due to the synchronization in MyDslActivator.getInjector().

Here are the relevant parts of the two deadlocked threads:

Thread 1 triggered by the builder
Scopes$1$1.get() line: 64	
InternalFactoryToProviderAdapter<T>.get(Errors, InternalContext, Dependency<?>, boolean) line: 40	
InternalInjectorCreator$1.call(InternalContext) line: 204	
InternalInjectorCreator$1.call(InternalContext) line: 198	
InjectorImpl.callInContext(ContextualCallable<T>) line: 1024	
InternalInjectorCreator.loadEagerSingletons(InjectorImpl, Stage, Errors) line: 198	
InternalInjectorCreator.injectDynamically() line: 179	
InternalInjectorCreator.build() line: 109	
Guice.createInjector(Stage, Iterable<Module>) line: 95	
Guice.createInjector(Iterable<Module>) line: 72	
Guice.createInjector(Module...) line: 62	
MyDslActivator(MyDslActivator).createInjector(String) line: 67	
MyDslActivator.createInjector(String) line: 89	
MyDslActivator.getInjector(String) line: 76	
MyDslExecutableExtensionFactory.getInjector() line: 26	
MyDslExecutableExtensionFactory(AbstractGuiceAwareExecutableExtensionFactory).create() line: 49	
ConfigurationElement.createExecutableExtension(String) line: 262	
ConfigurationElementHandle.createExecutableExtension(String) line: 55	
ResourceServiceProviderDescriptor.get(URI, String) line: 39	
ResourceServiceProviderRegistryImpl$InternalData.getServiceProvider(URI, String) line: 46	
ResourceServiceProviderRegistryImpl.getResourceServiceProvider(URI, String) line: 108	
ResourceServiceProviderRegistryImpl.getResourceServiceProvider(URI) line: 124	
UriValidator.isValid(URI, IStorage) line: 27	
Storage2UriMapperImpl.isValidUri(URI, IStorage) line: 233	
Storage2UriMapperImpl.getUri(IStorage) line: 219	
ToBeBuiltComputer.getUri(IStorage) line: 326	
ToBeBuiltComputer.updateStorage(IProgressMonitor, ToBeBuilt, IStorage) line: 268	
ToBeBuiltComputer$2.visit(IResource) line: 241	
Resource$2.visit(IResourceProxy) line: 126	
Resource$1.visitElement(ElementTree, IPathRequestor, Object) line: 85	
ElementTreeIterator.doIteration(DataTreeNode, IElementContentVisitor) line: 82	
ElementTreeIterator.doIteration(DataTreeNode, IElementContentVisitor) line: 86	
ElementTreeIterator.doIteration(DataTreeNode, IElementContentVisitor) line: 86	
ElementTreeIterator.doIteration(DataTreeNode, IElementContentVisitor) line: 86	
ElementTreeIterator.iterate(IElementContentVisitor) line: 127	
Project(Resource).accept(IResourceProxyVisitor, int, int) line: 95	
Project(Resource).accept(IResourceProxyVisitor, int) line: 52	
Project(Resource).accept(IResourceVisitor, int, int) line: 124	
Project(Resource).accept(IResourceVisitor) line: 108	
ToBeBuiltComputer.updateProject(IProject, IProgressMonitor) line: 236	
ToBeBuiltComputer.updateProjectNewResourcesOnly(IProject, IProgressMonitor) line: 205	
XtextBuilder.fullBuild(IProgressMonitor, boolean) line: 211	
XtextBuilder.build(int, Map, IProgressMonitor) line: 89	


Thread 2 triggered by initializing a view with injections
MyDslActivator.getInjector(String) line: 74	
MyDslExecutableExtensionFactory.getInjector() line: 26	
MyDslExecutableExtensionFactory(AbstractGuiceAwareExecutableExtensionFactory).create() line: 49	
ConfigurationElement.createExecutableExtension(String) line: 262	
ConfigurationElementHandle.createExecutableExtension(String) line: 55	
ElementSelectionConverter.initialize(Injector) line: 52	
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57	
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43	
Method.invoke(Object, Object...) line: 606	
SingleMethodInjector$1.invoke(Object, Object...) line: 71	
SingleMethodInjector.inject(Errors, InternalContext, Object) line: 90	
MembersInjectorImpl<T>.injectMembers(T, Errors, InternalContext, boolean) line: 110	
ConstructorInjector<T>.construct(Errors, InternalContext, Class<?>, boolean) line: 94	
ConstructorBindingImpl$Factory<T>.get(Errors, InternalContext, Dependency<?>, boolean) line: 254	
ProviderToInternalFactoryAdapter$1.call(InternalContext) line: 46	
InjectorImpl.callInContext(ContextualCallable<T>) line: 1031	
ProviderToInternalFactoryAdapter<T>.get() line: 40	
Scopes$1$1.get() line: 65	
InternalFactoryToProviderAdapter<T>.get(Errors, InternalContext, Dependency<?>, boolean) line: 40	
SingleFieldInjector.inject(Errors, InternalContext, Object) line: 53	
MembersInjectorImpl<T>.injectMembers(T, Errors, InternalContext, boolean) line: 110	
ConstructorInjector<T>.construct(Errors, InternalContext, Class<?>, boolean) line: 94	
ConstructorBindingImpl$Factory<T>.get(Errors, InternalContext, Dependency<?>, boolean) line: 254	
ProviderToInternalFactoryAdapter$1.call(InternalContext) line: 46	
InjectorImpl.callInContext(ContextualCallable<T>) line: 1031	
ProviderToInternalFactoryAdapter<T>.get() line: 40	
Scopes$1$1.get() line: 65	
InternalFactoryToProviderAdapter<T>.get(Errors, InternalContext, Dependency<?>, boolean) line: 40	
InjectorImpl$4$1.call(InternalContext) line: 978	
InjectorImpl.callInContext(ContextualCallable<T>) line: 1024	
InjectorImpl$4.get() line: 974	
InjectorImpl.getInstance(Class<T>) line: 1013	
GraphViewExecutableExtensionFactory(AbstractGuiceAwareExecutableExtensionFactory).create() line: 50	
ConfigurationElement.createExecutableExtension(String) line: 262	
ConfigurationElementHandle.createExecutableExtension(String) line: 55	
ViewDescriptor.createView() line: 63	


Contention regards

  • com.google.inject.internal.InternalInjectorCreator - owned by the view thread
  • Collections$SynchronizedMap<K,V> - which is MyDslActivator.injectors - owned by the builder thread


Has anybody seen anything like this before?

The problem started to occur after adding just one more injected action to the view.
The action itself has the same set of injected fields as other actions do, none of which caused problems before. Perhaps the risk of deadlock has always been there?

Should the (generated) method getInjector() try to first acquire the lock on InternalInjectorCreator before taking its own lock?

Stephan

Re: Deadlock during injector initialization [message #1679085 is a reply to message #1679046] Mon, 16 March 2015 13:11 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
Hi,

can you tell why GraphViewExecutableExtensionFactory triggers MyDslExecutableExtensionFactory?


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Deadlock during injector initialization [message #1679204 is a reply to message #1679085] Mon, 16 March 2015 14:11 Go to previous messageGo to next message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1853
Registered: July 2009
Senior Member
MyDsl provides an extension to an extension point in GraphView, or more correctly: I have a fragment to GraphView, which provides these extensions using MyDslExecutableExtensionFactory.

Looking at this more closely I can see that the above creates an implicit dependency cycle. I did this in an attempt to follow Jan's advice in the GraphView README. So maybe either that advice was bad or I misunderstood it in some way.

Stephan
Re: Deadlock during injector initialization [message #1679253 is a reply to message #1679204] Mon, 16 March 2015 14:37 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
hi,

shouldnt each plugin have its own ExecutableExtensionFactory + injector?


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Deadlock during injector initialization [message #1679284 is a reply to message #1679253] Mon, 16 March 2015 14:50 Go to previous messageGo to next message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1853
Registered: July 2009
Senior Member
as per Jan's hint, the fragment is only glue: it plugs the DSL into GraphView. For that reason it doesn't have it's own ExecutableExtensionFactory + injector but refers to those of the DSL.
Re: Deadlock during injector initialization [message #1688485 is a reply to message #1679284] Fri, 20 March 2015 20:16 Go to previous message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1853
Registered: July 2009
Senior Member
For posterity: I haven't observed this deadlock for some time now, which doesn't mean a whole lot, but I believe the below change in my activators did the trick:
	@SuppressWarnings("restriction")
	public Injector getInjector(String language) {
		synchronized (com.google.inject.internal.InternalInjectorCreator.class) {
			synchronized (injectors) {
				Injector injector = injectors.get(language);
				if (injector == null) {
					injectors.put(language, injector = createInjector(language));
				}
				return injector;
			}
		}
	}


I think one should never enter the inner synchronized block without owning the other lock that is necessary for successful completion of createInjector(..) -- in particular when several mechanisms for on-demand initialization are competing, like bundle activation, extension point evaluation and guice injection.
Previous Topic:Serialization issues
Next Topic:Generating Xtend code
Goto Forum:
  


Current Time: Thu Apr 25 19:58:04 GMT 2024

Powered by FUDForum. Page generated in 0.03256 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top