/ Changes On Branch lowlevel-lock-timeout
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch lowlevel-lock-timeout Excluding Merge-Ins

This is equivalent to a diff from 6c40c557 to 5474e560

2018-03-27
13:57
Provide the ability for the VFS to do a blocking wait on locks if compiled with SQLITE_ENABLE_SETLK_TIMEOUT. (check-in: e7dff982 user: drh tags: trunk)
2018-03-26
21:05
Do not inject OOM errors on SQLITE_FCNTL_LOCK_TIMEOUT calls as an OOM is not possible in that context. (Closed-Leaf check-in: 5474e560 user: drh tags: lowlevel-lock-timeout)
20:43
Avoid a race condition that might cause a busy_timeout to last longer than it should. (check-in: b8196056 user: drh tags: lowlevel-lock-timeout)
17:56
Fix a typo preventing test script avtrans.test from running in auto-vacuum mode. (check-in: c7473bdb user: dan tags: trunk)
17:40
Add infrastructure to support for using F_SETLKW with a timeout on system that support that functionality. Requires SQLITE_ENABLE_SETLK_TIMEOUT. (check-in: 2e54a743 user: drh tags: lowlevel-lock-timeout)
16:37
Refactor some internal object element names used by the busy handler, to simplify analysis. (check-in: 6c40c557 user: drh tags: trunk)
2018-03-24
23:16
Fix a couple issues in the 'session' module tests. (check-in: ccf734f7 user: mistachkin tags: trunk)

Changes to src/btree.c.

  2227   2227   /*
  2228   2228   ** Invoke the busy handler for a btree.
  2229   2229   */
  2230   2230   static int btreeInvokeBusyHandler(void *pArg){
  2231   2231     BtShared *pBt = (BtShared*)pArg;
  2232   2232     assert( pBt->db );
  2233   2233     assert( sqlite3_mutex_held(pBt->db->mutex) );
  2234         -  return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
         2234  +  return sqlite3InvokeBusyHandler(&pBt->db->busyHandler,
         2235  +                                  sqlite3PagerFile(pBt->pPager));
  2235   2236   }
  2236   2237   
  2237   2238   /*
  2238   2239   ** Open a database file.
  2239   2240   ** 
  2240   2241   ** zFilename is the name of the database file.  If zFilename is NULL
  2241   2242   ** then an ephemeral database is created.  The ephemeral database might
................................................................................
  3368   3369       }
  3369   3370     
  3370   3371       if( rc!=SQLITE_OK ){
  3371   3372         unlockBtreeIfUnused(pBt);
  3372   3373       }
  3373   3374     }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
  3374   3375             btreeInvokeBusyHandler(pBt) );
         3376  +  sqlite3PagerResetLockTimeout(pBt->pPager);
  3375   3377   
  3376   3378     if( rc==SQLITE_OK ){
  3377   3379       if( p->inTrans==TRANS_NONE ){
  3378   3380         pBt->nTransaction++;
  3379   3381   #ifndef SQLITE_OMIT_SHARED_CACHE
  3380   3382         if( p->sharable ){
  3381   3383           assert( p->lock.pBtree==p && p->lock.iTable==1 );

Changes to src/main.c.

  1472   1472   }
  1473   1473   
  1474   1474   /*
  1475   1475   ** This routine implements a busy callback that sleeps and tries
  1476   1476   ** again until a timeout value is reached.  The timeout value is
  1477   1477   ** an integer number of milliseconds passed in as the first
  1478   1478   ** argument.
         1479  +**
         1480  +** Return non-zero to retry the lock.  Return zero to stop trying
         1481  +** and cause SQLite to return SQLITE_BUSY.
  1479   1482   */
  1480   1483   static int sqliteDefaultBusyCallback(
  1481         - void *ptr,               /* Database connection */
  1482         - int count                /* Number of times table has been busy */
         1484  +  void *ptr,               /* Database connection */
         1485  +  int count,               /* Number of times table has been busy */
         1486  +  sqlite3_file *pFile      /* The file on which the lock occurred */
  1483   1487   ){
  1484   1488   #if SQLITE_OS_WIN || HAVE_USLEEP
         1489  +  /* This case is for systems that have support for sleeping for fractions of
         1490  +  ** a second.  Examples:  All windows systems, unix systems with usleep() */
  1485   1491     static const u8 delays[] =
  1486   1492        { 1, 2, 5, 10, 15, 20, 25, 25,  25,  50,  50, 100 };
  1487   1493     static const u8 totals[] =
  1488   1494        { 0, 1, 3,  8, 18, 33, 53, 78, 103, 128, 178, 228 };
  1489   1495   # define NDELAY ArraySize(delays)
  1490   1496     sqlite3 *db = (sqlite3 *)ptr;
  1491         -  int timeout = db->busyTimeout;
         1497  +  int tmout = db->busyTimeout;
  1492   1498     int delay, prior;
  1493   1499   
         1500  +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
         1501  +  if( sqlite3OsFileControl(pFile,SQLITE_FCNTL_LOCK_TIMEOUT,&tmout)==SQLITE_OK ){
         1502  +    if( count ){
         1503  +      tmout = 0;
         1504  +      sqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout);
         1505  +      return 0;
         1506  +    }else{
         1507  +      return 1;
         1508  +    }
         1509  +  }
         1510  +#endif
  1494   1511     assert( count>=0 );
  1495   1512     if( count < NDELAY ){
  1496   1513       delay = delays[count];
  1497   1514       prior = totals[count];
  1498   1515     }else{
  1499   1516       delay = delays[NDELAY-1];
  1500   1517       prior = totals[NDELAY-1] + delay*(count-(NDELAY-1));
  1501   1518     }
  1502         -  if( prior + delay > timeout ){
  1503         -    delay = timeout - prior;
         1519  +  if( prior + delay > tmout ){
         1520  +    delay = tmout - prior;
  1504   1521       if( delay<=0 ) return 0;
  1505   1522     }
  1506   1523     sqlite3OsSleep(db->pVfs, delay*1000);
  1507   1524     return 1;
  1508   1525   #else
         1526  +  /* This case for unix systems that lack usleep() support.  Sleeping
         1527  +  ** must be done in increments of whole seconds */
  1509   1528     sqlite3 *db = (sqlite3 *)ptr;
  1510         -  int timeout = ((sqlite3 *)ptr)->busyTimeout;
  1511         -  if( (count+1)*1000 > timeout ){
         1529  +  int tmout = ((sqlite3 *)ptr)->busyTimeout;
         1530  +  if( (count+1)*1000 > tmout ){
  1512   1531       return 0;
  1513   1532     }
  1514   1533     sqlite3OsSleep(db->pVfs, 1000000);
  1515   1534     return 1;
  1516   1535   #endif
  1517   1536   }
  1518   1537   
  1519   1538   /*
  1520   1539   ** Invoke the given busy handler.
  1521   1540   **
  1522         -** This routine is called when an operation failed with a lock.
         1541  +** This routine is called when an operation failed to acquire a
         1542  +** lock on VFS file pFile.
         1543  +**
  1523   1544   ** If this routine returns non-zero, the lock is retried.  If it
  1524   1545   ** returns 0, the operation aborts with an SQLITE_BUSY error.
  1525   1546   */
  1526         -int sqlite3InvokeBusyHandler(BusyHandler *p){
         1547  +int sqlite3InvokeBusyHandler(BusyHandler *p, sqlite3_file *pFile){
  1527   1548     int rc;
  1528   1549     if( p->xBusyHandler==0 || p->nBusy<0 ) return 0;
  1529         -  rc = p->xBusyHandler(p->pBusyArg, p->nBusy);
         1550  +  if( p->bExtraFileArg ){
         1551  +    /* Add an extra parameter with the pFile pointer to the end of the
         1552  +    ** callback argument list */
         1553  +    int (*xTra)(void*,int,sqlite3_file*);
         1554  +    xTra = (int(*)(void*,int,sqlite3_file*))p->xBusyHandler;
         1555  +    rc = xTra(p->pBusyArg, p->nBusy, pFile);
         1556  +  }else{
         1557  +    /* Legacy style busy handler callback */
         1558  +    rc = p->xBusyHandler(p->pBusyArg, p->nBusy);
         1559  +  }
  1530   1560     if( rc==0 ){
  1531   1561       p->nBusy = -1;
  1532   1562     }else{
  1533   1563       p->nBusy++;
  1534   1564     }
  1535   1565     return rc; 
  1536   1566   }
................................................................................
  1547   1577   #ifdef SQLITE_ENABLE_API_ARMOR
  1548   1578     if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
  1549   1579   #endif
  1550   1580     sqlite3_mutex_enter(db->mutex);
  1551   1581     db->busyHandler.xBusyHandler = xBusy;
  1552   1582     db->busyHandler.pBusyArg = pArg;
  1553   1583     db->busyHandler.nBusy = 0;
         1584  +  db->busyHandler.bExtraFileArg = 0;
  1554   1585     db->busyTimeout = 0;
  1555   1586     sqlite3_mutex_leave(db->mutex);
  1556   1587     return SQLITE_OK;
  1557   1588   }
  1558   1589   
  1559   1590   #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  1560   1591   /*
................................................................................
  1594   1625   ** specified number of milliseconds before returning 0.
  1595   1626   */
  1596   1627   int sqlite3_busy_timeout(sqlite3 *db, int ms){
  1597   1628   #ifdef SQLITE_ENABLE_API_ARMOR
  1598   1629     if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
  1599   1630   #endif
  1600   1631     if( ms>0 ){
  1601         -    sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
         1632  +    sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback,
         1633  +                             (void*)db);
  1602   1634       db->busyTimeout = ms;
         1635  +    db->busyHandler.bExtraFileArg = 1;
  1603   1636     }else{
  1604   1637       sqlite3_busy_handler(db, 0, 0);
  1605   1638     }
  1606   1639     return SQLITE_OK;
  1607   1640   }
  1608   1641   
  1609   1642   /*

Changes to src/os.c.

   122    122   ** when simply tossing information over the wall to the VFS and we do not
   123    123   ** really care if the VFS receives and understands the information since it
   124    124   ** is only a hint and can be safely ignored.  The sqlite3OsFileControlHint()
   125    125   ** routine has no return value since the return value would be meaningless.
   126    126   */
   127    127   int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
   128    128   #ifdef SQLITE_TEST
   129         -  if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){
          129  +  if( op!=SQLITE_FCNTL_COMMIT_PHASETWO
          130  +   && op!=SQLITE_FCNTL_LOCK_TIMEOUT
          131  +  ){
   130    132       /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
   131    133       ** is using a regular VFS, it is called after the corresponding
   132    134       ** transaction has been committed. Injecting a fault at this point
   133    135       ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM
   134    136       ** but the transaction is committed anyway.
   135    137       **
   136    138       ** The core must call OsFileControl() though, not OsFileControlHint(),

Changes to src/os_unix.c.

   225    225     int deviceCharacteristics;          /* Precomputed device characteristics */
   226    226   #if SQLITE_ENABLE_LOCKING_STYLE
   227    227     int openFlags;                      /* The flags specified at open() */
   228    228   #endif
   229    229   #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
   230    230     unsigned fsFlags;                   /* cached details from statfs() */
   231    231   #endif
          232  +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
          233  +  unsigned iBusyTimeout;              /* Wait this many millisec on locks */
          234  +#endif
   232    235   #if OS_VXWORKS
   233    236     struct vxworksFileId *pId;          /* Unique file ID */
   234    237   #endif
   235    238   #ifdef SQLITE_DEBUG
   236    239     /* The next group of variables are used to track whether or not the
   237    240     ** transaction counter in bytes 24-27 of database files are updated
   238    241     ** whenever any part of the database changes.  An assertion fault will
................................................................................
  1460   1463     
  1461   1464     unixLeaveMutex();
  1462   1465     OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved));
  1463   1466   
  1464   1467     *pResOut = reserved;
  1465   1468     return rc;
  1466   1469   }
         1470  +
         1471  +/*
         1472  +** Set a posix-advisory-lock.
         1473  +**
         1474  +** There are two versions of this routine.  If compiled with
         1475  +** SQLITE_ENABLE_SETLK_TIMEOUT then the routine has an extra parameter
         1476  +** which is a pointer to a unixFile.  If the unixFile->iBusyTimeout
         1477  +** value is set, then it is the number of milliseconds to wait before
         1478  +** failing the lock.  The iBusyTimeout value is always reset back to
         1479  +** zero on each call.
         1480  +**
         1481  +** If SQLITE_ENABLE_SETLK_TIMEOUT is not defined, then do a non-blocking
         1482  +** attempt to set the lock.
         1483  +*/
         1484  +#ifndef SQLITE_ENABLE_SETLK_TIMEOUT
         1485  +# define osSetPosixAdvisoryLock(h,x,t) osFcntl(h,F_SETLK,x)
         1486  +#else
         1487  +static int osSetPosixAdvisoryLock(
         1488  +  int h,                /* The file descriptor on which to take the lock */
         1489  +  struct flock *pLock,  /* The description of the lock */
         1490  +  unixFile *pFile       /* Structure holding timeout value */
         1491  +){
         1492  +  int rc = osFcntl(h,F_SETLK,pLock);
         1493  +  while( rc<0 && pFile->iBusyTimeout>0 ){
         1494  +    /* On systems that support some kind of blocking file lock with a timeout,
         1495  +    ** make appropriate changes here to invoke that blocking file lock.  On
         1496  +    ** generic posix, however, there is no such API.  So we simply try the
         1497  +    ** lock once every millisecond until either the timeout expires, or until
         1498  +    ** the lock is obtained. */
         1499  +    usleep(1000);
         1500  +    rc = osFcntl(h,F_SETLK,pLock);
         1501  +    pFile->iBusyTimeout--;
         1502  +  }
         1503  +  return rc;
         1504  +}
         1505  +#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
         1506  +
  1467   1507   
  1468   1508   /*
  1469   1509   ** Attempt to set a system-lock on the file pFile.  The lock is 
  1470   1510   ** described by pLock.
  1471   1511   **
  1472   1512   ** If the pFile was opened read/write from unix-excl, then the only lock
  1473   1513   ** ever obtained is an exclusive lock, and it is obtained exactly once
................................................................................
  1493   1533       if( pInode->bProcessLock==0 ){
  1494   1534         struct flock lock;
  1495   1535         assert( pInode->nLock==0 );
  1496   1536         lock.l_whence = SEEK_SET;
  1497   1537         lock.l_start = SHARED_FIRST;
  1498   1538         lock.l_len = SHARED_SIZE;
  1499   1539         lock.l_type = F_WRLCK;
  1500         -      rc = osFcntl(pFile->h, F_SETLK, &lock);
         1540  +      rc = osSetPosixAdvisoryLock(pFile->h, &lock, pFile);
  1501   1541         if( rc<0 ) return rc;
  1502   1542         pInode->bProcessLock = 1;
  1503   1543         pInode->nLock++;
  1504   1544       }else{
  1505   1545         rc = 0;
  1506   1546       }
  1507   1547     }else{
  1508         -    rc = osFcntl(pFile->h, F_SETLK, pLock);
         1548  +    rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile);
  1509   1549     }
  1510   1550     return rc;
  1511   1551   }
  1512   1552   
  1513   1553   /*
  1514   1554   ** Lock the file with the lock specified by parameter eFileLock - one
  1515   1555   ** of the following:
................................................................................
  3861   3901         }
  3862   3902         return SQLITE_OK;
  3863   3903       }
  3864   3904       case SQLITE_FCNTL_HAS_MOVED: {
  3865   3905         *(int*)pArg = fileHasMoved(pFile);
  3866   3906         return SQLITE_OK;
  3867   3907       }
         3908  +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
         3909  +    case SQLITE_FCNTL_LOCK_TIMEOUT: {
         3910  +      pFile->iBusyTimeout = *(int*)pArg;
         3911  +      return SQLITE_OK;
         3912  +    }
         3913  +#endif
  3868   3914   #if SQLITE_MAX_MMAP_SIZE>0
  3869   3915       case SQLITE_FCNTL_MMAP_SIZE: {
  3870   3916         i64 newLimit = *(i64*)pArg;
  3871   3917         int rc = SQLITE_OK;
  3872   3918         if( newLimit>sqlite3GlobalConfig.mxMmap ){
  3873   3919           newLimit = sqlite3GlobalConfig.mxMmap;
  3874   3920         }
................................................................................
  4180   4226   
  4181   4227     if( pShmNode->h>=0 ){
  4182   4228       /* Initialize the locking parameters */
  4183   4229       f.l_type = lockType;
  4184   4230       f.l_whence = SEEK_SET;
  4185   4231       f.l_start = ofst;
  4186   4232       f.l_len = n;
  4187         -    rc = osFcntl(pShmNode->h, F_SETLK, &f);
         4233  +    rc = osSetPosixAdvisoryLock(pShmNode->h, &f, pFile);
  4188   4234       rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
  4189   4235     }
  4190   4236   
  4191   4237     /* Update the global lock state and do debug tracing */
  4192   4238   #ifdef SQLITE_DEBUG
  4193   4239     { u16 mask;
  4194   4240     OSTRACE(("SHM-LOCK "));

Changes to src/pager.c.

  5689   5689   }
  5690   5690   void sqlite3PagerUnrefPageOne(DbPage *pPg){
  5691   5691     Pager *pPager;
  5692   5692     assert( pPg!=0 );
  5693   5693     assert( pPg->pgno==1 );
  5694   5694     assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
  5695   5695     pPager = pPg->pPager;
         5696  +  sqlite3PagerResetLockTimeout(pPager);
  5696   5697     sqlite3PcacheRelease(pPg);
  5697   5698     pagerUnlockIfUnused(pPager);
  5698   5699   }
  5699   5700   
  5700   5701   /*
  5701   5702   ** This function is called at the start of every write transaction.
  5702   5703   ** There must already be a RESERVED or EXCLUSIVE lock on the database 
................................................................................
  6966   6967   ** with the pager.  This might return NULL if the file has
  6967   6968   ** not yet been opened.
  6968   6969   */
  6969   6970   sqlite3_file *sqlite3PagerFile(Pager *pPager){
  6970   6971     return pPager->fd;
  6971   6972   }
  6972   6973   
         6974  +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
         6975  +/*
         6976  +** Reset the lock timeout for pager.
         6977  +*/
         6978  +void sqlite3PagerResetLockTimeout(Pager *pPager){
         6979  +  if( isOpen(pPager->fd) ){
         6980  +    int x = 0;
         6981  +    sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCK_TIMEOUT, &x);
         6982  +  }
         6983  +}
         6984  +#endif
         6985  +
  6973   6986   /*
  6974   6987   ** Return the file handle for the journal file (if it exists).
  6975   6988   ** This will be either the rollback journal or the WAL file.
  6976   6989   */
  6977   6990   sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){
  6978   6991   #if SQLITE_OMIT_WAL
  6979   6992     return pPager->jfd;
................................................................................
  7426   7439     if( pPager->pWal ){
  7427   7440       rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
  7428   7441           (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
  7429   7442           pPager->pBusyHandlerArg,
  7430   7443           pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
  7431   7444           pnLog, pnCkpt
  7432   7445       );
         7446  +    sqlite3PagerResetLockTimeout(pPager);
  7433   7447     }
  7434   7448     return rc;
  7435   7449   }
  7436   7450   
  7437   7451   int sqlite3PagerWalCallback(Pager *pPager){
  7438   7452     return sqlite3WalCallback(pPager->pWal);
  7439   7453   }

Changes to src/pager.h.

   208    208   sqlite3_file *sqlite3PagerJrnlFile(Pager*);
   209    209   const char *sqlite3PagerJournalname(Pager*);
   210    210   void *sqlite3PagerTempSpace(Pager*);
   211    211   int sqlite3PagerIsMemdb(Pager*);
   212    212   void sqlite3PagerCacheStat(Pager *, int, int, int *);
   213    213   void sqlite3PagerClearCache(Pager*);
   214    214   int sqlite3SectorSize(sqlite3_file *);
          215  +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
          216  +void sqlite3PagerResetLockTimeout(Pager *pPager);
          217  +#else
          218  +# define sqlite3PagerResetLockTimeout(X)
          219  +#endif
   215    220   
   216    221   /* Functions used to truncate the database file. */
   217    222   void sqlite3PagerTruncateImage(Pager*,Pgno);
   218    223   
   219    224   void sqlite3PagerRekey(DbPage*, Pgno, u16);
   220    225   
   221    226   #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)

Changes to src/sqlite.h.in.

  1060   1060   ** The [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE] opcode causes all write
  1061   1061   ** operations since the previous successful call to 
  1062   1062   ** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be rolled back.
  1063   1063   ** ^This file control takes the file descriptor out of batch write mode
  1064   1064   ** so that all subsequent write operations are independent.
  1065   1065   ** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without
  1066   1066   ** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
         1067  +**
         1068  +** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]
         1069  +** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain
         1070  +** a file lock using the xLock or xShmLock methods of the VFS to wait
         1071  +** for up to M milliseconds before failing, where M is the single 
         1072  +** unsigned integer parameter.
  1067   1073   ** </ul>
  1068   1074   */
  1069   1075   #define SQLITE_FCNTL_LOCKSTATE               1
  1070   1076   #define SQLITE_FCNTL_GET_LOCKPROXYFILE       2
  1071   1077   #define SQLITE_FCNTL_SET_LOCKPROXYFILE       3
  1072   1078   #define SQLITE_FCNTL_LAST_ERRNO              4
  1073   1079   #define SQLITE_FCNTL_SIZE_HINT               5
................................................................................
  1094   1100   #define SQLITE_FCNTL_VFS_POINTER            27
  1095   1101   #define SQLITE_FCNTL_JOURNAL_POINTER        28
  1096   1102   #define SQLITE_FCNTL_WIN32_GET_HANDLE       29
  1097   1103   #define SQLITE_FCNTL_PDB                    30
  1098   1104   #define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE     31
  1099   1105   #define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE    32
  1100   1106   #define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE  33
         1107  +#define SQLITE_FCNTL_LOCK_TIMEOUT           34
         1108  +#define SQLITE_FCNTL_LAST                   34 /* Last value */
  1101   1109   
  1102   1110   /* deprecated names */
  1103   1111   #define SQLITE_GET_LOCKPROXYFILE      SQLITE_FCNTL_GET_LOCKPROXYFILE
  1104   1112   #define SQLITE_SET_LOCKPROXYFILE      SQLITE_FCNTL_SET_LOCKPROXYFILE
  1105   1113   #define SQLITE_LAST_ERRNO             SQLITE_FCNTL_LAST_ERRNO
  1106   1114   
  1107   1115   

Changes to src/sqliteInt.h.

   960    960   ** callback is currently invoked only from within pager.c.
   961    961   */
   962    962   typedef struct BusyHandler BusyHandler;
   963    963   struct BusyHandler {
   964    964     int (*xBusyHandler)(void *,int);  /* The busy callback */
   965    965     void *pBusyArg;                   /* First arg to busy callback */
   966    966     int nBusy;                        /* Incremented with each busy call */
          967  +  u8 bExtraFileArg;                 /* Include sqlite3_file as callback arg */
   967    968   };
   968    969   
   969    970   /*
   970    971   ** Name of the master database table.  The master database table
   971    972   ** is a special table that holds the names and attributes of all
   972    973   ** user tables and indices.
   973    974   */
................................................................................
  4099   4100   int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
  4100   4101   void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
  4101   4102   void sqlite3AlterFinishAddColumn(Parse *, Token *);
  4102   4103   void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
  4103   4104   CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
  4104   4105   char sqlite3AffinityType(const char*, u8*);
  4105   4106   void sqlite3Analyze(Parse*, Token*, Token*);
  4106         -int sqlite3InvokeBusyHandler(BusyHandler*);
         4107  +int sqlite3InvokeBusyHandler(BusyHandler*, sqlite3_file*);
  4107   4108   int sqlite3FindDb(sqlite3*, Token*);
  4108   4109   int sqlite3FindDbName(sqlite3 *, const char *);
  4109   4110   int sqlite3AnalysisLoad(sqlite3*,int iDB);
  4110   4111   void sqlite3DeleteIndexSamples(sqlite3*,Index*);
  4111   4112   void sqlite3DefaultRowEst(Index*);
  4112   4113   void sqlite3RegisterLikeFunctions(sqlite3*, int);
  4113   4114   int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);