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

Reply via email to