summaryrefslogtreecommitdiff
path: root/qmake/tools/qmutexpool.cpp
Unidiff
Diffstat (limited to 'qmake/tools/qmutexpool.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/tools/qmutexpool.cpp78
1 files changed, 50 insertions, 28 deletions
diff --git a/qmake/tools/qmutexpool.cpp b/qmake/tools/qmutexpool.cpp
index 9ed2829..a8e7402 100644
--- a/qmake/tools/qmutexpool.cpp
+++ b/qmake/tools/qmutexpool.cpp
@@ -1,48 +1,67 @@
1/****************************************************************************
2** $Id$
3**
4** ...
5**
6** Copyright (C) 2002 Trolltech AS. All rights reserved.
7**
8** This file is part of the tools module of the Qt GUI Toolkit.
9**
10** This file may be distributed under the terms of the Q Public License
11** as defined by Trolltech AS of Norway and appearing in the file
12** LICENSE.QPL included in the packaging of this file.
13**
14** This file may be distributed and/or modified under the terms of the
15** GNU General Public License version 2 as published by the Free Software
16** Foundation and appearing in the file LICENSE.GPL included in the
17** packaging of this file.
18**
19** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
20** licenses may use this file in accordance with the Qt Commercial License
21** Agreement provided with the Software.
22**
23** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
24** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
25**
26** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
27** information about Qt Commercial License Agreements.
28** See http://www.trolltech.com/qpl/ for QPL licensing information.
29** See http://www.trolltech.com/gpl/ for GPL licensing information.
30**
31** Contact info@trolltech.com if any conditions of this licensing are
32** not clear to you.
33**
34**********************************************************************/
35
1#include "qmutexpool_p.h" 36#include "qmutexpool_p.h"
2 37
3#ifdef QT_THREAD_SUPPORT 38#ifdef QT_THREAD_SUPPORT
4 39
5#include <qthread.h> 40#include <qthread.h>
6#include <stdio.h>
7 41
8QMutexPool *qt_global_mutexpool = 0; 42QMutexPool *qt_global_mutexpool = 0;
9 43
10// this is an internal class used only for inititalizing the global mutexpool
11class QGlobalMutexPoolInitializer
12{
13public:
14 inline QGlobalMutexPoolInitializer()
15 {
16 /*
17 Purify will report a leak here. However, this mutex pool must be alive
18 until *everything* in Qt has been destructed. Unfortunately there is
19 no way to guarantee this, so we never destroy this mutex pool.
20 */
21 qt_global_mutexpool = new QMutexPool( TRUE );
22 }
23};
24QGlobalMutexPoolInitializer qt_global_mutexpool_initializer;
25 44
26/*! 45/*!
27 \class QMutexPool qmutexpool_p.h 46 \class QMutexPool qmutexpool_p.h
28 \brief The QMutexPool class provides a pool of QMutex objects. 47 \brief The QMutexPool class provides a pool of QMutex objects.
29 48
30 \internal 49 \internal
31 50
32 \ingroup thread 51 \ingroup thread
33 52
34 QMutexPool is a convenience class that provides access to a fixed 53 QMutexPool is a convenience class that provides access to a fixed
35 number of QMutex objects. 54 number of QMutex objects.
36 55
37 Typical use of a QMutexPool is in situations where it is not 56 Typical use of a QMutexPool is in situations where it is not
38 possible or feasible to use one QMutex for every protected object. 57 possible or feasible to use one QMutex for every protected object.
39 The mutex pool will return a mutex based on the address of the 58 The mutex pool will return a mutex based on the address of the
40 object that needs protection. 59 object that needs protection.
41 60
42 For example, consider this simple class: 61 For example, consider this simple class:
43 62
44 \code 63 \code
45 class Number { 64 class Number {
46 public: 65 public:
47 Number( double n ) : num ( n ) { } 66 Number( double n ) : num ( n ) { }
48 67
@@ -64,67 +83,70 @@ QGlobalMutexPoolInitializer qt_global_mutexpool_initializer;
64 83
65 \code 84 \code
66 void calcSquare( Number *num ) 85 void calcSquare( Number *num )
67 { 86 {
68 QMutexLocker locker( mutexpool.get( num ) ); 87 QMutexLocker locker( mutexpool.get( num ) );
69 num.setNumber( num.number() * num.number() ); 88 num.setNumber( num.number() * num.number() );
70 } 89 }
71 \endcode 90 \endcode
72 91
73 This function will safely calculate the square of a number, since 92 This function will safely calculate the square of a number, since
74 it uses a mutex from a QMutexPool. The mutex is locked and 93 it uses a mutex from a QMutexPool. The mutex is locked and
75 unlocked automatically by the QMutexLocker class. See the 94 unlocked automatically by the QMutexLocker class. See the
76 QMutexLocker documentation for more details. 95 QMutexLocker documentation for more details.
77*/ 96*/
78 97
79/*! 98/*!
80 Constructs a QMutexPool, reserving space for \a size QMutexes. If 99 Constructs a QMutexPool, reserving space for \a size QMutexes. If
81 \a recursive is TRUE, all QMutexes in the pool will be recursive 100 \a recursive is TRUE, all QMutexes in the pool will be recursive
82 mutexes; otherwise they will all be non-recursive (the default). 101 mutexes; otherwise they will all be non-recursive (the default).
83 102
84 The QMutexes are created when needed, and deleted when the 103 The QMutexes are created when needed, and deleted when the
85 QMutexPool is destructed. 104 QMutexPool is destructed.
86*/ 105*/
87QMutexPool::QMutexPool( bool recursive, int size ) 106QMutexPool::QMutexPool( bool recursive, int size )
88 : mutex( FALSE ), mutexes( size ), recurs( recursive ) 107 : mutex( FALSE ), count( size ), recurs( recursive )
89{ 108{
90 mutexes.fill( 0 ); 109 mutexes = new QMutex*[count];
110 for ( int index = 0; index < count; ++index ) {
111 mutexes[index] = 0;
112 }
91} 113}
92 114
93/*! 115/*!
94 Destructs a QMutexPool. All QMutexes that were created by the pool 116 Destructs a QMutexPool. All QMutexes that were created by the pool
95 are deleted. 117 are deleted.
96*/ 118*/
97QMutexPool::~QMutexPool() 119QMutexPool::~QMutexPool()
98{ 120{
99 QMutexLocker locker( &mutex ); 121 QMutexLocker locker( &mutex );
100 QMutex **d = mutexes.data(); 122 for ( int index = 0; index < count; ++index ) {
101 for ( int index = 0; (uint) index < mutexes.size(); index++ ) { 123 delete mutexes[index];
102 delete d[index]; 124 mutexes[index] = 0;
103 d[index] = 0;
104 } 125 }
126 delete [] mutexes;
127 mutexes = 0;
105} 128}
106 129
107/*! 130/*!
108 Returns a QMutex from the pool. QMutexPool uses the value \a 131 Returns a QMutex from the pool. QMutexPool uses the value \a
109 address to determine which mutex is retured from the pool. 132 address to determine which mutex is retured from the pool.
110*/ 133*/
111QMutex *QMutexPool::get( void *address ) 134QMutex *QMutexPool::get( void *address )
112{ 135{
113 QMutex **d = mutexes.data(); 136 int index = (int) ( (unsigned long) address % count );
114 int index = (int)( (ulong) address % mutexes.size() );
115 137
116 if ( ! d[index] ) { 138 if ( ! mutexes[index] ) {
117 // mutex not created, create one 139 // mutex not created, create one
118 140
119 QMutexLocker locker( &mutex ); 141 QMutexLocker locker( &mutex );
120 // we need to check once again that the mutex hasn't been created, since 142 // we need to check once again that the mutex hasn't been created, since
121 // 2 threads could be trying to create a mutex as the same index... 143 // 2 threads could be trying to create a mutex as the same index...
122 if ( ! d[index] ) { 144 if ( ! mutexes[index] ) {
123 d[index] = new QMutex( recurs ); 145 mutexes[index] = new QMutex( recurs );
124 } 146 }
125 } 147 }
126 148
127 return d[index]; 149 return mutexes[index];
128} 150}
129 151
130#endif 152#endif