tests/auto/qsharedmemory/src/qsystemlock.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include "qsystemlock.h"
       
    44 #include "qsystemlock_p.h"
       
    45 
       
    46 #include <qdebug.h>
       
    47 
       
    48 /*! \class QSystemLocker
       
    49 
       
    50     \brief The QSystemLocker class is a convenience class that simplifies
       
    51     locking and unlocking system locks.
       
    52 
       
    53     The purpose of QSystemLocker is to simplify QSystemLock locking and
       
    54     unlocking.  Locking and unlocking a QSystemLock in complex functions and
       
    55     statements or in exception handling code is error-prone and difficult to
       
    56     debug.  QSystemLocker can be used in such situations to ensure that the
       
    57     state of the locks is always well-defined.
       
    58 
       
    59     QSystemLocker should be created within a function where a QSystemLock needs
       
    60     to be locked. The system lock is locked when QSystemLocker is created.  If
       
    61     locked, the system lock will be unlocked when the QSystemLocker is
       
    62     destroyed.  QSystemLocker can be unlocked with unlock() and relocked with
       
    63     relock().
       
    64 
       
    65     \sa QSystemLock
       
    66  */
       
    67 
       
    68 /*! \fn QSystemLocker::QSystemLocker()
       
    69 
       
    70     Constructs a QSystemLocker and locks \a lock. The \a lock will be
       
    71     unlocked when the QSystemLocker is destroyed. If lock is zero,
       
    72     QSystemLocker does nothing.
       
    73 
       
    74     \sa QSystemLock::lock()
       
    75   */
       
    76 
       
    77 /*! \fn QSystemLocker::~QSystemLocker()
       
    78 
       
    79     Destroys the QSystemLocker and unlocks it if it was
       
    80     locked in the constructor.
       
    81 
       
    82     \sa QSystemLock::unlock()
       
    83  */
       
    84 
       
    85 /*! \fn QSystemLocker::systemLock()
       
    86 
       
    87     Returns a pointer to the lock that was locked in the constructor.
       
    88  */
       
    89 
       
    90 /*! \fn QSystemLocker::relock()
       
    91 
       
    92     Relocks an unlocked locker.
       
    93 
       
    94     \sa unlock()
       
    95   */
       
    96 
       
    97 /*! \fn QSystemLocker::unlock()
       
    98 
       
    99     Unlocks this locker. You can use relock() to lock it again.
       
   100     It does not need to be locked when destroyed.
       
   101 
       
   102     \sa relock()
       
   103  */
       
   104 
       
   105 /*! \class QSystemLock
       
   106 
       
   107     \brief The QSystemLock class provides a system wide lock
       
   108     that can be used between threads or processes.
       
   109 
       
   110     The purpose of a QSystemLocker is to protect an object that can be
       
   111     accessed by multiple threads or processes such as shared memory or a file.
       
   112 
       
   113     For example, say there is a method which prints a message to a log file:
       
   114 
       
   115     void log(const QString &logText)
       
   116     {
       
   117         QSystemLock systemLock(QLatin1String("logfile"));
       
   118         systemLock.lock();
       
   119         QFile file(QDir::temp() + QLatin1String("/log"));
       
   120         if (file.open(QIODevice::Append)) {
       
   121             QTextStream out(&file);
       
   122             out << logText;
       
   123         }
       
   124         systemLock.unlock();
       
   125     }
       
   126 
       
   127     If this is called from two seperate processes the resulting log file is
       
   128     guaranteed to contain both lines.
       
   129 
       
   130     When you call lock(), other threads or processes that try to call lock()
       
   131     with the same key will block until the thread or process that got the lock
       
   132     calls unlock().
       
   133 
       
   134     A non-blocking alternative to lock() is tryLock().
       
   135  */
       
   136 
       
   137 /*!
       
   138     Constructs a new system lock with \a key. The lock is created in an
       
   139     unlocked state.
       
   140 
       
   141     \sa lock(), key().
       
   142  */
       
   143 QSystemLock::QSystemLock(const QString &key)
       
   144 {
       
   145     d = new QSystemLockPrivate;
       
   146     setKey(key);
       
   147 }
       
   148 
       
   149 /*!
       
   150     Destroys a system lock.
       
   151 
       
   152     warning: This will not unlock the system lock if it has been locked.
       
   153 */
       
   154 QSystemLock::~QSystemLock()
       
   155 {
       
   156     d->cleanHandle();
       
   157     delete d;
       
   158 }
       
   159 
       
   160 /*!
       
   161     Sets a new key to this system lock.
       
   162 
       
   163     \sa key()
       
   164  */
       
   165 void QSystemLock::setKey(const QString &key)
       
   166 {
       
   167     if (key == d->key)
       
   168         return;
       
   169     d->cleanHandle();
       
   170     d->lockCount = 0;
       
   171     d->key = key;
       
   172     // cache the file name so it doesn't have to be generated all the time.
       
   173     d->fileName = d->makeKeyFileName();
       
   174     d->error = QSystemLock::NoError;
       
   175     d->errorString = QString();
       
   176     d->handle();
       
   177 }
       
   178 
       
   179 /*!
       
   180     Returns the key assigned to this system lock
       
   181 
       
   182     \sa setKey()
       
   183  */
       
   184 QString QSystemLock::key() const
       
   185 {
       
   186     return d->key;
       
   187 }
       
   188 
       
   189 /*!
       
   190     Locks the system lock.  Lock \a mode can either be ReadOnly or ReadWrite.
       
   191     If a mode is ReadOnly, attempts by other processes to obtain
       
   192     ReadOnly locks will succeed, and ReadWrite attempts will block until
       
   193     all of the ReadOnly locks are unlocked.  If locked as ReadWrite, all
       
   194     other attempts to lock will block until the lock is unlocked.  A given
       
   195     QSystemLock can be locked multiple times without blocking, and will
       
   196     only be unlocked after a corresponding number of unlock()
       
   197     calls are made.  Returns true on success; otherwise returns false.
       
   198 
       
   199     \sa unlock(), tryLock()
       
   200  */
       
   201 bool QSystemLock::lock(LockMode mode)
       
   202 {
       
   203     if (d->lockCount > 0 && mode == ReadOnly && d->lockedMode == ReadWrite) {
       
   204         qWarning() << "QSystemLock::lock readwrite lock on top of readonly lock.";
       
   205         return false;
       
   206     }
       
   207     return d->modifySemaphore(QSystemLockPrivate::Lock, mode);
       
   208 }
       
   209 
       
   210 /*!
       
   211     Unlocks the system lock.
       
   212     Returns true on success; otherwise returns false.
       
   213 
       
   214     \sa lock()
       
   215   */
       
   216 bool QSystemLock::unlock()
       
   217 {
       
   218     if (d->lockCount == 0) {
       
   219         qWarning() << "QSystemLock::unlock: unlock with no lock.";
       
   220         return false;
       
   221     }
       
   222     return d->modifySemaphore(QSystemLockPrivate::Unlock, d->lockedMode);
       
   223 }
       
   224 
       
   225 /*!
       
   226     Returns the type of error that occurred last or NoError.
       
   227 
       
   228     \sa errorString()
       
   229  */
       
   230 QSystemLock::SystemLockError QSystemLock::error() const
       
   231 {
       
   232     return d->error;
       
   233 }
       
   234 
       
   235 /*!
       
   236     Returns the human-readable message appropriate to the current error
       
   237     reported by error(). If no suitable string is available, an empty
       
   238     string is returned.
       
   239 
       
   240     \sa error()
       
   241  */
       
   242 QString QSystemLock::errorString() const
       
   243 {
       
   244     return d->errorString;
       
   245 }
       
   246