mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-24 19:02:53 +00:00
186 lines
6.2 KiB
C++
186 lines
6.2 KiB
C++
/* This file is part of KDevelop
|
|
Copyright 2007 Kris Wong <kris.p.wong@gmail.com>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License version 2 as published by the Free Software Foundation.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#ifndef KDEVPLATFORM_DUCHAINLOCK_H
|
|
#define KDEVPLATFORM_DUCHAINLOCK_H
|
|
|
|
#include "../languageexport.h"
|
|
|
|
namespace KDevelop
|
|
{
|
|
|
|
// #define NO_DUCHAIN_LOCK_TESTING
|
|
|
|
/**
|
|
* Macros for ensuring the DUChain is locked properly.
|
|
*
|
|
* These should be used in every method that accesses or modifies a
|
|
* member on the DUChain or one of its contexts, if ENSURE_CAN_WRITE and ENSURE_CAN_READ do not apply.
|
|
* From within a Declaration or DUContext, ENSURE_CAN_WRITE and ENSURE_CAN_READ should be used instead of these.
|
|
*/
|
|
#if !defined(NDEBUG) && !defined(NO_DUCHAIN_LOCK_TESTING)
|
|
#define ENSURE_CHAIN_READ_LOCKED Q_ASSERT(DUChain::lock()->currentThreadHasReadLock() || DUChain::lock()->currentThreadHasWriteLock());
|
|
#define ENSURE_CHAIN_WRITE_LOCKED Q_ASSERT(DUChain::lock()->currentThreadHasWriteLock());
|
|
#define ENSURE_CHAIN_NOT_LOCKED Q_ASSERT(!DUChain::lock()->currentThreadHasReadLock() && !DUChain::lock()->currentThreadHasWriteLock());
|
|
#else
|
|
#define ENSURE_CHAIN_READ_LOCKED
|
|
#define ENSURE_CHAIN_WRITE_LOCKED
|
|
#define ENSURE_CHAIN_NOT_LOCKED
|
|
#endif
|
|
|
|
/**
|
|
* Customized read/write locker for the definition-use chain.
|
|
*/
|
|
class KDEVPLATFORMLANGUAGE_EXPORT DUChainLock
|
|
{
|
|
public:
|
|
/// Constructor.
|
|
DUChainLock();
|
|
/// Destructor.
|
|
~DUChainLock();
|
|
|
|
/**
|
|
* Acquires a read lock. Will not return until the lock is acquired
|
|
* or timeout
|
|
*
|
|
* Any number of read locks can be acquired at once, but not while
|
|
* there is a write lock. Read locks are recursive.
|
|
* That means that a thread can acquire a read-lock when it already
|
|
* has an arbitrary count of read- and write-locks acquired.
|
|
* @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.
|
|
*/
|
|
bool lockForRead(unsigned int timeout = 0);
|
|
|
|
/**
|
|
* Releases a previously acquired read lock.
|
|
*/
|
|
void releaseReadLock();
|
|
|
|
/**
|
|
* Determines if the current thread has a read lock.
|
|
*/
|
|
bool currentThreadHasReadLock();
|
|
|
|
/**
|
|
* Acquires a write lock. Will not return until the lock is acquired
|
|
* or timeout is reached (10 seconds).
|
|
*
|
|
* Write locks are recursive. That means that they can by acquired by threads
|
|
* that already have an arbitrary count of write-locks acquired.
|
|
*
|
|
* @param timeout A timeout in milliseconds. If zero, the default-timeout is used(Currently 10 seconds).
|
|
*
|
|
* \warning Write-locks can NOT be acquired by threads that already have a read-lock.
|
|
*/
|
|
bool lockForWrite(uint timeout = 0);
|
|
|
|
/**
|
|
* Releases a previously acquired write lock.
|
|
*/
|
|
void releaseWriteLock();
|
|
|
|
/**
|
|
* Determines if the current thread has a write lock.
|
|
*/
|
|
bool currentThreadHasWriteLock();
|
|
|
|
private:
|
|
class DUChainLockPrivate* const d;
|
|
};
|
|
|
|
/**
|
|
* Customized read locker for the definition-use chain.
|
|
*/
|
|
class KDEVPLATFORMLANGUAGE_EXPORT DUChainReadLocker
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor. Attempts to acquire a read lock.
|
|
*
|
|
* \param duChainLock lock to read-acquire. If this is left zero, DUChain::lock() is used.
|
|
* \param timeout Timeout in milliseconds. If this is not zero, you've got to check locked() to see whether the lock succeeded.
|
|
*/
|
|
DUChainReadLocker(DUChainLock* duChainLock = 0, uint timeout = 0);
|
|
|
|
/// Destructor.
|
|
~DUChainReadLocker();
|
|
|
|
/// Acquire the read lock (again). Uses the same timeout given to the constructor.
|
|
bool lock();
|
|
/// Unlock the read lock.
|
|
void unlock();
|
|
|
|
///Returns true if a lock was requested and the lock succeeded, else false
|
|
bool locked() const;
|
|
|
|
private:
|
|
///This class does not use a d-pointer for performance reasons (allocation+deletion in every high frequency is expensive)
|
|
DUChainLock* m_lock;
|
|
bool m_locked;
|
|
uint m_timeout;
|
|
};
|
|
|
|
/**
|
|
* Customized write locker for the definition-use chain.
|
|
*/
|
|
class KDEVPLATFORMLANGUAGE_EXPORT DUChainWriteLocker
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor. Attempts to acquire a write lock.
|
|
*
|
|
* \param duChainLock lock to write-acquire. If this is left zero, DUChain::lock() is used.
|
|
* \param timeout Timeout in milliseconds. If this is not zero, you've got to check locked() to see whether the lock succeeded.
|
|
*/
|
|
DUChainWriteLocker(DUChainLock* duChainLock = 0, uint timeout = 0);
|
|
/// Destructor.
|
|
~DUChainWriteLocker();
|
|
|
|
/// Acquire the write lock (again). Uses the same timeout given to the constructor.
|
|
bool lock();
|
|
/// Unlock the write lock.
|
|
void unlock();
|
|
|
|
///Returns true if a lock was requested and the lock succeeded, else false
|
|
bool locked() const;
|
|
|
|
private:
|
|
///This class does not use a d-pointer for performance reasons (allocation+deletion in every high frequency is expensive)
|
|
DUChainLock* m_lock;
|
|
bool m_locked;
|
|
uint m_timeout;
|
|
};
|
|
|
|
/**
|
|
* 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.
|
|
* Those items must implement an inDUChain() function that returns whether the item is in the du-chain.
|
|
* Examples for such detachable items are DUContext's and Declarations, they can be written as long as they are not in the DUChain.
|
|
* */
|
|
#if !defined(NDEBUG) && !defined(NO_DUCHAIN_LOCK_TESTING)
|
|
#define ENSURE_CAN_WRITE {if( inDUChain()) { ENSURE_CHAIN_WRITE_LOCKED }}
|
|
#define ENSURE_CAN_READ {if( inDUChain()) { ENSURE_CHAIN_READ_LOCKED }}
|
|
#else
|
|
#define ENSURE_CAN_WRITE
|
|
#define ENSURE_CAN_READ
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif // KDEVPLATFORM_DUCHAINLOCK_H
|
|
|
|
// kate: space-indent on; indent-width 2; tab-width 4; replace-tabs on; auto-insert-doxygen on
|