On Mar 17, 2011, at 18:17 , Bram de Kruijff wrote: > running into deadlocks with service registration while refactorring > HttpContext mechanism for the OpenSocial stuff and I am not sure how > to deal with it. Seen it before, it has a smell but I can not pinpoint > the cause and solution... Hope you can point me in the right > direction. This is roughly/simplified what happens as far as I > understand it (stacktrace below): > > DM1 tracks service registrations of InterfaceA for ComponentX > DM2 registers a service with InterfaceA > DM1 invokes callback serviceAdded(ServiceA) on ComponentX (uses a lock) > ComponentX invokes a method on ServiceA > ServiceA registers new ServiceB with DM2, again with InterfaceA > DM2 registers a service with InterfaceA > DM1 invokes callback serviceAdded(ServiceA) on ComponentX (uses a lock) > *DEADLOCK* > > So, if you do something in a dependencycallback that thriggers (in any > kind of indirect way) another service registration that results in the > same callback and you do any kind of synchronization in the callback > your are in for trouble because everything DM does is synchronous and > framework serviceevents are as well. Fair enough I think, but how to > deal with this? > > 0. The design sucks.Never have service related side effects in > callbacks? Seems a common enough use case though..
Never ever invoke another service while holding a lock. That includes talking to the dependency manager, since it will always try to directly act on anything you declare, so many times, the thread you use to define some new service will be used to register that service, invoke callbacks of components that were listening to this service, etc. Not DM specific at all, in fact I yesterday patched a bug in the Felix whiteboard http bundle that did the same (in this case it was registering a servlet with the HttpService while holding a lock). > 1. Handle callback logic (at least the stuff that has any service > related side effects) asynchronous? Cumbersome.. Indeed, you end up launching massive amount of threads for all kinds of callbacks. > 2. Make DM do stuff asynchronous.. why is it all synchronous? I guess > you could get the same scenario with bare OSGi service listeners. It's synchronous because I don't want to start new threads or use thread pools all over the place. That would only slow things down and even if I would make things asynchronous, I can never assume everything uses DM. So in the end I think you need to be very defensive about what you do while holding a lock. In general I would say don't ever invoke something "external" to your class (especially if you cannot oversee what that external component will do). Greetings, Marcel _______________________________________________ Amdatu-developers mailing list [email protected] http://lists.amdatu.org/mailman/listinfo/amdatu-developers

