Compare commits

...

4 Commits

Author SHA1 Message Date
drh bcd3814bf3 The file_control_ofd_locks TCL command in testfixture distinguishes between
OFD locks unavailable on the platform and OFD locks not used.

FossilOrigin-Name: 87a9e9d776b6877a687711c1eb0e6ac318eca95dd3a9daae9ba08c2dc486424d
2018-06-19 19:16:13 +00:00
drh e688c3390c OFD locks are now mostly working, but need additional tests.
FossilOrigin-Name: 4f1fb5c94b55c871f9ab70e19ee968f67082f70851c624028967ff11ac856e4a
2018-06-19 19:01:01 +00:00
drh e8e6b157d7 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.

FossilOrigin-Name: d849ade396d2dda4ed18f8e44d19ab218f94ef41a76a99f937238253e716dc05
2018-06-19 17:19:46 +00:00
drh 9663411f8f Initial attempt to get SQLite working with OFD locks on Linux. The code here
does not function correctly. This is an incremental check-in for a work in
progress.

FossilOrigin-Name: 148f8dec9a26f11d343bfeb558fd12ba18d7f5d4d69da58fc8aa22f88e13c408
2018-06-19 13:45:48 +00:00
10 changed files with 226 additions and 56 deletions
+13 -13
View File
@@ -1,5 +1,5 @@
C Minor\schange\sto\sthe\sinput\sgrammar\sto\smake\sthe\sparser\stables\sslightly\ssmaller.
D 2018-06-19T11:15:19.013
C The\sfile_control_ofd_locks\sTCL\scommand\sin\stestfixture\sdistinguishes\sbetween\nOFD\slocks\sunavailable\son\sthe\splatform\sand\sOFD\slocks\snot\sused.
D 2018-06-19T19:16:13.660
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da
@@ -451,7 +451,7 @@ F src/expr.c 3ab855fb882d8758220edaf261d8d56ad2cb3736f92c818f4ae250ac4a2752a4
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c b1da9ef8dc834603bb0d28972378a7ce65897847f9a1e89ab800bbdf24c788ee
F src/func.c e2e3c02621a528a472933fd4733a5da635676f1461be73293f6e9f62f18d4eaa
F src/global.c 9bf034fd560bdd514715170ed8460bb7f823cec113f0569ef3f18a20c7ccd128
F src/global.c 58ab3df86a891570fa8f8f171174999b2fe83da854f0f879553b63961d18fddd
F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
@@ -459,7 +459,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c bcacf6a0d277f8fa0e4f9ffecda544a2330ca4478f904cd89564c2dd86d0b16b
F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
F src/loadext.c 6aae5739198d96c51ae6eb97c4a5b1744c22ed7a5a565a5399a717780d48a36b
F src/main.c a086ab7d6e4e3f07bd5789d16f977d425f9482e7b3baeeb2f17bde0e6bfb2bc1
F src/main.c 5ec5bc48f76ecbf464b2a481e3674c36f0a9ea9fb60e39adae8c7b692206028c
F src/malloc.c 07295435093ce354c6d9063ac05a2eeae28bd251d2e63c48b3d67c12c76f7e18
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
@@ -479,7 +479,7 @@ F src/os.c 8aeb0b0f40f8f5b0da03fe49706695adaf42d2f516ab95abc72e86c245e119de
F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
F src/os_unix.c c230a7a24766320d8414afd087edcd43e499fb45e86361f6f4f464f343d965a9
F src/os_unix.c 22faca3167b97188522df5082f606b94dc1141d4253bdfdaac9144087efd27fe
F src/os_win.c ac29c25cde4cfb4adacc59cdec4aa45698ca0e29164ea127859585ccd9faa354
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 1bb6a57fa0465296a4d6109a1a64610a0e7adde1f3acf3ef539a9d972908ce8f
@@ -497,15 +497,15 @@ F src/resolve.c 14602f46800ba182ea6a490e0f304127d29ac1f724bdadcc639e25d3223fcf6e
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
F src/select.c 8d3176c5258cc83942815ebe75b4c1f8dcf62b5e0f4d37373a14ebf23c046f9f
F src/shell.c.in 8578421c5fb2a972461b2a996f7173646e55e0dbd2a2eee30c8f5dc7d3dbadfd
F src/sqlite.h.in 19de593baa0667854730e7b8bc2e3039c20ee80a4d537e9b5ec2038947fe3daf
F src/sqlite.h.in 77fde2a5afd91152daa67c7a7167699635c495d3fa733556f65049fbd5098542
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7
F src/sqliteInt.h c8d304712b6b4e2150cbb5355b1a80427eee7b3ea1a6b5827afadf557360d7fe
F src/sqliteInt.h 95836c91a6ce6606d157ff508e23a0c2d6ac7ac499d9495097a9e668f9b802df
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
F src/tclsqlite.c 916a92de77ec5cbe27818ca194d8cf0c58aa7ad5b87527098f6aa5a6068800ce
F src/test1.c 51aa5f3030217ca45eb62e90944838794d4faaae7a8f60e0330ae01f30bc997b
F src/test1.c 05d8d168c11e419626d34d29e31851d8804987fc16e77f7b21a927215508611f
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6
@@ -532,7 +532,7 @@ F src/test_intarray.c 988fc61cb0ff539f4172c0d95f15287c92516f64
F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c
F src/test_journal.c 619f2aa10e0d7a5f87c0f06825bc61dfce1c6b9c7f3ad990fb13de6c3b8874a3
F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
F src/test_malloc.c dec0aa821b230773aeb3dd11d652c1193f7cedb18a20b25659bc672288115242
F src/test_malloc.c baf1888c5040ff190f318dbc25cfffc0bcbe5c9db5c7ccb911316e8337a08808
F src/test_md5.c 7268e1e8c399d4a5e181b64ac20e1e6f3bc4dd9fc87abac02db145a3d951fa8c
F src/test_multiplex.c e054459f7633f3ff8ce1245da724f9a8be189e4e
F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635
@@ -1511,7 +1511,7 @@ F test/unionvtab.test 595fb601de00188ca5e7c6dbe266c17a0faf234cf434ce85eccec1a929
F test/unionvtabfault.test 26b6854d5aef9005cd630513025690bff1b7378ae9c97b81e2a3cbe84eee0f58
F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264
F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2
F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97
F test/unixexcl.test 2efd77088afe73dd4b810f260121a5a2271f0c527f0788c70b414577daa104cd
F test/unordered.test ffeea7747d5ba962a8009a20b7e53d68cbae05b063604c68702c5998eb50c981
F test/update.test 1148de8d913e9817717990603aadeca07aab9ddbb10a30f167cbfd8d3a3ccb60
F test/update2.test 5e67667e1c54017d964e626db765cf8bedcf87483c184f4c575bdb8c1dd2313e
@@ -1731,7 +1731,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 39434262d5cf1af197ce0abb1f1ee84ee0797823e290a493c5bf8376fbe287a6
R b6cf2872dc6b136d2f9f02df3a45f74e
P 4f1fb5c94b55c871f9ab70e19ee968f67082f70851c624028967ff11ac856e4a
R d45744c23bc0ba6c95ae624be64a683c
U drh
Z ca3608404058acf123d3efb518cfb804
Z 4b06752b30319a8308f2262257913604
+1 -1
View File
@@ -1 +1 @@
320fa69e6aa2a7d67f6444d6c13de9893e27b85c36a933b06da113d753b6aafc
87a9e9d776b6877a687711c1eb0e6ac318eca95dd3a9daae9ba08c2dc486424d
+1
View File
@@ -240,6 +240,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
0, /* xTestCallback */
#endif
0, /* bLocaltimeFault */
1, /* bOfdLocks */
0x7ffffffe, /* iOnceResetThreshold */
SQLITE_DEFAULT_SORTERREF_SIZE /* szSorterRef */
};
+5
View File
@@ -653,6 +653,11 @@ int sqlite3_config(int op, ...){
}
#endif /* SQLITE_ENABLE_SORTER_REFERENCES */
case SQLITE_CONFIG_OFD_LOCKS: {
sqlite3GlobalConfig.bOfdLocks = va_arg(ap, int);
break;
}
default: {
rc = SQLITE_ERROR;
break;
+115 -41
View File
@@ -178,6 +178,21 @@
*/
#define IS_LOCK_ERROR(x) ((x != SQLITE_OK) && (x != SQLITE_BUSY))
/*
** Are OFD locks supported?
*/
#if defined(F_OFD_SETLK) && defined(F_OFD_GETLK)
# define HAVE_OFD_LOCKS 1
# define UsesOfd(F) ((F)->eGetLk==F_OFD_GETLK)
# define UsesOldStylePosixLocks(F) ((F)->eGetLk==F_GETLK)
#else
# define HAVE_OFD_LOCKS 0
# define UsesOfd(F) 0
# define UsesOldStylePosixLocks(F) 1
# define F_OFD_SETLK 0 /* Fake value so we can use the identifier */
# define F_OFD_GETLK 0 /* Fake value so we can use the identifier */
#endif
/* Forward references */
typedef struct unixShm unixShm; /* Connection shared memory */
typedef struct unixShmNode unixShmNode; /* Shared memory instance */
@@ -214,6 +229,7 @@ struct unixFile {
const char *zPath; /* Name of the file */
unixShm *pShm; /* Shared memory segment information */
int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
int eGetLk, eSetLk;
#if SQLITE_MAX_MMAP_SIZE>0
int nFetchOut; /* Number of outstanding xFetch refs */
sqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */
@@ -748,10 +764,16 @@ static int lockTrace(int fd, int op, struct flock *p){
char *zOpName, *zType;
int s;
int savedErrno;
if( op==F_GETLK ){
if( op==F_GETLK || op==F_OFD_GETLK ){
zOpName = "GETLK";
}else if( op==F_SETLK ){
}else if( op==F_SETLK || op==F_OFD_SETLK ){
zOpName = "SETLK";
#if HAVE_OFD_LOCKS
}else if( op==F_OFD_GETLK ){
zOpName = "OFD_GETLK";
}else if( op==F_OFD_SETLK ){
zOpName = "OFD_SETLK";
#endif
}else{
s = osFcntl(fd, op, p);
sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s);
@@ -772,10 +794,13 @@ static int lockTrace(int fd, int op, struct flock *p){
sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n",
threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len,
(int)p->l_pid, s);
if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){
if( s==(-1)
&& (op==F_SETLK || op==F_OFD_SETLK)
&& (p->l_type==F_RDLCK || p->l_type==F_WRLCK)
){
struct flock l2;
l2 = *p;
osFcntl(fd, F_GETLK, &l2);
osFcntl(fd, op==F_SETLK ? F_GETLK : F_OFD_GETLK, &l2);
if( l2.l_type==F_RDLCK ){
zType = "RDLCK";
}else if( l2.l_type==F_WRLCK ){
@@ -994,11 +1019,12 @@ static void vxworksReleaseFileId(struct vxworksFileId *pId){
*************************** Posix Advisory Locking ****************************
**
** POSIX advisory locks are broken by design. ANSI STD 1003.1 (1996)
** section 6.5.2.2 lines 483 through 490 specify that when a process
** section 6.5.2.2 lines 483 through 490 says that when a process
** sets or clears a lock, that operation overrides any prior locks set
** by the same process. It does not explicitly say so, but this implies
** that it overrides locks set by the same process using a different
** file descriptor. Consider this test case:
** by the *same process*. That means that if two different threads
** open the same file using different file descriptors, then POSIX
** advisory locking will not work to coordinate access between those two
** threads. Consider this test case:
**
** int fd1 = open("./file1", O_RDWR|O_CREAT, 0644);
** int fd2 = open("./file2", O_RDWR|O_CREAT, 0644);
@@ -1006,11 +1032,12 @@ static void vxworksReleaseFileId(struct vxworksFileId *pId){
** Suppose ./file1 and ./file2 are really the same file (because
** one is a hard or symbolic link to the other) then if you set
** an exclusive lock on fd1, then try to get an exclusive lock
** on fd2, it works. I would have expected the second lock to
** on fd2, it works. In a reasonable system, the second lock would
** fail since there was already a lock on the file due to fd1.
** But not so. Since both locks came from the same process, the
** second overrides the first, even though they were on different
** file descriptors opened on different file names.
** But this is not the case in POSIX advisory locking. Since both
** locks came from the same process, the second overrides the first,
** even though they were on different file descriptors opened on
** different file names.
**
** This means that we cannot use POSIX locks to synchronize file access
** among competing threads of the same process. POSIX locks will work fine
@@ -1030,21 +1057,17 @@ static void vxworksReleaseFileId(struct vxworksFileId *pId){
** For VxWorks, we have to use the alternative unique ID system based on
** canonical filename and implemented in the previous division.)
**
** The sqlite3_file structure for POSIX is no longer just an integer file
** descriptor. It is now a structure that holds the integer file
** descriptor and a pointer to a structure that describes the internal
** locks on the corresponding inode. There is one locking structure
** per inode, so if the same inode is opened twice, both unixFile structures
** point to the same locking structure. The locking structure keeps
** a reference count (so we will know when to delete it) and a "cnt"
** field that tells us its internal lock status. cnt==0 means the
** file is unlocked. cnt==-1 means the file has an exclusive lock.
** cnt>0 means there are cnt shared locks on the file.
** The sqlite3_file object for POSIX (a.k.a. the unixFile object) is more
** than just an integer file descriptor. It also holds a pointer
** a pointer to another object (unixInodeInfo) that describes the
** internal locks on the corresponding inode. There is one
** unixInodeInfo object per inode, so if the same inode is opened twice,
** both unixFile objects point to the same lunixInodeInfo. The unixInodeInfo
** keeps a reference count (nRef) so we will know when to delete it.
**
** Any attempt to lock or unlock a file first checks the locking
** structure. The fcntl() system call is only invoked to set a
** POSIX lock if the internal lock structure transitions between
** a locked and an unlocked state.
** Any attempt to lock or unlock a unixFile first checks the unixInodeInfo.
** The fcntl() system call is only invoked to set a POSIX lock if the
** unixInodeInfo transitions between a locked and an unlocked state.
**
** But wait: there are yet more problems with POSIX advisory locks.
**
@@ -1052,14 +1075,14 @@ static void vxworksReleaseFileId(struct vxworksFileId *pId){
** all locks on that file that are owned by the current process are
** released. To work around this problem, each unixInodeInfo object
** maintains a count of the number of pending locks on tha inode.
** When an attempt is made to close an unixFile, if there are
** other unixFile open on the same inode that are holding locks, the call
** When an attempt is made to close an unixFile, if there are other
** unixFile objcts open on the same inode that are holding locks, the call
** to close() the file descriptor is deferred until all of the locks clear.
** The unixInodeInfo structure keeps a list of file descriptors that need to
** be closed and that list is walked (and cleared) when the last lock
** clears.
**
** Yet another problem: LinuxThreads do not play well with posix locks.
** LinuxThreads:
**
** Many older versions of linux use the LinuxThreads library which is
** not posix compliant. Under LinuxThreads, a lock created by thread
@@ -1078,6 +1101,26 @@ static void vxworksReleaseFileId(struct vxworksFileId *pId){
** LinuxThreads provided that (1) there is no more than one connection
** per database file in the same process and (2) database connections
** do not move across threads.
**
** OFD Locks:
**
** Recent unix-like OSes have added support for Open File Description or "OFD"
** locks. (This is not a typo: the name is "Open File Description" not
** "Open File Descriptor". "-ion" not "-or". There is a subtle difference
** between "Discription" and "Descriptor" which is described on the Linux
** fcntl manpage and will not be repeated here.) The main difference
** between OFD locks and POSIX locks is that OFD locks are associated
** with a single open() system call and do not interfere with with file
** descriptors obtained from different open() system calls in the same
** process. In other words, OFD locks fix the brokenness of POSIX locks.
**
** As of 2018-06-19, SQLite will use OFD locks if they are available.
** But the older work-arounds for POSIX locks are still here in the code
** since SQLite also needs to work on systems that do not support
** OFD locks. Someday, perhaps, all unix systems will have reliable
** support for OFD locks, and at that time we can omit the unixInodeInfo
** object and all of its associated complication. But for now we still
** have to support the older POSIX lock work-around hack.
*/
/*
@@ -1085,6 +1128,7 @@ static void vxworksReleaseFileId(struct vxworksFileId *pId){
** 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. */
@@ -1341,6 +1385,7 @@ static int findInodeInfo(
memset(&fileId, 0, sizeof(fileId));
fileId.dev = statbuf.st_dev;
if( UsesOfd(pFile) ) fileId.pExtra = pFile;
#if OS_VXWORKS
fileId.pId = pFile->pId;
#else
@@ -1452,7 +1497,8 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
lock.l_start = RESERVED_BYTE;
lock.l_len = 1;
lock.l_type = F_WRLCK;
if( osFcntl(pFile->h, F_GETLK, &lock) ){
lock.l_pid = 0;
if( osFcntl(pFile->h, pFile->eGetLk, &lock) ){
rc = SQLITE_IOERR_CHECKRESERVEDLOCK;
storeLastErrno(pFile, errno);
} else if( lock.l_type!=F_UNLCK ){
@@ -1482,14 +1528,15 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
** attempt to set the lock.
*/
#ifndef SQLITE_ENABLE_SETLK_TIMEOUT
# define osSetPosixAdvisoryLock(h,x,t) osFcntl(h,F_SETLK,x)
# define osSetAdvisoryLock(h,e,x,t) osFcntl(h,e,x)
#else
static int osSetPosixAdvisoryLock(
static int osSetAdvisoryLock(
int h, /* The file descriptor on which to take the lock */
int eSetLk, /* ioctl verb for setting the lock */
struct flock *pLock, /* The description of the lock */
unixFile *pFile /* Structure holding timeout value */
){
int rc = osFcntl(h,F_SETLK,pLock);
int rc = osFcntl(h,eSetLk,pLock);
while( rc<0 && pFile->iBusyTimeout>0 ){
/* On systems that support some kind of blocking file lock with a timeout,
** make appropriate changes here to invoke that blocking file lock. On
@@ -1497,7 +1544,7 @@ static int osSetPosixAdvisoryLock(
** lock once every millisecond until either the timeout expires, or until
** the lock is obtained. */
usleep(1000);
rc = osFcntl(h,F_SETLK,pLock);
rc = osFcntl(h,eSetLk,pLock);
pFile->iBusyTimeout--;
}
return rc;
@@ -1537,7 +1584,8 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){
lock.l_start = SHARED_FIRST;
lock.l_len = SHARED_SIZE;
lock.l_type = F_WRLCK;
rc = osSetPosixAdvisoryLock(pFile->h, &lock, pFile);
lock.l_pid = 0;
rc = osSetAdvisoryLock(pFile->h, pFile->eSetLk, &lock, pFile);
if( rc<0 ) return rc;
pInode->bProcessLock = 1;
pInode->nLock++;
@@ -1545,7 +1593,8 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){
rc = 0;
}
}else{
rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile);
pLock->l_pid = 0;
rc = osSetAdvisoryLock(pFile->h, pFile->eSetLk, pLock, pFile);
}
return rc;
}
@@ -1664,8 +1713,10 @@ static int unixLock(sqlite3_file *id, int eFileLock){
** has a SHARED or RESERVED lock, then increment reference counts and
** return SQLITE_OK.
*/
if( eFileLock==SHARED_LOCK &&
(pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){
if( eFileLock==SHARED_LOCK
&& UsesOldStylePosixLocks(pFile)
&& (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK)
){
assert( eFileLock==SHARED_LOCK );
assert( pFile->eFileLock==0 );
assert( pInode->nShared>0 );
@@ -1675,7 +1726,6 @@ static int unixLock(sqlite3_file *id, int eFileLock){
goto end_lock;
}
/* A PENDING lock is needed before acquiring a SHARED lock and before
** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will
** be released.
@@ -3911,6 +3961,12 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
return SQLITE_OK;
}
#endif
#if HAVE_OFD_LOCKS
case SQLITE_FCNTL_OFD_LOCKS: {
*(int*)pArg = UsesOfd(pFile);
return SQLITE_OK;
}
#endif
#if SQLITE_MAX_MMAP_SIZE>0
case SQLITE_FCNTL_MMAP_SIZE: {
i64 newLimit = *(i64*)pArg;
@@ -4230,7 +4286,8 @@ static int unixShmSystemLock(
f.l_whence = SEEK_SET;
f.l_start = ofst;
f.l_len = n;
rc = osSetPosixAdvisoryLock(pShmNode->h, &f, pFile);
f.l_pid = 0;
rc = osSetAdvisoryLock(pShmNode->h, pFile->eSetLk, &f, pFile);
rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
}
@@ -4355,7 +4412,8 @@ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){
lock.l_start = UNIX_SHM_DMS;
lock.l_len = 1;
lock.l_type = F_WRLCK;
if( osFcntl(pShmNode->h, F_GETLK, &lock)!=0 ) {
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 ){
@@ -5425,6 +5483,22 @@ static int fillInUnixFile(
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);
+15
View File
@@ -1073,6 +1073,12 @@ struct sqlite3_io_methods {
** 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
@@ -1108,6 +1114,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32
#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
#define SQLITE_FCNTL_LOCK_TIMEOUT 34
#define SQLITE_FCNTL_OFD_LOCKS 35
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -1949,6 +1956,13 @@ struct sqlite3_mem_methods {
** 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 */
@@ -1979,6 +1993,7 @@ struct sqlite3_mem_methods {
#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
+1
View File
@@ -3370,6 +3370,7 @@ struct Sqlite3Config {
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 */
};
+42 -1
View File
@@ -5963,6 +5963,47 @@ static int SQLITE_TCLAPI file_control_persist_wal(
return TCL_OK;
}
/*
** tclcmd: file_control_ofd_locks DB
**
** Run sqlite3_file_control() to query the OFD lock capability. Return:
**
** 2 OFD locks are available and are used on DB
** 1 OFD locks are available but DB is not using them
** 0 OFD locks are not available
*/
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;
const char *z;
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);
if( rc!=SQLITE_OK ){
z = "0";
}else if( b ){
z = "2";
}else{
z = "1";
}
Tcl_AppendResult(interp, z, (char*)0);
return TCL_OK;
}
/*
** tclcmd: file_control_powersafe_overwrite DB PSOW-FLAG
**
@@ -5995,7 +6036,6 @@ static int SQLITE_TCLAPI file_control_powersafe_overwrite(
return TCL_OK;
}
/*
** tclcmd: file_control_vfsname DB ?AUXDB?
**
@@ -7705,6 +7745,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "file_control_win32_set_handle", file_control_win32_set_handle, 0 },
#endif
{ "file_control_persist_wal", file_control_persist_wal, 0 },
{ "file_control_ofd_locks", file_control_ofd_locks, 0 },
{ "file_control_powersafe_overwrite",file_control_powersafe_overwrite,0},
{ "file_control_vfsname", file_control_vfsname, 0 },
{ "file_control_tempfilename", file_control_tempfilename, 0 },
+26
View File
@@ -1274,6 +1274,31 @@ static int SQLITE_TCLAPI test_config_pmasz(
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
@@ -1530,6 +1555,7 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){
{ "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 },
+7
View File
@@ -24,6 +24,9 @@ if {$::tcl_platform(platform)!="unix" || [info commands test_syscall]==""} {
}
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
@@ -126,4 +129,8 @@ do_multiclient_test tn {
}
}
catch {db close}
sqlite3_shutdown
sqlite3_config_ofd_locks 1
finish_test