We found another DS deadlock with the current locking concurrency solution.

When we start, B is registered (its dependencies are optional) but not yet 
created (it's delayed)

Thread 1 creates and registers D so service registration and bind attempts 
propagate right to left <<<<<< starting with D.  Thread 1 obtains the lock on C 
and tries to get the lock on B

     A  ---- 1..1 -----> B -------0..n -------> C  --------- 1..1 ------->D
immediate         delayed                 delayed                       not a 
ds service

Thread 2 going left to right >>>>>>> creates A which calls getService on B 
(obtaining the B lock) which calls getService on C which is locked by thread 1.

I'm considering two possible approaches:

1. dont lock or don't lock as much for events that don't change the state (the 
C to B service event: B can't change state as a result)

2. a lock-free implementation using compare-and-set.  The idea is that an event 
such as a service event would get processed using a holder.  If at the 
completion of the processing the previous holder is the same then we'd 
compare-and-set the holder, otherwise undo whatever happened during processing.

(2) could result in multiple service registrations for a given component while 
the events are getting processed.  It's not completely obvious to me how to 
assure that all events will in fact get processed and that e.g the "winning" 
result will have all the highest-priority service references and that there 
won't be infinite update cycles.

On the other hand I have no confidence that (1) is possible to implement.  So 
I'm going to try for (2).  This is going to reopen the "how does it run on java 
< 5" debate since compare-and-set is not available there with the same 
characteristics of the java 5 implementation.

In the interests of making more code paths more consistent and similar I think 
I will change the immediate component handling to be as the spec describes, 
where the service is registered before the implementation object is created.  
This means all the services will be registered as service factories as the 
delayed components currently are.

In other DS issues:

I'd like to separate the felix specific non-spec ComponentFactory behavior 
(where it acts like a ManagedServiceFactory) into a separate class so I can 
understand the spec compliant behavior more easily.

I think that the behavior of ServiceFactory components that are configured by 
config admin is wrong.  AFAICT for service factory components we will never 
call a modify method but always destroy and recreate the instances.

I also have a few cleanup changes such as better javadoc and removing stray 
references to no-longer-present *ing transient states that I don't think will 
be controversial so I plan to just commit them.

thanks
david jencks

Reply via email to