summaryrefslogtreecommitdiffstats
path: root/src/tools/qsemaphore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/qsemaphore.cpp')
-rw-r--r--src/tools/qsemaphore.cpp255
1 files changed, 255 insertions, 0 deletions
diff --git a/src/tools/qsemaphore.cpp b/src/tools/qsemaphore.cpp
new file mode 100644
index 000000000..608563ee5
--- /dev/null
+++ b/src/tools/qsemaphore.cpp
@@ -0,0 +1,255 @@
+/****************************************************************************
+**
+** TQSemaphore class for Unix
+**
+** Created : 20010725
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing retquirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at [email protected].
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#if defined(QT_THREAD_SUPPORT)
+
+#include "qsemaphore.h"
+#include "qmutex.h"
+#include "qwaitcondition.h"
+
+
+/*!
+ \class TQSemaphore qsemaphore.h
+ \threadsafe
+ \brief The TQSemaphore class provides a robust integer semaphore.
+
+ \ingroup thread
+ \ingroup environment
+
+ A TQSemaphore can be used to serialize thread execution, in a
+ similar way to a TQMutex. A semaphore differs from a mutex, in
+ that a semaphore can be accessed by more than one thread at a
+ time.
+
+ For example, suppose we have an application that stores data in a
+ large tree structure. The application creates 10 threads
+ (commonly called a thread pool) to perform searches on the tree.
+ When the application searches the tree for some piece of data, it
+ uses one thread per base node to do the searching. A semaphore
+ could be used to make sure that two threads don't try to search
+ the same branch of the tree at the same time.
+
+ A non-computing example of a semaphore would be dining at a
+ restuarant. A semaphore is initialized to have a maximum count
+ equal to the number of chairs in the restuarant. As people
+ arrive, they want a seat. As seats are filled, the semaphore is
+ accessed, once per person. As people leave, the access is
+ released, allowing more people to enter. If a party of 10 people
+ want to be seated, but there are only 9 seats, those 10 people
+ will wait, but a party of 4 people would be seated (taking the
+ available seats to 5, making the party of 10 people wait longer).
+
+ When a semaphore is created it is given a number which is the
+ maximum number of concurrent accesses it will permit. Accesses to
+ the sempahore are gained using operator++() or operator+=(), and
+ released with operator--() or operator-=(). The number of
+ accesses allowed is retrieved with available(), and the total
+ number with total(). Note that the incrementing functions will
+ block if there aren't enough available accesses. Use tryAccess()
+ if you want to actquire accesses without blocking.
+*/
+
+
+class TQSemaphorePrivate {
+public:
+ TQSemaphorePrivate(int);
+
+ TQMutex mutex;
+ TQWaitCondition cond;
+
+ int value, max;
+};
+
+
+TQSemaphorePrivate::TQSemaphorePrivate(int m)
+ : mutex(FALSE), value(0), max(m)
+{
+}
+
+
+/*!
+ Creates a new semaphore. The semaphore can be concurrently
+ accessed at most \a maxcount times.
+*/
+TQSemaphore::TQSemaphore(int maxcount)
+{
+ d = new TQSemaphorePrivate(maxcount);
+}
+
+
+/*!
+ Destroys the semaphore.
+
+ \warning If you destroy a semaphore that has accesses in use the
+ resultant behavior is undefined.
+*/
+TQSemaphore::~TQSemaphore()
+{
+ delete d;
+}
+
+
+/*!
+ Postfix ++ operator.
+
+ Try to get access to the semaphore. If \l available() == 0, this
+ call will block until it can get access, i.e. until available() \>
+ 0.
+*/
+int TQSemaphore::operator++(int)
+{
+ TQMutexLocker locker(&d->mutex);
+ while (d->value >= d->max)
+ d->cond.wait(locker.mutex());
+
+ ++d->value;
+ if (d->value > d->max)
+ d->value = d->max;
+
+ return d->value;
+}
+
+
+/*!
+ Postfix -- operator.
+
+ Release access of the semaphore. This wakes all threads waiting
+ for access to the semaphore.
+*/
+int TQSemaphore::operator--(int)
+{
+ TQMutexLocker locker(&d->mutex);
+
+ --d->value;
+ if (d->value < 0)
+ d->value = 0;
+
+ d->cond.wakeAll();
+
+ return d->value;
+}
+
+
+/*!
+ Try to get access to the semaphore. If \l available() \< \a n, this
+ call will block until it can get all the accesses it wants, i.e.
+ until available() \>= \a n.
+*/
+int TQSemaphore::operator+=(int n)
+{
+ TQMutexLocker locker(&d->mutex);
+
+ if ( n < 0 || n > d->max ) {
+#ifdef QT_CHECK_RANGE
+ qWarning( "TQSemaphore::operator+=: paramter %d out of range", n );
+#endif // QT_CHECK_RANGE
+ n = n < 0 ? 0 : d->max;
+ }
+
+ while (d->value + n > d->max)
+ d->cond.wait(locker.mutex());
+
+ d->value += n;
+
+ return d->value;
+}
+
+
+/*!
+ Release \a n accesses to the semaphore.
+*/
+int TQSemaphore::operator-=(int n)
+{
+ TQMutexLocker locker(&d->mutex);
+
+ if ( n < 0 || n > d->value ) {
+#ifdef QT_CHECK_RANGE
+ qWarning( "TQSemaphore::operator-=: paramter %d out of range", n );
+#endif // QT_CHECK_RANGE
+ n = n < 0 ? 0 : d->value;
+ }
+
+ d->value -= n;
+ d->cond.wakeAll();
+
+ return d->value;
+}
+
+
+/*!
+ Returns the number of accesses currently available to the
+ semaphore.
+*/
+int TQSemaphore::available() const
+{
+ TQMutexLocker locker(&d->mutex);
+ return d->max - d->value;
+}
+
+
+/*!
+ Returns the total number of accesses to the semaphore.
+*/
+int TQSemaphore::total() const
+{
+ TQMutexLocker locker(&d->mutex);
+ return d->max;
+}
+
+
+/*!
+ Try to get access to the semaphore. If \l available() \< \a n, this
+ function will return FALSE immediately. If \l available() \>= \a n,
+ this function will take \a n accesses and return TRUE. This
+ function does \e not block.
+*/
+bool TQSemaphore::tryAccess(int n)
+{
+ TQMutexLocker locker(&d->mutex);
+
+ if (d->value + n > d->max)
+ return FALSE;
+
+ d->value += n;
+
+ return TRUE;
+}
+
+#endif // QT_THREAD_SUPPORT