1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #ifndef DBACCESS_CONNECTION_DEPENDENT_HXX 29 #define DBACCESS_CONNECTION_DEPENDENT_HXX 30 31 /** === begin UNO includes === **/ 32 #include <com/sun/star/sdbc/XConnection.hpp> 33 #include <com/sun/star/lang/DisposedException.hpp> 34 /** === end UNO includes === **/ 35 36 #include <comphelper/componentcontext.hxx> 37 #include <cppuhelper/weakref.hxx> 38 #include <osl/mutex.hxx> 39 40 //........................................................................ 41 namespace sdbtools 42 { 43 //........................................................................ 44 45 //==================================================================== 46 //= ConnectionDependentComponent 47 //==================================================================== 48 class ConnectionDependentComponent 49 { 50 private: 51 mutable ::osl::Mutex m_aMutex; 52 ::com::sun::star::uno::WeakReference< ::com::sun::star::sdbc::XConnection > 53 m_aConnection; 54 ::comphelper::ComponentContext 55 m_aContext; 56 57 /** a hard reference to the connection we're working for 58 59 This member is only valid as long as a EntryGuard is on the stack. 60 The guard will, in its constructor, set the member, and reset it in its destructor. 61 This ensures that the connection is only held hard when it's needed, and weak otherwise. 62 */ 63 ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > 64 m_xConnection; 65 66 protected: 67 ::osl::Mutex& getMutex() const { return m_aMutex; } 68 69 const ::comphelper::ComponentContext& 70 getContext() const { return m_aContext; } 71 72 protected: 73 class EntryGuard; 74 75 protected: 76 ConnectionDependentComponent( const ::comphelper::ComponentContext& _rContext ) 77 :m_aContext( _rContext ) 78 { 79 } 80 81 /** sets the connection we depend on. 82 83 To be called exactly once. 84 85 @param _rxConnection 86 the connection to set 87 */ 88 void setWeakConnection( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection ) 89 { 90 m_aConnection = _rxConnection; 91 } 92 93 const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& 94 getConnection() const { return m_xConnection; } 95 96 public: 97 struct GuardAccess; 98 friend struct GuardAccess; 99 /** helper for granting exclusive access to various other methods 100 */ 101 struct GuardAccess { friend class EntryGuard; private: GuardAccess() { } }; 102 103 ::osl::Mutex& getMutex( GuardAccess ) const { return m_aMutex; } 104 105 inline bool acquireConnection( GuardAccess ) 106 { 107 m_xConnection = (::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >)m_aConnection; 108 return m_xConnection.is(); 109 } 110 inline void releaseConnection( GuardAccess ) 111 { 112 m_xConnection.clear(); 113 } 114 }; 115 116 //==================================================================== 117 //= ConnectionDependentComponent::EntryGuard 118 //==================================================================== 119 /** a class for guarding methods of a connection-dependent component 120 121 This class serves multiple purposes: 122 <ul><li>It ensures multi-threading safety by guarding the component's mutex 123 as long as it lives.</li> 124 <li>It ensures that the component's connection is alive. The constructor 125 throws a DisposedException if no hard reference to the connection can 126 be obtained.</li> 127 </ul> 128 */ 129 class ConnectionDependentComponent::EntryGuard 130 { 131 private: 132 ::osl::MutexGuard m_aMutexGuard; 133 ConnectionDependentComponent& m_rComponent; 134 135 public: 136 EntryGuard( ConnectionDependentComponent& _rComponent ) 137 :m_aMutexGuard( _rComponent.getMutex( ConnectionDependentComponent::GuardAccess() ) ) 138 ,m_rComponent( _rComponent ) 139 { 140 if ( !m_rComponent.acquireConnection( ConnectionDependentComponent::GuardAccess() ) ) 141 throw ::com::sun::star::lang::DisposedException(); 142 } 143 144 ~EntryGuard() 145 { 146 m_rComponent.releaseConnection( ConnectionDependentComponent::GuardAccess() ); 147 } 148 }; 149 150 151 //........................................................................ 152 } // namespace sdbtools 153 //........................................................................ 154 155 #endif // DBACCESS_CONNECTION_DEPENDENT_HXX 156 157