summaryrefslogtreecommitdiff
path: root/ucb
diff options
context:
space:
mode:
authorTor Lillqvist <tlillqvist@suse.com>2013-05-30 06:48:39 +0200
committerTor Lillqvist <tlillqvist@suse.com>2013-05-30 07:48:42 +0300
commit9c15384bc67e7878e8efefa422b4ab39d438413f (patch)
tree077f56269a34477387d76bc7c0ddb715153c5785 /ucb
parent5ffde2307ba2d0d139bccf4e2cdf487849bf4f5f (diff)
bnc#805901: Lock WebDAV document that is opened for potential modification
Really horrible fix, breaking all rules of proper abstraction etc. Basically, two parts: 1) When opening a document over WebDAV, in Content::execute(), lock it too. This is simple. With just this change, the WebDAV resource gets locked but it stays locked for the rest of the soffice.bin lifetime, even if the document is closed much earlier. This also means you can't re-open it without re-starting LibreOffice... The NeonLockStore (which is effectively a singleton, as the only object of this type that exists is the static NeonSession::m_aNeonLockStore field) destructor takes care of blowing awway the locks when the process exists. So obviously that is not good enough. Thus a second part is needed: 2) Then closing a document, over in SfxObjectShell::Close(), do a horrible trick: look up the ucpdav1 module, and if it is loaded, look up the NeonSessionUnlockByUri() function in it, and call it, passing the document's URI. That function, in NeonSession.cxx, looks up the NeonLock for the URI, and if it exists, unlocks it, and removs the lock from the NeonLockStore.
Diffstat (limited to 'ucb')
-rw-r--r--ucb/source/ucp/webdav-neon/NeonLockStore.cxx15
-rw-r--r--ucb/source/ucp/webdav-neon/NeonLockStore.hxx2
-rw-r--r--ucb/source/ucp/webdav-neon/NeonSession.cxx11
-rw-r--r--ucb/source/ucp/webdav-neon/NeonSession.hxx3
-rw-r--r--ucb/source/ucp/webdav-neon/webdavcontent.cxx6
5 files changed, 36 insertions, 1 deletions
diff --git a/ucb/source/ucp/webdav-neon/NeonLockStore.cxx b/ucb/source/ucp/webdav-neon/NeonLockStore.cxx
index c4d853332655..e5f204fbe0ec 100644
--- a/ucb/source/ucp/webdav-neon/NeonLockStore.cxx
+++ b/ucb/source/ucp/webdav-neon/NeonLockStore.cxx
@@ -212,6 +212,21 @@ void NeonLockStore::removeLock( NeonLock * pLock )
stopTicker();
}
+void NeonLockStore::unlockLock( NeonLock * pLock )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ LockInfoMap::const_iterator it( m_aLockInfoMap.begin() );
+ const LockInfoMap::const_iterator end( m_aLockInfoMap.end() );
+ while ( it != end )
+ {
+ NeonLock * pLockIt = (*it).first;
+ if (pLockIt == pLock)
+ (*it).second.xSession->UNLOCK( pLock );
+ ++it;
+ }
+ }
+
// -------------------------------------------------------------------
void NeonLockStore::refreshLocks()
{
diff --git a/ucb/source/ucp/webdav-neon/NeonLockStore.hxx b/ucb/source/ucp/webdav-neon/NeonLockStore.hxx
index c8f0f0fcba99..27e37d43fff1 100644
--- a/ucb/source/ucp/webdav-neon/NeonLockStore.hxx
+++ b/ucb/source/ucp/webdav-neon/NeonLockStore.hxx
@@ -91,6 +91,8 @@ public:
void removeLock( NeonLock * pLock );
+ void unlockLock( NeonLock * pLock );
+
void refreshLocks();
private:
diff --git a/ucb/source/ucp/webdav-neon/NeonSession.cxx b/ucb/source/ucp/webdav-neon/NeonSession.cxx
index f1f3b9f38dae..b4a90a9c6c66 100644
--- a/ucb/source/ucp/webdav-neon/NeonSession.cxx
+++ b/ucb/source/ucp/webdav-neon/NeonSession.cxx
@@ -2204,4 +2204,15 @@ rtl::OUString NeonSession::makeAbsoluteURL( rtl::OUString const & rURL ) const
return rtl::OUString();
}
+extern "C" SAL_DLLPUBLIC_EXPORT void NeonSessionUnlockByUri(rtl::OUString uri)
+{
+ NeonLock *pLock = NeonSession::m_aNeonLockStore.findByUri(uri);
+
+ if (!pLock)
+ return;
+
+ NeonSession::m_aNeonLockStore.unlockLock(pLock);
+ NeonSession::m_aNeonLockStore.removeLock(pLock);
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/ucb/source/ucp/webdav-neon/NeonSession.hxx b/ucb/source/ucp/webdav-neon/NeonSession.hxx
index 15c88bb72ffc..0c6cc8d8c133 100644
--- a/ucb/source/ucp/webdav-neon/NeonSession.hxx
+++ b/ucb/source/ucp/webdav-neon/NeonSession.hxx
@@ -68,12 +68,13 @@ private:
DAVRequestEnvironment m_aEnv;
static bool m_bGlobalsInited;
- static NeonLockStore m_aNeonLockStore;
protected:
virtual ~NeonSession();
public:
+ static NeonLockStore m_aNeonLockStore;
+
NeonSession( const rtl::Reference< DAVSessionFactory > & rSessionFactory,
const rtl::OUString& inUri,
const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& rFlags,
diff --git a/ucb/source/ucp/webdav-neon/webdavcontent.cxx b/ucb/source/ucp/webdav-neon/webdavcontent.cxx
index a00763e7540d..03578fe4dc19 100644
--- a/ucb/source/ucp/webdav-neon/webdavcontent.cxx
+++ b/ucb/source/ucp/webdav-neon/webdavcontent.cxx
@@ -500,6 +500,12 @@ uno::Any SAL_CALL Content::execute(
}
aRet = open( aOpenCommand, Environment );
+#if 1
+ if ( (aOpenCommand.Mode == ucb::OpenMode::DOCUMENT ||
+ aOpenCommand.Mode == ucb::OpenMode::DOCUMENT_SHARE_DENY_WRITE) &&
+ supportsExclusiveWriteLock( Environment ) )
+ lock( Environment );
+#endif
}
else if ( aCommand.Name == "insert" )
{