1*2e2212a7SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*2e2212a7SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*2e2212a7SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*2e2212a7SAndrew Rist  * distributed with this work for additional information
6*2e2212a7SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*2e2212a7SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*2e2212a7SAndrew Rist  * "License"); you may not use this file except in compliance
9*2e2212a7SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*2e2212a7SAndrew Rist  *
11*2e2212a7SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*2e2212a7SAndrew Rist  *
13*2e2212a7SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*2e2212a7SAndrew Rist  * software distributed under the License is distributed on an
15*2e2212a7SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*2e2212a7SAndrew Rist  * KIND, either express or implied.  See the License for the
17*2e2212a7SAndrew Rist  * specific language governing permissions and limitations
18*2e2212a7SAndrew Rist  * under the License.
19*2e2212a7SAndrew Rist  *
20*2e2212a7SAndrew Rist  *************************************************************/
21*2e2212a7SAndrew Rist 
22*2e2212a7SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #ifndef DBACCESS_CONNECTION_DEPENDENT_HXX
25cdf0e10cSrcweir #define DBACCESS_CONNECTION_DEPENDENT_HXX
26cdf0e10cSrcweir 
27cdf0e10cSrcweir /** === begin UNO includes === **/
28cdf0e10cSrcweir #include <com/sun/star/sdbc/XConnection.hpp>
29cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp>
30cdf0e10cSrcweir /** === end UNO includes === **/
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <comphelper/componentcontext.hxx>
33cdf0e10cSrcweir #include <cppuhelper/weakref.hxx>
34cdf0e10cSrcweir #include <osl/mutex.hxx>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir //........................................................................
37cdf0e10cSrcweir namespace sdbtools
38cdf0e10cSrcweir {
39cdf0e10cSrcweir //........................................................................
40cdf0e10cSrcweir 
41cdf0e10cSrcweir 	//====================================================================
42cdf0e10cSrcweir 	//= ConnectionDependentComponent
43cdf0e10cSrcweir 	//====================================================================
44cdf0e10cSrcweir     class ConnectionDependentComponent
45cdf0e10cSrcweir     {
46cdf0e10cSrcweir     private:
47cdf0e10cSrcweir         mutable ::osl::Mutex    m_aMutex;
48cdf0e10cSrcweir         ::com::sun::star::uno::WeakReference< ::com::sun::star::sdbc::XConnection >
49cdf0e10cSrcweir                                 m_aConnection;
50cdf0e10cSrcweir         ::comphelper::ComponentContext
51cdf0e10cSrcweir                                 m_aContext;
52cdf0e10cSrcweir 
53cdf0e10cSrcweir         /** a hard reference to the connection we're working for
54cdf0e10cSrcweir 
55cdf0e10cSrcweir             This member is only valid as long as a EntryGuard is on the stack.
56cdf0e10cSrcweir             The guard will, in its constructor, set the member, and reset it in its destructor.
57cdf0e10cSrcweir             This ensures that the connection is only held hard when it's needed, and weak otherwise.
58cdf0e10cSrcweir         */
59cdf0e10cSrcweir         ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >
60cdf0e10cSrcweir                                 m_xConnection;
61cdf0e10cSrcweir 
62cdf0e10cSrcweir     protected:
getMutex() const63cdf0e10cSrcweir         ::osl::Mutex&   getMutex() const { return m_aMutex; }
64cdf0e10cSrcweir 
65cdf0e10cSrcweir         const ::comphelper::ComponentContext&
getContext() const66cdf0e10cSrcweir                         getContext() const { return m_aContext; }
67cdf0e10cSrcweir 
68cdf0e10cSrcweir     protected:
69cdf0e10cSrcweir         class EntryGuard;
70cdf0e10cSrcweir 
71cdf0e10cSrcweir     protected:
ConnectionDependentComponent(const::comphelper::ComponentContext & _rContext)72cdf0e10cSrcweir         ConnectionDependentComponent( const ::comphelper::ComponentContext& _rContext )
73cdf0e10cSrcweir             :m_aContext( _rContext )
74cdf0e10cSrcweir         {
75cdf0e10cSrcweir         }
76cdf0e10cSrcweir 
77cdf0e10cSrcweir         /** sets the connection we depend on.
78cdf0e10cSrcweir 
79cdf0e10cSrcweir             To be called exactly once.
80cdf0e10cSrcweir 
81cdf0e10cSrcweir             @param  _rxConnection
82cdf0e10cSrcweir                 the connection to set
83cdf0e10cSrcweir         */
setWeakConnection(const::com::sun::star::uno::Reference<::com::sun::star::sdbc::XConnection> & _rxConnection)84cdf0e10cSrcweir         void    setWeakConnection( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection )
85cdf0e10cSrcweir         {
86cdf0e10cSrcweir             m_aConnection = _rxConnection;
87cdf0e10cSrcweir         }
88cdf0e10cSrcweir 
89cdf0e10cSrcweir         const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >&
getConnection() const90cdf0e10cSrcweir                 getConnection() const { return m_xConnection; }
91cdf0e10cSrcweir 
92cdf0e10cSrcweir     public:
93cdf0e10cSrcweir 	struct GuardAccess;
94cdf0e10cSrcweir 	friend struct GuardAccess;
95cdf0e10cSrcweir         /** helper for granting exclusive access to various other methods
96cdf0e10cSrcweir         */
GuardAccesssdbtools::ConnectionDependentComponent::GuardAccess97cdf0e10cSrcweir         struct GuardAccess { friend class EntryGuard; private: GuardAccess() { } };
98cdf0e10cSrcweir 
getMutex(GuardAccess) const99cdf0e10cSrcweir         ::osl::Mutex&   getMutex( GuardAccess ) const { return m_aMutex; }
100cdf0e10cSrcweir 
acquireConnection(GuardAccess)101cdf0e10cSrcweir         inline bool acquireConnection( GuardAccess )
102cdf0e10cSrcweir         {
103cdf0e10cSrcweir             m_xConnection = (::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >)m_aConnection;
104cdf0e10cSrcweir             return m_xConnection.is();
105cdf0e10cSrcweir         }
releaseConnection(GuardAccess)106cdf0e10cSrcweir         inline void releaseConnection( GuardAccess )
107cdf0e10cSrcweir         {
108cdf0e10cSrcweir             m_xConnection.clear();
109cdf0e10cSrcweir         }
110cdf0e10cSrcweir     };
111cdf0e10cSrcweir 
112cdf0e10cSrcweir 	//====================================================================
113cdf0e10cSrcweir 	//= ConnectionDependentComponent::EntryGuard
114cdf0e10cSrcweir 	//====================================================================
115cdf0e10cSrcweir     /** a class for guarding methods of a connection-dependent component
116cdf0e10cSrcweir 
117cdf0e10cSrcweir         This class serves multiple purposes:
118cdf0e10cSrcweir         <ul><li>It ensures multi-threading safety by guarding the component's mutex
119cdf0e10cSrcweir                 as long as it lives.</li>
120cdf0e10cSrcweir             <li>It ensures that the component's connection is alive. The constructor
121cdf0e10cSrcweir                 throws a DisposedException if no hard reference to the connection can
122cdf0e10cSrcweir                 be obtained.</li>
123cdf0e10cSrcweir         </ul>
124cdf0e10cSrcweir     */
125cdf0e10cSrcweir     class ConnectionDependentComponent::EntryGuard
126cdf0e10cSrcweir     {
127cdf0e10cSrcweir     private:
128cdf0e10cSrcweir         ::osl::MutexGuard               m_aMutexGuard;
129cdf0e10cSrcweir         ConnectionDependentComponent&   m_rComponent;
130cdf0e10cSrcweir 
131cdf0e10cSrcweir     public:
EntryGuard(ConnectionDependentComponent & _rComponent)132cdf0e10cSrcweir         EntryGuard( ConnectionDependentComponent& _rComponent )
133cdf0e10cSrcweir             :m_aMutexGuard( _rComponent.getMutex( ConnectionDependentComponent::GuardAccess() ) )
134cdf0e10cSrcweir             ,m_rComponent( _rComponent )
135cdf0e10cSrcweir         {
136cdf0e10cSrcweir             if ( !m_rComponent.acquireConnection( ConnectionDependentComponent::GuardAccess() ) )
137cdf0e10cSrcweir                 throw ::com::sun::star::lang::DisposedException();
138cdf0e10cSrcweir         }
139cdf0e10cSrcweir 
~EntryGuard()140cdf0e10cSrcweir         ~EntryGuard()
141cdf0e10cSrcweir         {
142cdf0e10cSrcweir             m_rComponent.releaseConnection( ConnectionDependentComponent::GuardAccess() );
143cdf0e10cSrcweir         }
144cdf0e10cSrcweir     };
145cdf0e10cSrcweir 
146cdf0e10cSrcweir 
147cdf0e10cSrcweir //........................................................................
148cdf0e10cSrcweir } // namespace sdbtools
149cdf0e10cSrcweir //........................................................................
150cdf0e10cSrcweir 
151cdf0e10cSrcweir #endif // DBACCESS_CONNECTION_DEPENDENT_HXX
152cdf0e10cSrcweir 
153