help needed: hsqldb shutdown race condition, how to fix without deadlock
Lionel Elie Mamane
lionel at mamane.lu
Wed Jun 3 05:24:25 PDT 2015
On Wed, Jun 03, 2015 at 02:19:04PM +0200, Lionel Elie Mamane wrote:
> It now probably becomes a question for Stephan. See below.
>
> On Tue, Jun 02, 2015 at 03:17:16PM +0200, Lionel Elie Mamane wrote:
> > On Tue, Jun 02, 2015 at 03:12:51PM +0200, Noel Grandin wrote:
>
> >> I would suggest something like this in ODriverDelegator::flushConnections():
>
> >> take_mutex();
> >> std::vector<Connection> tmp = m_aConnections;
> >> release_mutex();
> >> for (Connection conn : tmp)
> >> conn.flush();
>
> >> so that the mutex is not held during the problematic phase
>
> > That makes sense. Will try that. Thanks!
> But let's take it from the other side...
>
> connectivity::hsqldb::ODriverDelegator::preCommit does:
>
>
> 654 Reference<XConnection> xConnection(i->first,UNO_QUERY);
> 655 if ( xConnection.is() )
> 656 {
> 657 Reference< XStatement> xStmt = xConnection->createStatement();
> Now, this goes through a whole rigmarole:
> #6 0x00002abc1b6e90d3 in AffineBridge::v_callInto_v (this=0x2d29b50, pCallee=0x2abbf94eedbe <s_pull(va_list*)>,
> pParam=0x2abc0fd9bdb0)
> at /home/master/src/libreoffice/workdirs/libreoffice-5-1/cppu/source/AffineBridge/AffineBridge.cxx:250
(...)
> #18 0x00002abc1b8f0ccc in Proxy::dispatch (this=this at entry=0x3577660,
> pReturnTypeRef=pReturnTypeRef at entry=0x3023920, pParams=pParams at entry=0x0, nParams=nParams at entry=0,
> pMemberType=pMemberType at entry=0x3436a40, pReturn=pReturn at entry=0x2abc0fd9c2f0, pArgs=0x2abc0fd9c2e0,
> ppException=0x2abc0fd9c390)
> at /home/master/src/libreoffice/workdirs/libreoffice-5-1/cppu/source/helper/purpenv/helper_purpenv_Proxy.cxx:445
(...)
> #21 0x00002abc0f3f2a6a in cpp_vtable_call (nFunctionIndex=<optimized out>, nVtableOffset=0,
> gpreg=0x2abc0fd9c710, fpreg=0x2abc0fd9c740, ovrflw=0x2abc0fd9c790, pRegisterReturn=0x2abc0fd9c6f0)
> at /home/master/src/libreoffice/workdirs/libreoffice-5-1/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx:377
> #22 0x00002abc0f409c12 in privateSnippetExecutor ()
> from /home/master/src/libreoffice/workdirs/libreoffice-5-1/instdir/program/libgcc3_uno.so
> #23 0x00002abc1b1a9fd8 in connectivity::hsqldb::ODriverDelegator::preCommit (this=0x2d24ef0, aEvent=...)
> at /home/master/src/libreoffice/workdirs/libreoffice-5-1/connectivity/source/drivers/hsqldb/HDriver.cxx:657
> #24 0x00002abc18bb7081 in OStorage::BroadcastTransaction (this=this at entry=0x3578030,
> The problem is essentially the serializing that happens at
> AffineBridge::v_callInto_v.
> Now, I guess that the whole privateSnippetExecutor / cpp_vtable_call /
> cpp2uno_call / s_Proxy_dispatch / ... / AffineBridge::v_callInto_v for
> a C++-to-C++ call is somehow linked to the fact that the calling code
> does not know the object that implements the XConnection
> interface. Can I avoid it in some way? For example, I *know* that
> m_xConnection is a connectivity::java_sql_connection.
> If I use that fact, can I avoid going through AffineBridge::v_callInto_v ?
I tried to do that in the attached patch, but as I was explained on
IRC, because the jdbc driver is in an affine component, that does not
work.
--
Lionel
-------------- next part --------------
diff --git a/connectivity/Library_hsqldb.mk b/connectivity/Library_hsqldb.mk
index 5fd647c..b97590b 100644
--- a/connectivity/Library_hsqldb.mk
+++ b/connectivity/Library_hsqldb.mk
@@ -26,6 +26,7 @@ $(eval $(call gb_Library_use_libraries,hsqldb,\
cppu \
cppuhelper \
dbtools \
+ jdbc \
jvmfwk \
sal \
salhelper \
diff --git a/connectivity/source/drivers/hsqldb/HDriver.cxx b/connectivity/source/drivers/hsqldb/HDriver.cxx
index 87eb271..b533819 100644
--- a/connectivity/source/drivers/hsqldb/HDriver.cxx
+++ b/connectivity/source/drivers/hsqldb/HDriver.cxx
@@ -21,6 +21,7 @@
#include "hsqldb/HDriver.hxx"
#include "hsqldb/HConnection.hxx"
+#include "java/sql/Connection.hxx"
#include <osl/diagnose.h>
#include <connectivity/dbexception.hxx>
#include <com/sun/star/configuration/theDefaultProvider.hpp>
@@ -613,8 +614,14 @@ namespace connectivity
void ODriverDelegator::flushConnections()
{
- TWeakPairVector::iterator aEnd = m_aConnections.end();
- for (TWeakPairVector::iterator i = m_aConnections.begin(); aEnd != i; ++i)
+ TWeakPairVector connections;
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ connections = m_aConnections;
+ }
+
+ TWeakPairVector::const_iterator aEnd = connections.end();
+ for (TWeakPairVector::iterator i = connections.begin(); aEnd != i; ++i)
{
try
{
@@ -648,15 +655,17 @@ namespace connectivity
Reference<XConnection> xConnection(i->first,UNO_QUERY);
if ( xConnection.is() )
{
- Reference< XStatement> xStmt = xConnection->createStatement();
+ rtl::Reference<java_sql_Connection> pConnection(dynamic_cast<java_sql_Connection*>(xConnection.get()));
+ assert(pConnection.is());
+ Reference< XStatement> xStmt = pConnection->createStatement();
OSL_ENSURE( xStmt.is(), "ODriverDelegator::preCommit: no statement!" );
if ( xStmt.is() )
xStmt->execute( OUString( "SET WRITE_DELAY 0" ) );
- bool bPreviousAutoCommit = xConnection->getAutoCommit();
- xConnection->setAutoCommit( sal_False );
- xConnection->commit();
- xConnection->setAutoCommit( bPreviousAutoCommit );
+ bool bPreviousAutoCommit = pConnection->getAutoCommit();
+ pConnection->setAutoCommit( sal_False );
+ pConnection->commit();
+ pConnection->setAutoCommit( bPreviousAutoCommit );
if ( xStmt.is() )
xStmt->execute( OUString( "SET WRITE_DELAY 60" ) );
diff --git a/connectivity/source/inc/java/sql/Connection.hxx b/connectivity/source/inc/java/sql/Connection.hxx
index 47281e4..c521d95 100644
--- a/connectivity/source/inc/java/sql/Connection.hxx
+++ b/connectivity/source/inc/java/sql/Connection.hxx
@@ -37,7 +37,7 @@ namespace connectivity
typedef OMetaConnection java_sql_Connection_BASE;
- class java_sql_Connection : public java_sql_Connection_BASE,
+ class SAL_DLLPUBLIC_EXPORT java_sql_Connection : public java_sql_Connection_BASE,
public java_lang_Object,
public OSubComponent<java_sql_Connection, java_sql_Connection_BASE>,
public OAutoRetrievingBase
diff --git a/dbaccess/JunitTest_dbaccess_complex.mk b/dbaccess/JunitTest_dbaccess_complex.mk
index e3f2c00..913d7aa 100644
--- a/dbaccess/JunitTest_dbaccess_complex.mk
+++ b/dbaccess/JunitTest_dbaccess_complex.mk
@@ -25,8 +25,7 @@ $(eval $(call gb_JunitTest_set_defs,dbaccess_complex,\
))
$(eval $(call gb_JunitTest_add_classes,dbaccess_complex,\
- complex.dbaccess.Beamer \
- complex.dbaccess.PropertyBag \
+ complex.dbaccess.RowSet \
))
$(eval $(call gb_JunitTest_add_sourcefiles,dbaccess_complex,\
diff --git a/dbaccess/qa/complex/dbaccess/RowSet.java b/dbaccess/qa/complex/dbaccess/RowSet.java
index 156776a..149f77c 100644
--- a/dbaccess/qa/complex/dbaccess/RowSet.java
+++ b/dbaccess/qa/complex/dbaccess/RowSet.java
@@ -207,23 +207,31 @@ public class RowSet extends TestCase
System.out.println("testing testRowSet");
createTestCase(true);
+ System.out.println("testing testRowSet sequential");
// sequential positioning
m_resultSet.beforeFirst();
testSequentialPositining(m_resultSet, m_row);
+ System.out.println("testing testRowSet absolute");
// absolute positioning
testAbsolutePositioning(m_resultSet, m_row);
+ System.out.println("testing testRowSet modify");
// position during modify
testModifyPosition(m_resultSet, m_row);
+ System.out.println("testing testRowSet 3rd");
// 3rd test
test3(createClone(), m_resultSet);
+ System.out.println("testing testRowSet 4th");
// 4th test
test4(m_resultSet);
+ System.out.println("finished testing testRowSet 4th");
+ // System.out.println("testing testRowSet concurrent");
// concurrent (multi threaded) access to the row set and its clones
- testConcurrentAccess(m_resultSet);
+ // testConcurrentAccess(m_resultSet);
+ // System.out.println("finished testRowSet concurrent");
}
@@ -400,7 +408,7 @@ public class RowSet extends TestCase
}
- @Test
+ // @Test
public void testRowSetEvents() throws java.lang.Exception
{
System.out.println("testing RowSet Events");
@@ -756,7 +764,7 @@ public class RowSet extends TestCase
/** checks whether deletions on the main RowSet properly interfere (or don't interfere) with the movement
* on a clone of the RowSet
*/
- @Test
+ // @Test
public void testCloneMovesPlusDeletions() throws SQLException, UnknownPropertyException, WrappedTargetException
{
createTestCase(true);
@@ -825,7 +833,7 @@ public class RowSet extends TestCase
/** checks whether insertions on the main RowSet properly interfere (or don't interfere) with the movement
* on a clone of the RowSet
*/
- @Test
+ // @Test
public void testCloneMovesPlusInsertions() throws SQLException, UnknownPropertyException, WrappedTargetException, PropertyVetoException, com.sun.star.lang.IllegalArgumentException
{
createTestCase(true);
@@ -1011,7 +1019,7 @@ public class RowSet extends TestCase
/** checks the XParametersSupplier functionality of a RowSet
*/
- @Test
+ // @Test
public void testParameters()
{
createTestCase(false);
More information about the LibreOffice
mailing list