Skip to content

Commit dab46c0

Browse files
caixr23deepin-bot[bot]
authored andcommitted
fix: add thread safety for pinyin dictionary initialization
Add mutex protection to prevent race condition in multi-threaded access to the static pinyin dictionary. The `InitDict()` function was not thread-safe when called concurrently from multiple threads, which could lead to double initialization or data corruption. 1. Add `QMutex` and `QMutexLocker` includes 2. Declare static `dictMutex` to protect the dictionary 3. Lock mutex at the beginning of `InitDict()` to ensure exclusive access 4. Prevent potential crash when multiple threads simultaneously trigger dictionary loading Influence: 1. Test concurrent pinyin conversion from multiple threads 2. Verify no crash occurs during high-frequency multi-threaded access 3. Test dictionary initialization under thread contention 4. Verify performance impact of mutex locking in single-threaded scenarios 5. Test edge cases where InitDict is called simultaneously from different threads fix: 添加拼音字典初始化的线程安全保护 添加互斥锁保护以防止多线程访问静态拼音字典时的竞态条件。`InitDict()` 函 数在被多线程并发调用时不是线程安全的,可能导致重复初始化或数据损坏。 1. 添加 `QMutex` 和 `QMutexLocker` 头文件包含 2. 声明静态 `dictMutex` 用于保护字典 3. 在 `InitDict()` 开头加锁以确保独占访问 4. 防止多线程同时触发字典加载时可能导致的崩溃 Influence: 1. 测试多线程并发进行拼音转换的场景 2. 验证高频多线程访问时无崩溃发生 3. 测试线程竞争条件下的字典初始化 4. 验证单线程场景下互斥锁锁定的性能影响 5. 测试不同线程同时调用 InitDict 的边界情况
1 parent 1a081d1 commit dab46c0

1 file changed

Lines changed: 16 additions & 11 deletions

File tree

src/util/dpinyin.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1-
// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd.
1+
// SPDX-FileCopyrightText: 2019 - 2026 UnionTech Software Technology Co., Ltd.
22
//
33
// SPDX-License-Identifier: LGPL-3.0-or-later
44

55
#include "dpinyin.h"
66

7+
#include <QDebug>
78
#include <QFile>
9+
#include <QMap>
810
#include <QSet>
911
#include <QTextStream>
10-
#include <QMap>
11-
#include <QDebug>
12+
13+
#include <mutex>
1214

1315
DCORE_BEGIN_NAMESPACE
1416

1517
static QHash<uint, QString> dict = {};
18+
static std::once_flag dictInitFlag;
1619
const char kDictFile[] = ":/dpinyin/resources/dpinyin.dict";
1720

18-
static void InitDict() {
19-
if (!dict.isEmpty()) {
20-
return;
21-
}
22-
21+
static void initDictImpl()
22+
{
2323
dict.reserve(25333);
2424

2525
QFile file(kDictFile);
@@ -46,6 +46,11 @@ static void InitDict() {
4646
}
4747
}
4848

49+
static void InitDict()
50+
{
51+
std::call_once(dictInitFlag, initDictImpl);
52+
}
53+
4954
static void initToneTable(QMap<QChar, QString> &toneTable)
5055
{
5156
if (toneTable.size() > 0)
@@ -71,7 +76,7 @@ static QString toned(const QString &str, ToneStyle ts)
7176

7277
QString newStr = str;
7378
QString toneNum = "";
74-
79+
7580
// First pass: find tone number and remove tone marks
7681
for (QChar c : str) {
7782
if (toneTable.contains(c)) {
@@ -89,12 +94,12 @@ static QString toned(const QString &str, ToneStyle ts)
8994
}
9095
}
9196
}
92-
97+
9398
// For TS_ToneNum, append tone number at the end
9499
if (ts == TS_ToneNum && !toneNum.isEmpty()) {
95100
newStr += toneNum;
96101
}
97-
102+
98103
return newStr;
99104
}
100105

0 commit comments

Comments
 (0)