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



Author: tml
Date: Sun Mar  8 12:38:51 2009
New Revision: 15499
URL: http://svn.gnome.org/viewvc/ooo-build?rev=15499&view=rev

Log:
2009-03-08  Tor Lillqvist  <tml novell com>

	* patches/dev300/webdav-locking-from-ooo-build-2-4-1.diff: Now it
	seems to work again. Basically what I did in the end, once I had
	an understanding of what is going on, was to move the periodical
	relocking and the unlocking of the WebDAV resource from
	webdav_ucp::NeonInputStream to webdav_ucp::Content. This was
	necessary because the NeonInputStream is live only while the
	document is being loaded. Presumably this was different then in
	2.4.1 and 3.0.x? Was that because of upstream code, or did the
	other patches for WebDAV in those versions make it so? Anyway, I
	didn't understand how to change that back now in 3.1, or whether
	that would even be a good idea.

	I don't know exactly what effect the SupportsActiveStreaming stuff
	exactly is supposed to have, and whether it in fact is necessary
	or not now that it's webdav_ucp::Content that manages both locking
	and unlocking.

	A sidenote: In my last testing against the Teaming innerweb
	server, WebDAV locks with timeouts did not expire at all... But
	presumably that is then just a bug in the teaming server or its
	configuration. Or maybe an intentional tweak by the site's
	admins to avoid some class of problems? After all, the Teaming UI
	does allow unlocking a document explicitly. So presumably if some
	document would remain locked because the software used to edit
	it crashed or otherwise didn't unlock it, and the lock doesn't
	time out by itself, that is not a serious problem.



Modified:
   trunk/ChangeLog
   trunk/patches/dev300/webdav-locking-from-ooo-build-2-4-1.diff

Modified: trunk/patches/dev300/webdav-locking-from-ooo-build-2-4-1.diff
==============================================================================
--- trunk/patches/dev300/webdav-locking-from-ooo-build-2-4-1.diff	(original)
+++ trunk/patches/dev300/webdav-locking-from-ooo-build-2-4-1.diff	Sun Mar  8 12:38:51 2009
@@ -324,15 +324,6 @@
  
      return GetStorage();
  }
-@@ -900,7 +900,7 @@
- 
-     sal_Bool bResult = pImp->m_bLocked;
- 
--    if ( ::utl::LocalFileHelper::IsLocalFile( aLogicName ) )
-+    if ( SupportsActiveStreaming( aLogicName ) )
-     {
-         // the special file locking should be used only for file URLs
- 
 @@ -1165,7 +1188,7 @@ uno::Reference < embed::XStorage > SfxMedium::GetStorage()
  
              try
@@ -607,10 +598,9 @@
  
  				case FileBase::E_FAULT: // Bad address
  				case FileBase::E_LOOP:	// Too many symbolic links encountered
-diff --git ucb/source/ucp/webdav/DAVRequestEnvironment.hxx ucb/source/ucp/webdav/DAVRequestEnvironment.hxx
-index d8cbe52..0cf5c85 100644
---- ucb/source/ucp/webdav/DAVRequestEnvironment.hxx
-+++ ucb/source/ucp/webdav/DAVRequestEnvironment.hxx
+diff -u ucb/webdav-orig/DAVRequestEnvironment.hxx ucb/source/ucp/webdav/DAVRequestEnvironment.hxx
+--- ucb/webdav-orig/DAVRequestEnvironment.hxx	2009-03-05 13:01:30.378250000 +0200
++++ ucb/source/ucp/webdav/DAVRequestEnvironment.hxx	2009-03-02 17:52:48.425125000 +0200
 @@ -34,6 +34,10 @@
  #include <rtl/ref.hxx>
  #include "DAVAuthListener.hxx"
@@ -622,7 +612,7 @@
  namespace webdav_ucp
  {
      typedef std::pair< rtl::OUString, rtl::OUString > DAVRequestHeader;
-@@ -46,12 +50,12 @@ struct DAVRequestEnvironment
+@@ -46,12 +50,12 @@
  //    rtl::Reference< DAVStatusListener >   m_xStatusListener;
  //    rtl::Reference< DAVProgressListener > m_xStatusListener;
      DAVRequestHeaders                     m_aRequestHeaders;
@@ -638,31 +628,24 @@
      : m_aRequestURI( rRequestURI ), 
        m_xAuthListener( xListener ),
        m_aRequestHeaders( rRequestHeaders ),
-diff --git ucb/source/ucp/webdav/DAVResourceAccess.cxx ucb/source/ucp/webdav/DAVResourceAccess.cxx
-index 75e0b64..0d4ce5a 100644
---- ucb/source/ucp/webdav/DAVResourceAccess.cxx
-+++ ucb/source/ucp/webdav/DAVResourceAccess.cxx
-@@ -42,6 +42,13 @@
+diff -u ucb/webdav-orig/DAVResourceAccess.cxx ucb/source/ucp/webdav/DAVResourceAccess.cxx
+--- ucb/webdav-orig/DAVResourceAccess.cxx	2009-03-05 13:01:30.409500000 +0200
++++ ucb/source/ucp/webdav/DAVResourceAccess.cxx	2009-03-05 19:50:51.659500000 +0200
+@@ -42,6 +42,9 @@
  #include "DAVAuthListenerImpl.hxx"
  #include "DAVResourceAccess.hxx"
  
-+#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
 +#include <comphelper/processfactory.hxx>
-+#endif
-+#ifndef _UCBHELPER_COMMANDENVIRONMENT_HXX
 +#include <ucbhelper/commandenvironment.hxx>
-+#endif
 +
  using namespace webdav_ucp;
  using namespace com::sun::star;
  
-@@ -61,56 +68,55 @@ int DAVAuthListener_Impl::authenticate(
+@@ -61,56 +64,55 @@
      ::rtl::OUString & inoutUserName,
      ::rtl::OUString & outPassWord )
  {
-+    uno::Reference< task::XInteractionHandler > xIH;
-+
-     if ( m_xEnv.is() )
+-    if ( m_xEnv.is() )
 -    {
 -        uno::Reference< task::XInteractionHandler > xIH
 -            = m_xEnv->getInteractionHandler();
@@ -682,7 +665,8 @@
 -                                                              inoutUserName,
 -                                                              outPassWord );
 -            xIH->handle( xRequest.get() );
--
++    uno::Reference< task::XInteractionHandler > xIH;
+ 
 -            rtl::Reference< ucbhelper::InteractionContinuation > xSelection
 -				= xRequest->getSelection();
 -            
@@ -703,15 +687,7 @@
 -                    // #102871# - Remember username and password.
 -                    m_aPrevUsername = inoutUserName;
 -                    m_aPrevPassword = outPassWord;
--
--                    // go on.
--                    return 0;
--                }
--            }
--        }
--    }
--    // Abort.
--    return -1;
++    if ( m_xEnv.is() )
 +        xIH = m_xEnv->getInteractionHandler();
 +    else
 +        xIH = DAVResourceAccess::createCommandEnvironment()->getInteractionHandler();
@@ -755,13 +731,21 @@
 +    // #102871# - Remember username and password.
 +    m_aPrevUsername = inoutUserName;
 +    m_aPrevPassword = outPassWord;
-+
+ 
+-                    // go on.
+-                    return 0;
+-                }
+-            }
+-        }
+-    }
+-    // Abort.
+-    return -1;
 +    // go on.
 +    return 0;
  }
  
  //=========================================================================
-@@ -444,15 +450,16 @@ void DAVResourceAccess::GET(
+@@ -444,15 +446,16 @@
  }
  
  //=========================================================================
@@ -781,7 +765,7 @@
  	int errorCount = 0;
      bool bRetry;
      do
-@@ -472,7 +479,8 @@ uno::Reference< io::XInputStream > DAVResourceAccess::GET(
+@@ -472,7 +475,8 @@
                                         DAVRequestEnvironment(
                                             getRequestURI(),
                                             new DAVAuthListener_Impl( xEnv ),
@@ -791,7 +775,7 @@
          }
          catch ( DAVException & e )
          {
-@@ -606,6 +614,45 @@ void DAVResourceAccess::PUT(
+@@ -606,6 +610,45 @@
  }
  
  //=========================================================================
@@ -837,7 +821,7 @@
  uno::Reference< io::XInputStream > DAVResourceAccess::POST(
  	const rtl::OUString & rContentType,
  	const rtl::OUString & rReferer,
-@@ -888,22 +935,44 @@ void DAVResourceAccess::DESTROY(
+@@ -888,22 +931,44 @@
  
  //=========================================================================
  void DAVResourceAccess::LOCK ( 
@@ -890,7 +874,7 @@
  }
  
  //=========================================================================
-@@ -1008,6 +1077,18 @@ void DAVResourceAccess::getUserRequestHeaders(
+@@ -1008,6 +1073,18 @@
      }
  }
  
@@ -909,11 +893,10 @@
  //=========================================================================
  sal_Bool DAVResourceAccess::detectRedirectCycle(
                                  const rtl::OUString& rRedirectURL )
-diff --git ucb/source/ucp/webdav/DAVResourceAccess.hxx ucb/source/ucp/webdav/DAVResourceAccess.hxx
-index ca6a188..b1a1d15 100644
---- ucb/source/ucp/webdav/DAVResourceAccess.hxx
-+++ ucb/source/ucp/webdav/DAVResourceAccess.hxx
-@@ -134,11 +134,12 @@ public:
+diff -u ucb/webdav-orig/DAVResourceAccess.hxx ucb/source/ucp/webdav/DAVResourceAccess.hxx
+--- ucb/webdav-orig/DAVResourceAccess.hxx	2009-03-05 13:01:30.409500000 +0200
++++ ucb/source/ucp/webdav/DAVResourceAccess.hxx	2009-03-02 17:52:48.440750000 +0200
+@@ -134,11 +134,12 @@
  	     com::sun::star::ucb::XCommandEnvironment > & xEnv )
          throw( DAVException );
  
@@ -928,7 +911,7 @@
          throw( DAVException );
  
      void
-@@ -157,6 +158,11 @@ public:
+@@ -157,6 +158,11 @@
  	     com::sun::star::ucb::XCommandEnvironment > & xEnv )
  	throw( DAVException );
  
@@ -940,7 +923,7 @@
      com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
      POST( const rtl::OUString & rContentType,
  	  const rtl::OUString & rReferer,
-@@ -204,13 +210,13 @@ public:
+@@ -204,13 +210,13 @@
  	throw( DAVException );
  
      void
@@ -956,7 +939,7 @@
  	    const com::sun::star::uno::Reference<
  	        com::sun::star::ucb::XCommandEnvironment > & xEnv )
  	throw( DAVException );
-@@ -223,6 +229,8 @@ public:
+@@ -223,6 +229,8 @@
  	const rtl::OUString & rMethod,
      DAVRequestHeaders & rRequestHeaders );
  
@@ -965,10 +948,9 @@
  private:
      const rtl::OUString & getRequestURI() const;
      sal_Bool detectRedirectCycle( const rtl::OUString& rRedirectURL )
-diff --git ucb/source/ucp/webdav/DAVSession.hxx ucb/source/ucp/webdav/DAVSession.hxx
-index 8f055ab..9a675cb 100644
---- ucb/source/ucp/webdav/DAVSession.hxx
-+++ ucb/source/ucp/webdav/DAVSession.hxx
+diff -u ucb/webdav-orig/DAVSession.hxx ucb/source/ucp/webdav/DAVSession.hxx
+--- ucb/webdav-orig/DAVSession.hxx	2009-03-05 13:01:30.425125000 +0200
++++ ucb/source/ucp/webdav/DAVSession.hxx	2009-03-02 17:52:48.440750000 +0200
 @@ -33,8 +33,11 @@
  
  #include <memory>
@@ -990,7 +972,7 @@
  namespace webdav_ucp
  {
  
-@@ -114,11 +115,12 @@ public:
+@@ -114,11 +115,12 @@
          const DAVRequestEnvironment & rEnv )
  		throw( DAVException ) = 0;
  
@@ -1005,7 +987,7 @@
          throw( DAVException ) = 0;
  
      virtual void    GET( const ::rtl::OUString & inPath,
-@@ -134,6 +136,12 @@ public:
+@@ -134,6 +136,12 @@
          const DAVRequestEnvironment & rEnv )
  		throw( DAVException ) = 0;
  
@@ -1018,7 +1000,7 @@
      virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream >
                      POST( const rtl::OUString & inPath,
                            const rtl::OUString & rContentType,
-@@ -173,16 +181,14 @@ public:
+@@ -173,16 +181,14 @@
                               const DAVRequestEnvironment & rEnv )
  		throw( DAVException ) = 0;
  
@@ -1038,18 +1020,16 @@
  protected:
      rtl::Reference< DAVSessionFactory > m_xFactory;
  
-diff --git ucb/source/ucp/webdav/NeonInputStream.cxx ucb/source/ucp/webdav/NeonInputStream.cxx
-index 581b284..3a97992 100644
---- ucb/source/ucp/webdav/NeonInputStream.cxx
-+++ ucb/source/ucp/webdav/NeonInputStream.cxx
-@@ -31,22 +31,146 @@
+diff -u ucb/webdav-orig/NeonInputStream.cxx ucb/source/ucp/webdav/NeonInputStream.cxx
+--- ucb/webdav-orig/NeonInputStream.cxx	2009-03-05 13:01:30.425125000 +0200
++++ ucb/source/ucp/webdav/NeonInputStream.cxx	2009-03-05 14:49:12.847000000 +0200
+@@ -31,21 +31,28 @@
  // MARKER(update_precomp.py): autogen include statement, do not remove
  #include "precompiled_ucb.hxx"
  #include "NeonInputStream.hxx"
 +#include "DAVResourceAccess.hxx"
 +
  #include <rtl/memory.h>
-+#include <osl/thread.hxx>
 +#include <com/sun/star/ucb/CommandFailedException.hpp>
 +
 +#include <comphelper/processfactory.hxx>
@@ -1064,117 +1044,7 @@
 +using namespace com::sun::star;
  using namespace webdav_ucp;
  
-+// 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 handler
-+// -------------------------------------------------------------------
-+oslSignalAction NeonInputStream::HandleLockingSignal( void* pData, oslSignalInfo* pSignalInfo )
-+{
-+    NeonInputStream *pStream = static_cast< NeonInputStream *>( pData );
-+
-+    if ( !pStream )
-+        return osl_Signal_ActCallNextHdl;
-+
-+    if ( pSignalInfo  &&
-+            pSignalInfo->Signal == osl_Signal_User &&
-+            pSignalInfo->UserSignal == TICKER_THREAD_USER_SIGNAL )
-+    {
-+        pStream->RefreshLock();
-+    }
-+    else if ( !pSignalInfo || ( pSignalInfo->Signal != osl_Signal_User ) )
-+    {
-+        // terminating or something, let's unlock the stream
-+        pStream->Unlock();
-+    }
-+
-+    return osl_Signal_ActCallNextHdl;
-+}
-+
-+static TickerThreadController sTickerThreadController;
- 
+-
  // -------------------------------------------------------------------
  // Constructor
  // -------------------------------------------------------------------
@@ -1184,29 +1054,11 @@
 +NeonInputStream::NeonInputStream()
 +: m_nLen( 0 ),
 +  m_nPos( 0 ),
-+  m_bDirty( sal_False ),
-+  m_pLock( NULL ),
-+  m_nToExpire( -1 )
++  m_bDirty( sal_False )
  {
-+    m_pSignalHandler = osl_addSignalHandler( NeonInputStream::HandleLockingSignal, this );
-+    
-+    sTickerThreadController.start();
  }
  
- // -------------------------------------------------------------------
-@@ -54,6 +178,11 @@ NeonInputStream::NeonInputStream( void )
- // -------------------------------------------------------------------
- NeonInputStream::~NeonInputStream( void )
- {
-+    sTickerThreadController.stop();
-+
-+    Unlock();
-+
-+    osl_removeSignalHandler( m_pSignalHandler );
- }
- 
- // -------------------------------------------------------------------
-@@ -62,24 +191,68 @@ NeonInputStream::~NeonInputStream( void )
+@@ -62,24 +69,59 @@
  // -------------------------------------------------------------------
  void NeonInputStream::AddToStream( const char * inBuf, sal_Int32 inLen )
  {
@@ -1221,22 +1073,13 @@
 +}
 +
 +// -------------------------------------------------------------------
-+// Associate a lock with this stream
++// Associate a URL with this stream
 +// -------------------------------------------------------------------
-+void NeonInputStream::SetLock( const com::sun::star::ucb::Lock &rLock,
-+        const rtl::OUString &rURL )
++void NeonInputStream::SetURL( const rtl::OUString &rURL )
 +{
 +    osl::MutexGuard aGuard( m_aLock );
 +
 +    m_aURL = rURL;
-+
-+    if ( !m_pLock )
-+        m_pLock = new ucb::Lock( rLock );
-+    else
-+        *m_pLock = rLock;
-+
-+    if ( m_pLock )
-+        m_nToExpire = m_pLock->Timeout;
  }
  
  // -------------------------------------------------------------------
@@ -1283,7 +1126,7 @@
  // readBytes
  // "Reads" the specified number of bytes from the stream
  // -------------------------------------------------------------------
-@@ -92,7 +265,7 @@ sal_Int32 SAL_CALL NeonInputStream::readBytes(
+@@ -92,7 +134,7 @@
  {
  	// Work out how much we're actually going to write
  	sal_Int32 theBytes2Read = nBytesToRead;
@@ -1292,7 +1135,7 @@
  	if ( theBytes2Read > theBytesLeft )
  		theBytes2Read = theBytesLeft;
  
-@@ -101,10 +274,10 @@ sal_Int32 SAL_CALL NeonInputStream::readBytes(
+@@ -101,10 +143,10 @@
  
  	// Write the data
  	rtl_copyMemory(
@@ -1305,7 +1148,7 @@
  
      return theBytes2Read;
  }
-@@ -133,9 +306,9 @@ void SAL_CALL NeonInputStream::skipBytes( sal_Int32 nBytesToSkip )
+@@ -133,9 +175,9 @@
                 ::com::sun::star::io::IOException,
                 ::com::sun::star::uno::RuntimeException )
  {
@@ -1318,7 +1161,7 @@
  }
  
  // -------------------------------------------------------------------
-@@ -147,7 +320,7 @@ sal_Int32 SAL_CALL NeonInputStream::available(  )
+@@ -147,7 +189,7 @@
                 ::com::sun::star::io::IOException,
                 ::com::sun::star::uno::RuntimeException )
  {
@@ -1327,7 +1170,7 @@
  }
  
  // -------------------------------------------------------------------
-@@ -168,12 +341,12 @@ void SAL_CALL NeonInputStream::seek( sal_Int64 location )
+@@ -168,12 +210,12 @@
  			   ::com::sun::star::io::IOException,
  			   ::com::sun::star::uno::RuntimeException )
  {
@@ -1345,7 +1188,7 @@
          throw ::com::sun::star::lang::IllegalArgumentException();
  }
  
-@@ -184,7 +357,7 @@ sal_Int64 SAL_CALL NeonInputStream::getPosition()
+@@ -184,7 +226,7 @@
  		throw( ::com::sun::star::io::IOException,
  			   ::com::sun::star::uno::RuntimeException )
  {
@@ -1354,7 +1197,7 @@
  }
  
  // -------------------------------------------------------------------
-@@ -194,5 +367,168 @@ sal_Int64 SAL_CALL NeonInputStream::getLength()
+@@ -194,5 +236,108 @@
  		throw( ::com::sun::star::io::IOException,
  			   ::com::sun::star::uno::RuntimeException )
  {
@@ -1410,7 +1253,6 @@
 +#endif
 +        // FIXME It's really hacky to create the new session
 +        // But so far it seems I have no other chance...
-+        // see also NeonInputStream::Unlock()
 +        uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
 +        rtl::Reference< DAVSessionFactory > rDAVFactory( new DAVSessionFactory() );
 +        
@@ -1464,70 +1306,10 @@
 +        m_nLen = m_nPos = 0;
 +        m_bDirty = sal_True;
 +    }
-+}
-+
-+// -------------------------------------------------------------------
-+// 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
-+
-+    if ( m_nToExpire > 0 )
-+        --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...
-+        uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
-+        rtl::Reference< DAVSessionFactory > rDAVFactory( new DAVSessionFactory() );
-+        
-+        DAVResourceAccess aResourceAccess( xFactory, rDAVFactory, m_aURL );
-+
-+        aResourceAccess.LOCK( *m_pLock, DAVResourceAccess::createCommandEnvironment() );
-+
-+        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
-+
-+    if ( m_pLock )
-+    {
-+        // FIXME It's really hacky to create the new session
-+        // But so far it seems I have no other chance...
-+        uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY );
-+        rtl::Reference< DAVSessionFactory > rDAVFactory( new DAVSessionFactory() );
-+        
-+        DAVResourceAccess aResourceAccess( xFactory, rDAVFactory, m_aURL );
-+
-+        aResourceAccess.UNLOCK( *m_pLock, DAVResourceAccess::createCommandEnvironment() );
-+
-+        delete m_pLock;
-+        m_pLock = NULL;
-+
-+        m_nToExpire = -1;
-+    }
  }
-diff --git ucb/source/ucp/webdav/NeonInputStream.hxx ucb/source/ucp/webdav/NeonInputStream.hxx
-index 2d83577..8f648e7 100644
---- ucb/source/ucp/webdav/NeonInputStream.hxx
-+++ ucb/source/ucp/webdav/NeonInputStream.hxx
+diff -u ucb/webdav-orig/NeonInputStream.hxx ucb/source/ucp/webdav/NeonInputStream.hxx
+--- ucb/webdav-orig/NeonInputStream.hxx	2009-03-05 13:01:30.440750000 +0200
++++ ucb/source/ucp/webdav/NeonInputStream.hxx	2009-03-05 13:29:30.425125000 +0200
 @@ -31,11 +31,19 @@
  #define _NEONINPUTSTREAM_HXX_
  
@@ -1548,7 +1330,7 @@
  
  namespace webdav_ucp
  {
-@@ -45,21 +53,38 @@ namespace webdav_ucp
+@@ -45,21 +53,33 @@
  // A simple XInputStream implementation provided specifically for use
  // by the DAVSession::GET method.
  // -------------------------------------------------------------------
@@ -1564,6 +1346,10 @@
 -		com::sun::star::uno::Sequence< sal_Int8 > mInputBuffer;
 -		sal_Int64 mLen;
 -		sal_Int64 mPos;
+-
+-	public:
+-				 NeonInputStream( void );
+-		virtual ~NeonInputStream();
 +private:
 +    com::sun::star::uno::Sequence< sal_Int8 > m_aInputBuffer;
 +    sal_Int64                  m_nLen; // cannot be just m_aInputBuffer.getLength() - the buffer can be bigger
@@ -1571,15 +1357,8 @@
 +
 +    sal_Bool                   m_bDirty;
 +
-+    com::sun::star::ucb::Lock *m_pLock;
-+    int                        m_nToExpire;
 +    rtl::OUString              m_aURL;
 +
-+    oslSignalHandler           m_pSignalHandler;
- 
--	public:
--				 NeonInputStream( void );
--		virtual ~NeonInputStream();
 +    osl::Mutex                 m_aLock;
  
 -		// Add some data to the end of the stream
@@ -1591,13 +1370,12 @@
 +    // Add some data to the end of the stream
 +    void AddToStream( const char * inBuf, sal_Int32 inLen );
 +
-+    // Associate a lock with this stream
-+    void SetLock( const com::sun::star::ucb::Lock &rLock,
-+                  const rtl::OUString &rURL );
++    // Associate a URL with this stream
++    void SetURL( const rtl::OUString &rURL );
  
  	// XInterface
  	virtual com::sun::star::uno::Any SAL_CALL queryInterface(
-@@ -74,6 +99,12 @@ class NeonInputStream : public ::com::sun::star::io::XInputStream,
+@@ -74,6 +94,12 @@
  							throw()
  								{ OWeakObject::release(); }
  
@@ -1610,7 +1388,7 @@
  
  	// XInputStream
  	virtual sal_Int32 SAL_CALL readBytes(
-@@ -121,6 +152,42 @@ class NeonInputStream : public ::com::sun::star::io::XInputStream,
+@@ -121,6 +147,30 @@
  	virtual sal_Int64 SAL_CALL getLength()
  		throw( ::com::sun::star::io::IOException,
  			   ::com::sun::star::uno::RuntimeException );
@@ -1638,25 +1416,12 @@
 +    virtual void SAL_CALL truncate( void )
 +        throw( com::sun::star::io::IOException,
 +                com::sun::star::uno::RuntimeException );
-+    
-+protected:
-+
-+    // Refresh the lock on the stream
-+    void RefreshLock( void );
-+
-+    // Unlock the stream & destroy the lock
-+    void Unlock( void );
-+
-+    // Refresh the lock if necessary, or unlock the stream when
-+    // OOo crashes/is terminated/...
-+    static oslSignalAction HandleLockingSignal( void* pData, oslSignalInfo* pInfo );
  };
  
  } // namespace webdav_ucp
-diff --git ucb/source/ucp/webdav/NeonSession.cxx ucb/source/ucp/webdav/NeonSession.cxx
-index 244ffaa..2daaddd 100644
---- ucb/source/ucp/webdav/NeonSession.cxx
-+++ ucb/source/ucp/webdav/NeonSession.cxx
+diff -u ucb/webdav-orig/NeonSession.cxx ucb/source/ucp/webdav/NeonSession.cxx
+--- ucb/webdav-orig/NeonSession.cxx	2009-03-05 13:01:30.456375000 +0200
++++ ucb/source/ucp/webdav/NeonSession.cxx	2009-03-06 13:29:19.847000000 +0200
 @@ -65,6 +65,9 @@
  #ifndef _SIMPLECERTIFICATIONVALIDATIONREQUEST_HXX_
  #include "ucbhelper/simplecertificatevalidationrequest.hxx"
@@ -1667,7 +1432,7 @@
  
  #include <cppuhelper/bootstrap.hxx> 
  
-@@ -153,6 +156,12 @@ static sal_uInt16 makeStatusCode( const rtl::OUString & rStatusText )
+@@ -153,6 +156,12 @@
      return sal_uInt16( rStatusText.copy( 0, nPos ).toInt32() );
  }
  
@@ -1680,7 +1445,7 @@
  // -------------------------------------------------------------------
  struct NeonRequestContext
  {
-@@ -196,12 +205,13 @@ struct NeonRequestContext
+@@ -196,12 +205,13 @@
  // -------------------------------------------------------------------
  
  #if NEON_VERSION >= 0x0250
@@ -1698,7 +1463,7 @@
  {
      // neon calls this function with (inLen == 0)...
      if ( inLen > 0 )
-@@ -226,12 +236,13 @@ extern "C" void NeonSession_ResponseBlockReader(void * inUserData,
+@@ -226,12 +236,13 @@
  // -------------------------------------------------------------------
  
  #if NEON_VERSION >= 0x0250
@@ -1716,7 +1481,7 @@
  {
      // neon calls this function with (inLen == 0)...
      if ( inLen > 0 )
-@@ -297,11 +308,10 @@ extern "C" int NeonSession_NeonAuth( void *       inUserData,
+@@ -299,11 +310,10 @@
  
          try
          {
@@ -1730,7 +1495,7 @@
                  if ( nPos == -1 )
                  {
                      theUserName = aUserInfo;
-@@ -561,6 +571,8 @@ extern "C" void NeonSession_PreSendRequest( ne_request * req,
+@@ -564,6 +574,8 @@
      }
  }
  
@@ -1739,7 +1504,7 @@
  // -------------------------------------------------------------------
  // Constructor
  // -------------------------------------------------------------------
-@@ -578,6 +590,7 @@ NeonSession::NeonSession(
+@@ -581,6 +593,7 @@
      m_aScheme    = theUri.GetScheme();
      m_aHostName  = theUri.GetHost();
      m_nPort      = theUri.GetPort();
@@ -1747,7 +1512,7 @@
  
  //   Init();
  }
-@@ -591,14 +604,6 @@ NeonSession::~NeonSession( )
+@@ -594,14 +607,6 @@
      {
          ne_session_destroy( m_pHttpSession );
          m_pHttpSession = 0;
@@ -1762,7 +1527,17 @@
      }
  
      delete static_cast<RequestDataMap*>(m_pRequestData);
-@@ -743,14 +748,15 @@ void NeonSession::Init()
+@@ -629,6 +634,9 @@
+                 throw DAVException( DAVException::DAV_SESSION_CREATE,
+                                     NeonUri::makeConnectionEndPointString(
+                                                     m_aHostName, m_nPort ) );
++#if OSL_DEBUG_LEVEL > 0
++			ne_debug_init( stderr, NE_DBG_LOCKS );
++#endif
+             // #122205# - libxml2 needs to be initialized once if used by 
+             // multithreaded programs like OOo.
+             xmlInitParser();
+@@ -746,14 +754,15 @@
                                m_nProxyPort );
          }
  
@@ -1784,7 +1559,7 @@
  
          // Register for redirects.
          ne_redirect_register( m_pHttpSession );
-@@ -1082,11 +1088,12 @@ void NeonSession::GET( const rtl::OUString &                 inPath,
+@@ -1086,11 +1095,12 @@
  // -------------------------------------------------------------------
  // GET
  // -------------------------------------------------------------------
@@ -1799,7 +1574,7 @@
      throw ( DAVException )
  {
      osl::Guard< osl::Mutex > theGuard( m_aMutex );
-@@ -1098,16 +1105,23 @@ NeonSession::GET( const rtl::OUString & inPath,
+@@ -1102,16 +1112,23 @@
      ioResource.uri = inPath;
      ioResource.properties.clear();
  
@@ -1827,7 +1602,7 @@
  }
  
  // -------------------------------------------------------------------
-@@ -1147,22 +1161,38 @@ void NeonSession::PUT( const rtl::OUString &                      inPath,
+@@ -1151,22 +1168,38 @@
                         const DAVRequestEnvironment & rEnv )
      throw ( DAVException )
  {
@@ -1873,7 +1648,7 @@
  
      HandleError( theRetVal );
  }
-@@ -1338,9 +1368,7 @@ void NeonSession::DESTROY( const rtl::OUString & inPath,
+@@ -1342,9 +1375,7 @@
  // -------------------------------------------------------------------
  // LOCK
  // -------------------------------------------------------------------
@@ -1884,7 +1659,7 @@
                          const DAVRequestEnvironment & rEnv )
  	throw ( DAVException )
  {
-@@ -1350,16 +1378,13 @@ void NeonSession::LOCK( const Lock & inLock,
+@@ -1354,16 +1385,13 @@
  
      m_aEnv = rEnv;
  
@@ -1903,7 +1678,7 @@
                            const DAVRequestEnvironment & rEnv )
  	throw ( DAVException )
  {
-@@ -1369,9 +1394,8 @@ void NeonSession::UNLOCK( const Lock & inLock,
+@@ -1373,9 +1401,8 @@
  
      m_aEnv = rEnv;
  
@@ -1914,7 +1689,7 @@
  
  // -------------------------------------------------------------------
  const ucbhelper::InternetProxyServer & NeonSession::getProxySettings() const
-@@ -1410,7 +1434,10 @@ void NeonSession::HandleError( int nError )
+@@ -1414,7 +1441,10 @@
          case NE_ERROR:        // Generic error
          {
              rtl::OUString aText = rtl::OUString::createFromAscii(
@@ -1926,7 +1701,7 @@
              throw DAVException( DAVException::DAV_HTTP_ERROR,
                                  aText,
                                  makeStatusCode( aText ) );
-@@ -1467,77 +1494,151 @@ void NeonSession::HandleError( int nError )
+@@ -1471,77 +1501,151 @@
      }
  }
  
@@ -1941,25 +1716,14 @@
 -	// Create the neon lock
 -	NeonLock * theLock = new NeonLock;
 -	int theRetVal;
-+    if ( !s_aNeonLockStore )
-+        throw DAVException( DAVException::DAV_INVALID_ARG );
- 
+-
 -	// Set the lock uri
 -	NeonUri theUri( inLock.uri );
 -	theLock->uri = const_cast< char * >
 -        ( rtl::OUStringToOString(
 -                theUri.GetPath(), RTL_TEXTENCODING_UTF8 ).getStr() );
-+    ne_uri aUri;
-+    ne_uri_parse( rtl::OUStringToOString( m_aEnv.m_aRequestURI, RTL_TEXTENCODING_UTF8 ).getStr(),
-+            &aUri );
-+    
-+#if NEON_VERSION < 0x0260
-+#define FILLIN( field, val ) aUri.field = aUri.field? aUri.field: strdup( rtl::OUStringToOString( val, RTL_TEXTENCODING_UTF8 ).getStr() )
-+    FILLIN( scheme, m_aScheme );
-+    FILLIN( host, m_aHostName );
-+    aUri.port = aUri.port? aUri.port: m_nPort;
-+#undef FILLIN
-+#endif
++    if ( !s_aNeonLockStore )
++        throw DAVException( DAVException::DAV_INVALID_ARG );
  
 -	if ( inLockit )
 -	{
@@ -1974,14 +1738,17 @@
 -				throw DAVException( DAVException::DAV_INVALID_ARG );
 -				break;
 -		}
-+    // Create the neon lock
-+    NeonLock * theLock = ne_lockstore_findbyuri( s_aNeonLockStore, &aUri );
-+    bool bAlreadyExists = false;
-+    if ( theLock )
-+        bAlreadyExists = true;
-+    else
-+    {
-+        theLock = ne_lock_create();
++    ne_uri aUri;
++    ne_uri_parse( rtl::OUStringToOString( m_aEnv.m_aRequestURI, RTL_TEXTENCODING_UTF8 ).getStr(),
++            &aUri );
++    
++#if NEON_VERSION < 0x0260
++#define FILLIN( field, val ) aUri.field = aUri.field? aUri.field: strdup( rtl::OUStringToOString( val, RTL_TEXTENCODING_UTF8 ).getStr() )
++    FILLIN( scheme, m_aScheme );
++    FILLIN( host, m_aHostName );
++    aUri.port = aUri.port? aUri.port: m_nPort;
++#undef FILLIN
++#endif
  
 -		// Set the lock scope
 -		switch ( inLock.scope )
@@ -1996,13 +1763,30 @@
 -				throw DAVException( DAVException::DAV_INVALID_ARG );
 -				break;
 -		}
-+        // Set the lock uri
-+        theLock->uri = aUri;
++    // Create the neon lock
++    NeonLock * theLock = ne_lockstore_findbyuri( s_aNeonLockStore, &aUri );
++    bool bAlreadyExists = false;
++    if ( theLock )
++        bAlreadyExists = true;
++    else
++    {
++        theLock = ne_lock_create();
  
 -		// Set the lock owner
 -        const char * theOwner = rtl::OUStringToOString( inLock.owner,
 -                                                        RTL_TEXTENCODING_UTF8 );
 -		theLock->owner = const_cast< char * > ( theOwner );
+-
+-		// Set the lock timeout
+-		// Note: Neon ignores the timeout
+-		//theLock->timeout = inLock.timeout;
++        // Set the lock uri
++        theLock->uri = aUri;
+ 
+-        theRetVal = ne_lock( m_pHttpSession, theLock );
+-	}
+-	else
+-	{
 +        // Set the lock depth
 +        switch( rLock.Depth )
 +        {
@@ -2013,9 +1797,11 @@
 +                                          throw DAVException( DAVException::DAV_INVALID_ARG );
 +        }
  
--		// Set the lock timeout
--		// Note: Neon ignores the timeout
--		//theLock->timeout = inLock.timeout;
+-		// Set the lock token
+-        rtl::OUString theToken = inLock.locktoken.getConstArray()[ 0 ];
+-		theLock->token = const_cast< char * >
+-            ( rtl::OUStringToOString(
+-                    theToken, RTL_TEXTENCODING_UTF8 ).getStr() );
 +        // Set the lock scope
 +        switch ( rLock.Scope )
 +        {
@@ -2026,29 +1812,20 @@
 +                                           break;
 +        }
  
--        theRetVal = ne_lock( m_pHttpSession, theLock );
+-        theRetVal = ne_unlock( m_pHttpSession, theLock );
 -	}
--	else
--	{
 +        // Set the lock owner
 +        rtl::OUString aValue;
 +        rLock.Owner >>= aValue;
  
--		// Set the lock token
--        rtl::OUString theToken = inLock.locktoken.getConstArray()[ 0 ];
--		theLock->token = const_cast< char * >
--            ( rtl::OUStringToOString(
--                    theToken, RTL_TEXTENCODING_UTF8 ).getStr() );
+-	HandleError( theRetVal );
 +        theLock->owner = strdup( rtl::OUStringToOString( aValue, RTL_TEXTENCODING_UTF8 ).getStr() );
- 
--        theRetVal = ne_unlock( m_pHttpSession, theLock );
--	}
++
 +        // Set the lock timeout
 +        // We re-new the lock while the stream is open
 +        theLock->timeout = rLock.Timeout;
 +    }
- 
--	HandleError( theRetVal );
++
 +    if ( bLockit )
 +    {
 +        int nRet;
@@ -2135,11 +1912,10 @@
  
  // -------------------------------------------------------------------
  namespace {
-diff --git ucb/source/ucp/webdav/NeonSession.hxx ucb/source/ucp/webdav/NeonSession.hxx
-index 2dbb7af..343cb2c 100644
---- ucb/source/ucp/webdav/NeonSession.hxx
-+++ ucb/source/ucp/webdav/NeonSession.hxx
-@@ -57,6 +57,7 @@ class NeonSession : public DAVSession
+diff -u ucb/webdav-orig/NeonSession.hxx ucb/source/ucp/webdav/NeonSession.hxx
+--- ucb/webdav-orig/NeonSession.hxx	2009-03-05 13:01:30.472000000 +0200
++++ ucb/source/ucp/webdav/NeonSession.hxx	2009-03-02 17:52:48.487625000 +0200
+@@ -57,6 +57,7 @@
          rtl::OUString     m_aScheme;
          rtl::OUString     m_aHostName;
          rtl::OUString     m_aProxyName;
@@ -2147,7 +1923,7 @@
          sal_Int32         m_nPort;
          sal_Int32         m_nProxyPort;
          HttpSession *     m_pHttpSession;
-@@ -70,8 +71,7 @@ class NeonSession : public DAVSession
+@@ -70,8 +71,7 @@
          // moment.
          DAVRequestEnvironment m_aEnv;
  
@@ -2157,7 +1933,7 @@
  
          static bool       m_bGlobalsInited;
  
-@@ -92,6 +92,8 @@ class NeonSession : public DAVSession
+@@ -92,6 +92,8 @@
          const DAVRequestEnvironment & getRequestEnvironment() const
          { return m_aEnv; }
  
@@ -2166,7 +1942,7 @@
          virtual void
          OPTIONS( const ::rtl::OUString &  inPath,
                   DAVCapabilities & outCapabilities,
-@@ -142,11 +144,12 @@ class NeonSession : public DAVSession
+@@ -142,11 +144,12 @@
  			throw ( DAVException );
  
          virtual com::sun::star::uno::Reference<
@@ -2181,7 +1957,7 @@
              throw ( DAVException );
  
          virtual void
-@@ -165,6 +168,13 @@ class NeonSession : public DAVSession
+@@ -165,6 +168,13 @@
                  const DAVRequestEnvironment & rEnv )
  			throw ( DAVException );
  
@@ -2195,7 +1971,7 @@
          virtual com::sun::star::uno::Reference<
              com::sun::star::io::XInputStream >
          POST( const rtl::OUString & inPath,
-@@ -209,16 +219,13 @@ class NeonSession : public DAVSession
+@@ -209,16 +219,13 @@
                                const DAVRequestEnvironment & rEnv )
  			throw ( DAVException );
  
@@ -2216,7 +1992,7 @@
  
          // helpers
          const rtl::OUString & getHostName() const { return m_aHostName; }
-@@ -243,9 +250,8 @@ class NeonSession : public DAVSession
+@@ -239,9 +246,8 @@
  
          const ucbhelper::InternetProxyServer & getProxySettings() const;
  
@@ -2228,10 +2004,9 @@
  
          // low level GET implementation, used by public GET implementations
          static int GET( ne_session * sess,
-diff --git ucb/source/ucp/webdav/NeonTypes.hxx ucb/source/ucp/webdav/NeonTypes.hxx
-index 08c7d07..6e80fee 100644
---- ucb/source/ucp/webdav/NeonTypes.hxx
-+++ ucb/source/ucp/webdav/NeonTypes.hxx
+diff -u ucb/webdav-orig/NeonTypes.hxx ucb/source/ucp/webdav/NeonTypes.hxx
+--- ucb/webdav-orig/NeonTypes.hxx	2009-03-05 13:01:30.472000000 +0200
++++ ucb/source/ucp/webdav/NeonTypes.hxx	2009-03-02 17:52:48.487625000 +0200
 @@ -35,6 +35,7 @@
  #include <ne_utils.h>
  #include <ne_basic.h>
@@ -2240,7 +2015,7 @@
  
  typedef ne_session                  HttpSession;
  typedef ne_status                   HttpStatus;
-@@ -43,4 +44,7 @@ typedef ne_server_capabilities      HttpServerCapabilities;
+@@ -43,4 +44,7 @@
  typedef ne_propname                 NeonPropName;
  typedef ne_prop_result_set          NeonPropFindResultSet;
  
@@ -2248,9 +2023,18 @@
 +typedef struct ne_lock              NeonLock;
 +
  #endif // _NEONTYPES_HXX_
---- ucb/source/ucp/webdav/webdavcontent.cxx.original	2009-02-25 12:57:25.180000000 +0200
-+++ ucb/source/ucp/webdav/webdavcontent.cxx	2009-02-25 13:04:04.992500000 +0200
-@@ -76,6 +76,7 @@
+diff -u ucb/webdav-orig/webdavcontent.cxx ucb/source/ucp/webdav/webdavcontent.cxx
+--- ucb/webdav-orig/webdavcontent.cxx	2009-03-05 13:01:30.487625000 +0200
++++ ucb/source/ucp/webdav/webdavcontent.cxx	2009-03-08 14:00:39.935935600 +0200
+@@ -37,6 +37,7 @@
+ 
+  *************************************************************************/
+ #include <osl/diagnose.h>
++#include <osl/thread.hxx>
+ 
+ #include "osl/doublecheckedlocking.h"
+ #include <rtl/uri.hxx>
+@@ -48,20 +49,17 @@
  #include <com/sun/star/beans/PropertySetInfoChangeEvent.hpp>
  #include <com/sun/star/beans/PropertyValue.hpp>
  #include <com/sun/star/io/XActiveDataSink.hpp>
@@ -2258,7 +2042,21 @@
  #include <com/sun/star/io/XOutputStream.hpp>
  #include <com/sun/star/lang/IllegalAccessException.hpp>
  #include "com/sun/star/ucb/AuthenticationRequest.hpp"
-@@ -190,6 +193,8 @@
+ #include <com/sun/star/ucb/CommandFailedException.hpp>
+ #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
+ #include <com/sun/star/ucb/InsertCommandArgument.hpp>
+-#ifndef _COM_SUN_STAR_UCB_INTERACTIVEBADTRANSFRERURLEXCEPTION_HPP_
+ #include <com/sun/star/ucb/InteractiveBadTransferURLException.hpp>
+-#endif
+ #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
+ #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
+-#ifndef _COM_SUN_STAR_UCB_INTERACTIVENETWORKGENBERALEXCEPTION_HPP_
+ #include <com/sun/star/ucb/InteractiveNetworkGeneralException.hpp>
+-#endif
+ #include <com/sun/star/ucb/InteractiveNetworkReadException.hpp>
+ #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
+ #include <com/sun/star/ucb/InteractiveNetworkWriteException.hpp>
+@@ -90,6 +88,8 @@
  #include "NeonUri.hxx"
  #include "UCBDeadPropertyValue.hxx"
  
@@ -2267,27 +2065,232 @@
  using namespace com::sun::star;
  using namespace webdav_ucp;
  
-@@ -353,7 +352,8 @@ Content::Content(
+@@ -345,6 +345,123 @@
+ //=========================================================================
+ //=========================================================================
+ 
++// 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 handler
++// -------------------------------------------------------------------
++oslSignalAction Content::HandleLockingSignal( void* pData, oslSignalInfo* pSignalInfo )
++{
++    Content *pContent = static_cast< Content *>( pData );
++
++#if OSL_DEBUG_LEVEL > 0
++	fprintf( stderr, "Content::HandleLockingSignal: pContent=%p\n", pContent );
++#endif
++
++    if ( !pContent )
++        return osl_Signal_ActCallNextHdl;
++
++    if ( pSignalInfo  &&
++            pSignalInfo->Signal == osl_Signal_User &&
++            pSignalInfo->UserSignal == TICKER_THREAD_USER_SIGNAL )
++    {
++        pContent->RefreshLock();
++    }
++    else if ( !pSignalInfo || ( pSignalInfo->Signal != osl_Signal_User ) )
++    {
++        // terminating or something
++		pContent->m_xResAccess->UNLOCK( *pContent->m_pLock, *pContent->m_pLockEnv );
++		delete pContent->m_pLock;
++		pContent->m_pLock = NULL;
++    }
++
++    return osl_Signal_ActCallNextHdl;
++}
++
++static TickerThreadController sTickerThreadController;
++
+ //=========================================================================
+ // ctr for content on an existing webdav resource
+ Content::Content(
+@@ -358,7 +475,11 @@
    m_pProvider( pProvider ),
    m_bTransient( false ),
    m_bCollection( false ),
 -  m_bDidGetOrHead( false )
 +  m_bDidGetOrHead( false ),
-+  m_bForceReadOnly( false )
++  m_bForceReadOnly( false ),
++  m_pLock( NULL ),
++  m_nToExpire( -1 ),
++  m_pSignalHandler( NULL )
  {
      try
      {
-@@ -390,7 +390,8 @@
+@@ -369,6 +490,13 @@
+ 
+         NeonUri aURI( Identifier->getContentIdentifier() );
+         m_aEscapedTitle = aURI.GetPathBaseName();
++
++		m_pSignalHandler = osl_addSignalHandler( HandleLockingSignal, this );
++
++#if OSL_DEBUG_LEVEL > 0
++		fprintf( stderr, "Content::Content: this=%p m_pSignalHandler=%p\n", this, m_pSignalHandler );
++#endif
++		sTickerThreadController.start();
+     }
+     catch ( DAVException const & )
+     {
+@@ -390,12 +518,23 @@
    m_pProvider( pProvider ),
    m_bTransient( true ),
    m_bCollection( isCollection ),
 -  m_bDidGetOrHead( false )
 +  m_bDidGetOrHead( false ),
-+  m_bForceReadOnly( false )
++  m_bForceReadOnly( false ),
++  m_pLock( NULL ),
++  m_nToExpire( -1 ),
++  m_pSignalHandler( NULL )
  {
      try
      {
-@@ -722,6 +728,11 @@ uno::Any SAL_CALL Content::execute(
+         m_xResAccess.reset( new DAVResourceAccess(
+             rxSMgr, rSessionFactory, Identifier->getContentIdentifier() ) );
++
++		m_pSignalHandler = osl_addSignalHandler( HandleLockingSignal, this );
++
++#if OSL_DEBUG_LEVEL > 0
++		fprintf( stderr, "Content::Content: this=%p m_pSignalHandler=%p\n", this, m_pSignalHandler );
++#endif
++		sTickerThreadController.start();
+     }
+     catch ( DAVException const & )
+     {
+@@ -409,6 +548,48 @@
+ // virtual
+ Content::~Content()
+ {
++#if OSL_DEBUG_LEVEL > 0
++	fprintf( stderr, "Content::~Content: this=%p m_pSignalHandler=%p\n", this, m_pSignalHandler );
++#endif
++	sTickerThreadController.stop();
++
++	osl_removeSignalHandler( m_pSignalHandler );
++
++	if (m_pLock != NULL)
++	{
++		try {
++			m_xResAccess->UNLOCK( *m_pLock, *m_pLockEnv );
++			delete m_pLock;
++			m_pLock = NULL;
++		}
++		catch ( ucb::CommandFailedException const & )
++		{
++		}
++	}
++}
++
++// -------------------------------------------------------------------
++// Lock the resource again
++// -------------------------------------------------------------------
++void Content::RefreshLock( void )
++{
++    osl::MutexGuard aGuard( m_aLock );
++
++#if OSL_DEBUG_LEVEL > 0
++	if (m_nToExpire > 0)
++		fprintf( stderr, "WebDAV: RefreshLock() - will refresh in %d sec\n", m_nToExpire - 30 );
++#endif
++
++    if ( m_nToExpire > 0 )
++        --m_nToExpire;
++
++    // Refresh the lock if it expires in less than 30 s
++    if ( m_pLock && m_nToExpire >= 0 && m_nToExpire < 30 )
++    {
++        m_xResAccess->LOCK( *m_pLock, *m_pLockEnv );
++
++        m_nToExpire = m_pLock->Timeout;
++    }
+ }
+ 
+ //=========================================================================
+@@ -630,6 +811,11 @@
             ucb::CommandAbortedException,
             uno::RuntimeException )
  {
@@ -2299,7 +2302,7 @@
      uno::Any aRet;
      
      if ( aCommand.Name.equalsAsciiL(
-@@ -1441,6 +1452,31 @@ uno::Reference< sdbc::XRow > Content::ge
+@@ -1349,6 +1535,31 @@
      uno::Reference< ucb::XContentIdentifier >    xIdentifier;
      rtl::Reference< ::ucbhelper::ContentProviderImplHelper > xProvider;
  
@@ -2331,35 +2334,37 @@
      {
          osl::Guard< osl::Mutex > aGuard( m_aMutex );
  
-@@ -1522,10 +1558,15 @@ uno::Reference< sdbc::XRow > Content::ge
+@@ -1475,8 +1686,13 @@
  						
  						if ( !bNetworkAccessAllowed )
  						{
+-							cancelCommandExecution( e, xEnv );
+-							// unreachable
 +                            if ( e.getStatus() == SC_NOT_FOUND )
 +                                xProps.reset();
 +                            else
 +                            {
- 							cancelCommandExecution( e, xEnv );
- 							// unreachable
++                                cancelCommandExecution( e, xEnv );
++                                // unreachable
++                            }
  						}
  					}
-+                            }
  				}
- 			}
-         }
-@@ -2140,8 +2181,9 @@ uno::Any Content::open(
+@@ -2092,9 +2308,10 @@
          }
      }
  
 -    if ( rArg.Sink.is() )
 -    {
+-        // Open document.
 +    if ( !rArg.Sink.is() )
 +        return aRet;
 +
-         // Open document.
++       // Open document.
  
      if ( rArg.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE )
-@@ -2163,6 +2205,9 @@ uno::Any Content::open(
+         {
+@@ -2114,6 +2331,9 @@
              = uno::Reference< io::XOutputStream >( rArg.Sink, uno::UNO_QUERY );
          if ( xOut.is() )
          {
@@ -2369,7 +2374,7 @@
              // PUSH: write data
              try
              {
-@@ -2209,6 +2254,58 @@ uno::Any Content::open(
+@@ -2158,6 +2378,60 @@
                                                           uno::UNO_QUERY );
              if ( xDataSink.is() )
              {
@@ -2420,22 +2425,25 @@
 +                fprintf( stderr, "WebDAV: rArg.Sink is XActiveDataStreamer\n" );
 +#endif
 +                // prepare the lock
-+                ucb::Lock aLock;
-+                aLock.Depth = ucb::LockDepth_ZERO;
-+                aLock.Scope = ucb::LockScope_EXCLUSIVE;
-+                aLock.Timeout = 2*60; // 2 minutes
++                m_pLock = new ucb::Lock;
++                m_pLock->Depth = ucb::LockDepth_ZERO;
++                m_pLock->Scope = ucb::LockScope_EXCLUSIVE;
++                m_pLock->Timeout = 2*60; // 2 minutes
++
++				m_nToExpire = m_pLock->Timeout;
 +
                  // PULL: wait for client read
                  try
                  {
-@@ -2230,9 +2327,28 @@ uno::Any Content::open(
+@@ -2173,9 +2447,31 @@
                      DAVResource aResource;
                      std::vector< rtl::OUString > aHeaders;
  
 -                    uno::Reference< io::XInputStream > xIn
 -                        = xResAccess->GET( aHeaders, aResource, xEnv );
 +                    try {
-+                        m_xResAccess->LOCK( aLock, xEnv );
++                        m_xResAccess->LOCK( *m_pLock, xEnv );
++						m_pLockEnv = &xEnv;
 +                    }
 +                    catch ( ucb::CommandFailedException const &e )
 +                    {
@@ -2443,6 +2451,8 @@
 +                        ucb::InteractiveIOException aIoException;
 +                        if ( ( e.Reason >>= aIoException ) && ( aIoException.Code == ucb::IOErrorCode_LOCKING_VIOLATION ) )
 +                        {
++							delete m_pLock;
++							m_pLock = NULL;
 +                            // yes => we must be read only at the next try
 +                            m_bForceReadOnly = sal_True;
 +                        }
@@ -2454,12 +2464,12 @@
 +                        = xResAccess->GET( aHeaders, aResource, xEnv, sal_True );
  					m_bDidGetOrHead = true;
 +
-+                    // pass the lock to the stream
-+                    static_cast< NeonInputStream* >( xStream.get() )->SetLock( aLock, m_xResAccess->getURL() );
++                    // pass the URL to the stream
++                    static_cast< NeonInputStream* >( xStream.get() )->SetURL( m_xResAccess->getURL() );
  					
                      {
                          osl::MutexGuard aGuard( m_aMutex );
-@@ -2243,16 +2360,22 @@ uno::Any Content::open(
+@@ -2190,16 +2486,24 @@
                              new DAVResourceAccess( *xResAccess.get() ) );
                      }
  
@@ -2468,7 +2478,9 @@
                  }
                  catch ( DAVException const & e )
                  {
-+                    m_xResAccess->UNLOCK( aLock, xEnv );
++                    m_xResAccess->UNLOCK( *m_pLock, xEnv );
++					delete m_pLock;
++					m_pLock = NULL;
 +                    m_bForceReadOnly = sal_False;
 +
                      cancelCommandExecution( e, xEnv );
@@ -2483,7 +2495,7 @@
                  // Note: aOpenCommand.Sink may contain an XStream
                  //       implementation. Support for this type of
                  //       sink is optional...
-@@ -2280,6 +2403,9 @@ void Content::post(
+@@ -2227,6 +2531,9 @@
      uno::Reference< io::XActiveDataSink > xSink( rArg.Sink, uno::UNO_QUERY );
      if ( xSink.is() )
      {
@@ -2493,7 +2505,7 @@
          try
          {
              std::auto_ptr< DAVResourceAccess > xResAccess;
-@@ -2314,6 +2440,9 @@ void Content::post(
+@@ -2261,6 +2568,9 @@
          uno::Reference< io::XOutputStream > xResult( rArg.Sink, uno::UNO_QUERY );
          if ( xResult.is() )
          {
@@ -2503,7 +2515,7 @@
              try
              {
                  std::auto_ptr< DAVResourceAccess > xResAccess;
-@@ -2343,6 +2472,9 @@ void Content::post(
+@@ -2290,6 +2600,9 @@
          }
          else
          {
@@ -2513,17 +2525,16 @@
              ucbhelper::cancelCommandExecution(
                  uno::makeAny(
                      ucb::UnsupportedDataSinkException(
-@@ -2683,12 +2815,24 @@ void Content::transfer(
-             sourceURI.SetScheme(
+@@ -2642,11 +2955,23 @@
                  rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) );
          }
-+        else if ( aScheme.equalsAsciiL(
+         else if ( aScheme.equalsAsciiL(
 +                RTL_CONSTASCII_STRINGPARAM( PLAIN_WEBDAV_URL_SCHEME ) ) )
 +        {
 +            sourceURI.SetScheme(
 +                rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) );
 +        }
-         else if ( aScheme.equalsAsciiL(
++        else if ( aScheme.equalsAsciiL(
                  RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) )
          {
              sourceURI.SetScheme(
@@ -2538,7 +2549,7 @@
          else
          {
              if ( !aScheme.equalsAsciiL(
-@@ -2707,6 +2851,18 @@ void Content::transfer(
+@@ -2673,6 +2998,18 @@
                   RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) )
              targetURI.SetScheme(
                  rtl::OUString::createFromAscii( HTTP_URL_SCHEME ) );
@@ -2557,21 +2568,55 @@
  	
          // @@@ This implementation of 'transfer' only works
          //     if the source and target are located at same host.
---- ucb/source/ucp/webdav/webdavcontent.hxx
-+++ ucb/source/ucp/webdav/webdavcontent.hxx
-@@ -90,6 +90,7 @@ class Content : public ::ucbhelper::ContentImplHelper,
+diff -u ucb/webdav-orig/webdavcontent.hxx ucb/source/ucp/webdav/webdavcontent.hxx
+--- ucb/webdav-orig/webdavcontent.hxx	2009-03-05 13:01:30.503250000 +0200
++++ ucb/source/ucp/webdav/webdavcontent.hxx	2009-03-06 14:29:05.378250000 +0200
+@@ -33,10 +33,13 @@
+ 
+ #include <memory>
+ #include <list>
++#include <osl/signal.h>
+ #include <rtl/ref.hxx>
+ #include <com/sun/star/ucb/ContentCreationException.hpp>
+ #include <com/sun/star/ucb/XContentCreator.hpp>
++#include <com/sun/star/ucb/Lock.hpp>
+ #include <ucbhelper/contenthelper.hxx>
++
+ #include "DAVResourceAccess.hxx"
+ #include "PropertyMap.hxx"
+ 
+@@ -91,6 +94,9 @@
    	bool			  m_bTransient;
  	bool              m_bCollection;
  	bool              m_bDidGetOrHead;
 +	bool              m_bForceReadOnly;
++	com::sun::star::ucb::Lock *m_pLock;
++	const uno::Reference< ucb::XCommandEnvironment > *m_pLockEnv;
  	std::vector< rtl::OUString > m_aFailedPropNames;
  
  private:
-diff --git ucb/source/ucp/webdav/webdavcontentcaps.cxx ucb/source/ucp/webdav/webdavcontentcaps.cxx
-index ba3d4bc..f5c5652 100644
---- ucb/source/ucp/webdav/webdavcontentcaps.cxx
-+++ ucb/source/ucp/webdav/webdavcontentcaps.cxx
-@@ -263,6 +263,24 @@ bool ContentProvider::getProperty(
+@@ -184,6 +190,17 @@
+ 
+     static bool shouldAccessNetworkAfterException( const DAVException & e );
+ 
++    oslSignalHandler           m_pSignalHandler;
++    int                        m_nToExpire;
++    osl::Mutex                 m_aLock;
++
++    // Refresh the lock of the resource
++    void RefreshLock( void );
++
++    // Refresh the lock if necessary, or unlock the resource when
++    // OOo crashes or is terminated
++    static oslSignalAction HandleLockingSignal( void* pData, oslSignalInfo* pInfo );
++
+ public:
+   	Content( const ::com::sun::star::uno::Reference<
+ 	   		 ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr,
+diff -u ucb/webdav-orig/webdavcontentcaps.cxx ucb/source/ucp/webdav/webdavcontentcaps.cxx
+--- ucb/webdav-orig/webdavcontentcaps.cxx	2009-03-05 13:01:30.503250000 +0200
++++ ucb/source/ucp/webdav/webdavcontentcaps.cxx	2009-03-02 17:52:48.518875000 +0200
+@@ -263,6 +263,24 @@
  				    -1,
                      getCppuType( static_cast< const rtl::OUString * >( 0 ) ),
                      beans::PropertyAttribute::BOUND ) );
@@ -2596,10 +2641,9 @@
  		}
  	}
  
-diff --git ucb/source/ucp/webdav/webdavprovider.cxx ucb/source/ucp/webdav/webdavprovider.cxx
-index 67f670f..5675c2d 100644
---- ucb/source/ucp/webdav/webdavprovider.cxx
-+++ ucb/source/ucp/webdav/webdavprovider.cxx
+diff -u ucb/webdav-orig/webdavprovider.cxx ucb/source/ucp/webdav/webdavprovider.cxx
+--- ucb/webdav-orig/webdavprovider.cxx	2009-03-05 13:01:30.518875000 +0200
++++ ucb/source/ucp/webdav/webdavprovider.cxx	2009-03-02 17:52:48.518875000 +0200
 @@ -36,6 +36,9 @@
   **************************************************************************
  
@@ -2610,7 +2654,7 @@
  #include <ucbhelper/contentidentifier.hxx>
  #include "webdavprovider.hxx"
  #include "webdavcontent.hxx"
-@@ -138,7 +141,11 @@ ContentProvider::queryContent(
+@@ -138,7 +141,11 @@
              RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) &&
           !aScheme.equalsAsciiL(
              RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) &&
@@ -2623,7 +2667,7 @@
               RTL_CONSTASCII_STRINGPARAM( FTP_URL_SCHEME ) )       )
          throw ucb::IllegalIdentifierException();
  
-@@ -157,32 +164,27 @@ ContentProvider::queryContent(
+@@ -157,32 +164,27 @@
      uno::Reference< ucb::XContentIdentifier > xCanonicId;
  
      bool bNewId = false;
@@ -2676,16 +2720,15 @@
      }
  
      sal_Int32 nPos = aURL.lastIndexOf( '/' );
-@@ -232,4 +234,3 @@ ContentProvider::queryContent(
+@@ -232,4 +234,3 @@
  
  	return xContent;
  }
 -
-diff --git ucb/source/ucp/webdav/webdavprovider.hxx ucb/source/ucp/webdav/webdavprovider.hxx
-index 4ca8395..d9fc947 100644
---- ucb/source/ucp/webdav/webdavprovider.hxx
-+++ ucb/source/ucp/webdav/webdavprovider.hxx
-@@ -52,13 +52,10 @@ namespace webdav_ucp {
+diff -u ucb/webdav-orig/webdavprovider.hxx ucb/source/ucp/webdav/webdavprovider.hxx
+--- ucb/webdav-orig/webdavprovider.hxx	2009-03-05 13:01:30.518875000 +0200
++++ ucb/source/ucp/webdav/webdavprovider.hxx	2009-03-02 17:52:48.518875000 +0200
+@@ -52,13 +52,10 @@
  // contents ) according to this scheme.
  #define WEBDAV_URL_SCHEME \
  				"vnd.sun.star.webdav"
@@ -2699,7 +2742,7 @@
  
  #define DAV_URL_SCHEME			"dav"
  #define DAV_URL_SCHEME_LENGTH	3	
-@@ -70,6 +67,12 @@ namespace webdav_ucp {
+@@ -70,6 +67,12 @@
  
  #define FTP_URL_SCHEME "ftp"
  



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