From c012ee2940bc087720b4aa0d257540921cf9a139 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 21 Sep 2013 17:42:33 +0200 Subject: 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 --- src/corelib/thread/qthread_p.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/corelib/thread') diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index 5e4eedaac7..fa1f7414f1 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -242,6 +242,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(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; @@ -252,6 +272,7 @@ public: bool canWait; QVector tls; bool isAdopted; + FlaggedDebugSignatures flaggedSignatures; }; class QScopedLoopLevelCounter -- cgit v1.2.3