... 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 ?
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
