summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2010-09-30 16:45:24 +0100
committerCaolán McNamara <caolanm@redhat.com>2010-09-30 16:45:24 +0100
commitc0aaf73d6d561c092b4488affe4da5deacfe7531 (patch)
treee51051581a741f75ef7eca61927bf604d2d16f2f
parent653d2ad012009aff08d8a2939a694411f9821700 (diff)
libsane leaks and threading crashes
-rw-r--r--extensions/source/scanner/scanner.cxx3
-rw-r--r--extensions/source/scanner/scanner.hxx5
-rw-r--r--extensions/source/scanner/scanunx.cxx101
-rw-r--r--extensions/source/scanner/scanwin.cxx12
4 files changed, 79 insertions, 42 deletions
diff --git a/extensions/source/scanner/scanner.cxx b/extensions/source/scanner/scanner.cxx
index 0f4e05b41..83fce0735 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 3fae6e8dc..a1179e6a6 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 f40253497..45e6e3180 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 ebdee62d3..83f7e1371 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 );
}