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

David Jencks commented on FELIX-3456:
-------------------------------------

Just in case anyone was wondering, as I was, I checked the spec and (4.3 
section 5.3) all service events must be delivered synchronously.  Thus there is 
definitely a possibility of deadlocks if we're not careful (more careful than 
my patch).

A colleague tried a completely asynchronous model for service events in scr and 
although start seemed to work, stopping resulted in a lot of work on stopped 
bundles and component objects.  I think if we can convince ourselves that it 
conforms to the spec this is a viable approach but it will take quite a bit of 
work to identify all the cases where we're working with closed stuff.

I wonder to what extent we can remove the deadlock scenarios by
(a) avoiding the synchronized block entirely when possible.  For instance the 
first place we found this, DependencyManager.serviceAdded, I think we can skip 
the block I synchronized if the dependency is not mandatory, because if its not 
mandatory it showing up can't result in service activation.
(b) avoiding calling out, such as the bind and unbind methods, from a 
synchronized block.  This might be a wacky and non-plausible idea....  We might 
have an internal and external state.  for instance:

thread 1 supplies service A
thread 1 gets the lock and updates internal and external state to "activating"
thread 2 supplies service B and can't get the lock
thread 1 does the calculations in Unsatisfied.activate up to the point where it 
calls out to the bind methods, and then updates the internal state to "active" 
and releases the lock
thread 2 gets the lock and sees the internal state is "active" so it doesn't do 
much except release the lock
thread 1 finishes calling the bind methods and updates the external state to 
"active".

                
> Component ignores required static service addition when in Activating state
> ---------------------------------------------------------------------------
>
>                 Key: FELIX-3456
>                 URL: https://issues.apache.org/jira/browse/FELIX-3456
>             Project: Felix
>          Issue Type: Bug
>          Components: Declarative Services (SCR)
>    Affects Versions:  scr-1.6.0
>         Environment: Using org.apache.felix.scr svn rev 1298268 on Mac
>            Reporter: Richard Ellis
>            Priority: Critical
>         Attachments: FELIX-3456-1.diff
>
>
> I have a component with two required static service references (A and B). In 
> my scenario A and B are registered nearly simultaneously on different threads 
> and this causes the DependencyManager to ignore the addition of one of these 
> two services (B). This causes the component to remain unsatisfied and never 
> activate, since the service that was ignored is not re-registered at any time 
> and nothing subsequently causes the component to re-activate.
> This happens as follows:
> 12:30:59:317 Thread 1 - Registers Service B/257
> 12:30:59:320 Thread 2 - Registers Service A/258
> 12:30:59:320 Thread 2 - Dependency Manager: Adding Service A/258
> 12:30:59:321 Thread 2 - Dependency Manager: Service serviceA registered, 
> activate component
> 12:30:59:321 Thread 2 - State transition : Unsatisfied -> Activating
> 12:30:59:321 Thread 2 - Activating component
> 12:30:59:321 Thread 1 - Dependency Manager: Adding Service B/257
> 12:30:59:321 Thread 2 - Dependency not satisfied: serviceB
> 12:30:59:321 Thread 1 - Dependency Manager: Added service serviceB is ignored 
> for static reference <--- I believe we end up here because Thread 2 has moved 
> the component from Unsatisfied to Activating and the reference is a static 
> reference
> 12:30:59:321 Thread 2 - Not all dependencies satisified, cannot activate
> 12:30:59:321 Thread 2 - State transition : Activating -> Unsatisfied
> Because the addition of Service B has been ignored and serviceB is a required 
> dependency my component then never activates even though my reqiured service 
> is present.
> There is a comment in DependencyManager#serviceAdded method:
> // FELIX-1413: if the dependency is static and the component is
> // satisfied (active) added services are not considered until
> // the component is reactivated for other reasons.
> This suggests that the static service should only be ignored if the component 
> is satisfied(active), which would be correct, but in this case the component 
> is only activating (and will fail to activate because one of the two 
> dependencies is not yet satisfied) and there is no check of state at this 
> time.
> A simple fix would be to check the state of the component as well as if the 
> service is static e.g.
> replace if ( m_dependencyMetadata.isStatic() )
> with if ( m_dependencyMetadata.isStatic() && m_componentManager.getState() == 
> AbstractComponentManager.STATE_ACTIVE )
> This is an easy fix, but I guess may leave a small window where a static 
> reference could get replaced while a component was still activating if 
> another instance of the same service was registered on a different thread.
> There are other fixes that could be done by synchronizing more around service 
> additions.
> Is anyone willing to make this fix or does anyone have any thoughts about 
> this issue?
> Thanks

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to