[ 
https://issues.apache.org/jira/browse/CONFIGURATION-390?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12759942#action_12759942
 ] 

Oliver Heger commented on CONFIGURATION-390:
--------------------------------------------

Okay, using the reloading lock for all methods that might be affected is 
certainly the way to go (I was only too lazy to do this ;-) But to be 
consistent, analogous changes should be applied to 
{{AbstractFileConfiguration}}: Here we have the same pattern that methods first 
call {{reload()}} and then do something with the data, which might already be 
invalid due to another {{reload()}} operation.

Just an idea: Would it make sense to have a method like {{syncReload(Accessor 
acc)}} in {{AbstractFileConfiguration}} like the following:

{code}
protected interface Accessor
{
    Object access(FileConfiguration config);
}

protected Object syncReload(Accessor acc)
{
    synchronized(reloadLock)
    {
        reload();
        return acc.access(this);
    }
}
{code}

Maybe this would reduce the clutter in the affected methods a bit and allow a 
more closure-oriented programming.

Now to {{CombinedConfiguration}}: AFAICT the problem lies in the 
{{getTransformedRoot()}} method of the helper class {{ConfigData}}. We have 
here the following code:

{code}
// Copy data of the root node to the new path
rootNode = ConfigurationUtils.convertToHierarchical(getConfiguration(),
    getConversionExpressionEngine()).getRootNode();
atParent.appendChildren(rootNode);
atParent.appendAttributes(rootNode);
{code}

To be save, this fragment has to be executed with the reload lock of the 
processed configuration hold. A dirty hack could be to add the 
{{getReloadLock()}} method to the {{FileConfiguration}} interface and check 
whether the configuration implements this interface:

{code}
if(getConfiguration() instanceof FileConfiguration)
{
    synchronized(((FileConfiguration) getConfiguration()).getReloadLock())
    {
        // Copy data of the root node to the new path
        ...
    }
}
{code}

However, changing the {{FileConfiguration}} interface is a binary incompatible 
change. So we might have to introduce an additional interface solely for this 
purpose.

WDYT?

> AbstractHierarchicalFileConfiguration is not thread safe
> --------------------------------------------------------
>
>                 Key: CONFIGURATION-390
>                 URL: https://issues.apache.org/jira/browse/CONFIGURATION-390
>             Project: Commons Configuration
>          Issue Type: Bug
>          Components: File reloading
>    Affects Versions: 1.6
>            Reporter: Emmanuel Bourg
>             Fix For: 1.7
>
>         Attachments: commons-configuration-390.patch, configtest.tar.gz, 
> TestSuite.txt
>
>
> AbstractHierarchicalFileConfiguration doesn't implement the same locking 
> mechanism found in AbstractFileConfiguration. The consequence is that getting 
> a property while the configuration is being reloaded by another thread can 
> return an invalid result.
> This can be demonstrated by changing testDeadlockWithReload() in 
> TestCombinedConfiguration to use an XMLConfiguration instead of a 
> PropertiesConfiguration.
> Here is a reduced test case:
> {code:java}
> public void testConcurrentGetAndReload() throws Exception
> {
>     //final FileConfiguration config = new 
> PropertiesConfiguration("test.properties");
>     final FileConfiguration config = new XMLConfiguration("test.xml");
>     config.setReloadingStrategy(new FileAlwaysReloadingStrategy());
>     assertTrue("Property not found", config.getProperty("test.short") != 
> null);
>     new Thread()
>     {
>         public void run()
>         {
>             for (int i = 0; i < 1000; i++)
>             {
>                 config.reload();
>             }
>         }
>     }.start();
>     
>     for (int i = 0; i < 1000; i++)
>     {
>         assertTrue("Property not found", config.getProperty("test.short") != 
> null); // failure here
>     }
> }
> {code}
> The test doesn't always fail. It does about 50% of the time.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to