Right.
I suppose I can enhance my BaseManagedServiceFactory the following way
https://gist.github.com/2786874
It will wait for a certain amount of time before interrupting the
threads, which should get rid of the deadlock in case it happens.

I think I'll put that class in the utils project so that other people
can benefit from it.

On Fri, May 25, 2012 at 10:57 AM, Felix Meschberger <[email protected]> wrote:
> 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
>



-- 
------------------------
Guillaume Nodet
------------------------
Blog: http://gnodet.blogspot.com/
------------------------
FuseSource, Integration everywhere
http://fusesource.com

Reply via email to