summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2013-09-21 15:42:33 (GMT)
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-11-16 15:55:39 (GMT)
commit27b7c8ac2f372232e0add9489086c91753033b20 (patch)
treedb95f14d2afbf1b6cb09966943e9a7b85e7f0582 /src
parentcecceb0cdd87482124a73ecf537f3445d68be13e (diff)
downloadQt-27b7c8ac2f372232e0add9489086c91753033b20.zip
Qt-27b7c8ac2f372232e0add9489086c91753033b20.tar.gz
Qt-27b7c8ac2f372232e0add9489086c91753033b20.tar.bz2
QObject: use per-thread storage for qFlagLocation()
qFlagLocation() uses a global char* array to transport source location information from the connect() side to the metaobject side. The size of the array is 2 (two), which just about suffices for a single connect() statement. Obviously, if more than one thread makes a (_any_) connection at the same time, the data is useless and, worse, there's a data race. The non-reentrancy of qFlagLocations() cannot and need not be fixed, but use a per-thread flagged_locations array in QThreadData so threads don't disturb each other. Task-number: QTBUG-3680 Change-Id: If1797c60751f551694def69afee6fbe295bbe2d2 Reviewed-by: Olivier Goffart <ogoffart@woboq.com> (cherry picked from qtbase/c012ee2940bc087720b4aa0d257540921cf9a139) Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qobject.cpp20
-rw-r--r--src/corelib/thread/qthread_p.h22
2 files changed, 28 insertions, 14 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index b355e33..aa1a00c 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -2159,14 +2159,9 @@ void QObject::deleteLater()
*****************************************************************************/
-const int flagged_locations_count = 2;
-static const char* flagged_locations[flagged_locations_count] = {0};
-
const char *qFlagLocation(const char *method)
{
- static int idx = 0;
- flagged_locations[idx] = method;
- idx = (idx+1) % flagged_locations_count;
+ QThreadData::current()->flaggedSignatures.store(method);
return method;
}
@@ -2178,14 +2173,11 @@ static int extract_code(const char *member)
static const char * extract_location(const char *member)
{
- for (int i = 0; i < flagged_locations_count; ++i) {
- if (member == flagged_locations[i]) {
- // signature includes location information after the first null-terminator
- const char *location = member + qstrlen(member) + 1;
- if (*location != '\0')
- return location;
- return 0;
- }
+ if (QThreadData::current()->flaggedSignatures.contains(member)) {
+ // signature includes location information after the first null-terminator
+ const char *location = member + qstrlen(member) + 1;
+ if (*location != '\0')
+ return location;
}
return 0;
}
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index d404b53..7c9cfc4 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -229,6 +229,26 @@ public:
return canWait;
}
+ // This class provides per-thread (by way of being a QThreadData
+ // member) storage for qFlagLocation()
+ class FlaggedDebugSignatures
+ {
+ static const uint Count = 2;
+
+ uint idx;
+ const char* locations[Count];
+
+ public:
+ FlaggedDebugSignatures() : idx(0)
+ { std::fill_n(locations, Count, static_cast<char*>(0)); }
+
+ void store(const char* method)
+ { locations[idx++ % Count] = method; }
+
+ bool contains(const char *method) const
+ { return std::find(locations, locations + Count, method) != locations + Count; }
+ };
+
QThread *thread;
Qt::HANDLE threadId;
bool quitNow;
@@ -243,6 +263,8 @@ public:
# ifdef Q_OS_SYMBIAN
RThread symbian_thread_handle;
# endif
+
+ FlaggedDebugSignatures flaggedSignatures;
};
class QScopedLoopLevelCounter