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

Felix Meschberger commented on FELIX-1044:
------------------------------------------

Closer inspection showed, that the component state handling is quite correct. 
The problem is, that the serviceAdded method must provide the invokeBindMethod 
with the component instance to call the method on, which may be null.

The reason for this is the following process setting up an immediate component:

  1 set state to ACTIVATING
  2 create instance
  3 call bind methods  (currently calling DependencyManager.bind( Object ))
  4 call the activate method
  5 set the implementation instance field
  6 etc.

What happens is, that the interesting service is being registered _after_ the 
component has become ACTIVATING (step 1) but _before_ the implementation 
instance field is set (step 5). This causes the registation to fail and the 
service to be missed.

The solution is for the bind(Object) method to keep the implementation instance 
in an internal field, which may subsequently be used by service registration 
event handling. This will cause all service registration between setting the 
component to ACTIVATING (step 1) and calling the bind(Object) method (step 3) 
to not be handled. But since the bind(Object) method calls for all services 
registered before this time, the service will be correctly picked up.

It turns out, that storing the component instance in a field of the 
DependencyManager instance can also be used as the "open" flag described in the 
initial report.

> DependencyManager may miss service registrations
> ------------------------------------------------
>
>                 Key: FELIX-1044
>                 URL: https://issues.apache.org/jira/browse/FELIX-1044
>             Project: Felix
>          Issue Type: Bug
>          Components: Declarative Services (SCR)
>    Affects Versions: scr-1.0.6
>            Reporter: Felix Meschberger
>            Assignee: Felix Meschberger
>             Fix For: scr-1.0.8
>
>
> Instances of the DependencyManager class are used to track component 
> references and to call the bind/unbind methods as appropriate.
> There are timing issues, which may cause instances of this class to miss 
> services.
> The serviceAdded method checks whether the component is active before 
> handling a service registration. Generally this works because the activation 
> of the component will call the bind() method for all dependency managers. The 
> problem arises if the service is registered _after_ the DependencyManager has 
> bound registered services but before the component is fully active (e.g. 
> while the activate() method is still running): In this case the service is 
> received but not bound because the component is activating and because the 
> dependency manager has already been called to bind to registered services, 
> the registering service is lost.
> An approach to explore is to ignore the component state when deciding on 
> whether to handle the event or not but to add a flag: The flag indicates 
> whether the DependencyManager.bind method has already been called and hence 
> future events should be handled. When the DependencyManager.unbind method is 
> called, the flag should be cleare to prevent event handling. In other words:
>    * Add boolean flag "open"
>    * Add open(Object) method to be called during activation. This binds 
> existing services and sets the "open" flag
>    * Rename undinb(Object) called during deactivation to close(Object) . This 
> unbinds all bound services and clears the "open" flag
>    * Add a check for the "open" flag to the serviceChanged method
>    * Remove the "handleEvent" method, whose functionality is replaced by the 
> "open" flag

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to