Add AbstractDeclarationNavigationContext, and move the html-method from
[kdevelopdvcssupport.git] / language / duchain / duchainlock.h
blob77cb66a2950f8ec48027400f57eb4fab2f803b7e
1 /* This file is part of KDevelop
2 Copyright 2007 Kris Wong <kris.p.wong@gmail.com>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
19 #ifndef DUCHAINLOCK_H
20 #define DUCHAINLOCK_H
22 #include "../languageexport.h"
25 /**
26 * In a DEBUG build, keeps track of additional locking information.
27 * In a non-DEBUG build, is actually a QReadWriteLock.
29 #if 0
31 //krazy:excludeall=dpointer
33 #include <QtCore/QReadWriteLock>
35 namespace KDevelop
38 #define ENSURE_CHAIN_READ_LOCKED
39 #define ENSURE_CHAIN_WRITE_LOCKED
42 class KDEVPLATFORMLANGUAGE_EXPORT DUChainLock : public QReadWriteLock //krazy:exclude=dpointer
44 public:
45 DUChainLock() : QReadWriteLock() {}
46 ~DUChainLock() {}
49 class KDEVPLATFORMLANGUAGE_EXPORT DUChainReadLocker : public QReadLocker //krazy:exclude=dpointer
51 public:
52 DUChainReadLocker(DUChainLock* duChainLock) : QReadLocker(duChainLock) {}
53 ~DUChainReadLocker() {}
56 class KDEVPLATFORMLANGUAGE_EXPORT DUChainWriteLocker : public QWriteLocker //krazy:exclude=dpointer
58 public:
59 DUChainWriteLocker(DUChainLock* duChainLock) : QWriteLocker(duChainLock) {}
60 ~DUChainWriteLocker() {}
63 #else
65 namespace KDevelop
68 /**
69 * Macros for ensuring the DUChain is locked properly.
71 * These should be used in every method that accesses or modifies a
72 * member on the DUChain or one of its contexts, if ENSURE_CAN_WRITE and ENSURE_CAN_READ do not apply.
73 * From within a Declaration or DUContext, ENSURE_CAN_WRITE and ENSURE_CAN_READ should be used instead of these.
75 #ifndef NDEBUG
76 #define ENSURE_CHAIN_READ_LOCKED Q_ASSERT(DUChain::lock()->currentThreadHasReadLock() || DUChain::lock()->currentThreadHasWriteLock());
77 #define ENSURE_CHAIN_WRITE_LOCKED Q_ASSERT(DUChain::lock()->currentThreadHasWriteLock());
78 #else
79 #define ENSURE_CHAIN_READ_LOCKED
80 #define ENSURE_CHAIN_WRITE_LOCKED
81 #endif
83 /**
84 * Customised read/write locker for the definition-use chain.
86 class KDEVPLATFORMLANGUAGE_EXPORT DUChainLock
88 public:
89 /// Constructor.
90 DUChainLock();
91 /// Destructor.
92 ~DUChainLock();
94 /**
95 * Acquires a read lock. Will not return until the lock is acquired
96 * or timeout
98 * Any number of read locks can be acquired at once, but not while
99 * there is a write lock. Read locks are recursive.
100 * That means that a thread can acquire a read-lock when it already
101 * has an arbitrary count of read- and write-locks acquired.
102 * @param timeout A locking timeout in milliseconds. If it is reached, and the lock could not be acquired, false is returned. If null, the default timeout is used.
104 bool lockForRead(unsigned int timeout);
107 * Acquires a read lock. Will not return until the lock is acquired
108 * or timeout of 10 seconds is reached.
110 * Any number of read locks can be acquired at once, but not while
111 * there is a write lock. Read locks are recursive.
112 * That means that a thread can acquire a read-lock when it already
113 * has an arbitrary count of read- and write-locks acquired.
115 bool lockForRead();
118 * Releases a previously acquired read lock.
120 void releaseReadLock();
123 * Determines if the current thread has a read lock.
125 bool currentThreadHasReadLock();
128 * Acquires a write lock. Will not return until the lock is acquired
129 * or timeout is reached (10 seconds).
131 * Write locks are recursive. That means that they can by acquired by threads
132 * that already have an arbitrary count of write-locks acquired.
134 * @param timeout A timeout in milliseconds. If zero, the default-timeout is used(Currently 10 seconds).
136 * \warning Write-locks can NOT be acquired by threads that already have a read-lock.
138 bool lockForWrite(uint timeout = 0);
141 * Releases a previously acquired write lock.
143 void releaseWriteLock();
146 * Determines if the current thread has a write lock.
148 bool currentThreadHasWriteLock();
150 private:
151 class DUChainLockPrivate* const d;
155 * Customised read locker for the definition-use chain.
157 class KDEVPLATFORMLANGUAGE_EXPORT DUChainReadLocker
159 public:
161 * Constructor. Attempts to acquire a read lock.
163 * \param duChainLock lock to read-acquire.
164 * \param timeout Timeout in milliseconds. If this is not zero, you've got to check locked() to see whether the lock succeeded.
166 DUChainReadLocker(DUChainLock* duChainLock, uint timeout = 0);
168 /// Destructor.
169 ~DUChainReadLocker();
171 /// Acquire the read lock (again). Uses the same timeout given to the constructor.
172 bool lock();
173 /// Unlock the read lock.
174 void unlock();
176 ///Returns true if a lock was requested and the lock succeeded, else false
177 bool locked() const;
179 private:
180 DUChainLock* m_lock;
181 bool m_locked;
182 uint m_timeout;
186 * Customised write locker for the definition-use chain.
188 class KDEVPLATFORMLANGUAGE_EXPORT DUChainWriteLocker
190 public:
192 * Constructor. Attempts to acquire a write lock.
194 * \param duChainLock lock to write-acquire.
195 * \param timeout Timeout in milliseconds. If this is not zero, you've got to check locked() to see whether the lock succeeded.
197 DUChainWriteLocker(DUChainLock* duChainLock, uint timeout = 0);
198 /// Destructor.
199 ~DUChainWriteLocker();
201 /// Acquire the write lock (again). Uses the same timeout given to the constructor.
202 bool lock();
203 /// Unlock the write lock.
204 void unlock();
206 ///Returns true if a lock was requested and the lock succeeded, else false
207 bool locked() const;
209 private:
210 class DUChainWriteLockerPrivate* const d;
213 #endif // NDEBUG
216 * Like the ENSURE_CHAIN_WRITE_LOCKED and .._READ_LOCKED, except that this should be used in items that can be detached from the du-chain, like DOContext's and Declarations.
217 * Those items must implement an inDUChain() function that returns whether the item is in the du-chain.
218 * Examples for such detachable items are DUContext's and Declarations, they can be written as long as they are not in the DUChain.
219 * */
220 #ifndef NDEBUG
221 #define ENSURE_CAN_WRITE {if( inDUChain()) { ENSURE_CHAIN_WRITE_LOCKED }}
222 #define ENSURE_CAN_READ {if( inDUChain()) { ENSURE_CHAIN_READ_LOCKED }}
223 #else
224 #define ENSURE_CAN_WRITE
225 #define ENSURE_CAN_READ
226 #endif
230 #endif // DUCHAINLOCK_H
232 // kate: space-indent on; indent-width 2; tab-width 4; replace-tabs on; auto-insert-doxygen on