diff --git a/src/sqlite3.c b/src/sqlite3.c index 09a999ffd2ef574031495ea75d8a6afc0fdd91a0..1188d1cc10a5846f4f1daf72e74bafadc58440f6 100644 --- a/src/sqlite3.c +++ b/src/sqlite3.c @@ -36889,6 +36889,7 @@ typedef struct LocalLockStatus { u8 reserved; u32 lockLen; u32 busyLine; + int curTid; u8 lockStatus[MAX_LOCK_NUM]; // last index is trx lock } LocalLockStatus; __thread LocalLockStatus g_lockStatus = {0}; @@ -67560,7 +67561,7 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint( assert( pWal->ckptLock==0 ); assert( pWal->writeLock==0 ); - ResetLockStatus(); + /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked ** in the SQLITE_CHECKPOINT_PASSIVE mode. */ assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 ); @@ -72044,7 +72045,7 @@ SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){ } } #endif - + ResetLockStatus(); /* Rollback any active transaction and free the handle structure. ** The call to sqlite3BtreeRollback() drops any table-locks held by ** this handle. @@ -80215,6 +80216,7 @@ SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int * if( p ){ BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); + ResetLockStatus(); if( pBt->inTransaction!=TRANS_NONE ){ rc = SQLITE_LOCKED; MARK_LAST_BUSY_LINE(rc); @@ -247116,33 +247118,34 @@ static inline int OsGetTid(void) static void ResetLockStatus(void) { (void)memset(&g_lockStatus, 0, sizeof(g_lockStatus)); + g_lockStatus.curTid = OsGetTid(); } /* ** Record lock info, correspond wal aLock buf, 1 aLock: 1 */ -static void TryRecordTid(int *tidBuf, int ofs, int lockLen) +static inline void TryRecordTid(int *tidBuf, int ofs, int lockLen) { int lockOfs = ofs + lockLen; for (int i = ofs; i < lockOfs; i++) { if (tidBuf[i] == 0) { - tidBuf[i] = OsGetTid(); + tidBuf[i] = g_lockStatus.curTid; } } } /* ** Clear locks info. */ -static void TryClearTid(int *tidBuf, int ofs, int lockLen) +static inline void TryClearTid(int *tidBuf, int ofs, int lockLen) { int lockOfs = ofs + lockLen; for (int i = ofs; i < lockOfs; i++) { - if (tidBuf[i] == OsGetTid()) { + if (tidBuf[i] == g_lockStatus.curTid) { tidBuf[i] = 0; } } } -static void MarkLockBusy(u32 lockIdx, u32 lockLen, u8 lockType, u8 lockByProcess) +static inline void MarkLockBusy(u32 lockIdx, u32 lockLen, u8 lockType, u8 lockByProcess) { g_lockStatus.busyLockIdx = lockIdx; g_lockStatus.busyLockType = lockType; @@ -247152,12 +247155,14 @@ static void MarkLockBusy(u32 lockIdx, u32 lockLen, u8 lockType, u8 lockByProcess static void MarkLockStatus(u32 lockIdx, u32 lockLen, u8 lockType) { - if ((lockIdx + lockLen) > MAX_LOCK_NUM || lockLen == 0) { + if (lockLen == 0 || (lockIdx + lockLen) > MAX_LOCK_NUM) { sqlite3_log(SQLITE_ERROR, "Unexpect lock index %u lockLen %d!", lockIdx, lockLen); return; } - if (lockIdx == g_lockStatus.busyLockIdx) { + // only busy error code need record + if (g_lockStatus.lockLen != 0 && lockIdx == g_lockStatus.busyLockIdx) { g_lockStatus.busyLockIdx = 0; + g_lockStatus.busyLockType = NO_LOCK; g_lockStatus.lockLen = 0; } if (lockLen == 1) { @@ -247168,20 +247173,12 @@ static void MarkLockStatus(u32 lockIdx, u32 lockLen, u8 lockType) } } -static void MarkLockStatusByRc(int rc, u32 lockIdx, u32 lockLen, u8 lockType, u8 lockByProcess) +static inline void MarkLockStatusByRc(int rc, u32 lockIdx, u32 lockLen, u8 lockType, u8 lockByProcess) { - if (rc == SQLITE_BUSY) { - MarkLockBusy(lockIdx, lockLen, lockType, lockByProcess); - return; - } if (rc == SQLITE_OK) { MarkLockStatus(lockIdx, lockLen, lockType); - } - // only busy error code need record - if (lockIdx == g_lockStatus.busyLockIdx && g_lockStatus.lockLen != 0) { - g_lockStatus.busyLockIdx = 0; - g_lockStatus.busyLockType = NO_LOCK; - g_lockStatus.lockLen = 0; + } else if (rc == SQLITE_BUSY) { + MarkLockBusy(lockIdx, lockLen, lockType, lockByProcess); } } @@ -247191,7 +247188,7 @@ static inline const char *TrxLockName(int eLock) eLock == RESERVED_LOCK ? "RESERVED" : eLock == EXCLUSIVE_LOCK ? "EXCLUSIVE" : eLock == SHARED_LOCK ? "SHARED" : - eLock == UNKNOWN_LOCK ? "UNKNOWN" : "?error?"; + eLock == UNKNOWN_LOCK ? "UNKNOWN" : "UNKNOWN_LOCK"; } static inline const char *IdxToLockName(u32 idx) @@ -247221,7 +247218,7 @@ static void DumpHandleLock(char *dumpBuf, int dumpBufLen) g_lockStatus.lockLen, tmp != dumpBuf ? dumpBuf : "none"); } -static const char *FlockToName(int l_type) +static inline const char *FlockToName(int l_type) { return l_type == F_RDLCK ? "F_RDLCK" : l_type == F_WRLCK ? "F_WRLCK" :