Hi, Am 24.05.2012 um 18:18 schrieb Guillaume Nodet:
> ... which makes me thing that being able to register services (or at > least try) while the bundle is stopping is still wrong. > What's the use case for that ? I agree it is arguable, but the core spec states in Section 5.2.3, Registering Services : > The Framework permits bundles to register and unregister service objects > dynamically. Therefore, a bundle is permitted to register service objects at > any time during the STARTING, ACTIVE or STOPPING states. So, it must be possible. Regards Felix > > On Thu, May 24, 2012 at 6:05 PM, Guillaume Nodet <[email protected]> wrote: >> That's actually a really good idea. >> For the record, I came up with the following class >> https://gist.github.com/2782423 >> which can't prevent all deadlocks (I think there's still a small >> window of time where the service registration could be attempted while >> the bundle lock is grabbed by the framework when stopping the bundle, >> but before the factory destroy() method is called), but it's way >> better. >> Though, the mere fact I don't see a nice way to avoid the deadlock >> kinda bothers me. >> >> On Thu, May 24, 2012 at 3:58 PM, Marcel Offermans >> <[email protected]> wrote: >>> Another pattern you could use here is to have the updated method only >>> validate if the configuration it received is valid and not process it at >>> all in the updated method but delegate that to a different method. That >>> way, you can probably even prevent the creation of the objects you mention >>> in your example altogether. Of course there then has to be "something else" >>> to delegate to (like some other thread). >>> >>> Greetings, Marcel >>> >>> >>> On May 24, 2012, at 15:37 PM, Felix Meschberger wrote: >>> >>>> Hi, >>>> >>>> Am 24.05.2012 um 15:29 schrieb Guillaume Nodet: >>>> >>>>> The assumptions are right. >>>>> >>>>> Do you have any pointer to a well written ManagedServiceFactory that >>>>> can make sure calls to updates are finished before destroying the >>>>> ManagedServiceFactory without any synchronized blocks ? >>>> >>>> Not, off the top of my head. >>>> >>>> I think it is not possible to fully synchronized (ok you could Java 5 >>>> locks which may time out, but after a timeout there is no guarantee, >>>> either). >>>> >>>> I think the best thing that can be done, is that shutting down a >>>> ManagedServiceFactory must just be made lenient. >>>> >>>> For example, consider a MSF.updated method creates some object and adds it >>>> to a table in the MSF class. When stopping the MSF you start by setting a >>>> "stopped" flag and then cleanup all objects in the table. In the updated >>>> method you check the stopped flag on entry and only add the generated >>>> object to the table at the very end of updated after an additional check >>>> for the stopped flag. If the flag is set at that point in time, cleanup >>>> the object just created instead of adding it to the table. >>>> >>>> Usually, I do work with such a "stopped" flag preventing further >>>> concurrent operation. >>>> >>>> Regards >>>> Felix >>>> >>>>> >>>>> On Thu, May 24, 2012 at 3:20 PM, Felix Meschberger <[email protected]> >>>>> wrote: >>>>>> Hi, >>>>>> >>>>>> >>>>>> Am 24.05.2012 um 12:09 schrieb Guillaume Nodet: >>>>>> >>>>>>> I have the following deadlock that sometimes happen: >>>>>>> >>>>>>> Thread 1: >>>>>> >>>>>>> start the bundle >>>>>>> register a ManagedServiceFactory >>>>>> >>>>>> Assumption: Thread 1 has finished processing when Thread 2 and 3 start >>>>>> with their processing >>>>>> >>>>>>> >>>>>>> Thread 2: >>>>>>> stop the bundle >>>>>> >>>>>> Assumption: This followin code runs in the BundleActivator.stop method. >>>>>> >>>>>>> grab the bundle lock >>>>>>> try to destroy the ManagedServiceFactory >>>>>>> deadlock on grabbing the ManagedServiceFactory lock >>>>>>> >>>>>>> Thread 3: >>>>>> >>>>>> Assumption: This is the CM_Update thread calling back due to Thread 1's >>>>>> service registration. >>>>>> >>>>>>> in a different thread, the ConfigAdmin will call the >>>>>>> ManagedServiceFactory#update() >>>>>>> enter synchronized block in the ManagedServiceFactory >>>>>>> register a service >>>>>>> try to grab the bundle lock >>>>>>> >>>>>>> >>>>>>> I don't think the problem comes from my ManagedServiceFactory, as it >>>>>>> has to be synchronized in order for the destruction of the >>>>>>> ManagedServiceFactory to make sure we destroy all the previously >>>>>>> created services. >>>>>> >>>>>> I disagree. >>>>>> >>>>>> I think you are violating the recommendations in section 4.7.3, >>>>>> Synchronization Pitfalls, in the Core Spec. >>>>>> >>>>>> Regards >>>>>> Felix >>>>>> >>>>>>> >>>>>>> It seems to me that the problem comes from FELIX-3082 which allows the >>>>>>> registration of services while the bundle is stopping. >>>>>>> I think if we remove that bit, the third thread will reject the >>>>>>> service registration, exit the ManagedServiceFactory#update() and >>>>>>> release the ManagedServiceFactory lock. >>>>>>> >>>>>>> I'll give it a try, but thoughts are welcomed. >>>>>>> >>>>>>> -- >>>>>>> ------------------------ >>>>>>> Guillaume Nodet >>>>>>> ------------------------ >>>>>>> Blog: http://gnodet.blogspot.com/ >>>>>>> ------------------------ >>>>>>> FuseSource, Integration everywhere >>>>>>> http://fusesource.com >>>>>> >>>>> >>>>> >>>>> >>>>> -- >>>>> ------------------------ >>>>> Guillaume Nodet >>>>> ------------------------ >>>>> Blog: http://gnodet.blogspot.com/ >>>>> ------------------------ >>>>> FuseSource, Integration everywhere >>>>> http://fusesource.com >>>> >>>> >>>> >>> >> >> >> >> -- >> ------------------------ >> Guillaume Nodet >> ------------------------ >> Blog: http://gnodet.blogspot.com/ >> ------------------------ >> FuseSource, Integration everywhere >> http://fusesource.com > > > > -- > ------------------------ > Guillaume Nodet > ------------------------ > Blog: http://gnodet.blogspot.com/ > ------------------------ > FuseSource, Integration everywhere > http://fusesource.com
