//# define sqlite3BtreeMutexArrayLeave(X) static void sqlite3BtreeMutexArrayLeave( BtreeMutexArray X ) { }
//# define sqlite3BtreeMutexArrayInsert(X,Y) static void sqlite3BtreeMutexArrayInsert( BtreeMutexArray X, Btree Y ) { }
//# define sqlite3BtreeMutexArrayInsert(X,Y) static void sqlite3BtreeMutexArrayInsert(BtreeMutexArray X, Btree Y) { }
//# define sqlite3BtreeMutexArrayEnter(X) static void sqlite3BtreeMutexArrayEnter( BtreeMutexArray X ) { }
//# define sqlite3BtreeMutexArrayLeave(X) static void sqlite3BtreeMutexArrayLeave(BtreeMutexArray X) { }
//# define sqlite3BtreeMutexArrayEnter(X) static void sqlite3BtreeMutexArrayEnter(BtreeMutexArray X) { }
/* ** Leave the mutex of every btree in the group. */ void sqlite3BtreeMutexArrayLeave(BtreeMutexArray *pArray) { int i; for(i=0; i<pArray->nMutex; i++){ Btree *p = pArray->aBtree[i]; /* Some basic sanity checking */ assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt ); assert( p->locked); assert( p->wantToLock>0 ); /* We should already hold a lock on the database connection */ assert( sqlite3_mutex_held(p->db->mutex) ); p->wantToLock--; if( p->wantToLock==0){ unlockBtreeMutex(p); } } }
/* ** Enter the mutex of every btree in the array. This routine is ** called at the beginning of sqlite3VdbeExec(). The mutexes are ** exited at the end of the same function. */ void sqlite3BtreeMutexArrayEnter(BtreeMutexArray *pArray) { int i; for(i=0; i<pArray->nMutex; i++){ Btree *p = pArray->aBtree[i]; /* Some basic sanity checking */ assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt ); assert( !p->locked || p->wantToLock>0 ); /* We should already hold a lock on the database connection */ assert( sqlite3_mutex_held(p->db->mutex) ); /* The Btree is sharable because only sharable Btrees are entered ** into the array in the first place. */ assert( p->sharable ); p->wantToLock++; if( !p->locked ){ lockBtreeMutex(p); } } }
/* ** Add a new Btree pointer to a BtreeMutexArray. ** if the pointer can possibly be shared with ** another database connection. ** ** The pointers are kept in sorted order by pBtree->pBt. That ** way when we go to enter all the mutexes, we can enter them ** in order without every having to backup and retry and without ** worrying about deadlock. ** ** The number of shared btrees will always be small (usually 0 or 1) ** so an insertion sort is an adequate algorithm here. */ void sqlite3BtreeMutexArrayInsert(BtreeMutexArray *pArray, Btree *pBtree) { int i, j; BtShared *pBt; if( pBtree==0 || pBtree->sharable==0 ) return; #if !NDEBUG { for(i=0; i<pArray->nMutex; i++){ assert( pArray->aBtree[i]!=pBtree ); } } #endif assert( pArray->nMutex>=0 ); assert( pArray->nMutex<ArraySize(pArray->aBtree)-1 ); pBt = pBtree->pBt; for(i=0; i<pArray->nMutex; i++){ assert( pArray->aBtree[i]!=pBtree ); if( pArray->aBtree[i]->pBt>pBt ){ for(j=pArray->nMutex; j>i; j--){ pArray->aBtree[j] = pArray->aBtree[j-1]; } pArray->aBtree[i] = pBtree; pArray->nMutex++; return; } } pArray->aBtree[pArray->nMutex++] = pBtree; }