felix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Pierre De Rop (JIRA)" <j...@apache.org>
Subject [jira] [Resolved] (FELIX-4913) DM Optional callbacks may sometimes be invoked twice
Date Thu, 04 Jun 2015 21:09:38 GMT

     [ https://issues.apache.org/jira/browse/FELIX-4913?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel

Pierre De Rop resolved FELIX-4913.
    Resolution: Fixed

> DM Optional callbacks may sometimes be invoked twice
> ----------------------------------------------------
>                 Key: FELIX-4913
>                 URL: https://issues.apache.org/jira/browse/FELIX-4913
>             Project: Felix
>          Issue Type: Bug
>          Components: Dependency Manager
>    Affects Versions: org.apache.felix.dependencymanager-r3
>            Reporter: Pierre De Rop
>            Assignee: Pierre De Rop
>             Fix For: org.apache.felix.dependencymanager-r4
> The following use case is not currently supported by the DM state machine, which suffers
from a bug where sometimes, when the use case happens, the same optional callback may be invoked
> The following case is supported by DS, so DM should support it, regardless of the fact
that the design of this use case is arguable/questionable:
> - there is a component B
> - there is a component BFactory (registered in the OSGI registry). And BFactory.createB()
creates a B instance and simply registers it in the OSGi registry.
> - there is a A component that has two OPTIONAL dependencies:
> {code}
>   A.bind(BFactory)
>   A.bind(B b)
> {code}
> - Then A is created and is starting. Since BFactory is available, the DM state machine
> {code}
>         if (oldState == ComponentState.INSTANTIATED_AND_WAITING_FOR_REQUIRED &&
newState == ComponentState.TRACKING_OPTIONAL) {
>             invokeAutoConfigInstanceBoundDependencies();
>             invokeAddRequiredInstanceBoundDependencies();
>             invoke(m_callbackStart);
>             invokeAddOptionalDependencies();
>             registerService();
>             notifyListeners(newState);
>             return true;
>         }
> {code}
> - then, when the invokeAddOptionalDependencies() is running, it is invoking A.bind(BFactory
b). At this exact point, the A.bind(BFactory) method calls bf.createB():
> {code}
> A.bind(BFactory bf) {
>     bf.createB();
> }
> {code}
> - this has the following side effect: a B service is synchronously registered in the
OSGI service registry. So ComponentImpl.handleAdded() is called, and since we are in the
> TRACKING_OPTIONAL state (we are entering into this state), then the A.bindB(B b) callback
is invoked.
> - BUT ... we are still running in the invokeAddOptionalDependencies() method. So when
that method is about to iterate on the available services of the B dependency, then it calls
> second time the "A.bind(B)" callback.
> I have a patch for this use case, which I have extensively tested since two days.
> To preserve my soul, the patch is simple and conservative: I use the same technique that
was done in the ConfigurationDependencyImpl class: I'm using a cache of callbacks that ensures
that the same callback won't be invoked more than one time. The advantage of this patch is
that it does not make too much polutions in the state machine which is not altered too much.
> I will also commit a test case which demonstrates the issue.

This message was sent by Atlassian JIRA

View raw message