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

Reply via email to