1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
21 #include <sal/log.hxx>
23 #include <framework/transactionmanager.hxx>
25 #include <com/sun/star/lang/DisposedException.hpp>
29 /*-************************************************************************************************************
31 @descr Initialize instance with right start values for correct working.
32 *//*-*************************************************************************************************************/
33 TransactionManager::TransactionManager()
34 : m_eWorkingMode ( E_INIT
)
35 , m_nTransactionCount ( 0 )
40 /*-************************************************************************************************************
42 *//*-*************************************************************************************************************/
43 TransactionManager::~TransactionManager()
47 /*-****************************************************************************************************
48 @short set new working mode
49 @descr These implementation knows for states of working: E_INIT, E_WORK, E_BEFORECLOSE, E_CLOSE
50 You can step during this ones only from the left to the right side and start at left side again!
51 (This is necessary e.g. for refcounted objects!)
52 This call will block till all current existing transactions was finished.
53 Following results can occur:
54 E_INIT : All requests on this implementation are refused.
55 It's your decision to react in a right way.
57 E_WORK : The object can work now. The full functionality is available.
59 E_BEFORECLOSE : The object start the closing mechanism ... but sometimes
60 e.g. the dispose() method need to call some private methods.
61 These some special methods should use E_SOFTEXCEPTIONS
62 to detect this special case!
64 E_CLOSE : Object is already dead! All further requests will be refused.
65 It's your decision to react in a right way.
66 @param "eMode", is the new mode - but we don't accept setting mode in wrong order!
67 @onerror We do nothing.
68 *//*-*****************************************************************************************************/
69 void TransactionManager::setWorkingMode( EWorkingMode eMode
)
71 // Safe member access.
72 bool bWaitFor
= false;
74 std::unique_lock
aAccessGuard(m_aAccessLock
);
75 // Change working mode first!
77 (m_eWorkingMode
== E_INIT
&& eMode
== E_WORK
) ||
78 ((m_eWorkingMode
== E_WORK
|| m_eWorkingMode
== E_INIT
) && eMode
== E_BEFORECLOSE
) ||
79 (m_eWorkingMode
== E_BEFORECLOSE
&& eMode
== E_CLOSE
) ||
80 (m_eWorkingMode
== E_CLOSE
&& eMode
== E_INIT
)
83 m_eWorkingMode
= eMode
;
84 if (m_eWorkingMode
== E_BEFORECLOSE
|| m_eWorkingMode
== E_CLOSE
)
90 // Wait for current existing transactions then!
91 // (Only necessary for changing to E_BEFORECLOSE or E_CLOSE!...
92 // otherwise; if you wait at setting E_WORK another thread could finish an acquire-call during our unlock() and wait() call
93 // ... and we will wait forever here!!!)
94 // Don't forget to release access mutex before.
101 /*-****************************************************************************************************
102 @short get current working mode
103 @descr If you stand in your close() or init() method ... but don't know
104 if you called more than ones(!) ... you can use this function to get
106 e.g: You have a method init() which is used to change working mode from
107 E_INIT to E_WORK and should be used to initialize some member too ...
110 void init( sal_Int32 nValue )
112 // Reject this call if our transaction manager say: "Object already initialized!"
113 // Otherwise initialize your member.
114 if( m_aTransactionManager.getWorkingMode() == E_INIT )
116 // Object is uninitialized ...
117 // Make member access threadsafe!
118 Guard aGuard( m_aMutex );
120 // Check working mode again .. because another instance could be faster.
121 // (It's possible to set this guard at first of this method too!)
122 if( m_aTransactionManager.getWorkingMode() == E_INIT )
126 // Object is initialized now ... set working mode to E_WORK!
127 m_aTransactionManager.setWorkingMode( E_WORK );
132 @seealso method setWorkingMode()
133 @return Current set mode.
135 @onerror No error should occur.
136 *//*-*****************************************************************************************************/
137 EWorkingMode
TransactionManager::getWorkingMode() const
139 // Synchronize access to internal member!
140 std::unique_lock
aAccessLock( m_aAccessLock
);
141 return m_eWorkingMode
;
144 /*-****************************************************************************************************
145 @short start new transaction
146 @descr A guard should use this method to start a new transaction. He should look for rejected
147 calls to by using parameter eMode and eReason.
148 If call was not rejected your transaction will be non breakable during releasing your transaction
149 guard! BUT ... your code isn't threadsafe then! It's a transaction manager only...
151 @seealso method unregisterTransaction()
153 @param "eMode" ,used to enable/disable throwing exceptions automatically for rejected calls
154 *//*-*****************************************************************************************************/
155 void TransactionManager::registerTransaction( EExceptionMode eMode
)
157 std::unique_lock
aAccessGuard( m_aAccessLock
);
158 switch( m_eWorkingMode
)
161 if( eMode
== E_HARDEXCEPTIONS
)
163 // Help programmer to find out, why this exception is thrown!
164 SAL_WARN( "fwk", "TransactionManager...: Owner instance not correctly initialized yet. Call was rejected! Normally it's an algorithm error ... wrong use of class!" );
165 //ATTENTION: temp. disabled - till all bad code positions are detected and changed! */
166 // throw css::uno::RuntimeException( "TransactionManager.: Owner instance not right initialized yet. Call was rejected! Normally it's an algorithm error... wrong using of class!\n", css::uno::Reference< css::uno::XInterface >() );
172 if( eMode
== E_HARDEXCEPTIONS
)
174 // Help programmer to find out, why this exception is thrown!
175 SAL_WARN( "fwk", "TransactionManager...: Owner instance stand in close method. Call was rejected!" );
176 throw css::lang::DisposedException( u
"TransactionManager: Owner instance stand in close method. Call was rejected!"_ustr
);
180 // Help programmer to find out, why this exception is thrown!
181 SAL_WARN( "fwk", "TransactionManager...: Owner instance already closed. Call was rejected!" );
182 throw css::lang::DisposedException( u
"TransactionManager: Owner instance already closed. Call was rejected!"_ustr
);
185 // Register this new transaction.
186 // If it is the first one .. close gate to disable changing of working mode.
187 ++m_nTransactionCount
;
188 if( m_nTransactionCount
== 1 )
194 /*-****************************************************************************************************
195 @short finish transaction
196 @descr A guard should call this method to release current transaction.
198 @seealso method registerTransaction()
199 *//*-*****************************************************************************************************/
200 void TransactionManager::unregisterTransaction()
202 // This call could not rejected!
203 // Safe access to internal member.
204 std::unique_lock
aAccessGuard( m_aAccessLock
);
206 // Deregister this transaction.
207 // If it was the last one ... open gate to enable changing of working mode!
208 // (see setWorkingMode())
210 --m_nTransactionCount
;
211 if( m_nTransactionCount
== 0 )
217 } // namespace framework
219 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */