ooo-build r12966 - in trunk: . patches/dev300



Author: jholesovsky
Date: Wed Jun 25 22:04:43 2008
New Revision: 12966
URL: http://svn.gnome.org/viewvc/ooo-build?rev=12966&view=rev

Log:
2008-06-25  Jan Holesovsky  <kendy suse cz>

        * patches/dev300/webdav-locking-refresh-lock.diff,
          patches/dev300/apply: Don't lock for infinite, instead set timeout
          to 3 minutes, and refresh 30 sec before expiration.


Added:
   trunk/patches/dev300/webdav-locking-refresh-lock.diff
Modified:
   trunk/ChangeLog
   trunk/patches/dev300/apply

Modified: trunk/patches/dev300/apply
==============================================================================
--- trunk/patches/dev300/apply	(original)
+++ trunk/patches/dev300/apply	Wed Jun 25 22:04:43 2008
@@ -15,7 +15,7 @@
 	 Icons, Branding, CalcFixes, WriterFixes, EasterEgg, \
 	 GStreamer, CWSBackports, WPG, Cleanups, WMF, GnomeVFS, \
 	 Layout, VBABits, VBAObjects, CalcErrors, Store, CJK, GCJ, Lwp, \
-	 OOXML, SVGImport, AutoCorrectCapsLock, UnitTesting, \
+	 OOXML, SVGImport, WebDAV, AutoCorrectCapsLock, UnitTesting, \
 	 CalcDataPilotDrillDown, PopupRemoval, LinkWarningDlg, RadioButtons, InternalCairo, \
 	 FedoraCommonFixes
 
@@ -326,6 +326,13 @@
 
 cws-cmcfixes47-sw.diff, i#90306
 
+[ WebDAV ]
+# don't lock for infinite, instead set timeout to 3 minutes, and refresh 30
+# sec before expiration
+# TODO file up-stream
+webdav-locking-refresh-lock.diff, n#403724, jholesov
+
+
 [ WPG ]
 # libwpg-based import filter for WordPerfect Graphics
 libwpg.diff

Added: trunk/patches/dev300/webdav-locking-refresh-lock.diff
==============================================================================
--- (empty file)
+++ trunk/patches/dev300/webdav-locking-refresh-lock.diff	Wed Jun 25 22:04:43 2008
@@ -0,0 +1,355 @@
+diff --git ucb/source/ucp/webdav/NeonInputStream.cxx ucb/source/ucp/webdav/NeonInputStream.cxx
+index 37a8580..7db7fca 100644
+--- ucb/source/ucp/webdav/NeonInputStream.cxx
++++ ucb/source/ucp/webdav/NeonInputStream.cxx
+@@ -33,6 +33,7 @@
+ #include "NeonInputStream.hxx"
+ #include "DAVResourceAccess.hxx"
+ 
++#include <osl/thread.hxx>
+ #include <rtl/memory.h>
+ 
+ #include <com/sun/star/ucb/CommandFailedException.hpp>
+@@ -46,16 +47,120 @@ using namespace com::sun::star::io;
+ using namespace com::sun::star;
+ using namespace webdav_ucp;
+ 
+-oslSignalAction NeonInputStream::UnlockOnSignal( void* pData, oslSignalInfo* )
++// Our signal - 246 is just a random number ;-)
++#define TICKER_THREAD_USER_SIGNAL ( OSL_SIGNAL_USER_RESERVED + 246 )
++
++// -------------------------------------------------------------------
++// A thread that 'ticks' - emits the user signal every second
++// -------------------------------------------------------------------
++class TickerThread : public osl::Thread
++{
++    bool m_bFinish;
++
++public:
++
++    TickerThread() : osl::Thread(), m_bFinish( false ) {}
++
++    void finish() { m_bFinish = true; }
++
++protected:
++
++    virtual void SAL_CALL run();
++};
++
++void TickerThread::run()
++{
++    // we have to go through the loop more often to be able to finish ~quickly
++    const int nNth = 25;
++
++    int nCount = nNth;
++    while ( !m_bFinish )
++    {
++        if ( nCount-- <= 0 )
++        {
++            osl_raiseSignal( TICKER_THREAD_USER_SIGNAL, NULL );
++            nCount = nNth;
++        }
++
++        TimeValue aTV;
++        aTV.Seconds = 0;
++        aTV.Nanosec = 1000000000/nNth;
++        wait( aTV );
++    }
++}
++
++// -------------------------------------------------------------------
++// A class that takes care of creating and destroying the ticker thread
++// -------------------------------------------------------------------
++class TickerThreadController
++{
++    osl::Mutex    m_aMutex;
++    int           m_nCount;
++    TickerThread *m_pTickerThread;
++
++public:
++
++    TickerThreadController() : m_nCount( 0 ), m_pTickerThread( NULL ) {}
++
++    void start();
++    void stop();
++};
++
++void TickerThreadController::start()
++{
++    osl::MutexGuard aGuard( m_aMutex );
++    
++    if ( ( m_nCount++ == 0 ) && !m_pTickerThread )
++    {
++        m_pTickerThread = new TickerThread();
++        m_pTickerThread->create();
++    }
++}
++        
++void TickerThreadController::stop()
++{
++    osl::MutexGuard aGuard( m_aMutex );
++
++    if ( ( --m_nCount == 0 ) && m_pTickerThread )
++    {
++        m_pTickerThread->finish();
++        m_pTickerThread->join();
++
++        delete m_pTickerThread;
++        m_pTickerThread = NULL;
++    }
++}
++
++// -------------------------------------------------------------------
++// Signal handlers
++// -------------------------------------------------------------------
++oslSignalAction NeonInputStream::RefreshLockOnSignal( void* pData, oslSignalInfo* pSignalInfo )
+ {
+     NeonInputStream *pStream = static_cast< NeonInputStream *>( pData );
+ 
+-    if ( pStream )
++    if ( pStream &&
++            pSignalInfo &&
++            pSignalInfo->Signal == osl_Signal_User &&
++            pSignalInfo->UserSignal == TICKER_THREAD_USER_SIGNAL )
++    {
++        pStream->RefreshLock();
++    }
++
++    return osl_Signal_ActCallNextHdl;
++}
++
++oslSignalAction NeonInputStream::UnlockOnSignal( void* pData, oslSignalInfo* pSignalInfo )
++{
++    NeonInputStream *pStream = static_cast< NeonInputStream *>( pData );
++
++    if ( pStream && ( !pSignalInfo || ( pSignalInfo && pSignalInfo->Signal != osl_Signal_User ) ) )
+         pStream->Unlock();
+ 
+     return osl_Signal_ActCallNextHdl;
+ }
+ 
++static TickerThreadController sTickerThreadController;
++
+ // -------------------------------------------------------------------
+ // Constructor
+ // -------------------------------------------------------------------
+@@ -65,10 +170,14 @@ NeonInputStream::NeonInputStream( const uno::Reference< lang::XMultiServiceFacto
+   m_nPos( 0 ),
+   m_bDirty( sal_False ),
+   m_pLock( NULL ),
++  m_nToExpire( -1 ),
+   m_xMSF( m_rMSF ),
+   m_xEnv( m_rEnv )
+ {
+-    m_pSignalHandler = osl_addSignalHandler( NeonInputStream::UnlockOnSignal, this );
++    m_pRefreshLockSignalHandler = osl_addSignalHandler( NeonInputStream::RefreshLockOnSignal, this );
++    m_pUnlockSignalHandler = osl_addSignalHandler( NeonInputStream::UnlockOnSignal, this );
++
++    sTickerThreadController.start();
+ }
+ 
+ // -------------------------------------------------------------------
+@@ -76,9 +185,12 @@ NeonInputStream::NeonInputStream( const uno::Reference< lang::XMultiServiceFacto
+ // -------------------------------------------------------------------
+ NeonInputStream::~NeonInputStream( void )
+ {
++    sTickerThreadController.stop();
++
+     Unlock();
+ 
+-    osl_removeSignalHandler( m_pSignalHandler );
++    osl_removeSignalHandler( m_pUnlockSignalHandler );
++    osl_removeSignalHandler( m_pRefreshLockSignalHandler );
+ }
+ 
+ // -------------------------------------------------------------------
+@@ -106,6 +218,9 @@ void NeonInputStream::SetLock( const com::sun::star::ucb::Lock &rLock,
+         m_pLock = new ucb::Lock( rLock );
+     else
+         *m_pLock = rLock;
++
++    if ( m_pLock )
++        m_nToExpire = m_pLock->Timeout;
+ }
+ 
+ // -------------------------------------------------------------------
+@@ -364,10 +479,40 @@ void SAL_CALL NeonInputStream::truncate( void )
+ }
+ 
+ // -------------------------------------------------------------------
++// Lock the stream again
++// -------------------------------------------------------------------
++void NeonInputStream::RefreshLock( void )
++{
++    osl::MutexGuard aGuard( m_aLock );
++
++#if OSL_DEBUG_LEVEL > 0
++    fprintf( stderr, "WebDAV: RefreshLock() - will refresh in %d sec\n", m_nToExpire - 30 );
++#endif
++
++    --m_nToExpire;
++
++    // Refresh the lock if it expires in less than 30 sec
++    if ( m_pLock && m_nToExpire >= 0 && m_nToExpire < 30 )
++    {
++        // FIXME It's really hacky to create the new session
++        // But so far it seems I have no other chance...
++        rtl::Reference< DAVSessionFactory > rDAVFactory( new DAVSessionFactory() );
++        
++        DAVResourceAccess aResourceAccess( m_xMSF, rDAVFactory, m_aURL );
++
++        aResourceAccess.LOCK( *m_pLock, m_xEnv );
++
++        m_nToExpire = m_pLock->Timeout;
++    }
++}
++
++// -------------------------------------------------------------------
+ // Unlock the stream & destroy the lock
+ // -------------------------------------------------------------------
+ void NeonInputStream::Unlock( void )
+ {
++    osl::MutexGuard aGuard( m_aLock );
++
+ #if OSL_DEBUG_LEVEL > 0
+     fprintf( stderr, "WebDAV: unlock()\n" );
+ #endif
+@@ -384,5 +529,7 @@ void NeonInputStream::Unlock( void )
+ 
+         delete m_pLock;
+         m_pLock = NULL;
++
++        m_nToExpire = -1;
+     }
+ }
+diff --git ucb/source/ucp/webdav/NeonInputStream.hxx ucb/source/ucp/webdav/NeonInputStream.hxx
+index bf8c4a7..6c713e3 100644
+--- ucb/source/ucp/webdav/NeonInputStream.hxx
++++ ucb/source/ucp/webdav/NeonInputStream.hxx
+@@ -31,6 +31,7 @@
+ #define _NEONINPUTSTREAM_HXX_
+ 
+ #include <sal/types.h>
++#include <osl/mutex.hxx>
+ #include <osl/signal.h>
+ #include <rtl/ustring.hxx>
+ #include <cppuhelper/weak.hxx>
+@@ -71,13 +72,17 @@ private:
+     sal_Bool                   m_bDirty;
+ 
+     com::sun::star::ucb::Lock *m_pLock;
++    int                        m_nToExpire;
+     rtl::OUString              m_aURL;
+ 
+-    oslSignalHandler           m_pSignalHandler;
++    oslSignalHandler           m_pRefreshLockSignalHandler;
++    oslSignalHandler           m_pUnlockSignalHandler;
+ 
+     com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xMSF;
+     com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > m_xEnv;
+ 
++    osl::Mutex                 m_aLock;
++
+ public:
+              NeonInputStream( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > &m_rMSF,
+                               const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment > &m_rEnv );
+@@ -183,9 +188,15 @@ public:
+     
+ protected:
+ 
++    // Refresh the lock on the stream
++    void RefreshLock( void );
++
+     // Unlock the stream & destroy the lock
+     void Unlock( void );
+ 
++    // Refresh the lock if necessary
++    static oslSignalAction RefreshLockOnSignal( void* pData, oslSignalInfo* pInfo );
++
+     // Unlock the stream when OOo crashes/is terminated/...
+     static oslSignalAction UnlockOnSignal( void* pData, oslSignalInfo* pInfo );
+ };
+diff --git ucb/source/ucp/webdav/NeonSession.cxx ucb/source/ucp/webdav/NeonSession.cxx
+index 4194c11..9f14c11 100644
+--- ucb/source/ucp/webdav/NeonSession.cxx
++++ ucb/source/ucp/webdav/NeonSession.cxx
+@@ -1515,7 +1515,10 @@ void NeonSession::Lockit( ucb::Lock & rLock, bool bLockit )
+ 
+     // Create the neon lock
+     NeonLock * theLock = ne_lockstore_findbyuri( s_aNeonLockStore, &aUri );
+-    if ( !theLock )
++    bool bAlreadyExists = false;
++    if ( theLock )
++        bAlreadyExists = true;
++    else
+     {
+         theLock = ne_lock_create();
+ 
+@@ -1549,28 +1552,34 @@ void NeonSession::Lockit( ucb::Lock & rLock, bool bLockit )
+         theLock->owner = strdup( rtl::OUStringToOString( aValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+ 
+         // Set the lock timeout
+-        // Note: Neon ignores the timeout
+-        //theLock->timeout = rLock.timeout;
+-        theLock->timeout = -1;
++        // We re-new the lock while the stream is open
++        theLock->timeout = rLock.Timeout;
+     }
+ 
+     if ( bLockit )
+     {
+-        int nRet = ne_lock( m_pHttpSession, theLock );
+-
+-        if ( nRet == NE_OK )
++        int nRet;
++        if ( !bAlreadyExists )
+         {
+-            ne_lockstore_add( s_aNeonLockStore, theLock );
++            nRet = ne_lock( m_pHttpSession, theLock );
++
++            if ( nRet == NE_OK )
++            {
++                ne_lockstore_add( s_aNeonLockStore, theLock );
+ 
+-            uno::Sequence< rtl::OUString > aTokens( 1 );
+-            aTokens[0] = rtl::OUString::createFromAscii( theLock->token );
+-            rLock.LockTokens = aTokens;
++                uno::Sequence< rtl::OUString > aTokens( 1 );
++                aTokens[0] = rtl::OUString::createFromAscii( theLock->token );
++                rLock.LockTokens = aTokens;
+ 
+ #if OSL_DEBUG_LEVEL > 0
+-            fprintf( stderr, "WebDAV: locked the URL, the token is: %s\n", theLock->token );
++                fprintf( stderr, "WebDAV: locked the URL, the token is: %s\n", theLock->token );
+ #endif
++            }
+         }
+-        else if ( ( nRet == NE_ERROR ) && ( getStatusCode( m_pHttpSession ) == SC_LOCKED ) )
++        else
++            nRet = ne_lock_refresh( m_pHttpSession, theLock );
++
++        if ( ( nRet == NE_ERROR ) && ( getStatusCode( m_pHttpSession ) == SC_LOCKED ) )
+         {
+             ucbhelper::cancelCommandExecution( ucb::IOErrorCode_LOCKING_VIOLATION,
+                     uno::Sequence< uno::Any >( 0 ), // FIXME more info about the file?
+@@ -1579,6 +1588,8 @@ void NeonSession::Lockit( ucb::Lock & rLock, bool bLockit )
+                     uno::Reference< ucb::XCommandProcessor >() );
+         }
+ #if OSL_DEBUG_LEVEL > 0
++        else if ( nRet == NE_OK )
++            fprintf( stderr, "WebDAV: locked/refreshed lock OK\n" );
+         else
+             fprintf( stderr, "WebDAV: failed to lock the file, status code is: %d\n", getStatusCode( m_pHttpSession ) );
+ #endif
+diff --git ucb/source/ucp/webdav/webdavcontent.cxx ucb/source/ucp/webdav/webdavcontent.cxx
+index f4fcbc2..e02f66b 100644
+--- ucb/source/ucp/webdav/webdavcontent.cxx
++++ ucb/source/ucp/webdav/webdavcontent.cxx
+@@ -2192,6 +2192,7 @@ uno::Any Content::open(
+                 ucb::Lock aLock;
+                 aLock.Depth = ucb::LockDepth_ZERO;
+                 aLock.Scope = ucb::LockScope_EXCLUSIVE;
++                aLock.Timeout = 3*60; // 3 minutes
+ 
+                 // PULL: wait for client read
+                 try



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]