/* ** 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); } } }
/* ** 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); } } }
/* ** 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; }