Index: src/btmutex.c ================================================================== --- src/btmutex.c +++ src/btmutex.c @@ -43,32 +43,14 @@ assert( p->locked==1 ); assert( sqlite3_mutex_held(pBt->mutex) ); assert( sqlite3_mutex_held(p->db->mutex) ); assert( p->db==pBt->db ); - pBt->iMutexCounter++; sqlite3_mutex_leave(pBt->mutex); p->locked = 0; } -#ifdef SQLITE_DEBUG -/* -** Return the number of times that the mutex has been exited for -** the given btree. -** -** This is a small circular counter that wraps around to zero on -** overflow. It is used only for sanity checking - to verify that -** mutexes are held continously by asserting that the value of -** this counter at the beginning of a region is the same as at -** the end. -*/ -u32 sqlite3BtreeMutexCounter(Btree *p){ - assert( p->locked==1 || p->sharable==0 ); - return p->pBt->iMutexCounter; -} -#endif - /* ** Enter a mutex on the given BTree object. ** ** If the object is not sharable, then no mutex is ever required ** and this routine is a no-op. The underlying mutex is non-recursive. @@ -109,28 +91,10 @@ if( !p->sharable ) return; p->wantToLock++; if( p->locked ) return; - /* Increment the mutex counter on all locked btrees in the same - ** database connection. This simulates the unlocking that would - ** occur on a worst-case mutex dead-lock avoidance scenario. - */ -#ifdef SQLITE_DEBUG - { - int ii; - sqlite3 *db = p->db; - Btree *pOther; - for(ii=0; iinDb; ii++){ - if( ii==1 ) continue; - pOther = db->aDb[ii].pBt; - if( pOther==0 || pOther->sharable==0 || pOther->locked==0 ) continue; - pOther->pBt->iMutexCounter++; - } - } -#endif - /* In most cases, we should be able to acquire the lock we ** want without having to go throught the ascending lock ** procedure that follows. Just be sure not to block. */ if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){ Index: src/btree.h ================================================================== --- src/btree.h +++ src/btree.h @@ -219,22 +219,20 @@ #ifndef NDEBUG /* These routines are used inside assert() statements only. */ int sqlite3BtreeHoldsMutex(Btree*); int sqlite3BtreeHoldsAllMutexes(sqlite3*); int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*); - u32 sqlite3BtreeMutexCounter(Btree*); #endif #else # define sqlite3BtreeLeave(X) -# define sqlite3BtreeMutexCounter(X) 0 # define sqlite3BtreeEnterCursor(X) # define sqlite3BtreeLeaveCursor(X) # define sqlite3BtreeLeaveAll(X) # define sqlite3BtreeHoldsMutex(X) 1 # define sqlite3BtreeHoldsAllMutexes(X) 1 -# define sqlite3BtreeSchemaMutexHeld(X,Y) 1 +# define sqlite3SchemaMutexHeld(X,Y,Z) 1 #endif #endif /* _BTREE_H_ */ Index: src/btreeInt.h ================================================================== --- src/btreeInt.h +++ src/btreeInt.h @@ -433,11 +433,10 @@ BtShared *pNext; /* Next on a list of sharable BtShared structs */ BtLock *pLock; /* List of locks held on this shared-btree struct */ Btree *pWriter; /* Btree with currently open write transaction */ u8 isExclusive; /* True if pWriter has an EXCLUSIVE lock on the db */ u8 isPending; /* If waiting for read-locks to clear */ - u16 iMutexCounter; /* The number of mutex_leave(mutex) calls */ #endif u8 *pTmpSpace; /* BtShared.pageSize bytes of space for tmp use */ }; /* Index: src/vdbe.c ================================================================== --- src/vdbe.c +++ src/vdbe.c @@ -1392,11 +1392,10 @@ assert( pOp[-1].p4type==P4_COLLSEQ ); assert( pOp[-1].opcode==OP_CollSeq ); ctx.pColl = pOp[-1].p4.pColl; } (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */ - sqlite3VdbeMutexResync(p); if( db->mallocFailed ){ /* Even though a malloc() has failed, the implementation of the ** user function may have called an sqlite3_result_XXX() function ** to return a value. The following call releases any resources ** associated with such a value. @@ -2658,11 +2657,10 @@ } } if( p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){ sqlite3ExpirePreparedStatements(db); sqlite3ResetInternalSchema(db, -1); - sqlite3VdbeMutexResync(p); db->flags = (db->flags | SQLITE_InternChanges); } } /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all @@ -5196,27 +5194,15 @@ assert( pOp[-1].p4type==P4_COLLSEQ ); assert( pOp[-1].opcode==OP_CollSeq ); ctx.pColl = pOp[-1].p4.pColl; } (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */ - sqlite3VdbeMutexResync(p); if( ctx.isError ){ sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s)); rc = ctx.isError; } - /* The app-defined function has done something that as caused this - ** statement to expire. (Perhaps the function called sqlite3_exec() - ** with a CREATE TABLE statement.) - */ -#if 0 - if( p->expired ){ - rc = SQLITE_ABORT; - break; - } -#endif - sqlite3VdbeMemRelease(&ctx.s); break; } @@ -5236,15 +5222,12 @@ Mem *pMem; assert( pOp->p1>0 && pOp->p1<=p->nMem ); pMem = &aMem[pOp->p1]; assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); - sqlite3VdbeMutexResync(p); if( rc ){ sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(pMem)); - }else if( p->expired ){ - rc = SQLITE_ABORT; } sqlite3VdbeChangeEncoding(pMem, encoding); UPDATE_MAX_BLOBSIZE(pMem); if( sqlite3VdbeMemTooBig(pMem) ){ goto too_big; Index: src/vdbeInt.h ================================================================== --- src/vdbeInt.h +++ src/vdbeInt.h @@ -301,11 +301,10 @@ u8 usesStmtJournal; /* True if uses a statement journal */ u8 readOnly; /* True for read-only statements */ u8 isPrepareV2; /* True if prepared with prepare_v2() */ int nChange; /* Number of db changes made since last reset */ yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ - u32 iMutexCounter; /* Mutex counter upon sqlite3VdbeEnter() */ int iStatement; /* Statement number (or 0 if has not opened stmt) */ int aCounter[3]; /* Counters used by sqlite3_stmt_status() */ #ifndef SQLITE_OMIT_TRACE i64 startTime; /* Time when query started - used for profiling */ #endif @@ -385,13 +384,18 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); int sqlite3VdbeCloseStatement(Vdbe *, int); void sqlite3VdbeFrameDelete(VdbeFrame*); int sqlite3VdbeFrameRestore(VdbeFrame *); void sqlite3VdbeMemStoreType(Mem *pMem); -void sqlite3VdbeEnter(Vdbe*); -void sqlite3VdbeLeave(Vdbe*); -void sqlite3VdbeMutexResync(Vdbe*); + +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 + void sqlite3VdbeEnter(Vdbe*); + void sqlite3VdbeLeave(Vdbe*); +#else +# define sqlite3VdbeEnter(X) +# define sqlite3VdbeLeave(X) +#endif #ifdef SQLITE_DEBUG void sqlite3VdbeMemPrepareToChange(Vdbe*,Mem*); #endif Index: src/vdbeaux.c ================================================================== --- src/vdbeaux.c +++ src/vdbeaux.c @@ -958,35 +958,11 @@ assert( i>=0 && idb->nDb && ibtreeMask)*8 ); p->btreeMask |= ((yDbMask)1)<db; - Db *aDb = db->aDb; - int nDb = db->nDb; - for(i=0, mask=1; ibtreeMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ - cntSum += sqlite3BtreeMutexCounter(aDb[i].pBt); - } - } -#else - UNUSED_PARAMETER(p); -#endif - return cntSum; -} -#endif - +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 /* ** If SQLite is compiled to support shared-cache mode and to be threadsafe, ** this routine obtains the mutex associated with each BtShared structure ** that may be accessed by the VM passed as an argument. In doing so it also ** sets the BtShared.db member of each of the BtShared structures, ensuring @@ -1005,11 +981,10 @@ ** corresponding to btrees that use shared cache. Then the runtime of ** this routine is N*N. But as N is rarely more than 1, this should not ** be a problem. */ void sqlite3VdbeEnter(Vdbe *p){ -#ifndef SQLITE_OMIT_SHARED_CACHE int i; yDbMask mask; sqlite3 *db = p->db; Db *aDb = db->aDb; int nDb = db->nDb; @@ -1016,67 +991,31 @@ for(i=0, mask=1; ibtreeMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ sqlite3BtreeEnter(aDb[i].pBt); } } - p->iMutexCounter = mutexCounterSum(p); -#else - UNUSED_PARAMETER(p); +} #endif -} +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 /* ** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter(). */ void sqlite3VdbeLeave(Vdbe *p){ -#ifndef SQLITE_OMIT_SHARED_CACHE int i; yDbMask mask; sqlite3 *db = p->db; Db *aDb = db->aDb; int nDb = db->nDb; - /* Assert that the all mutexes have been held continously since - ** the most recent sqlite3VdbeEnter() or sqlite3VdbeMutexResync(). - */ - assert( mutexCounterSum(p) == p->iMutexCounter ); - for(i=0, mask=1; ibtreeMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ sqlite3BtreeLeave(aDb[i].pBt); } } -#else - UNUSED_PARAMETER(p); -#endif -} - -/* -** Recompute the sum of the mutex counters on all btrees used by the -** prepared statement p. -** -** Call this routine while holding a sqlite3VdbeEnter() after doing something -** that might cause one or more of the individual mutexes held by the -** prepared statement to be released. Calling sqlite3BtreeEnter() on -** any BtShared mutex which is not used by the prepared statement is one -** way to cause one or more of the mutexes in the prepared statement -** to be temporarily released. The anti-deadlocking logic in -** sqlite3BtreeEnter() can cause mutexes to be released temporarily then -** reacquired. -** -** Calling this routine is an acknowledgement that some of the individual -** mutexes in the prepared statement might have been released and reacquired. -** So checks to verify that mutex-protected content did not change -** unexpectedly should accompany any call to this routine. -*/ -void sqlite3VdbeMutexResync(Vdbe *p){ -#if !defined(SQLITE_OMIT_SHARED_CACHE) && defined(SQLITE_DEBUG) - p->iMutexCounter = mutexCounterSum(p); -#else - UNUSED_PARAMETER(p); -#endif -} +} +#endif #if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) /* ** Print a single opcode. This routine is used for debugging only. */ @@ -2281,11 +2220,10 @@ sqlite3ResetInternalSchema(db, -1); db->flags = (db->flags | SQLITE_InternChanges); } /* Release the locks */ - sqlite3VdbeMutexResync(p); sqlite3VdbeLeave(p); } /* We have successfully halted and closed the VM. Record this fact. */ if( p->pc>=0 ){