On Fri, Mar 20, 2015 at 7:41 PM, David Bosschaert <david.bosscha...@gmail.com> wrote: > Some more thoughts about this... > > The wait() call in the getService() method is as follows: > > synchronized (this) > { > // First make sure that no existing operation is currently > // being performed by another thread on the service registration. > for (Object o = m_lockedRegsMap.get(reg); (o != null); o = > m_lockedRegsMap.get(reg)) > { > // We don't allow cycles when we call out to the > service factory. > if (o.equals(Thread.currentThread())) > { > throw new ServiceException( > "ServiceFactory.getService() resulted in a cycle.", > ServiceException.FACTORY_ERROR, > null); > } > > // Otherwise, wait for it to be freed. > try > { > wait(); > } > catch (InterruptedException ex) > { > Thread.currentThread().interrupt(); > } > } >
Resetting the interrupt flag on a thread after it has been interrupted is a usual practice and it allows the thread pool managing said thread to to see that a cancellation has been requested. So IMO the interrupt call should remain. However, the code should also break out of the loop, as an interrupt invariably is a request to stop the thread's execution. IMO the code should end up looking something like try { wait(); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); break; } Robert > I'm wondering why the code doesn't break out of the loop in the catch block? > > Cheers, > > David > > On 20 March 2015 at 12:16, David Bosschaert <david.bosscha...@gmail.com> > wrote: >> Hi all, >> >> I'm looking at an issue that I'm experiencing (with Felix 4.6.1/Java >> 7) where the ServiceRegsitry.getService() [1] method seems to be in an >> endless loop. It doesn't happen very often, but when it does happen >> the thread executing getService() seems to never exit that method >> apparently switch between the following two states: >> >> 1: Thread 22059: (state = IN_VM) >> - java.lang.Object.wait(long) @bci=0 (Compiled frame; information may >> be imprecise) >> - java.lang.Object.wait() @bci=2, line=503 (Compiled frame) >> - >> org.apache.felix.framework.ServiceRegistry.getService(org.osgi.framework.Bundle, >> org.osgi.framework.ServiceReference, boolean) @bci=86, line=313 >> (Compiled frame) >> >> 2: Thread 22059: (state = IN_VM) >> - java.lang.Throwable.fillInStackTrace(int) @bci=0 (Compiled frame; >> information may be imprecise) >> - java.lang.Throwable.fillInStackTrace() @bci=16, line=783 (Compiled frame) >> - java.lang.Throwable.<init>() @bci=24, line=250 (Compiled frame) >> - java.lang.Exception.<init>() @bci=1, line=54 (Compiled frame) >> - java.lang.InterruptedException.<init>() @bci=1, line=57 (Compiled frame) >> - java.lang.Object.wait(long) @bci=0 (Compiled frame) >> - java.lang.Object.wait() @bci=2, line=503 (Compiled frame) >> - >> org.apache.felix.framework.ServiceRegistry.getService(org.osgi.framework.Bundle, >> org.osgi.framework.ServiceReference, boolean) @bci=86, line=313 >> (Compiled frame) >> >> Even though the thread is executing wait() all of the other Felix >> SR-accessing threads are blocked on the Service Registry lock. The net >> effect is that any operation on the Service Registry is blocked. >> There is one thing that I don't understand and that is that in the >> above frames the lock should really be released, as the code is in >> wait(). However, it seems like the lock is still held because none of >> the other threads are getting access to the Service Registry. For >> example another such thread is the following which is actually about >> to decrease the usage count on the service and then call notifyAll(): >> >> Thread 48643: (state = BLOCKED) >> - >> org.apache.felix.framework.ServiceRegistry.getService(org.osgi.framework.Bundle, >> org.osgi.framework.ServiceReference, boolean) @bci=241, line=367 >> (Compiled frame) >> - >> org.apache.felix.framework.util.EventDispatcher.filterListenersUsingHooks(org.osgi.framework.ServiceEvent, >> org.osgi.framework.launch.Framework, java.util.Map) @bci=349, line=618 >> (Compiled frame) >> - >> org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(org.osgi.framework.ServiceEvent, >> java.util.Dictionary, org.osgi.framework.launch.Framework) @bci=33, >> line=542 (Interpreted frame) >> - >> org.apache.felix.framework.Felix.fireServiceEvent(org.osgi.framework.ServiceEvent, >> java.util.Dictionary) @bci=7, line=4547 (Compiled frame) >> - >> org.apache.felix.framework.Felix.access$000(org.apache.felix.framework.Felix, >> org.osgi.framework.ServiceEvent, java.util.Dictionary) @bci=3, >> line=106 (Compiled frame) >> - >> org.apache.felix.framework.Felix$1.serviceChanged(org.osgi.framework.ServiceEvent, >> java.util.Dictionary) @bci=6, line=436 (Compiled frame) >> - >> org.apache.felix.framework.ServiceRegistry.unregisterService(org.osgi.framework.Bundle, >> org.osgi.framework.ServiceRegistration) @bci=100, line=165 (Compiled >> frame) >> - org.apache.felix.framework.ServiceRegistrationImpl.unregister() >> @bci=52, line=140 (Interpreted frame) >> >> I just don't understand why all the other threads are blocked on the >> service registry. I'm probably missing something simple, so would be >> grateful if someone else has an idea. >> >> Many thanks, >> >> David >> >> [1] >> http://svn.apache.org/repos/asf/felix/releases/org.apache.felix.framework-4.6.1/src/main/java/org/apache/felix/framework/ServiceRegistry.java