[ 
https://issues.apache.org/jira/browse/FELIX-3644?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13456376#comment-13456376
 ] 

Zhou commented on FELIX-3644:
-----------------------------

It seems Spring DM's use of a separate thread to handle bundle event is causing 
acquireGlobalLock to be a problem. from felix source code, Global lock is not 
possible to be acquired again in a separate thread. After making Spring DM 
handle event in the same thread, the problem disappears. I haven't evaluated 
the impact of a synchronous shutdown of application context, but I feel it is 
currently the right way to go until Felix changes its locking mechanism.

                
> Refreshing package causes contending for acquireGlobalLock()
> ------------------------------------------------------------
>
>                 Key: FELIX-3644
>                 URL: https://issues.apache.org/jira/browse/FELIX-3644
>             Project: Felix
>          Issue Type: Bug
>          Components: Framework
>    Affects Versions: framework-4.0.3
>         Environment: JRE 1.6.0_21-b06, Win7
>            Reporter: Zhou
>
> I am experiencing a situation contending for acquireGlobalLock(). 
> Consider two user bundles A and B in this scenario. B depends on some class 
> from A. When I uninstall bundle A (via fileinstall), it triggers a package 
> refresh. Since B depends on A, the refresh action leads to stop B. B uses 
> Sping DM, so it tries to close its application context and to unregister the 
> service instance exposed. At this moment, the framework needs to notify 
> service listeners of the service changes. A resolve action is then started 
> when the service listener's bundle has dynamic-import specified, in my case, 
> the EventAdmin bundle (v1.2.14). Spring dm then will not be able to finish 
> unregistering the service as the "resolve" will block in acquiring the global 
> Lock. This deadlock will not break until the framework times out on the sync 
> handling of bundle stopping event. 
> Although this deadlock situation is not permanent, I don't feel it's normal. 
> How to understand it? Where should we fix it? Felix, Sping DM, or EventAdmin? 
> See the related stack trace below.
> Daemon Thread [Spring DM context shutdown thread] (Suspended) 
>               Object.wait(long) line: not available [native method]   
>               Object[](Object).wait() line: 485       
>               Felix.acquireGlobalLock() line: 4944    
>               StatefulResolver.resolve(BundleRevision, String) line: 219      
>               BundleWiringImpl.searchDynamicImports(String, String, boolean) 
> line: 1539       
>               BundleWiringImpl.findClassOrResourceByDelegation(String, 
> boolean) line: 1439    
>               BundleWiringImpl.access$400(BundleWiringImpl, String, boolean) 
> line: 72 
>               
> BundleWiringImpl$BundleClassLoaderJava5(BundleWiringImpl$BundleClassLoader).loadClass(String,
>  boolean) line: 1843       
>               
> BundleWiringImpl$BundleClassLoaderJava5(ClassLoader).loadClass(String) line: 
> not available      
>               BundleWiringImpl.getClassByDelegation(String) line: 1317        
>               
> ServiceRegistrationImpl$ServiceReferenceImpl.isAssignableTo(Bundle, String) 
> line: 548   
>               Util.isServiceAssignable(Bundle, ServiceReference) line: 280    
>               EventDispatcher.invokeServiceListenerCallback(Bundle, 
> EventListener, Filter, Object, EventObject, Dictionary) line: 916 
>               EventDispatcher.fireEventImmediately(EventDispatcher, int, Map, 
> EventObject, Dictionary) line: 793      
>               EventDispatcher.fireServiceEvent(ServiceEvent, Dictionary, 
> Framework) line: 543 
>               Felix.fireServiceEvent(ServiceEvent, Dictionary) line: 4260     
>               Felix.access$000(Felix, ServiceEvent, Dictionary) line: 74      
>               Felix$1.serviceChanged(ServiceEvent, Dictionary) line: 390      
>               ServiceRegistry.unregisterService(Bundle, ServiceRegistration) 
> line: 148        
>               ServiceRegistrationImpl.unregister() line: 127  
>               OsgiServiceUtils.unregisterService(ServiceRegistration) line: 
> 41        
>               
> OsgiBundleXmlApplicationContext(AbstractOsgiBundleApplicationContext).unpublishContextAsOsgiService()
>  line: 377 
>               
> OsgiBundleXmlApplicationContext(AbstractOsgiBundleApplicationContext).doClose()
>  line: 186       
>               
> AbstractDelegatedExecutionApplicationContext.access$501(AbstractDelegatedExecutionApplicationContext)
>  line: 62  
>               AbstractDelegatedExecutionApplicationContext$2.run() line: 196  
>               PrivilegedUtils.executeWithCustomTCCL(ClassLoader, 
> UnprivilegedExecution<T>) line: 87   
>               
> OsgiBundleXmlApplicationContext(AbstractDelegatedExecutionApplicationContext).normalClose()
>  line: 192   
>               DependencyWaiterApplicationContextExecutor.close() line: 383    
>               
> OsgiBundleXmlApplicationContext(AbstractDelegatedExecutionApplicationContext).doClose()
>  line: 216       
>               
> OsgiBundleXmlApplicationContext(AbstractApplicationContext).close() line: 970 
>   
>               
> LifecycleManager.closeApplicationContext(ConfigurableOsgiBundleApplicationContext)
>  line: 328    
>               LifecycleManager.access$200(LifecycleManager, 
> ConfigurableOsgiBundleApplicationContext) line: 63        
>               LifecycleManager$2.run() line: 303      
>               RunnableTimedExecution$MonitoredRunnable.run() line: 57 
>               DelegatingTimerTask.run() line: 70      
>               TimerThread.mainLoop() line: not available [local variables 
> unavailable]        
>               TimerThread.run() line: not available [local variables 
> unavailable]     
>       
>       
>       Daemon Thread [FelixFrameworkWiring] (Suspended)        
>               Object.wait(long) line: not available [native method]   
>               Counter.waitFor(int, long) line: 162    
>               Counter.waitForZero(long) line: 138     
>               RunnableTimedExecution.execute(Runnable, long, TaskExecutor) 
> line: 102  
>               LifecycleManager.maybeCloseApplicationContextFor(Bundle) line: 
> 298      
>               
> ContextLoaderListener$ContextBundleListener.handleEvent(BundleEvent) line: 
> 220  
>               
> ContextLoaderListener$ContextBundleListener(ContextLoaderListener$BaseListener).bundleChanged(BundleEvent)
>  line: 139    
>               EventDispatcher.invokeBundleListenerCallback(Bundle, 
> EventListener, EventObject) line: 868      
>               EventDispatcher.fireEventImmediately(EventDispatcher, int, Map, 
> EventObject, Dictionary) line: 789      
>               EventDispatcher.fireBundleEvent(BundleEvent, Framework) line: 
> 514       
>               Felix.fireBundleEvent(int, Bundle) line: 4244   
>               Felix.stopBundle(BundleImpl, boolean) line: 2351        
>               Felix$RefreshHelper.stop() line: 4629   
>               Felix.refreshPackages(Collection, FrameworkListener[]) line: 
> 3951       
>               FrameworkWiringImpl.run() line: 172     
>               Thread.run() line: not available        

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to