fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / framework / source / fwi / threadhelp / transactionmanager.cxx
blob784266adb039e210939da124fd20881a03bc9804
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <cassert>
24 #include <threadhelp/transactionmanager.hxx>
26 #include <macros/generic.hxx>
28 #include <com/sun/star/lang/DisposedException.hpp>
30 namespace framework{
32 /*-************************************************************************************************************
33 @short standard ctor
34 @descr Initialize instance with right start values for correct working.
35 *//*-*************************************************************************************************************/
36 TransactionManager::TransactionManager()
37 : m_eWorkingMode ( E_INIT )
38 , m_nTransactionCount ( 0 )
40 m_aBarrier.open();
43 /*-************************************************************************************************************
44 @short standard dtor
45 *//*-*************************************************************************************************************/
46 TransactionManager::~TransactionManager()
50 /*-****************************************************************************************************
51 @short set new working mode
52 @descr These implementation knows for states of working: E_INIT, E_WORK, E_CLOSING, E_CLOSE
53 You can step during this ones only from the left to the right side and start at left side again!
54 (This is necessary e.g. for refcounted objects!)
55 This call will block till all current existing transactions was finished.
56 Following results can occur:
57 E_INIT : All requests on this implementation are refused.
58 It's your decision to react in a right way.
60 E_WORK : The object can work now. The full functionality is available.
62 E_BEFORECLOSE : The object start the closing mechanism ... but sometimes
63 e.g. the dispose() method need to call some private methods.
64 These some special methods should use E_SOFTEXCEPTIONS
65 to detect this special case!
67 E_CLOSE : Object is already dead! All further requests will be refused.
68 It's your decision to react in a right way.
69 @param "eMode", is the new mode - but we don't accept setting mode in wrong order!
70 @onerror We do nothing.
71 *//*-*****************************************************************************************************/
72 void TransactionManager::setWorkingMode( EWorkingMode eMode )
74 // Safe member access.
75 ::osl::ClearableMutexGuard aAccessGuard( m_aAccessLock );
76 bool bWaitFor = false;
77 // Change working mode first!
78 if (
79 ( m_eWorkingMode == E_INIT && eMode == E_WORK ) ||
80 ( (m_eWorkingMode == E_WORK || m_eWorkingMode == E_INIT) && eMode == E_BEFORECLOSE ) ||
81 ( m_eWorkingMode == E_BEFORECLOSE && eMode == E_CLOSE ) ||
82 ( m_eWorkingMode == E_CLOSE && eMode == E_INIT )
85 m_eWorkingMode = eMode;
86 if( m_eWorkingMode == E_BEFORECLOSE || m_eWorkingMode == E_CLOSE )
88 bWaitFor = true;
92 // Wait for current existing transactions then!
93 // (Only necessary for changing to E_BEFORECLOSE or E_CLOSE! ...
94 // otherwise; if you wait at setting E_WORK another thrad could finish a acquire-call during our unlock() and wait() call
95 // ... and we will wait forever here!!!)
96 // Don't forget to release access mutex before.
97 aAccessGuard.clear();
98 if( bWaitFor )
100 m_aBarrier.wait();
104 /*-****************************************************************************************************
105 @short get current working mode
106 @descr If you stand in your close() or init() method ... but don't know
107 if you called more than ones(!) ... you can use this function to get
108 right information.
109 e.g: You have a method init() which is used to change working mode from
110 E_INIT to E_WORK and should be used to initialize some member too ...
111 What should you do:
113 void init( sal_Int32 nValue )
115 // Reject this call if our transaction manager say: "Object already initialized!"
116 // Otherwise initialize your member.
117 if( m_aTransactionManager.getWorkingMode() == E_INIT )
119 // Object is uninitialized ...
120 // Make member access threadsafe!
121 Guard aGuard( m_aMutex );
123 // Check working mode again .. because another instance could be faster.
124 // (It's possible to set this guard at first of this method too!)
125 if( m_aTransactionManager.getWorkingMode() == E_INIT )
127 m_aMember = nValue;
129 // Object is initialized now ... set working mode to E_WORK!
130 m_aTransactionManager.setWorkingMode( E_WORK );
135 @seealso method setWorkingMode()
136 @return Current set mode.
138 @onerror No error should occur.
139 *//*-*****************************************************************************************************/
140 EWorkingMode TransactionManager::getWorkingMode() const
142 // Synchronize access to internal member!
143 ::osl::MutexGuard aAccessLock( m_aAccessLock );
144 return m_eWorkingMode;
147 /*-****************************************************************************************************
148 @short start new transaction
149 @descr A guard should use this method to start a new transaction. He should looks for rejected
150 calls to by using parameter eMode and eReason.
151 If call was not rejected your transaction will be non breakable during releasing your transaction
152 guard! BUT ... your code isn't threadsafe then! It's a transaction manager only ....
154 @seealso method unregisterTransaction()
156 @param "eMode" ,used to enable/disable throwing exceptions automatically for rejected calls
157 @param "eReason" ,reason for rejected calls
158 *//*-*****************************************************************************************************/
159 void TransactionManager::registerTransaction( EExceptionMode eMode, ERejectReason& eReason ) throw( css::uno::RuntimeException, css::lang::DisposedException )
161 // Look for rejected calls first.
162 // If call was refused we throw some exceptions or do nothing!
163 // It depends from given parameter eMode.
164 if( isCallRejected( eReason ) )
166 impl_throwExceptions( eMode, eReason );
169 // BUT if no exception was thrown ... (may be eMode = E_SOFTEXCEPTIONS!)
170 // we must register this transaction too!
171 // Don't use "else" or a new scope here!!!
173 // Safe access to internal member.
174 ::osl::MutexGuard aAccessGuard( m_aAccessLock );
176 // Register this new transaction.
177 // If it is the first one .. close gate to disable changing of working mode.
178 ++m_nTransactionCount;
179 if( m_nTransactionCount == 1 )
181 m_aBarrier.close();
185 /*-****************************************************************************************************
186 @short finish transaction
187 @descr A guard should call this method to release current transaction.
189 @seealso method registerTransaction()
190 *//*-*****************************************************************************************************/
191 void TransactionManager::unregisterTransaction() throw( css::uno::RuntimeException, css::lang::DisposedException )
193 // This call could not rejected!
194 // Safe access to internal member.
195 ::osl::MutexGuard aAccessGuard( m_aAccessLock );
197 // Deregister this transaction.
198 // If it was the last one ... open gate to enable changing of working mode!
199 // (see setWorkingMode())
201 --m_nTransactionCount;
202 if( m_nTransactionCount == 0 )
204 m_aBarrier.open();
208 /*-****************************************************************************************************
209 @short look for rejected calls
210 @descr Sometimes user need a possibility to get information about rejected calls
211 without starting a transaction!
212 @param "eReason" returns reason of a rejected call
213 @return true if call was rejected, false otherwise
215 @onerror We return false.
216 *//*-*****************************************************************************************************/
217 bool TransactionManager::isCallRejected( ERejectReason& eReason ) const
219 // This call must safe access to internal member only.
220 // Set "possible reason" for return and check reject-state then!
221 // User should look for return value first - reason then ...
222 ::osl::MutexGuard aAccessGuard( m_aAccessLock );
223 switch( m_eWorkingMode )
225 case E_INIT : eReason = E_UNINITIALIZED;
226 break;
227 case E_WORK : eReason = E_NOREASON;
228 break;
229 case E_BEFORECLOSE : eReason = E_INCLOSE;
230 break;
231 case E_CLOSE : eReason = E_CLOSED;
232 break;
234 return( eReason!=E_NOREASON );
237 /*-****************************************************************************************************
238 @short throw any exceptions for rejected calls
239 @descr If a user wishes to use our automatic exception mode we use this impl-method.
240 We check all combinations of eReason and eExceptionMode and throw correct exception with some
241 descriptions for the recipient.
243 @seealso method registerTransaction()
244 @seealso enum ERejectReason
245 @seealso enum EExceptionMode
247 @param "eReason" , reason for rejected call
248 @param "eMode" , exception mode - set by user
249 *//*-*****************************************************************************************************/
250 void TransactionManager::impl_throwExceptions( EExceptionMode eMode, ERejectReason eReason ) const throw( css::uno::RuntimeException, css::lang::DisposedException )
252 switch( eReason )
254 case E_UNINITIALIZED : if( eMode == E_HARDEXCEPTIONS )
256 // Help programmer to find out, why this exception is thrown!
257 SAL_WARN( "fwk", "TransactionManager...: Owner instance not correctly initialized yet. Call was rejected! Normally it's an algorithm error ... wrong use of class!" );
258 //ATTENTION: temp. disabled - till all bad code positions are detected and changed! */
259 // throw css::uno::RuntimeException( "TransactionManager...\nOwner instance not right initialized yet. Call was rejected! Normally it's an algorithm error ... wrong usin of class!\n", css::uno::Reference< css::uno::XInterface >() );
261 break;
262 case E_INCLOSE : if( eMode == E_HARDEXCEPTIONS )
264 // Help programmer to find out, why this exception is thrown!
265 SAL_WARN( "fwk", "TransactionManager...: Owner instance stand in close method. Call was rejected!" );
266 throw css::lang::DisposedException( "TransactionManager...\nOwner instance stand in close method. Call was rejected!" );
268 break;
269 case E_CLOSED : {
270 // Help programmer to find out, why this exception is thrown!
271 SAL_WARN( "fwk", "TransactionManager...: Owner instance already closed. Call was rejected!" );
272 throw css::lang::DisposedException( "TransactionManager...\nOwner instance already closed. Call was rejected!" );
274 case E_NOREASON : {
275 // Help programmer to find out
276 SAL_WARN( "fwk", "TransactionManager...: Impossible case E_NOREASON!" );
278 break;
279 default:
280 assert(false);
284 } // namespace framework
286 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */