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

Reply via email to