File: qreadwritelock_data_race.diff

package info (click to toggle)
qtbase-opensource-src 5.15.17%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 351,220 kB
  • sloc: cpp: 2,097,695; ansic: 343,237; xml: 115,491; python: 9,447; java: 7,499; asm: 4,023; sh: 2,090; perl: 2,047; yacc: 1,687; lex: 1,333; javascript: 878; makefile: 271; objc: 70
file content (33 lines) | stat: -rw-r--r-- 1,270 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Description: QReadWriteLock: fix data race on the d_ptr members
 The loadRelaxed() at the beginning of tryLockForRead/tryLockForWrite
 isn't enough to bring us the non-atomic write of the recursive bool.
 Same issue with the std::mutex itself.
Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit?id=80d01c4ccb697b9d
Last-Update: 2025-12-14

--- a/src/corelib/thread/qreadwritelock.cpp
+++ b/src/corelib/thread/qreadwritelock.cpp
@@ -258,7 +258,10 @@ bool QReadWriteLock::tryLockForRead(int
             d = val;
         }
         Q_ASSERT(!isUncontendedLocked(d));
-        // d is an actual pointer;
+        // d is an actual pointer; acquire its contents
+        d = d_ptr.loadAcquire();
+        if (!d || isUncontendedLocked(d))
+            continue;
 
         if (d->recursive)
             return d->recursiveLockForRead(timeout);
@@ -365,7 +368,10 @@ bool QReadWriteLock::tryLockForWrite(int
             d = val;
         }
         Q_ASSERT(!isUncontendedLocked(d));
-        // d is an actual pointer;
+        // d is an actual pointer; acquire its contents
+        d = d_ptr.loadAcquire();
+        if (!d || isUncontendedLocked(d))
+            continue;
 
         if (d->recursive)
             return d->recursiveLockForWrite(timeout);