summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2020-11-17 22:04:39 +0300
committerGeorge Hazan <ghazan@miranda.im>2020-11-17 22:04:39 +0300
commite1721a9474dc2906771e6c98ada72d41854ce5a9 (patch)
treecffab9a2252165ad5285ba4af1eee8e575a8966c
parentd5df87b152c42caadd2f41bd2712663caf4bd4e2 (diff)
fixes #2569 (Ломается профиль после ребута компа. Miranda NG не может открыть '*', профиль в неизвестном формате)
-rw-r--r--libs/libmdbx/libmdbx.vcxproj2
-rw-r--r--plugins/Dbx_mdbx/src/dbcheck.cpp6
-rw-r--r--plugins/Dbx_mdbx/src/dbcontacts.cpp43
-rw-r--r--plugins/Dbx_mdbx/src/dbcrypt.cpp20
-rw-r--r--plugins/Dbx_mdbx/src/dbevents.cpp10
-rw-r--r--plugins/Dbx_mdbx/src/dbintf.cpp69
-rw-r--r--plugins/Dbx_mdbx/src/dbintf.h2
-rw-r--r--plugins/Dbx_mdbx/src/dbmodulechain.cpp2
-rw-r--r--plugins/Dbx_mdbx/src/dbsettings.cpp10
-rw-r--r--plugins/Dbx_mdbx/src/dbutils.cpp40
-rw-r--r--plugins/Dbx_mdbx/src/stdafx.h56
11 files changed, 144 insertions, 116 deletions
diff --git a/libs/libmdbx/libmdbx.vcxproj b/libs/libmdbx/libmdbx.vcxproj
index 9f89657789..9351bea039 100644
--- a/libs/libmdbx/libmdbx.vcxproj
+++ b/libs/libmdbx/libmdbx.vcxproj
@@ -36,7 +36,7 @@
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
- <PreprocessorDefinitions>MDBX_BUILD_SHARED_LIBRARY=1;LIBMDBX_EXPORTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>MDBX_BUILD_SHARED_LIBRARY=1;MDBX_TXN_CHECKOWNER=0;LIBMDBX_EXPORTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalDependencies>ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies>
diff --git a/plugins/Dbx_mdbx/src/dbcheck.cpp b/plugins/Dbx_mdbx/src/dbcheck.cpp
index f1e50414de..6b031f5a8f 100644
--- a/plugins/Dbx_mdbx/src/dbcheck.cpp
+++ b/plugins/Dbx_mdbx/src/dbcheck.cpp
@@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
int CDbxMDBX::CheckEvents1(void)
{
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
cursor_ptr cursor(trnlck, m_dbEventsSort);
MDBX_val key, data;
@@ -61,7 +61,7 @@ int CDbxMDBX::CheckEvents1(void)
int CDbxMDBX::CheckEvents2(void)
{
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
cursor_ptr cursor(trnlck, m_dbEventIds);
MDBX_val key, data;
@@ -83,7 +83,7 @@ int CDbxMDBX::CheckEvents2(void)
int CDbxMDBX::CheckEvents3(void)
{
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
cursor_ptr cursor(trnlck, m_dbSettings);
MDBX_val key, data;
diff --git a/plugins/Dbx_mdbx/src/dbcontacts.cpp b/plugins/Dbx_mdbx/src/dbcontacts.cpp
index 0236a3ea08..7145bdbfe1 100644
--- a/plugins/Dbx_mdbx/src/dbcontacts.cpp
+++ b/plugins/Dbx_mdbx/src/dbcontacts.cpp
@@ -53,7 +53,7 @@ LONG CDbxMDBX::DeleteContact(MCONTACT contactID)
DBEventSortingKey keyS = { contactID, 0, 0 };
MDBX_val key = { &keyS, sizeof(keyS) }, data;
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
cursor_ptr cursor(trnlck, m_dbEventsSort);
for (int res = mdbx_cursor_get(cursor, &key, &data, MDBX_SET_RANGE); res == MDBX_SUCCESS; res = mdbx_cursor_get(cursor, &key, &data, MDBX_NEXT)) {
@@ -80,7 +80,7 @@ LONG CDbxMDBX::DeleteContact(MCONTACT contactID)
DBSettingKey keyS = { contactID, 0, 0 };
MDBX_val key = { &keyS, sizeof(keyS) }, data;
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
cursor_ptr cursor(trnlck, m_dbSettings);
for (int res = mdbx_cursor_get(cursor, &key, &data, MDBX_SET_RANGE); res == MDBX_SUCCESS; res = mdbx_cursor_get(cursor, &key, &data, MDBX_NEXT)) {
@@ -100,7 +100,7 @@ LONG CDbxMDBX::DeleteContact(MCONTACT contactID)
Netlib_Log(0, "Started wipe contact itself");
MDBX_val key = { &contactID, sizeof(MCONTACT) };
{
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
if (mdbx_del(trnlck, m_dbContacts, &key, nullptr) != MDBX_SUCCESS)
return 1;
if (trnlck.Commit() != MDBX_SUCCESS)
@@ -122,7 +122,7 @@ MCONTACT CDbxMDBX::AddContact()
MDBX_val key = { &dwContactId, sizeof(MCONTACT) };
MDBX_val data = { &cc->dbc, sizeof(cc->dbc) };
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
if (mdbx_put(trnlck, m_dbContacts, &key, &data, MDBX_UPSERT) != MDBX_SUCCESS)
return 0;
if (trnlck.Commit() != MDBX_SUCCESS)
@@ -166,7 +166,7 @@ BOOL CDbxMDBX::MetaMergeHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub)
GatherContactHistory(ccSub->contactID, list);
for (auto &EI : list) {
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
DBEventSortingKey insVal = { ccMeta->contactID, EI->eventId, EI->ts };
MDBX_val key = { &insVal, sizeof(insVal) }, data = { (void*)"", 1 };
@@ -178,13 +178,15 @@ BOOL CDbxMDBX::MetaMergeHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub)
ccMeta->dbc.dwEventCount++;
}
+ {
+ MDBX_val keyc = { &ccMeta->contactID, sizeof(MCONTACT) }, datac = { &ccMeta->dbc, sizeof(ccMeta->dbc) };
- MDBX_val keyc = { &ccMeta->contactID, sizeof(MCONTACT) }, datac = { &ccMeta->dbc, sizeof(ccMeta->dbc) };
- txn_ptr trnlck(StartTran());
- if (mdbx_put(trnlck, m_dbContacts, &keyc, &datac, MDBX_UPSERT) != MDBX_SUCCESS)
- return 1;
- if (trnlck.Commit() != MDBX_SUCCESS)
- return 1;
+ txn_ptr trnlck(this);
+ if (mdbx_put(trnlck, m_dbContacts, &keyc, &datac, MDBX_UPSERT) != MDBX_SUCCESS)
+ return 1;
+ if (trnlck.Commit() != MDBX_SUCCESS)
+ return 1;
+ }
DBFlush();
return 0;
@@ -198,7 +200,7 @@ BOOL CDbxMDBX::MetaSplitHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub)
GatherContactHistory(ccSub->contactID, list);
for (auto &EI : list) {
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
DBEventSortingKey insVal = { ccMeta->contactID, EI->eventId, EI->ts };
MDBX_val key = { &insVal, sizeof(insVal) };
if (mdbx_del(trnlck, m_dbEventsSort, &key, nullptr) != MDBX_SUCCESS)
@@ -208,13 +210,14 @@ BOOL CDbxMDBX::MetaSplitHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub)
ccMeta->dbc.dwEventCount--;
}
-
- txn_ptr trnlck(StartTran());
- MDBX_val keyc = { &ccMeta->contactID, sizeof(MCONTACT) }, datac = { &ccMeta->dbc, sizeof(ccMeta->dbc) };
- if (mdbx_put(trnlck, m_dbContacts, &keyc, &datac, MDBX_UPSERT) != MDBX_SUCCESS)
- return 1;
- if (trnlck.Commit() != MDBX_SUCCESS)
- return 1;
+ {
+ txn_ptr trnlck(this);
+ MDBX_val keyc = { &ccMeta->contactID, sizeof(MCONTACT) }, datac = { &ccMeta->dbc, sizeof(ccMeta->dbc) };
+ if (mdbx_put(trnlck, m_dbContacts, &keyc, &datac, MDBX_UPSERT) != MDBX_SUCCESS)
+ return 1;
+ if (trnlck.Commit() != MDBX_SUCCESS)
+ return 1;
+ }
DBFlush();
return 0;
@@ -228,7 +231,7 @@ BOOL CDbxMDBX::MetaRemoveSubHistory(DBCachedContact *ccSub)
GatherContactHistory(ccSub->contactID, list);
for (auto &EI : list) {
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
{
MDBX_val key = { &EI->eventId, sizeof(MEVENT) }, data;
if (mdbx_get(trnlck, m_dbEvents, &key, &data) == MDBX_SUCCESS) {
diff --git a/plugins/Dbx_mdbx/src/dbcrypt.cpp b/plugins/Dbx_mdbx/src/dbcrypt.cpp
index 7fd002cf00..1d815c00f9 100644
--- a/plugins/Dbx_mdbx/src/dbcrypt.cpp
+++ b/plugins/Dbx_mdbx/src/dbcrypt.cpp
@@ -101,7 +101,7 @@ CRYPTO_PROVIDER* CDbxMDBX::SelectProvider()
else pProv = ppProvs[0];
{
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
MDBX_val key = { DBKey_Crypto_Provider, sizeof(DBKey_Crypto_Provider) }, value = { pProv->pszName, mir_strlen(pProv->pszName) + 1 };
if (mdbx_put(trnlck, m_dbCrypto, &key, &value, MDBX_UPSERT) != MDBX_SUCCESS)
return nullptr;
@@ -272,7 +272,7 @@ void CDbxMDBX::StoreKey()
BYTE *pKey = (BYTE*)_alloca(iKeyLength);
m_crypto->getKey(pKey, iKeyLength);
{
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
MDBX_val key = { DBKey_Crypto_Key, sizeof(DBKey_Crypto_Key) }, value = { pKey, iKeyLength };
int rc = mdbx_put(trnlck, m_dbCrypto, &key, &value, MDBX_UPSERT);
if (rc == MDBX_SUCCESS)
@@ -327,7 +327,7 @@ int CDbxMDBX::EnableEncryption(bool bEncrypted)
do {
size_t portion = min(lstEvents.size(), 1000);
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
for (size_t i = 0; i < portion; i++) {
MEVENT &hDbEvent = lstEvents[i];
MDBX_val key = { &hDbEvent, sizeof(MEVENT) }, data;
@@ -376,12 +376,14 @@ int CDbxMDBX::EnableEncryption(bool bEncrypted)
}
while (lstEvents.size() > 0);
- txn_ptr trnlck(StartTran());
- MDBX_val key = { DBKey_Crypto_IsEncrypted, sizeof(DBKey_Crypto_IsEncrypted) }, value = { &bEncrypted, sizeof(bool) };
- if (mdbx_put(trnlck, m_dbCrypto, &key, &value, MDBX_UPSERT) != MDBX_SUCCESS)
- return 1;
- if (trnlck.Commit() != MDBX_SUCCESS)
- return 1;
+ {
+ txn_ptr trnlck(this);
+ MDBX_val key = { DBKey_Crypto_IsEncrypted, sizeof(DBKey_Crypto_IsEncrypted) }, value = { &bEncrypted, sizeof(bool) };
+ if (mdbx_put(trnlck, m_dbCrypto, &key, &value, MDBX_UPSERT) != MDBX_SUCCESS)
+ return 1;
+ if (trnlck.Commit() != MDBX_SUCCESS)
+ return 1;
+ }
DBFlush();
m_bEncrypted = bEncrypted;
diff --git a/plugins/Dbx_mdbx/src/dbevents.cpp b/plugins/Dbx_mdbx/src/dbevents.cpp
index e0ce827049..787b680590 100644
--- a/plugins/Dbx_mdbx/src/dbevents.cpp
+++ b/plugins/Dbx_mdbx/src/dbevents.cpp
@@ -73,7 +73,7 @@ BOOL CDbxMDBX::DeleteEvent(MEVENT hDbEvent)
if (!CheckEvent(cc, &dbe, cc2))
return 1;
{
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
DBEventSortingKey key2 = { dbe.dwContactID, hDbEvent, dbe.timestamp };
MDBX_val key = { &key2, sizeof(key2) }, data;
@@ -215,7 +215,7 @@ bool CDbxMDBX::EditEvent(MCONTACT contactID, MEVENT hDbEvent, const DBEVENTINFO
dbe.flags |= DBEF_HAS_ID;
}
- BYTE *recBuf = (BYTE*)_alloca(sizeof(DBEvent) + dbe.cbBlob + cbSrvId + 1), *p = recBuf;
+ BYTE *recBuf = (BYTE*)_alloca(sizeof(dbe) + dbe.cbBlob + cbSrvId + 2), *p = recBuf;
memcpy(p, &dbe, sizeof(dbe)); p += sizeof(dbe);
memcpy(p, pBlob, dbe.cbBlob); p += dbe.cbBlob;
if (*p != 0)
@@ -226,7 +226,7 @@ bool CDbxMDBX::EditEvent(MCONTACT contactID, MEVENT hDbEvent, const DBEVENTINFO
}
{
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
MDBX_val key = { &hDbEvent, sizeof(MEVENT) }, data = { recBuf, size_t(p - recBuf) };
if (mdbx_put(trnlck, m_dbEvents, &key, &data, MDBX_UPSERT) != MDBX_SUCCESS)
return false;
@@ -278,7 +278,7 @@ bool CDbxMDBX::EditEvent(MCONTACT contactID, MEVENT hDbEvent, const DBEVENTINFO
return false;
}
- DBFlush();
+ DBFlush(true);
// Notify only in safe mode or on really new events
if (m_safetyMode && !(dbei->flags & DBEF_TEMPORARY))
@@ -410,7 +410,7 @@ BOOL CDbxMDBX::MarkEventRead(MCONTACT contactID, MEVENT hDbEvent)
uint32_t wRetVal = -1;
{
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
MDBX_val key = { &hDbEvent, sizeof(MEVENT) }, data;
if (mdbx_get(trnlck, m_dbEvents, &key, &data) != MDBX_SUCCESS)
return -1;
diff --git a/plugins/Dbx_mdbx/src/dbintf.cpp b/plugins/Dbx_mdbx/src/dbintf.cpp
index d03d0ab498..ad22d1f850 100644
--- a/plugins/Dbx_mdbx/src/dbintf.cpp
+++ b/plugins/Dbx_mdbx/src/dbintf.cpp
@@ -36,6 +36,9 @@ CDbxMDBX::CDbxMDBX(const wchar_t *tszFileName, int iMode) :
CDbxMDBX::~CDbxMDBX()
{
+ if (m_pWriteTran)
+ mdbx_txn_commit(m_pWriteTran);
+
if (m_curEventsSort)
mdbx_cursor_close(m_curEventsSort);
@@ -144,52 +147,52 @@ void CDbxMDBX::DBFlush(bool bForce)
int CDbxMDBX::Load()
{
MDBX_db_flags_t defFlags = MDBX_CREATE;
- {
- txn_ptr trnlck(StartTran());
- if (trnlck == nullptr) {
- if (m_dbError == MDBX_TXN_FULL) {
- if (IDOK == MessageBox(NULL, TranslateT("Your database is in the obsolete format. Click OK to read the upgrade instructions or Cancel to exit"), TranslateT("Error"), MB_ICONERROR | MB_OKCANCEL))
- Utils_OpenUrl("https://www.miranda-ng.org/news/unknown-profile-format");
- return EGROKPRF_OBSOLETE;
- }
- return EGROKPRF_DAMAGED;
+
+ m_pWriteTran = nullptr;
+ m_dbError = mdbx_txn_begin(m_env, nullptr, MDBX_TXN_READWRITE, &m_pWriteTran);
+ if (m_pWriteTran == nullptr) {
+ if (m_dbError == MDBX_TXN_FULL) {
+ if (IDOK == MessageBox(NULL, TranslateT("Your database is in the obsolete format. Click OK to read the upgrade instructions or Cancel to exit"), TranslateT("Error"), MB_ICONERROR | MB_OKCANCEL))
+ Utils_OpenUrl("https://www.miranda-ng.org/news/unknown-profile-format");
+ return EGROKPRF_OBSOLETE;
}
+ return EGROKPRF_DAMAGED;
+ }
- mdbx_dbi_open(trnlck, "global", defFlags | MDBX_INTEGERKEY, &m_dbGlobal);
- mdbx_dbi_open(trnlck, "crypto", defFlags, &m_dbCrypto);
- mdbx_dbi_open(trnlck, "contacts", defFlags | MDBX_INTEGERKEY, &m_dbContacts);
- mdbx_dbi_open(trnlck, "modules", defFlags | MDBX_INTEGERKEY, &m_dbModules);
- mdbx_dbi_open(trnlck, "events", defFlags | MDBX_INTEGERKEY, &m_dbEvents);
+ mdbx_dbi_open(m_pWriteTran, "global", defFlags | MDBX_INTEGERKEY, &m_dbGlobal);
+ mdbx_dbi_open(m_pWriteTran, "crypto", defFlags, &m_dbCrypto);
+ mdbx_dbi_open(m_pWriteTran, "contacts", defFlags | MDBX_INTEGERKEY, &m_dbContacts);
+ mdbx_dbi_open(m_pWriteTran, "modules", defFlags | MDBX_INTEGERKEY, &m_dbModules);
+ mdbx_dbi_open(m_pWriteTran, "events", defFlags | MDBX_INTEGERKEY, &m_dbEvents);
- mdbx_dbi_open_ex(trnlck, "eventids", defFlags, &m_dbEventIds, DBEventIdKey::Compare, nullptr);
- mdbx_dbi_open_ex(trnlck, "eventsrt", defFlags, &m_dbEventsSort, DBEventSortingKey::Compare, nullptr);
- mdbx_dbi_open_ex(trnlck, "settings", defFlags, &m_dbSettings, DBSettingKey::Compare, nullptr);
+ mdbx_dbi_open_ex(m_pWriteTran, "eventids", defFlags, &m_dbEventIds, DBEventIdKey::Compare, nullptr);
+ mdbx_dbi_open_ex(m_pWriteTran, "eventsrt", defFlags, &m_dbEventsSort, DBEventSortingKey::Compare, nullptr);
+ mdbx_dbi_open_ex(m_pWriteTran, "settings", defFlags, &m_dbSettings, DBSettingKey::Compare, nullptr);
- uint32_t keyVal = 1;
+ uint32_t keyVal = 1;
+ {
MDBX_val key = { &keyVal, sizeof(keyVal) }, data;
- if (mdbx_get(trnlck, m_dbGlobal, &key, &data) == MDBX_SUCCESS) {
- const DBHeader *hdr = (const DBHeader*)data.iov_base;
+ if (mdbx_get(m_pWriteTran, m_dbGlobal, &key, &data) == MDBX_SUCCESS) {
+ const DBHeader *hdr = (const DBHeader *)data.iov_base;
if (hdr->dwSignature != DBHEADER_SIGNATURE)
return EGROKPRF_DAMAGED;
if (hdr->dwVersion != DBHEADER_VERSION)
return EGROKPRF_OBSOLETE;
m_header = *hdr;
- }
- else {
+ } else {
m_header.dwSignature = DBHEADER_SIGNATURE;
m_header.dwVersion = DBHEADER_VERSION;
data.iov_base = &m_header; data.iov_len = sizeof(m_header);
- mdbx_put(trnlck, m_dbGlobal, &key, &data, MDBX_UPSERT);
+ mdbx_put(m_pWriteTran, m_dbGlobal, &key, &data, MDBX_UPSERT);
DBFlush();
}
keyVal = 2;
- if (mdbx_get(trnlck, m_dbGlobal, &key, &data) == MDBX_SUCCESS)
- m_ccDummy.dbc = *(const DBContact*)data.iov_base;
-
- trnlck.Commit();
+ if (mdbx_get(m_pWriteTran, m_dbGlobal, &key, &data) == MDBX_SUCCESS)
+ m_ccDummy.dbc = *(const DBContact *)data.iov_base;
}
+ mdbx_txn_commit(m_pWriteTran); m_pWriteTran = nullptr;
mdbx_txn_begin(m_env, nullptr, MDBX_TXN_RDONLY, &m_txn_ro);
@@ -256,7 +259,7 @@ int CDbxMDBX::Map()
if (rc != MDBX_SUCCESS)
return EGROKPRF_CANTREAD;
- MDBX_env_flags_t mode = MDBX_NOSUBDIR | MDBX_MAPASYNC | MDBX_WRITEMAP | MDBX_SAFE_NOSYNC | MDBX_COALESCE | MDBX_EXCLUSIVE;
+ MDBX_env_flags_t mode = MDBX_NOSUBDIR | MDBX_NOTLS | MDBX_SAFE_NOSYNC | MDBX_COALESCE | MDBX_EXCLUSIVE;
if (m_bReadOnly)
mode |= MDBX_RDONLY;
@@ -286,17 +289,19 @@ void CDbxMDBX::SetCacheSafetyMode(BOOL bIsSet)
MDBX_txn* CDbxMDBX::StartTran()
{
- /*
+ if (m_bReadOnly)
+ return nullptr;
+
mir_cslock lck(m_csDbAccess);
if (m_pWriteTran == nullptr) {
- m_dbError = mdbx_txn_begin(m_env, nullptr, (m_bReadOnly) ? MDBX_TXN_RDONLY : MDBX_TXN_READWRITE, &m_pWriteTran);
+ m_dbError = mdbx_txn_begin(m_env, nullptr, MDBX_TXN_READWRITE, &m_pWriteTran);
// FIXME: throw an exception
_ASSERT(m_dbError == MDBX_SUCCESS);
- }*/
+ }
MDBX_txn *res = nullptr;
- m_dbError = mdbx_txn_begin(m_env, m_pWriteTran, (m_bReadOnly) ? MDBX_TXN_RDONLY : MDBX_TXN_READWRITE, &res);
+ m_dbError = mdbx_txn_begin(m_env, m_pWriteTran, MDBX_TXN_READWRITE, &res);
_ASSERT(m_dbError == MDBX_SUCCESS);
return res;
}
diff --git a/plugins/Dbx_mdbx/src/dbintf.h b/plugins/Dbx_mdbx/src/dbintf.h
index 5d6e35aa5c..126501147b 100644
--- a/plugins/Dbx_mdbx/src/dbintf.h
+++ b/plugins/Dbx_mdbx/src/dbintf.h
@@ -139,6 +139,8 @@ struct EventItem
class CDbxMDBX : public MDatabaseCommon, public MIDatabaseChecker, public MZeroedObject
{
friend class CMdbxEventCursor;
+ friend class txn_ptr;
+
typedef std::map<uint32_t, std::string> TModuleMap;
struct Impl {
diff --git a/plugins/Dbx_mdbx/src/dbmodulechain.cpp b/plugins/Dbx_mdbx/src/dbmodulechain.cpp
index fd41acd623..54e9631c43 100644
--- a/plugins/Dbx_mdbx/src/dbmodulechain.cpp
+++ b/plugins/Dbx_mdbx/src/dbmodulechain.cpp
@@ -47,7 +47,7 @@ uint32_t CDbxMDBX::GetModuleID(const char *szName)
if (m_Modules.find(iHash) == m_Modules.end()) {
MDBX_val key = { &iHash, sizeof(iHash) }, data = { (void*)szName, strlen(szName) + 1 };
{
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
if (mdbx_put(trnlck, m_dbModules, &key, &data, MDBX_UPSERT) != MDBX_SUCCESS)
return -1;
if (trnlck.Commit() != MDBX_SUCCESS)
diff --git a/plugins/Dbx_mdbx/src/dbsettings.cpp b/plugins/Dbx_mdbx/src/dbsettings.cpp
index 9d1f32fc5d..ee439369e8 100644
--- a/plugins/Dbx_mdbx/src/dbsettings.cpp
+++ b/plugins/Dbx_mdbx/src/dbsettings.cpp
@@ -339,7 +339,7 @@ LBL_WriteString:
}
{
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
if (mdbx_put(trnlck, m_dbSettings, &key, &data, MDBX_UPSERT) != MDBX_SUCCESS)
return 1;
@@ -373,7 +373,7 @@ BOOL CDbxMDBX::DeleteContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR
keyVal->dwModuleId = GetModuleID(szModule);
memcpy(&keyVal->szSettingName, szSetting, settingNameLen + 1);
- txn_ptr trnlck(StartTran());
+ txn_ptr trnlck(this);
MDBX_val key = { keyVal, sizeof(DBSettingKey) + settingNameLen };
if (mdbx_del(trnlck, m_dbSettings, &key, nullptr) != MDBX_SUCCESS)
return 1;
@@ -399,12 +399,12 @@ BOOL CDbxMDBX::EnumContactSettings(MCONTACT hContact, DBSETTINGENUMPROC pfnEnumP
{
LIST<char> arKeys(100);
{
- txn_ptr_ro txn(m_txn_ro);
- cursor_ptr pCursor(m_txn_ro, m_dbSettings);
-
DBSettingKey keyVal = { hContact, GetModuleID(szModule), 0 };
MDBX_val key = { &keyVal, sizeof(keyVal) }, data;
+ txn_ptr_ro txn(m_txn_ro);
+ cursor_ptr pCursor(m_txn_ro, m_dbSettings);
+
for (int res = mdbx_cursor_get(pCursor, &key, &data, MDBX_SET_RANGE); res == MDBX_SUCCESS; res = mdbx_cursor_get(pCursor, &key, &data, MDBX_NEXT)) {
const DBSettingKey *pKey = (const DBSettingKey*)key.iov_base;
if (pKey->hContact != hContact || pKey->dwModuleId != keyVal.dwModuleId)
diff --git a/plugins/Dbx_mdbx/src/dbutils.cpp b/plugins/Dbx_mdbx/src/dbutils.cpp
index be0ad2ad4b..a1a758a53b 100644
--- a/plugins/Dbx_mdbx/src/dbutils.cpp
+++ b/plugins/Dbx_mdbx/src/dbutils.cpp
@@ -55,6 +55,7 @@ int DBSettingKey::Compare(const MDBX_val *ax, const MDBX_val *bx) MDBX_CXX17_NOE
}
/////////////////////////////////////////////////////////////////////////////////////////
+// txn_ptr_ro class
txn_ptr_ro::txn_ptr_ro(CMDBX_txn_ro &_txn) :
txn(_txn),
@@ -87,3 +88,42 @@ txn_ptr_ro::~txn_ptr_ro()
Sleep(0);
}
}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// txn_ptr class
+
+txn_ptr::txn_ptr(CDbxMDBX *_db) :
+ pDb(_db),
+ txn(_db->StartTran())
+{
+ _db->m_csDbAccess.Lock();
+}
+
+txn_ptr::~txn_ptr()
+{
+ if (txn)
+ Abort();
+
+ pDb->m_csDbAccess.Unlock();
+}
+
+int txn_ptr::Commit()
+{
+ int rc = mdbx_txn_commit(txn);
+ if (rc != MDBX_SUCCESS) {
+ /* FIXME: throw an exception */
+ Abort();
+ return rc;
+ }
+ txn = nullptr;
+ return MDBX_SUCCESS;
+}
+
+void txn_ptr::Abort()
+{
+ int rc = mdbx_txn_abort(txn);
+ /* FIXME: throw an exception */
+ _ASSERT(rc == MDBX_SUCCESS);
+ UNREFERENCED_PARAMETER(rc);
+ txn = nullptr;
+}
diff --git a/plugins/Dbx_mdbx/src/stdafx.h b/plugins/Dbx_mdbx/src/stdafx.h
index 0dcad889ed..82e2e8be53 100644
--- a/plugins/Dbx_mdbx/src/stdafx.h
+++ b/plugins/Dbx_mdbx/src/stdafx.h
@@ -58,46 +58,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# define thread_local __declspec(thread)
#endif
-class txn_ptr
-{
- MDBX_txn *txn;
-public:
- __forceinline txn_ptr(MDBX_txn *_txn) :
- txn(_txn)
- {}
-
- __forceinline ~txn_ptr()
- {
- if (txn) {
- /* FIXME: see https://github.com/leo-yuriev/libfpta/blob/77a7251fde2030165a3916ee68fd86a1374b3dd8/src/common.cxx#L370 */
- Abort();
- }
- }
-
- __forceinline operator MDBX_txn*() const { return txn; }
-
- __forceinline int Commit()
- {
- int rc = mdbx_txn_commit(txn);
- if (rc != MDBX_SUCCESS) {
- /* FIXME: throw an exception */
- Abort();
- return rc;
- }
- txn = nullptr;
- return MDBX_SUCCESS;
- }
-
- __forceinline void Abort()
- {
- int rc = mdbx_txn_abort(txn);
- /* FIXME: throw an exception */
- _ASSERT(rc == MDBX_SUCCESS);
- UNREFERENCED_PARAMETER(rc);
- txn = nullptr;
- }
-};
-
struct CMDBX_txn_ro
{
MDBX_txn *txn = nullptr;
@@ -140,6 +100,22 @@ public:
};
#include "dbintf.h"
+
+class txn_ptr
+{
+ CDbxMDBX *pDb;
+ MDBX_txn *txn;
+
+public:
+ txn_ptr(CDbxMDBX *_db);
+ ~txn_ptr();
+
+ __forceinline operator MDBX_txn*() const { return txn; }
+
+ int Commit();
+ void Abort();
+};
+
#include "resource.h"
#include "version.h"