解决多线程情况下写数据库导致的数据库崩溃问题
This commit is contained in:
parent
c251e80145
commit
3b15c7b050
|
@ -99,7 +99,6 @@ namespace ver_2
|
|||
|
||||
// 保存路径表
|
||||
sqlite3_exec(m_sqlite, "create table save_filenames (filename text)", NULL, NULL, NULL);
|
||||
|
||||
// 设备配置表
|
||||
sqlite3_exec(m_sqlite, "create table device_params (name text, value_type text, value text)", NULL, NULL, NULL);
|
||||
|
||||
|
@ -114,32 +113,25 @@ namespace ver_2
|
|||
|
||||
std::vector<MainTableInfo> tables;
|
||||
|
||||
char** result = NULL;
|
||||
int rows, cols;
|
||||
ret = sqlite3_get_table(m_sqlite, "select * from table_", &result, &rows, &cols, NULL);
|
||||
assert(0 == ret && rows > 0 && cols == 2);
|
||||
sqlite3_stmt* stmt = NULL;
|
||||
ret = sqlite3_prepare(m_sqlite, "select * from table_", -1, &stmt, NULL);
|
||||
assert(0 == ret);
|
||||
|
||||
for (int i = 0; i < rows; i++)
|
||||
ret = sqlite3_step(stmt);
|
||||
while (SQLITE_ROW == ret)
|
||||
{
|
||||
MainTableInfo info;
|
||||
for (int j = 0; j < cols; j++)
|
||||
{
|
||||
if (0 == strcmp("id", result[j]))
|
||||
{
|
||||
info.id = atoi(result[(i + 1) * cols + j]);
|
||||
}
|
||||
else if (0 == strcmp("name", result[j]))
|
||||
{
|
||||
info.tableName = result[(i + 1) * cols + j];
|
||||
}
|
||||
}
|
||||
|
||||
info.id = sqlite3_column_int(stmt, 0);
|
||||
info.tableName = (const char*)sqlite3_column_text(stmt, 1);
|
||||
tables.push_back(info);
|
||||
|
||||
ret = sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
sqlite3_free_table(result);
|
||||
assert(!tables.empty());
|
||||
ret = sqlite3_finalize(stmt);
|
||||
assert(0 == ret);
|
||||
|
||||
assert(!tables.empty());
|
||||
std::sort(tables.begin(), tables.end(), MainTableSort);
|
||||
m_currBatchId = tables[tables.size() - 1].tableName;
|
||||
}
|
||||
|
@ -185,6 +177,14 @@ namespace ver_2
|
|||
StopScan(errInfo);
|
||||
}
|
||||
|
||||
void ManagerV2::ScanImage(const ScanImageParam* param)
|
||||
{
|
||||
assert(NULL != param && this == param->mgr);
|
||||
|
||||
m_saveFilePathList.push_back(param->fileName);
|
||||
RestoreSaveFilePathList(m_saveFilePathList);
|
||||
}
|
||||
|
||||
void ManagerV2::SetSaneEvent(SaneEvent event, void* param)
|
||||
{
|
||||
assert(NULL != event && NULL != param);
|
||||
|
@ -353,10 +353,8 @@ namespace ver_2
|
|||
return ret;
|
||||
|
||||
imagePath = imagePath2;
|
||||
HGBase_EnterLock(m_lock);
|
||||
m_saveFilePathList.push_back(imagePath);
|
||||
RestoreSaveFilePathList(m_saveFilePathList);
|
||||
HGBase_LeaveLock(m_lock);
|
||||
|
||||
errInfo.clear();
|
||||
return 0;
|
||||
|
@ -367,7 +365,6 @@ namespace ver_2
|
|||
int ret = -1;
|
||||
errInfo = "错误";
|
||||
|
||||
HGBase_EnterLock(m_lock);
|
||||
for (int i = 0; i < (int)m_saveFilePathList.size(); ++i)
|
||||
{
|
||||
if (filePath == m_saveFilePathList[i])
|
||||
|
@ -383,14 +380,12 @@ namespace ver_2
|
|||
}
|
||||
}
|
||||
RestoreSaveFilePathList(m_saveFilePathList);
|
||||
HGBase_LeaveLock(m_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ManagerV2::ClearGlobalFileSavePath(std::string& errInfo)
|
||||
{
|
||||
HGBase_EnterLock(m_lock);
|
||||
int i = 0;
|
||||
while (i < (int)m_saveFilePathList.size())
|
||||
{
|
||||
|
@ -413,7 +408,6 @@ namespace ver_2
|
|||
}
|
||||
}
|
||||
RestoreSaveFilePathList(m_saveFilePathList);
|
||||
HGBase_LeaveLock(m_lock);
|
||||
|
||||
HGBase_DeleteDir(m_globalCfg.fileSavePath.c_str());
|
||||
errInfo.clear();
|
||||
|
@ -530,10 +524,8 @@ namespace ver_2
|
|||
int ret = SaveImage(outImage, outImagePath);
|
||||
if (0 == ret)
|
||||
{
|
||||
HGBase_EnterLock(m_lock);
|
||||
m_saveFilePathList.push_back(outImagePath);
|
||||
RestoreSaveFilePathList(m_saveFilePathList);
|
||||
HGBase_LeaveLock(m_lock);
|
||||
errInfo.clear();
|
||||
}
|
||||
|
||||
|
@ -600,10 +592,8 @@ namespace ver_2
|
|||
}
|
||||
|
||||
outImagePath = outImagePath2;
|
||||
HGBase_EnterLock(m_lock);
|
||||
m_saveFilePathList.push_back(outImagePath);
|
||||
RestoreSaveFilePathList(m_saveFilePathList);
|
||||
HGBase_LeaveLock(m_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -672,10 +662,8 @@ namespace ver_2
|
|||
if (0 == SaveImage(img, imgPath))
|
||||
{
|
||||
outImagePathList.push_back(imgPath);
|
||||
HGBase_EnterLock(m_lock);
|
||||
m_saveFilePathList.push_back(imgPath);
|
||||
RestoreSaveFilePathList(m_saveFilePathList);
|
||||
HGBase_LeaveLock(m_lock);
|
||||
errInfo.clear();
|
||||
ret = 0;
|
||||
}
|
||||
|
@ -762,10 +750,8 @@ namespace ver_2
|
|||
}
|
||||
|
||||
outZipPath = outZipPath2;
|
||||
HGBase_EnterLock(m_lock);
|
||||
m_saveFilePathList.push_back(outZipPath);
|
||||
RestoreSaveFilePathList(m_saveFilePathList);
|
||||
HGBase_LeaveLock(m_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -788,10 +774,8 @@ namespace ver_2
|
|||
{
|
||||
if (0 == SaveImage(img, outImagePath))
|
||||
{
|
||||
HGBase_EnterLock(m_lock);
|
||||
m_saveFilePathList.push_back(outImagePath);
|
||||
RestoreSaveFilePathList(m_saveFilePathList);
|
||||
HGBase_LeaveLock(m_lock);
|
||||
errInfo.clear();
|
||||
ret = 0;
|
||||
}
|
||||
|
@ -965,10 +949,8 @@ namespace ver_2
|
|||
{
|
||||
if (0 == SaveImage(image, outImagePath))
|
||||
{
|
||||
HGBase_EnterLock(m_lock);
|
||||
m_saveFilePathList.push_back(outImagePath);
|
||||
RestoreSaveFilePathList(m_saveFilePathList);
|
||||
HGBase_LeaveLock(m_lock);
|
||||
errInfo.clear();
|
||||
ret = 0;
|
||||
}
|
||||
|
@ -1237,32 +1219,25 @@ namespace ver_2
|
|||
|
||||
std::vector<MainTableInfo> tables;
|
||||
|
||||
char** result = NULL;
|
||||
int rows, cols;
|
||||
int ret = sqlite3_get_table(m_sqlite, "select * from table_", &result, &rows, &cols, NULL);
|
||||
assert(0 == ret && rows > 0 && cols == 2);
|
||||
sqlite3_stmt* stmt = NULL;
|
||||
int ret = sqlite3_prepare(m_sqlite, "select * from table_", -1, &stmt, NULL);
|
||||
assert(0 == ret);
|
||||
|
||||
for (int i = 0; i < rows; i++)
|
||||
ret = sqlite3_step(stmt);
|
||||
while (SQLITE_ROW == ret)
|
||||
{
|
||||
MainTableInfo info;
|
||||
for (int j = 0; j < cols; j++)
|
||||
{
|
||||
if (0 == strcmp("id", result[j]))
|
||||
{
|
||||
info.id = atoi(result[(i + 1) * cols + j]);
|
||||
}
|
||||
else if (0 == strcmp("name", result[j]))
|
||||
{
|
||||
info.tableName = result[(i + 1) * cols + j];
|
||||
}
|
||||
}
|
||||
|
||||
info.id = sqlite3_column_int(stmt, 0);
|
||||
info.tableName = (const char*)sqlite3_column_text(stmt, 1);
|
||||
tables.push_back(info);
|
||||
|
||||
ret = sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
sqlite3_free_table(result);
|
||||
assert(!tables.empty());
|
||||
ret = sqlite3_finalize(stmt);
|
||||
assert(0 == ret);
|
||||
|
||||
assert(!tables.empty());
|
||||
std::sort(tables.begin(), tables.end(), MainTableSort);
|
||||
for (int i = 0; i < (int)tables.size(); ++i)
|
||||
batchIdList.push_back(tables[i].tableName);
|
||||
|
@ -1616,10 +1591,8 @@ namespace ver_2
|
|||
if (SaveToFile((const HGByte*)imgData, imgSize, imagePath2))
|
||||
{
|
||||
imagePath = imagePath2;
|
||||
HGBase_EnterLock(m_lock);
|
||||
m_saveFilePathList.push_back(imagePath);
|
||||
RestoreSaveFilePathList(m_saveFilePathList);
|
||||
HGBase_LeaveLock(m_lock);
|
||||
|
||||
errInfo.clear();
|
||||
rc = 0;
|
||||
|
@ -1686,6 +1659,10 @@ namespace ver_2
|
|||
int ret;
|
||||
char sql[1024];
|
||||
|
||||
ret = sqlite3_exec(m_sqlite, "begin", NULL, NULL, NULL);
|
||||
assert(0 == ret);
|
||||
|
||||
bool ok = true;
|
||||
for (int i = 0; i < (int)tables.size(); ++i)
|
||||
{
|
||||
if (tables[i].idx >= insertPos)
|
||||
|
@ -1693,9 +1670,22 @@ namespace ver_2
|
|||
sprintf(sql, "update 'table_%s' set idx = '%d' where id = '%d'",
|
||||
m_currBatchId.c_str(), tables[i].idx + 1, tables[i].id);
|
||||
ret = sqlite3_exec(m_sqlite, sql, NULL, NULL, NULL);
|
||||
assert(0 == ret);
|
||||
if (0 != ret)
|
||||
{
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
ret = sqlite3_exec(m_sqlite, "rollback", NULL, NULL, NULL);
|
||||
assert(0 == ret);
|
||||
delete[] thumbData;
|
||||
delete[] imgData;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(sql, "insert into 'table_%s' (idx, format, tag, image, thumb) values ('%d', '%s', '%s', ?, ?)", m_currBatchId.c_str(),
|
||||
insertPos, imgFormat.c_str(), imageTag.c_str());
|
||||
|
@ -1708,6 +1698,16 @@ namespace ver_2
|
|||
assert(0 == ret);
|
||||
sqlite3_step(stmt);
|
||||
ret = sqlite3_finalize(stmt);
|
||||
if (0 != ret)
|
||||
{
|
||||
ret = sqlite3_exec(m_sqlite, "rollback", NULL, NULL, NULL);
|
||||
assert(0 == ret);
|
||||
delete[] thumbData;
|
||||
delete[] imgData;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = sqlite3_exec(m_sqlite, "commit", NULL, NULL, NULL);
|
||||
assert(0 == ret);
|
||||
|
||||
if (!m_bindFolder.empty())
|
||||
|
@ -3515,36 +3515,27 @@ namespace ver_2
|
|||
{
|
||||
tables.clear();
|
||||
|
||||
char** result = NULL;
|
||||
sqlite3_stmt* stmt = NULL;
|
||||
char sql[256];
|
||||
sprintf(sql, "select id, idx, format from 'table_%s'", m_currBatchId.c_str());
|
||||
int rows, cols;
|
||||
int ret = sqlite3_get_table(m_sqlite, sql, &result, &rows, &cols, NULL);
|
||||
int ret = sqlite3_prepare(m_sqlite, sql, -1, &stmt, NULL);
|
||||
assert(0 == ret);
|
||||
|
||||
for (int i = 0; i < rows; i++)
|
||||
ret = sqlite3_step(stmt);
|
||||
while (SQLITE_ROW == ret)
|
||||
{
|
||||
BatchTableInfo info;
|
||||
for (int j = 0; j < cols; j++)
|
||||
{
|
||||
if (0 == strcmp("id", result[j]))
|
||||
{
|
||||
info.id = atoi(result[(i + 1) * cols + j]);
|
||||
}
|
||||
else if (0 == strcmp("idx", result[j]))
|
||||
{
|
||||
info.idx = atoi(result[(i + 1) * cols + j]);
|
||||
}
|
||||
else if (0 == strcmp("format", result[j]))
|
||||
{
|
||||
info.format = result[(i + 1) * cols + j];
|
||||
}
|
||||
}
|
||||
|
||||
info.id = sqlite3_column_int(stmt, 0);
|
||||
info.idx = sqlite3_column_int(stmt, 1);
|
||||
info.format = (const char *)sqlite3_column_text(stmt, 2);
|
||||
tables.push_back(info);
|
||||
|
||||
ret = sqlite3_step(stmt);
|
||||
}
|
||||
|
||||
sqlite3_free_table(result);
|
||||
ret = sqlite3_finalize(stmt);
|
||||
assert(0 == ret);
|
||||
|
||||
std::sort(tables.begin(), tables.end(), BatchTableSort);
|
||||
}
|
||||
|
||||
|
@ -3937,8 +3928,17 @@ namespace ver_2
|
|||
int ret = p->SaveImage(img, imagePath);
|
||||
if (0 == ret)
|
||||
{
|
||||
p->m_saveFilePathList.push_back(imagePath);
|
||||
p->RestoreSaveFilePathList(p->m_saveFilePathList);
|
||||
ScanImageParam* scanImageParam = new ScanImageParam;
|
||||
scanImageParam->mgr = p;
|
||||
scanImageParam->fileName = imagePath;
|
||||
|
||||
HGMsg msg;
|
||||
msg.id = MSGID_SCAN_IMAGE;
|
||||
msg.data = scanImageParam;
|
||||
if (HGBASE_ERR_OK != HGBase_PostPumpMessage(p->m_msgPump, &msg))
|
||||
{
|
||||
delete scanImageParam;
|
||||
}
|
||||
|
||||
if (NULL != p->m_saneImageCallback)
|
||||
p->m_saneImageCallback(imagePath.c_str(), p->m_saneImageParam);
|
||||
|
|
|
@ -130,6 +130,8 @@ namespace ver_2
|
|||
void CloseDev(const CloseDevParam* param);
|
||||
// 扫描完成
|
||||
void ScanFinish(const ScanFinishParam* param);
|
||||
// 扫描图像
|
||||
void ScanImage(const ScanImageParam* param);
|
||||
|
||||
// 设置回调
|
||||
void SetSaneEvent(SaneEvent event, void* param);
|
||||
|
|
|
@ -96,6 +96,7 @@ namespace ver_2
|
|||
{
|
||||
MSGID_CLOSE_DEVICE = 3L,
|
||||
MSGID_SCAN_FINISH,
|
||||
MSGID_SCAN_IMAGE,
|
||||
MSGID_WS_COMMAND,
|
||||
MSGID_WS_EVENT
|
||||
};
|
||||
|
@ -114,6 +115,12 @@ namespace ver_2
|
|||
ManagerV2* mgr;
|
||||
};
|
||||
|
||||
struct ScanImageParam
|
||||
{
|
||||
ManagerV2* mgr;
|
||||
std::string fileName;
|
||||
};
|
||||
|
||||
struct WSCmdParam
|
||||
{
|
||||
WSServer* svr;
|
||||
|
|
|
@ -116,6 +116,13 @@ namespace ver_2
|
|||
delete param;
|
||||
}
|
||||
break;
|
||||
case MSGID_SCAN_IMAGE:
|
||||
{
|
||||
ScanImageParam* param = (ScanImageParam*)msg->data;
|
||||
param->mgr->ScanImage(param);
|
||||
delete param;
|
||||
}
|
||||
break;
|
||||
case MSGID_WS_COMMAND:
|
||||
{
|
||||
WSCmdParam* param = (WSCmdParam*)msg->data;
|
||||
|
|
Loading…
Reference in New Issue