db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Dag H. Wanvik (JIRA)" <j...@apache.org>
Subject [jira] Updated: (DERBY-2861) Thread safety issue in TableDescriptor
Date Wed, 18 Jun 2008 00:42:45 GMT

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


Mime
View raw message