meos-2024/code/meosdb/mysql++/lockable.h
2017-08-30 08:57:46 +02:00

164 lines
4.5 KiB
C++

/// \file lockable.h
/// \brief Declares interface that allows a class to declare itself as
/// "lockable".
///
/// The meaning of a class being lockable is very much per-class
/// specific in this version of MySQL++. In a future version, it will
/// imply that operations that aren't normally thread-safe will use
/// platform mutexes if MySQL++ is configured to support them. This is
/// planned for a version beyond v2.0. (See the Wishlist for the plan.)
/// In the meantime, do not depend on this mechanism for thread safety;
/// you will have to serialize access to some resources yourself.
///
/// To effect this variability in what it means for an object to be
/// "locked", Lockable is only an interface. It delegates the actual
/// implementation to a subclass of the Lock interface, using the
/// Bridge pattern. (See Gamma et al.)
/***********************************************************************
Copyright (c) 2005 by Educational Technology Resources, Inc.
Others may also hold copyrights on code in this file. See the CREDITS
file in the top directory of the distribution for details.
This file is part of MySQL++.
MySQL++ is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
MySQL++ 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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
License along with MySQL++; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
***********************************************************************/
#ifndef MYSQLPP_LOCKABLE_H
#define MYSQLPP_LOCKABLE_H
namespace mysqlpp {
/// \brief Abstract base class for lock implementation, used by
/// Lockable.
class MYSQLPP_EXPORT Lock
{
public:
/// \brief Destroy object
virtual ~Lock() { }
/// \brief Lock the object
///
/// \return true if object was already locked
virtual bool lock() = 0;
/// \brief Unlock the object
virtual void unlock() = 0;
/// \brief Returns true if object is locked
virtual bool locked() const = 0;
/// \brief Set the lock state.
virtual void set(bool b) = 0;
};
/// \brief Trivial Lock subclass, using a boolean variable as the
/// lock flag.
///
/// This is the only Lock implementation available in this version of
/// MySQL++. It will be supplemented with a better implementation for
/// use with threads at a later date.
class MYSQLPP_EXPORT BasicLock : public Lock
{
public:
/// \brief Create object
BasicLock(bool is_locked = false) :
locked_(is_locked)
{
}
/// \brief Destroy object
~BasicLock() { }
/// \brief Lock the object
///
/// \return true if object was already locked
bool lock()
{
if (locked_) {
return true;
}
locked_ = true;
return false;
}
/// \brief Unlock the object
void unlock() { locked_ = false; }
/// \brief Returns true if object is locked
bool locked() const { return locked_; }
/// \brief Set the lock state.
void set(bool b) { locked_ = b; }
private:
bool locked_;
};
/// \brief Interface allowing a class to declare itself as "lockable".
///
/// A class derives from this one to acquire a standard interface for
/// serializing operations that may not be thread-safe.
class MYSQLPP_EXPORT Lockable
{
protected:
/// \brief Default constructor
Lockable(bool is_locked) :
pimpl_(new BasicLock(is_locked))
{
}
/// \brief Destroy object
virtual ~Lockable()
{
delete pimpl_;
}
/// \brief Lock the object
///
/// \return true if object was already locked
virtual bool lock() { return pimpl_->lock(); }
/// \brief Unlock the object
virtual void unlock() { pimpl_->unlock(); }
/// \brief Returns true if object is locked
bool locked() const { return pimpl_->locked(); }
protected:
/// \brief Set the lock state. Protected, because this method is
/// only for use by subclass assignment operators and the like.
void set_lock(bool b) { pimpl_->set(b); }
private:
// Don't allow default construction
Lockable();
// Pointer to implementation object
Lock* pimpl_;
};
} // end namespace mysqlpp
#endif // MYSQLPP_LOCKABLE_H