SQLite Forum

What is the poll frequency of `sqlite3_busy_timeout`?
Login
The callback function is set using the sqlite3_busy_handler API as described here <https://sqlite.org/c3ref/busy_handler.html>

The callback function takes two parameters -- a void* and an int -- the int being the number of times it has been called.

```
busy = True;
times = 0;
while (busy && callbackFunction(void*, times))
{
  busy = amIstillBusy?
  times++
}
if (busy) throw SQLITE_BUSY error;
... carry on ...
```

So, the callback function is invoked as long as SQLite3 is still "busy" and uses the void* to retrieve the total timeout set for the connection and the "times" as an index into the array of delays (capped at the last element).  It then uses the "times" to compute how long it has been waiting (more or less accurate depending on the OS, the hardware, the phase of the moon, and the existence of werewolves).  If it determines that the timeout has not yet expired, it "goes to sleep" for whatever it decides is the appropriate interval, and then wakes up and returns True.  If it determines that it has been called and the timeout total time has expired, it immediately returns False.

The callback function merely implements the "wait".  The polling for whatever is causing the "busy" to clear is done by whatever thing decided that a "busyness" occurred.

The default busy handler is:

```
static int sqliteDefaultBusyCallback(
  void *ptr,               /* Database connection */
  int count                /* Number of times table has been busy */
){
#if SQLITE_OS_WIN || HAVE_USLEEP
  /* This case is for systems that have support for sleeping for fractions of
  ** a second.  Examples:  All windows systems, unix systems with usleep() */
  static const u8 delays[] =
     { 1, 2, 5, 10, 15, 20, 25, 25,  25,  50,  50, 100 };
  static const u8 totals[] =
     { 0, 1, 3,  8, 18, 33, 53, 78, 103, 128, 178, 228 };
# define NDELAY ArraySize(delays)
  sqlite3 *db = (sqlite3 *)ptr;
  int tmout = db->busyTimeout;
  int delay, prior;

  assert( count>=0 );
  if( count < NDELAY ){
    delay = delays[count];
    prior = totals[count];
  }else{
    delay = delays[NDELAY-1];
    prior = totals[NDELAY-1] + delay*(count-(NDELAY-1));
  }
  if( prior + delay > tmout ){
    delay = tmout - prior;
    if( delay<=0 ) return 0;
  }
  sqlite3OsSleep(db->pVfs, delay*1000);
  return 1;
#else
  /* This case for unix systems that lack usleep() support.  Sleeping
  ** must be done in increments of whole seconds */
  sqlite3 *db = (sqlite3 *)ptr;
  int tmout = ((sqlite3 *)ptr)->busyTimeout;
  if( (count+1)*1000 > tmout ){
    return 0;
  }
  sqlite3OsSleep(db->pVfs, 1000000);
  return 1;
#endif
}
```

and it is set on a connection using the equivalent of the following code:

```
 sqlite3* db = sqlite3_open ....
 sqlite3_busy_timeout(db, <value>);
 sqlite3_busy_handler(db, sqliteDefaultBusyCallback, db);
```