SQLite

Check-in [4f1fb5c94b]
Login

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

Overview
Comment:OFD locks are now mostly working, but need additional tests.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | ofd-locks
Files: files | file ages | folders
SHA3-256: 4f1fb5c94b55c871f9ab70e19ee968f67082f70851c624028967ff11ac856e4a
User & Date: drh 2018-06-19 19:01:01.578
Context
2018-06-19
19:16
The file_control_ofd_locks TCL command in testfixture distinguishes between OFD locks unavailable on the platform and OFD locks not used. (Leaf check-in: 87a9e9d776 user: drh tags: ofd-locks)
19:01
OFD locks are now mostly working, but need additional tests. (check-in: 4f1fb5c94b user: drh tags: ofd-locks)
17:19
Miscellaneous cleanup of OFD logic. Add an #if 0 to disable the use of OFD logic, temporarily, until I can get it to actually work. (check-in: d849ade396 user: drh tags: ofd-locks)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/global.c.
236
237
238
239
240
241
242

243
244
245
246
247
248
249
   0,                         /* xVdbeBranch */
   0,                         /* pVbeBranchArg */
#endif
#ifndef SQLITE_UNTESTABLE
   0,                         /* xTestCallback */
#endif
   0,                         /* bLocaltimeFault */

   0x7ffffffe,                /* iOnceResetThreshold */
   SQLITE_DEFAULT_SORTERREF_SIZE   /* szSorterRef */
};

/*
** Hash table for global functions - functions common to all
** database connections.  After initialization, this table is







>







236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
   0,                         /* xVdbeBranch */
   0,                         /* pVbeBranchArg */
#endif
#ifndef SQLITE_UNTESTABLE
   0,                         /* xTestCallback */
#endif
   0,                         /* bLocaltimeFault */
   1,                         /* bOfdLocks */
   0x7ffffffe,                /* iOnceResetThreshold */
   SQLITE_DEFAULT_SORTERREF_SIZE   /* szSorterRef */
};

/*
** Hash table for global functions - functions common to all
** database connections.  After initialization, this table is
Changes to src/main.c.
648
649
650
651
652
653
654





655
656
657
658
659
660
661
      if( iVal<0 ){
        iVal = SQLITE_DEFAULT_SORTERREF_SIZE;
      }
      sqlite3GlobalConfig.szSorterRef = (u32)iVal;
      break;
    }
#endif /* SQLITE_ENABLE_SORTER_REFERENCES */






    default: {
      rc = SQLITE_ERROR;
      break;
    }
  }
  va_end(ap);







>
>
>
>
>







648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
      if( iVal<0 ){
        iVal = SQLITE_DEFAULT_SORTERREF_SIZE;
      }
      sqlite3GlobalConfig.szSorterRef = (u32)iVal;
      break;
    }
#endif /* SQLITE_ENABLE_SORTER_REFERENCES */

    case SQLITE_CONFIG_OFD_LOCKS: {
      sqlite3GlobalConfig.bOfdLocks = va_arg(ap, int);
      break;
    }

    default: {
      rc = SQLITE_ERROR;
      break;
    }
  }
  va_end(ap);
Changes to src/os_unix.c.
1124
1125
1126
1127
1128
1129
1130

1131
1132
1133
1134
1135
1136
1137
*/

/*
** An instance of the following structure serves as the key used
** to locate a particular unixInodeInfo object.
*/
struct unixFileId {

  dev_t dev;                  /* Device number */
#if OS_VXWORKS
  struct vxworksFileId *pId;  /* Unique file ID for vxworks. */
#else
  /* We are told that some versions of Android contain a bug that
  ** sizes ino_t at only 32-bits instead of 64-bits. (See
  ** https://android-review.googlesource.com/#/c/115351/3/dist/sqlite3.c)







>







1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
*/

/*
** An instance of the following structure serves as the key used
** to locate a particular unixInodeInfo object.
*/
struct unixFileId {
  void *pExtra;
  dev_t dev;                  /* Device number */
#if OS_VXWORKS
  struct vxworksFileId *pId;  /* Unique file ID for vxworks. */
#else
  /* We are told that some versions of Android contain a bug that
  ** sizes ino_t at only 32-bits instead of 64-bits. (See
  ** https://android-review.googlesource.com/#/c/115351/3/dist/sqlite3.c)
1380
1381
1382
1383
1384
1385
1386

1387
1388
1389
1390
1391
1392
1393
      return SQLITE_IOERR;
    }
  }
#endif

  memset(&fileId, 0, sizeof(fileId));
  fileId.dev = statbuf.st_dev;

#if OS_VXWORKS
  fileId.pId = pFile->pId;
#else
  fileId.ino = (u64)statbuf.st_ino;
#endif
  assert( inodeList!=0 || nUnusedFd==0 );
  pInode = inodeList;







>







1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
      return SQLITE_IOERR;
    }
  }
#endif

  memset(&fileId, 0, sizeof(fileId));
  fileId.dev = statbuf.st_dev;
  if( UsesOfd(pFile) ) fileId.pExtra = pFile;
#if OS_VXWORKS
  fileId.pId = pFile->pId;
#else
  fileId.ino = (u64)statbuf.st_ino;
#endif
  assert( inodeList!=0 || nUnusedFd==0 );
  pInode = inodeList;
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
    case SQLITE_FCNTL_LOCK_TIMEOUT: {
      pFile->iBusyTimeout = *(int*)pArg;
      return SQLITE_OK;
    }
#endif
    case SQLITE_FCNTL_OFD_LOCKS: {
      int x = *(int*)pArg;
      if( x==0 ){
        pFile->eSetLk = F_SETLK;
        pFile->eGetLk = F_GETLK;
      }
      *(int*)pArg = pFile->eSetLk==F_OFD_SETLK;
      return SQLITE_OK;
    }
#if SQLITE_MAX_MMAP_SIZE>0
    case SQLITE_FCNTL_MMAP_SIZE: {
      i64 newLimit = *(i64*)pArg;
      int rc = SQLITE_OK;
      if( newLimit>sqlite3GlobalConfig.mxMmap ){







|
<
<
<
<
<







3958
3959
3960
3961
3962
3963
3964
3965





3966
3967
3968
3969
3970
3971
3972
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
    case SQLITE_FCNTL_LOCK_TIMEOUT: {
      pFile->iBusyTimeout = *(int*)pArg;
      return SQLITE_OK;
    }
#endif
    case SQLITE_FCNTL_OFD_LOCKS: {
      *(int*)pArg = UsesOfd(pFile);





      return SQLITE_OK;
    }
#if SQLITE_MAX_MMAP_SIZE>0
    case SQLITE_FCNTL_MMAP_SIZE: {
      i64 newLimit = *(i64*)pArg;
      int rc = SQLITE_OK;
      if( newLimit>sqlite3GlobalConfig.mxMmap ){
4409
4410
4411
4412
4413
4414
4415

4416
4417
4418
4419
4420
4421
4422
  ** process might open and use the *-shm file without truncating it.
  ** And if the *-shm file has been corrupted by a power failure or
  ** system crash, the database itself may also become corrupt.  */
  lock.l_whence = SEEK_SET;
  lock.l_start = UNIX_SHM_DMS;
  lock.l_len = 1;
  lock.l_type = F_WRLCK;

  if( osFcntl(pShmNode->h, pDbFd->eGetLk, &lock)!=0 ) {
    rc = SQLITE_IOERR_LOCK;
  }else if( lock.l_type==F_UNLCK ){
    if( pShmNode->isReadonly ){
      pShmNode->isUnlocked = 1;
      rc = SQLITE_READONLY_CANTINIT;
    }else{







>







4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
  ** process might open and use the *-shm file without truncating it.
  ** And if the *-shm file has been corrupted by a power failure or
  ** system crash, the database itself may also become corrupt.  */
  lock.l_whence = SEEK_SET;
  lock.l_start = UNIX_SHM_DMS;
  lock.l_len = 1;
  lock.l_type = F_WRLCK;
  lock.l_pid = 0;
  if( osFcntl(pShmNode->h, pDbFd->eGetLk, &lock)!=0 ) {
    rc = SQLITE_IOERR_LOCK;
  }else if( lock.l_type==F_UNLCK ){
    if( pShmNode->isReadonly ){
      pShmNode->isUnlocked = 1;
      rc = SQLITE_READONLY_CANTINIT;
    }else{
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
















5502
5503
5504
5505
5506
5507
5508
  assert( pNew->pInode==NULL );

  /* No locking occurs in temporary files */
  assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 );

  OSTRACE(("OPEN    %-3d %s\n", h, zFilename));
  pNew->h = h;
  pNew->eSetLk = F_SETLK;
  pNew->eGetLk = F_GETLK;
#if HAVE_OFD_LOCKS && 0
  {
    struct flock lock;
    lock.l_whence = SEEK_SET;
    lock.l_start = RESERVED_BYTE;
    lock.l_len = 1;
    lock.l_type = F_WRLCK;
    lock.l_pid = 0;
    if( osFcntl(h, F_OFD_GETLK, &lock)==0 ){
      pNew->eSetLk = F_OFD_SETLK;
      pNew->eGetLk = F_OFD_GETLK;
    }
  }
#endif
  pNew->pVfs = pVfs;
  pNew->zPath = zFilename;
  pNew->ctrlFlags = (u8)ctrlFlags;
#if SQLITE_MAX_MMAP_SIZE>0
  pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap;
#endif
  if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
                           "psow", SQLITE_POWERSAFE_OVERWRITE) ){
    pNew->ctrlFlags |= UNIXFILE_PSOW;
  }
  if( strcmp(pVfs->zName,"unix-excl")==0 ){
    pNew->ctrlFlags |= UNIXFILE_EXCL;
  }

















#if OS_VXWORKS
  pNew->pId = vxworksFindFileId(zFilename);
  if( pNew->pId==0 ){
    ctrlFlags |= UNIXFILE_NOLOCK;
    rc = SQLITE_NOMEM_BKPT;
  }







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







5464
5465
5466
5467
5468
5469
5470
















5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
  assert( pNew->pInode==NULL );

  /* No locking occurs in temporary files */
  assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 );

  OSTRACE(("OPEN    %-3d %s\n", h, zFilename));
  pNew->h = h;
















  pNew->pVfs = pVfs;
  pNew->zPath = zFilename;
  pNew->ctrlFlags = (u8)ctrlFlags;
#if SQLITE_MAX_MMAP_SIZE>0
  pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap;
#endif
  if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
                           "psow", SQLITE_POWERSAFE_OVERWRITE) ){
    pNew->ctrlFlags |= UNIXFILE_PSOW;
  }
  if( strcmp(pVfs->zName,"unix-excl")==0 ){
    pNew->ctrlFlags |= UNIXFILE_EXCL;
  }
  pNew->eSetLk = F_SETLK;
  pNew->eGetLk = F_GETLK;
#if HAVE_OFD_LOCKS
  if( sqlite3GlobalConfig.bOfdLocks && (pNew->ctrlFlags & UNIXFILE_EXCL)==0 ){
    struct flock lock;
    lock.l_whence = SEEK_SET;
    lock.l_start = RESERVED_BYTE;
    lock.l_len = 1;
    lock.l_type = F_WRLCK;
    lock.l_pid = 0;
    if( osFcntl(h, F_OFD_GETLK, &lock)==0 ){
      pNew->eSetLk = F_OFD_SETLK;
      pNew->eGetLk = F_OFD_GETLK;
    }
  }
#endif

#if OS_VXWORKS
  pNew->pId = vxworksFindFileId(zFilename);
  if( pNew->pId==0 ){
    ctrlFlags |= UNIXFILE_NOLOCK;
    rc = SQLITE_NOMEM_BKPT;
  }
Changes to src/sqlite.h.in.
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain
** a file lock using the xLock or xShmLock methods of the VFS to wait
** for up to M milliseconds before failing, where M is the single 
** unsigned integer parameter.
**
** <li>[[SQLITE_FCNTL_OFD_LOCKS]]
** The [SQLITE_FCNTL_OFD_LOCKS] opcode will query whether or not OFD
** locking is currently being used for an open file, or disable the use
** of OFD locking on the file.  The argument is a pointer to an integer
** in the callers context.  If that integer is initially -1, then it is
** set to 1 or 0 if the system is or is not using OFD locks for the file.
** If the integer is initially 0, then OFD locks are disabled for the file.
** This file-control is intended for testing and validation use only.
** Applications that strive for correctness and error-free operation should
** not mess with this file-control.
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE               1
#define SQLITE_FCNTL_GET_LOCKPROXYFILE       2
#define SQLITE_FCNTL_SET_LOCKPROXYFILE       3
#define SQLITE_FCNTL_LAST_ERRNO              4
#define SQLITE_FCNTL_SIZE_HINT               5







|
|
<
<
|
<
<
<







1072
1073
1074
1075
1076
1077
1078
1079
1080


1081



1082
1083
1084
1085
1086
1087
1088
** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain
** a file lock using the xLock or xShmLock methods of the VFS to wait
** for up to M milliseconds before failing, where M is the single 
** unsigned integer parameter.
**
** <li>[[SQLITE_FCNTL_OFD_LOCKS]]
** The [SQLITE_FCNTL_OFD_LOCKS] opcode will query whether or not OFD
** locking is currently being used for an open file.  The argument is
** a pointer to an integer into which is written a value of 1 if OFD


** locks are being used for the file and 0 if OFD locks are not used.



** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE               1
#define SQLITE_FCNTL_GET_LOCKPROXYFILE       2
#define SQLITE_FCNTL_SET_LOCKPROXYFILE       3
#define SQLITE_FCNTL_LAST_ERRNO              4
#define SQLITE_FCNTL_SIZE_HINT               5
1957
1958
1959
1960
1961
1962
1963







1964
1965
1966
1967
1968
1969
1970
** than the configured sorter-reference size threshold - then a reference
** is stored in each sorted record and the required column values loaded
** from the database as records are returned in sorted order. The default
** value for this option is to never use this optimization. Specifying a 
** negative value for this option restores the default behaviour.
** This option is only available if SQLite is compiled with the
** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option.







** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
#define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
#define SQLITE_CONFIG_SERIALIZED    3  /* nil */
#define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */







>
>
>
>
>
>
>







1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
** than the configured sorter-reference size threshold - then a reference
** is stored in each sorted record and the required column values loaded
** from the database as records are returned in sorted order. The default
** value for this option is to never use this optimization. Specifying a 
** negative value for this option restores the default behaviour.
** This option is only available if SQLite is compiled with the
** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option.
**
** [[SQLITE_CONFIG_OFD_LOCKS]]
** <dt>SQLITE_CONFIG_OFD_LOCKS
** <dd>The SQLITE_CONFIG_OFD_LOCKS option accepts a single parameter
** of type (int).  If the value is true then OFD Locks are used on systems
** that support that feature.  If the vlaue is false, then OFD locks are
** never used.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
#define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
#define SQLITE_CONFIG_SERIALIZED    3  /* nil */
#define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
1987
1988
1989
1990
1991
1992
1993

1994
1995
1996
1997
1998
1999
2000
#define SQLITE_CONFIG_MMAP_SIZE    22  /* sqlite3_int64, sqlite3_int64 */
#define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */
#define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */
#define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
#define SQLITE_CONFIG_STMTJRNL_SPILL      26  /* int nByte */
#define SQLITE_CONFIG_SMALL_MALLOC        27  /* boolean */
#define SQLITE_CONFIG_SORTERREF_SIZE      28  /* int nByte */


/*
** CAPI3REF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
** can be passed as the second argument to the [sqlite3_db_config()] interface.
**







>







1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
#define SQLITE_CONFIG_MMAP_SIZE    22  /* sqlite3_int64, sqlite3_int64 */
#define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */
#define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */
#define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
#define SQLITE_CONFIG_STMTJRNL_SPILL      26  /* int nByte */
#define SQLITE_CONFIG_SMALL_MALLOC        27  /* boolean */
#define SQLITE_CONFIG_SORTERREF_SIZE      28  /* int nByte */
#define SQLITE_CONFIG_OFD_LOCKS           29  /* int */

/*
** CAPI3REF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
** can be passed as the second argument to the [sqlite3_db_config()] interface.
**
Changes to src/sqliteInt.h.
3366
3367
3368
3369
3370
3371
3372

3373
3374
3375
3376
3377
3378
3379
  void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx);  /* Callback */
  void *pVdbeBranchArg;                                     /* 1st argument */
#endif
#ifndef SQLITE_UNTESTABLE
  int (*xTestCallback)(int);        /* Invoked by sqlite3FaultSim() */
#endif
  int bLocaltimeFault;              /* True to fail localtime() calls */

  int iOnceResetThreshold;          /* When to reset OP_Once counters */
  u32 szSorterRef;                  /* Min size in bytes to use sorter-refs */
};

/*
** This macro is used inside of assert() statements to indicate that
** the assert is only valid on a well-formed database.  Instead of:







>







3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
  void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx);  /* Callback */
  void *pVdbeBranchArg;                                     /* 1st argument */
#endif
#ifndef SQLITE_UNTESTABLE
  int (*xTestCallback)(int);        /* Invoked by sqlite3FaultSim() */
#endif
  int bLocaltimeFault;              /* True to fail localtime() calls */
  int bOfdLocks;                    /* Use OFD locks on supported systems */
  int iOnceResetThreshold;          /* When to reset OP_Once counters */
  u32 szSorterRef;                  /* Min size in bytes to use sorter-refs */
};

/*
** This macro is used inside of assert() statements to indicate that
** the assert is only valid on a well-formed database.  Instead of:
Changes to src/test1.c.
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
  rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_PERSIST_WAL, (void*)&bPersist);
  sqlite3_snprintf(sizeof(z), z, "%d %d", rc, bPersist);
  Tcl_AppendResult(interp, z, (char*)0);
  return TCL_OK;  
}

/*
** tclcmd:   file_control_ofd_locks DB ?DISABLE?
**
** Run sqlite3_file_control() to query the OFD lock capability.  Return
** true if OFD locks are available and false if not.
**
** If the DISABLE argument is true, then disable OFD locking, if it is
** enabled.  The returned value will show that OFD locks are disabled.
*/
static int SQLITE_TCLAPI file_control_ofd_locks(
  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  sqlite3 *db;
  int rc;
  int b = 0;

  if( objc!=2 && objc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"",
        Tcl_GetStringFromObj(objv[0], 0), " DB ?DISABLE?", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
    return TCL_ERROR;
  }
  if( objc==3 && Tcl_GetIntFromObj(interp, objv[2], &b) ) return TCL_ERROR;
  b = b ? 0 : -1;
  rc = sqlite3_file_control(db,NULL,SQLITE_FCNTL_OFD_LOCKS,(void*)&b);
  Tcl_AppendResult(interp, (rc==SQLITE_OK && b) ? "1" : "0", (char*)0);
  return TCL_OK;  
}

/*
** tclcmd:   file_control_powersafe_overwrite DB PSOW-FLAG







|



<
<
<











|

|





<
|







5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970



5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989

5990
5991
5992
5993
5994
5995
5996
5997
  rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_PERSIST_WAL, (void*)&bPersist);
  sqlite3_snprintf(sizeof(z), z, "%d %d", rc, bPersist);
  Tcl_AppendResult(interp, z, (char*)0);
  return TCL_OK;  
}

/*
** tclcmd:   file_control_ofd_locks DB
**
** Run sqlite3_file_control() to query the OFD lock capability.  Return
** true if OFD locks are available and false if not.



*/
static int SQLITE_TCLAPI file_control_ofd_locks(
  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  sqlite3 *db;
  int rc;
  int b = 0;

  if( objc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"",
        Tcl_GetStringFromObj(objv[0], 0), " DB", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
    return TCL_ERROR;
  }

  b = 0;
  rc = sqlite3_file_control(db,NULL,SQLITE_FCNTL_OFD_LOCKS,(void*)&b);
  Tcl_AppendResult(interp, (rc==SQLITE_OK && b) ? "1" : "0", (char*)0);
  return TCL_OK;  
}

/*
** tclcmd:   file_control_powersafe_overwrite DB PSOW-FLAG
Changes to src/test_malloc.c.
1270
1271
1272
1273
1274
1275
1276

























1277
1278
1279
1280
1281
1282
1283

  rc = sqlite3_config(SQLITE_CONFIG_PMASZ, iPmaSz);
  Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);

  return TCL_OK;
}



























/*
** Usage:    sqlite3_dump_memsys3  FILENAME
**           sqlite3_dump_memsys5  FILENAME
**
** Write a summary of unfreed memsys3 allocations to FILENAME.
*/







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308

  rc = sqlite3_config(SQLITE_CONFIG_PMASZ, iPmaSz);
  Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);

  return TCL_OK;
}

/*
** Usage:    sqlite3_config_ofd_locks  INTEGER
**
** Enable or disable the use of OFD locks.
*/
static int SQLITE_TCLAPI test_config_ofd_locks(
  void * clientData, 
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int eOk;

  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "BOOL");
    return TCL_ERROR;
  }
  if( Tcl_GetIntFromObj(interp, objv[1], &eOk) ){
    return TCL_ERROR;
  }

  sqlite3_config(SQLITE_CONFIG_OFD_LOCKS, eOk);

  return TCL_OK;
}

/*
** Usage:    sqlite3_dump_memsys3  FILENAME
**           sqlite3_dump_memsys5  FILENAME
**
** Write a summary of unfreed memsys3 allocations to FILENAME.
*/
1526
1527
1528
1529
1530
1531
1532

1533
1534
1535
1536
1537
1538
1539
     { "sqlite3_config_heap_size",   test_config_heap_size         ,0 },
     { "sqlite3_config_memstatus",   test_config_memstatus         ,0 },
     { "sqlite3_config_lookaside",   test_config_lookaside         ,0 },
     { "sqlite3_config_error",       test_config_error             ,0 },
     { "sqlite3_config_uri",         test_config_uri               ,0 },
     { "sqlite3_config_cis",         test_config_cis               ,0 },
     { "sqlite3_config_pmasz",       test_config_pmasz             ,0 },

     { "sqlite3_db_config_lookaside",test_db_config_lookaside      ,0 },
     { "sqlite3_dump_memsys3",       test_dump_memsys3             ,3 },
     { "sqlite3_dump_memsys5",       test_dump_memsys3             ,5 },
     { "sqlite3_install_memsys3",    test_install_memsys3          ,0 },
     { "sqlite3_memdebug_vfs_oom_test", test_vfs_oom_test          ,0 },
  };
  int i;







>







1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
     { "sqlite3_config_heap_size",   test_config_heap_size         ,0 },
     { "sqlite3_config_memstatus",   test_config_memstatus         ,0 },
     { "sqlite3_config_lookaside",   test_config_lookaside         ,0 },
     { "sqlite3_config_error",       test_config_error             ,0 },
     { "sqlite3_config_uri",         test_config_uri               ,0 },
     { "sqlite3_config_cis",         test_config_cis               ,0 },
     { "sqlite3_config_pmasz",       test_config_pmasz             ,0 },
     { "sqlite3_config_ofd_locks",   test_config_ofd_locks         ,0 },
     { "sqlite3_db_config_lookaside",test_db_config_lookaside      ,0 },
     { "sqlite3_dump_memsys3",       test_dump_memsys3             ,3 },
     { "sqlite3_dump_memsys5",       test_dump_memsys3             ,5 },
     { "sqlite3_install_memsys3",    test_install_memsys3          ,0 },
     { "sqlite3_memdebug_vfs_oom_test", test_vfs_oom_test          ,0 },
  };
  int i;
Changes to test/unixexcl.test.
20
21
22
23
24
25
26



27
28
29
30
31
32
33

if {$::tcl_platform(platform)!="unix" || [info commands test_syscall]==""} {
  finish_test
  return
} 
set testprefix unixexcl






# Test that when using VFS "unix-excl", the first time the database is read
# a process-wide exclusive lock is taken on it. This means other connections
# within the process may still access the db normally, but connections from
# outside the process cannot.
#







>
>
>







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

if {$::tcl_platform(platform)!="unix" || [info commands test_syscall]==""} {
  finish_test
  return
} 
set testprefix unixexcl

catch {db close}
sqlite3_shutdown
sqlite3_config_ofd_locks 0


# Test that when using VFS "unix-excl", the first time the database is read
# a process-wide exclusive lock is taken on it. This means other connections
# within the process may still access the db normally, but connections from
# outside the process cannot.
#
122
123
124
125
126
127
128




129
    } {1 2 3 4}
    do_test unixexcl-3.$tn.7 {
      sql1 { PRAGMA wal_checkpoint; }
    } {0 7 7}
  }
}





finish_test







>
>
>
>

125
126
127
128
129
130
131
132
133
134
135
136
    } {1 2 3 4}
    do_test unixexcl-3.$tn.7 {
      sql1 { PRAGMA wal_checkpoint; }
    } {0 7 7}
  }
}

catch {db close}
sqlite3_shutdown
sqlite3_config_ofd_locks 1

finish_test