[ 
https://issues.apache.org/jira/browse/DERBY-2861?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Dag H. Wanvik updated DERBY-2861:
---------------------------------

    Attachment: derby-2861-1.diff

It seems the TableDescriptors are only ever taken from the cache
(i.e. not read from SYSTABLES) during compile time. The problem seen
in the repro happens at compile time when threads access the same
TableDescriptor instance and use save state in referencedColumnMap.

Attaching a patch which makes the "sleep modified" repro work.  It
makes the field referencedColumnMap thread local. This should be OK
since the field is not present in SYSTABLES, so it must be transitory.
So with this patch, each new thread will experience that the field is
null when the thread first accesses it.

Quoting the comment from TableDescriptor.java:

* It contains a weak hash map keyed by the the TableDescriptor
* and the value is the actual referencedColumnMap bitmap.  So,
* each thread has a weak hash map it uses to find the appropriate
* referencedColumnMap for 'this' TableDescriptor.
*
* Since the hash map is weak, when the TableDescriptor is no
* longer referenced the hash entry can be garbage collected (it
* is the *key* of a weak hash map that is weak, not the value).

I did not add any test since I don't know how to reliably make one. 
Running regressions now.


> Thread safety issue in TableDescriptor
> --------------------------------------
>
>                 Key: DERBY-2861
>                 URL: https://issues.apache.org/jira/browse/DERBY-2861
>             Project: Derby
>          Issue Type: Bug
>          Components: SQL
>         Environment: Tested on a dual-core 3GHz Pentium machine running 
> Windows Vista Business, using JDK 1.4.2_13 and Derby trunk revision 548822.
>            Reporter: Jeff Clary
>         Attachments: derby-2861-1.diff, experiment.diff, 
> TestEmbeddedMultiThreading.java
>
>
> A NullPointerException occurs in 
> org.apache.derby.iapi.sql.dictionary.TableDescriptor.getObjectName when 
> accessing the same object on many threads (each with its own connection).  
> The attached test program starts N threads each creating and then dropping a 
> separate view against the same source view, repeated M times.  I can 
> reproduce the problem with N=100 and M=100 on my machine, but not every run.
> An instance member named referencedColumnMap is checked for null at the top 
> of the getObjectName method, but later when it is dereferenced it is null, 
> because it was set to null by another thread.  I am not sure what 
> getObjectName is used for other than error reporting.  I have considered a 
> fix of just saving the non-null reference as a method variable, to avoid the 
> later NullPointerException.   But I don't know what unintended consequences 
> this may have. 
> When the test program does show the exception, the stack trace looks like 
> this:
>  java.lang.NullPointerException
>    at 
> org.apache.derby.iapi.sql.dictionary.TableDescriptor.getObjectName(TableDescriptor.java:758)
>    at 
> org.apache.derby.impl.sql.depend.BasicDependencyManager.getPersistentProviderInfos(BasicDependencyManager.java:677)
>    at 
> org.apache.derby.impl.sql.compile.CreateViewNode.bindViewDefinition(CreateViewNode.java:287)
>    at 
> org.apache.derby.impl.sql.compile.CreateViewNode.bind(CreateViewNode.java:183)
>    at 
> org.apache.derby.impl.sql.GenericStatement.prepMinion(GenericStatement.java:345)
>    at 
> org.apache.derby.impl.sql.GenericStatement.prepare(GenericStatement.java:119)
>    at 
> org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(GenericLanguageConnectionContext.java:745)
>    at 
> org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:568)
>    at 
> org.apache.derby.impl.jdbc.EmbedStatement.execute(EmbedStatement.java:517)
>    at 
> TestEmbeddedMultiThreading.executeStatement(TestEmbeddedMultiThreading.java:109)
>    at 
> TestEmbeddedMultiThreading.access$100(TestEmbeddedMultiThreading.java:10)
>    at 
> TestEmbeddedMultiThreading$ViewCreatorDropper.run(TestEmbeddedMultiThreading.java:173)
>    at java.lang.Thread.run(Thread.java:534)
>  

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