/* ** Try to obtain a lock of type locktype on the database file. If ** a similar or greater lock is already held, this function is a no-op ** (returning SQLITE_OK immediately). ** ** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke ** the busy callback if the lock is currently not available. Repeat ** until the busy callback returns false or until the attempt to ** obtain the lock succeeds. ** ** Return SQLITE_OK on success and an error code if we cannot obtain ** the lock. If the lock is obtained successfully, set the Pager.state ** variable to locktype before returning. */ static int pager_wait_on_lock( Pager pPager, int locktype ) { int rc; /* Return code */ /* The OS lock values must be the same as the Pager lock values */ Debug.Assert( PAGER_SHARED == SHARED_LOCK ); Debug.Assert( PAGER_RESERVED == RESERVED_LOCK ); Debug.Assert( PAGER_EXCLUSIVE == EXCLUSIVE_LOCK ); /* If the file is currently unlocked then the size must be unknown. It ** must not have been modified at this point. */ Debug.Assert( pPager.state >= PAGER_SHARED || pPager.dbSizeValid == false ); Debug.Assert( pPager.state >= PAGER_SHARED || pPager.dbModified == false ); /* Check that this is either a no-op (because the requested lock is ** already held, or one of the transistions that the busy-handler ** may be invoked during, according to the comment above ** sqlite3PagerSetBusyhandler(). */ Debug.Assert( ( pPager.state >= locktype ) || ( pPager.state == PAGER_UNLOCK && locktype == PAGER_SHARED ) || ( pPager.state == PAGER_RESERVED && locktype == PAGER_EXCLUSIVE ) ); if ( pPager.state >= locktype ) { rc = SQLITE_OK; } else { do { rc = sqlite3OsLock( pPager.fd, locktype ); } while ( rc == SQLITE_BUSY && pPager.xBusyHandler( pPager.pBusyHandlerArg ) != 0 ); if ( rc == SQLITE_OK ) { pPager.state = (u8)locktype; IOTRACE( "LOCK %p %d\n", pPager, locktype ); } } return rc; }
/* ** Try to obtain a lock of type locktype on the database file. If ** a similar or greater lock is already held, this function is a no-op ** (returning SQLITE_OK immediately). ** ** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke ** the busy callback if the lock is currently not available. Repeat ** until the busy callback returns false or until the attempt to ** obtain the lock succeeds. ** ** Return SQLITE_OK on success and an error code if we cannot obtain ** the lock. If the lock is obtained successfully, set the Pager.state ** variable to locktype before returning. */ static int pager_wait_on_lock( Pager pPager, int locktype ) { int rc; /* Return code */ /* Check that this is either a no-op (because the requested lock is ** already held, or one of the transistions that the busy-handler ** may be invoked during, according to the comment above ** sqlite3PagerSetBusyhandler(). */ Debug.Assert( ( pPager.eLock >= locktype ) || ( pPager.eLock == NO_LOCK && locktype == SHARED_LOCK ) || ( pPager.eLock == RESERVED_LOCK && locktype == EXCLUSIVE_LOCK ) ); do { rc = pagerLockDb( pPager, locktype ); } while ( rc == SQLITE_BUSY && pPager.xBusyHandler( pPager.pBusyHandlerArg ) != 0 ); return rc; }