[ooo-build-commit] .: extensions/source

Caolán McNamara caolan at kemper.freedesktop.org
Thu Sep 30 09:20:48 PDT 2010


 extensions/source/scanner/scanner.cxx |    3 -
 extensions/source/scanner/scanner.hxx |    5 +
 extensions/source/scanner/scanunx.cxx |  101 ++++++++++++++++++++++------------
 extensions/source/scanner/scanwin.cxx |   12 ++--
 4 files changed, 79 insertions(+), 42 deletions(-)

New commits:
commit c0aaf73d6d561c092b4488affe4da5deacfe7531
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Thu Sep 30 16:45:24 2010 +0100

    libsane leaks and threading crashes

diff --git a/extensions/source/scanner/scanner.cxx b/extensions/source/scanner/scanner.cxx
index 0f4e05b..83fce07 100644
--- a/extensions/source/scanner/scanner.cxx
+++ b/extensions/source/scanner/scanner.cxx
@@ -43,13 +43,14 @@ REF( XInterface ) SAL_CALL ScannerManager_CreateInstance( const REF( com::sun::s
 ScannerManager::ScannerManager() :
     mpData( NULL )
 {
+    AcquireData();
 }
 
 // -----------------------------------------------------------------------------
 
 ScannerManager::~ScannerManager()
 {
-    DestroyData();
+    ReleaseData();
 }
 
 // -----------------------------------------------------------------------------
diff --git a/extensions/source/scanner/scanner.hxx b/extensions/source/scanner/scanner.hxx
index 3fae6e8..a1179e6 100644
--- a/extensions/source/scanner/scanner.hxx
+++ b/extensions/source/scanner/scanner.hxx
@@ -73,7 +73,8 @@ protected:
     vos::OMutex								maProtector;
     void*									mpData;
 
-    void									DestroyData();
+    void									AcquireData();
+    void									ReleaseData();
 
 public:
 
@@ -105,7 +106,7 @@ public:
     void									Unlock() { maProtector.release(); }
 
     void*									GetData() const { return mpData; }
-    void									SetData( void* pData ) { DestroyData(); mpData = pData; }
+    void									SetData( void* pData ) { ReleaseData(); mpData = pData; }
 };
 
 // -----------------------------------------------------------------------------
diff --git a/extensions/source/scanner/scanunx.cxx b/extensions/source/scanner/scanunx.cxx
index f402534..45e6e31 100644
--- a/extensions/source/scanner/scanunx.cxx
+++ b/extensions/source/scanner/scanunx.cxx
@@ -31,6 +31,7 @@
 #include <sanedlg.hxx>
 #include <vos/thread.hxx>
 #include <tools/list.hxx>
+#include <boost/shared_ptr.hpp>
 
 #if OSL_DEBUG_LEVEL > 1
 #include <stdio.h>
@@ -113,12 +114,41 @@ struct SaneHolder
     vos::OMutex			m_aProtector;
     ScanError			m_nError;
     bool				m_bBusy;
+
+    SaneHolder() : m_nError(ScanError_ScanErrorNone), m_bBusy(false) {}
 };
 
-DECLARE_LIST( SaneHolderList, SaneHolder* )
+namespace
+{
+    typedef std::vector< boost::shared_ptr<SaneHolder> > sanevec;
+    class allSanes
+    {
+    private:
+        int mnRefCount;
+    public:
+        sanevec m_aSanes;
+        allSanes() : mnRefCount(0) {}
+        void acquire();
+        void release();
+    };
+
+    void allSanes::acquire()
+    {
+        ++mnRefCount;
+    }
+
+    void allSanes::release()
+    {
+        // was unused, now because of i99835: "Scanning interface not SANE API
+        // compliant" destroy all SaneHolder to get Sane Dtor called
+        --mnRefCount;
+        if (!mnRefCount)
+            m_aSanes.clear();
+    }
 
-static SaneHolderList	allSanes;
-static vos::OMutex		aSaneProtector;
+    struct theSaneProtector : public rtl::Static<vos::OMutex, theSaneProtector> {};
+    struct theSanes : public rtl::Static<allSanes, theSanes> {};
+}
 
 // -----------------
 // - ScannerThread -
@@ -126,7 +156,7 @@ static vos::OMutex		aSaneProtector;
 
 class ScannerThread : public vos::OThread
 {
-    SaneHolder*									m_pHolder;
+    boost::shared_ptr<SaneHolder>				m_pHolder;
     REF( com::sun::star::lang::XEventListener )	m_xListener;
     ScannerManager*								m_pManager; // just for the disposing call
 
@@ -134,7 +164,7 @@ public:
     virtual void run();
     virtual void onTerminated() { delete this; }
 public:
-    ScannerThread( SaneHolder* pHolder,
+    ScannerThread( boost::shared_ptr<SaneHolder> pHolder,
                    const REF( com::sun::star::lang::XEventListener )& listener,
                    ScannerManager* pManager );
     virtual ~ScannerThread();
@@ -143,7 +173,7 @@ public:
 // -----------------------------------------------------------------------------
 
 ScannerThread::ScannerThread(
-                             SaneHolder* pHolder,
+                             boost::shared_ptr<SaneHolder> pHolder,
                              const REF( com::sun::star::lang::XEventListener )& listener,
                              ScannerManager* pManager )
         : m_pHolder( pHolder ), m_xListener( listener ), m_pManager( pManager )
@@ -192,16 +222,16 @@ void ScannerThread::run()
 // - ScannerManager -
 // ------------------
 
-void ScannerManager::DestroyData()
+void ScannerManager::AcquireData()
 {
-    // was unused, now because of i99835: "Scanning interface not SANE API compliant"
-    // delete all SaneHolder to get Sane Dtor called
-    int i;
-    for ( i = allSanes.Count(); i > 0; i-- )
-    {
-        SaneHolder *pSaneHolder = allSanes.GetObject(i-1);
-        if ( pSaneHolder ) delete pSaneHolder;
-    }
+    vos::OGuard aGuard( theSaneProtector::get() );
+    theSanes::get().acquire();
+}
+
+void ScannerManager::ReleaseData()
+{
+    vos::OGuard aGuard( theSaneProtector::get() );
+    theSanes::get().release();
 }
 
 // -----------------------------------------------------------------------------
@@ -224,17 +254,14 @@ SEQ( sal_Int8 ) ScannerManager::getDIB() throw()
 
 SEQ( ScannerContext ) ScannerManager::getAvailableScanners() throw()
 {
-    vos::OGuard aGuard( aSaneProtector );
+    vos::OGuard aGuard( theSaneProtector::get() );
+    sanevec &rSanes = theSanes::get().m_aSanes;
 
-    if( ! allSanes.Count() )
+    if( rSanes.empty() )
     {
-        SaneHolder* pSaneHolder = new SaneHolder;
-        pSaneHolder->m_nError = ScanError_ScanErrorNone;
-        pSaneHolder->m_bBusy = false;
+        boost::shared_ptr<SaneHolder> pSaneHolder(new SaneHolder);
         if( Sane::IsSane() )
-            allSanes.Insert( pSaneHolder );
-        else
-            delete pSaneHolder;
+            rSanes.push_back( pSaneHolder );
     }
 
     if( Sane::IsSane() )
@@ -252,20 +279,21 @@ SEQ( ScannerContext ) ScannerManager::getAvailableScanners() throw()
 
 BOOL ScannerManager::configureScanner( ScannerContext& scanner_context ) throw( ScannerException )
 {
-    vos::OGuard aGuard( aSaneProtector );
+    vos::OGuard aGuard( theSaneProtector::get() );
+    sanevec &rSanes = theSanes::get().m_aSanes;
 
 #if OSL_DEBUG_LEVEL > 1
     fprintf( stderr, "ScannerManager::configureScanner\n" );
 #endif
 
-    if( scanner_context.InternalData < 0 || (ULONG)scanner_context.InternalData >= allSanes.Count() )
+    if( scanner_context.InternalData < 0 || (ULONG)scanner_context.InternalData >= rSanes.size() )
         throw ScannerException(
             ::rtl::OUString::createFromAscii( "Scanner does not exist" ),
             REF( XScannerManager )( this ),
             ScanError_InvalidContext
             );
 
-    SaneHolder* pHolder = allSanes.GetObject( scanner_context.InternalData );
+    boost::shared_ptr<SaneHolder> pHolder = rSanes[scanner_context.InternalData];
     if( pHolder->m_bBusy )
         throw ScannerException(
             ::rtl::OUString::createFromAscii( "Scanner is busy" ),
@@ -286,19 +314,20 @@ BOOL ScannerManager::configureScanner( ScannerContext& scanner_context ) throw(
 void ScannerManager::startScan( const ScannerContext& scanner_context,
                                 const REF( com::sun::star::lang::XEventListener )& listener ) throw( ScannerException )
 {
-    vos::OGuard aGuard( aSaneProtector );
+    vos::OGuard aGuard( theSaneProtector::get() );
+    sanevec &rSanes = theSanes::get().m_aSanes;
 
 #if OSL_DEBUG_LEVEL > 1
     fprintf( stderr, "ScannerManager::startScan\n" );
 #endif
 
-    if( scanner_context.InternalData < 0 || (ULONG)scanner_context.InternalData >= allSanes.Count() )
+    if( scanner_context.InternalData < 0 || (ULONG)scanner_context.InternalData >= rSanes.size() )
         throw ScannerException(
             ::rtl::OUString::createFromAscii( "Scanner does not exist" ),
             REF( XScannerManager )( this ),
             ScanError_InvalidContext
             );
-    SaneHolder* pHolder = allSanes.GetObject( scanner_context.InternalData );
+    boost::shared_ptr<SaneHolder> pHolder = rSanes[scanner_context.InternalData];
     if( pHolder->m_bBusy )
         throw ScannerException(
             ::rtl::OUString::createFromAscii( "Scanner is busy" ),
@@ -315,16 +344,17 @@ void ScannerManager::startScan( const ScannerContext& scanner_context,
 
 ScanError ScannerManager::getError( const ScannerContext& scanner_context ) throw( ScannerException )
 {
-    vos::OGuard aGuard( aSaneProtector );
+    vos::OGuard aGuard( theSaneProtector::get() );
+    sanevec &rSanes = theSanes::get().m_aSanes;
 
-    if( scanner_context.InternalData < 0 || (ULONG)scanner_context.InternalData >= allSanes.Count() )
+    if( scanner_context.InternalData < 0 || (ULONG)scanner_context.InternalData >= rSanes.size() )
         throw ScannerException(
             ::rtl::OUString::createFromAscii( "Scanner does not exist" ),
             REF( XScannerManager )( this ),
             ScanError_InvalidContext
             );
 
-    SaneHolder* pHolder = allSanes.GetObject( scanner_context.InternalData );
+    boost::shared_ptr<SaneHolder> pHolder = rSanes[scanner_context.InternalData];
 
     return pHolder->m_nError;
 }
@@ -333,15 +363,16 @@ ScanError ScannerManager::getError( const ScannerContext& scanner_context ) thro
 
 REF( AWT::XBitmap ) ScannerManager::getBitmap( const ScannerContext& scanner_context ) throw( ScannerException )
 {
-    vos::OGuard aGuard( aSaneProtector );
+    vos::OGuard aGuard( theSaneProtector::get() );
+    sanevec &rSanes = theSanes::get().m_aSanes;
 
-    if( scanner_context.InternalData < 0 || (ULONG)scanner_context.InternalData >= allSanes.Count() )
+    if( scanner_context.InternalData < 0 || (ULONG)scanner_context.InternalData >= rSanes.size() )
         throw ScannerException(
             ::rtl::OUString::createFromAscii( "Scanner does not exist" ),
             REF( XScannerManager )( this ),
             ScanError_InvalidContext
             );
-    SaneHolder* pHolder = allSanes.GetObject( scanner_context.InternalData );
+    boost::shared_ptr<SaneHolder> pHolder = rSanes[scanner_context.InternalData];
 
     vos::OGuard aProtGuard( pHolder->m_aProtector );
 
diff --git a/extensions/source/scanner/scanwin.cxx b/extensions/source/scanner/scanwin.cxx
index ebdee62..83f7e13 100644
--- a/extensions/source/scanner/scanwin.cxx
+++ b/extensions/source/scanner/scanwin.cxx
@@ -887,7 +887,11 @@ static Twain aTwain;
 // - ScannerManager -
 // ------------------
 
-void ScannerManager::DestroyData()
+void ScannerManager::AcquireData()
+{
+}
+
+void ScannerManager::ReleaseData()
 {
     if( mpData )
     {
@@ -979,7 +983,7 @@ SEQ( sal_Int8 ) ScannerManager::getDIB() throw()
         }
 
         GlobalUnlock( hDIB );
-        DestroyData();
+        ReleaseData();
     }
 
     return aRet;
@@ -1009,7 +1013,7 @@ BOOL SAL_CALL ScannerManager::configureScanner( ScannerContext& rContext )
     if( rContext.InternalData != 0 || rContext.ScannerName != ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TWAIN" ) ) )
         throw ScannerException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Scanner does not exist" ) ), xThis, ScanError_InvalidContext );
 
-    DestroyData();
+    ReleaseData();
 
     return aTwain.SelectSource( *this );
 }
@@ -1025,7 +1029,7 @@ void SAL_CALL ScannerManager::startScan( const ScannerContext& rContext, const u
     if( rContext.InternalData != 0 || rContext.ScannerName != ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TWAIN" ) ) )
         throw ScannerException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Scanner does not exist" ) ), xThis, ScanError_InvalidContext );
 
-    DestroyData();
+    ReleaseData();
     aTwain.PerformTransfer( *this, rxListener );
 }
 


More information about the ooo-build-commit mailing list