mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
A better fix for ticket #530 - one that is likely to work on unix
implementations in addition to linux. Also more tests for multi-thread locking added. (CVS 1138) FossilOrigin-Name: 7dddbeb586504de30c64a1e61614da447f18c8ba
This commit is contained in:
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
|||||||
C Add\snew\sthread-testing\scode\sand\sfix\slocking\sunder\sLinux\sthreads.\s\sTicket\s#530.\s(CVS\s1137)
|
C A\sbetter\sfix\sfor\sticket\s#530\s-\sone\sthat\sis\slikely\sto\swork\son\sunix\nimplementations\sin\saddition\sto\slinux.\s\sAlso\smore\stests\sfor\smulti-thread\nlocking\sadded.\s(CVS\s1138)
|
||||||
D 2003-12-19T02:52:06
|
D 2003-12-19T08:40:23
|
||||||
F Makefile.in 5cb273b7d0e945d47ee8b9ad1c2a04ce79927d2d
|
F Makefile.in 5cb273b7d0e945d47ee8b9ad1c2a04ce79927d2d
|
||||||
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
||||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||||
@ -38,7 +38,7 @@ F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
|
|||||||
F src/insert.c 01f66866f35c986eab4a57373ca689a3255ef2df
|
F src/insert.c 01f66866f35c986eab4a57373ca689a3255ef2df
|
||||||
F src/main.c 3dd3cae00bade294011da5a3cf9ff660a610c545
|
F src/main.c 3dd3cae00bade294011da5a3cf9ff660a610c545
|
||||||
F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
|
F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
|
||||||
F src/os.c 000b62b95cad6e3518cb7b71ba9376be192b19dc
|
F src/os.c 3460bc83541eb276a69723d8babb533559b09344
|
||||||
F src/os.h 729395fefcca4b81ae056aa9ff67b72bb40dd9e0
|
F src/os.h 729395fefcca4b81ae056aa9ff67b72bb40dd9e0
|
||||||
F src/pager.c ca24fced1ca4c2b8ea519d5fe8ec69a2d846276f
|
F src/pager.c ca24fced1ca4c2b8ea519d5fe8ec69a2d846276f
|
||||||
F src/pager.h 5da62c83443f26b1792cfd72c96c422f91aadd31
|
F src/pager.h 5da62c83443f26b1792cfd72c96c422f91aadd31
|
||||||
@ -130,7 +130,7 @@ F test/tableapi.test d881e787779a175238b72f55b5e50d3a85ab47a6
|
|||||||
F test/tclsqlite.test f141303e0f2e9a616b551813e2b21bd38c5dca50
|
F test/tclsqlite.test f141303e0f2e9a616b551813e2b21bd38c5dca50
|
||||||
F test/temptable.test c82bd6f800f10e8cf96921af6315e5f1c21e2692
|
F test/temptable.test c82bd6f800f10e8cf96921af6315e5f1c21e2692
|
||||||
F test/tester.tcl 2671536d3650c29e7c105219f277568b0884cb58
|
F test/tester.tcl 2671536d3650c29e7c105219f277568b0884cb58
|
||||||
F test/thread1.test e98de6574910978017a621d0851fda13e257763d
|
F test/thread1.test 0c1fcc2f9bdd887225e56f48db8ddfbb3d0794ba
|
||||||
F test/trans.test 75e7a171b5d2d94ee56766459113e2ad0e5f809d
|
F test/trans.test 75e7a171b5d2d94ee56766459113e2ad0e5f809d
|
||||||
F test/trigger1.test 3fe06daecf8334df840025e154e95fd4727600d7
|
F test/trigger1.test 3fe06daecf8334df840025e154e95fd4727600d7
|
||||||
F test/trigger2.test 0767ab30cb5a2c8402c8524f3d566b410b6f5263
|
F test/trigger2.test 0767ab30cb5a2c8402c8524f3d566b410b6f5263
|
||||||
@ -179,7 +179,7 @@ F www/speed.tcl 2f6b1155b99d39adb185f900456d1d592c4832b3
|
|||||||
F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
|
F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
|
||||||
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
|
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
|
||||||
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
|
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
|
||||||
P 80b1e277123c07b2db7441a9e600dd69ef55a0da
|
P b36a4bb61094d539273c21a9e4042384f10a7806
|
||||||
R ea1fab6d3d994f942c20af002987010c
|
R de39b8252b64bbe001153a824a71610f
|
||||||
U drh
|
U drh
|
||||||
Z b3907cc74f1a3c0fe5cfc79f0eafa427
|
Z 22268d4d15b83af3c4ce1b4c3335ae45
|
||||||
|
@ -1 +1 @@
|
|||||||
b36a4bb61094d539273c21a9e4042384f10a7806
|
7dddbeb586504de30c64a1e61614da447f18c8ba
|
21
src/os.c
21
src/os.c
@ -168,14 +168,15 @@ static unsigned int elapse;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** An instance of the following structure serves as the key used
|
** An instance of the following structure serves as the key used
|
||||||
** to locate a particular lockInfo structure given its inode.
|
** to locate a particular lockInfo structure given its inode. Note
|
||||||
|
** that we have to include the process ID as part of the key. On some
|
||||||
|
** threading implementations (ex: linux), each thread has a separate
|
||||||
|
** process ID.
|
||||||
*/
|
*/
|
||||||
struct inodeKey {
|
struct lockKey {
|
||||||
dev_t dev; /* Device number */
|
dev_t dev; /* Device number */
|
||||||
ino_t ino; /* Inode number */
|
ino_t ino; /* Inode number */
|
||||||
#ifdef SQLITE_UNIX_THREADS
|
pid_t pid; /* Process ID */
|
||||||
pthread_t thread_id; /* Which thread are we */
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -185,13 +186,13 @@ struct inodeKey {
|
|||||||
** object keeps a count of the number of OsFiles pointing to it.
|
** object keeps a count of the number of OsFiles pointing to it.
|
||||||
*/
|
*/
|
||||||
struct lockInfo {
|
struct lockInfo {
|
||||||
struct inodeKey key; /* The lookup key */
|
struct lockKey key; /* The lookup key */
|
||||||
int cnt; /* 0: unlocked. -1: write lock. 1...: read lock. */
|
int cnt; /* 0: unlocked. -1: write lock. 1...: read lock. */
|
||||||
int nRef; /* Number of pointers to this structure */
|
int nRef; /* Number of pointers to this structure */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This hash table maps inodes (in the form of inodeKey structures) into
|
** This hash table maps inodes (in the form of lockKey structures) into
|
||||||
** pointers to lockInfo structures.
|
** pointers to lockInfo structures.
|
||||||
*/
|
*/
|
||||||
static Hash lockHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
|
static Hash lockHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
|
||||||
@ -203,7 +204,7 @@ static Hash lockHash = { SQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
|
|||||||
*/
|
*/
|
||||||
static struct lockInfo *findLockInfo(int fd){
|
static struct lockInfo *findLockInfo(int fd){
|
||||||
int rc;
|
int rc;
|
||||||
struct inodeKey key;
|
struct lockKey key;
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
struct lockInfo *pInfo;
|
struct lockInfo *pInfo;
|
||||||
rc = fstat(fd, &statbuf);
|
rc = fstat(fd, &statbuf);
|
||||||
@ -211,9 +212,7 @@ static struct lockInfo *findLockInfo(int fd){
|
|||||||
memset(&key, 0, sizeof(key));
|
memset(&key, 0, sizeof(key));
|
||||||
key.dev = statbuf.st_dev;
|
key.dev = statbuf.st_dev;
|
||||||
key.ino = statbuf.st_ino;
|
key.ino = statbuf.st_ino;
|
||||||
#ifdef SQLITE_UNIX_THREADS
|
key.pid = getpid();
|
||||||
key.thread_id = pthread_self();
|
|
||||||
#endif
|
|
||||||
pInfo = (struct lockInfo*)sqliteHashFind(&lockHash, &key, sizeof(key));
|
pInfo = (struct lockInfo*)sqliteHashFind(&lockHash, &key, sizeof(key));
|
||||||
if( pInfo==0 ){
|
if( pInfo==0 ){
|
||||||
struct lockInfo *pOld;
|
struct lockInfo *pOld;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this script is multithreading behavior
|
# focus of this script is multithreading behavior
|
||||||
#
|
#
|
||||||
# $Id: thread1.test,v 1.1 2003/12/19 02:52:09 drh Exp $
|
# $Id: thread1.test,v 1.2 2003/12/19 08:40:24 drh Exp $
|
||||||
|
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
@ -38,7 +38,15 @@ do_test thread1-1.1 {
|
|||||||
} {8 64}
|
} {8 64}
|
||||||
|
|
||||||
# Interleave two threads on read access. Then make sure a third
|
# Interleave two threads on read access. Then make sure a third
|
||||||
# thread can write the database.
|
# thread can write the database. In other words:
|
||||||
|
#
|
||||||
|
# read-lock A
|
||||||
|
# read-lock B
|
||||||
|
# unlock A
|
||||||
|
# unlock B
|
||||||
|
# write-lock C
|
||||||
|
#
|
||||||
|
# At one point, the write-lock of C would fail on Linux.
|
||||||
#
|
#
|
||||||
do_test thread1-1.2 {
|
do_test thread1-1.2 {
|
||||||
thread_create A test.db
|
thread_create A test.db
|
||||||
@ -82,7 +90,69 @@ do_test thread1-1.11 {
|
|||||||
thread_finalize C
|
thread_finalize C
|
||||||
thread_result C
|
thread_result C
|
||||||
} SQLITE_OK
|
} SQLITE_OK
|
||||||
|
do_test thread1-1.12 {
|
||||||
|
catchsql {SELECT name FROM sqlite_master}
|
||||||
|
execsql {SELECT name FROM sqlite_master}
|
||||||
|
} {t1 t2}
|
||||||
|
|
||||||
|
|
||||||
|
# Under this scenario:
|
||||||
|
#
|
||||||
|
# read-lock A
|
||||||
|
# read-lock B
|
||||||
|
# unlock A
|
||||||
|
# write-lock C
|
||||||
|
#
|
||||||
|
# Make sure the write-lock fails with SQLITE_BUSY
|
||||||
|
#
|
||||||
|
do_test thread1-2.1 {
|
||||||
|
thread_halt *
|
||||||
|
thread_create A test.db
|
||||||
|
thread_compile A {SELECT a FROM t1}
|
||||||
|
thread_step A
|
||||||
|
thread_result A
|
||||||
|
} SQLITE_ROW
|
||||||
|
do_test thread1-2.2 {
|
||||||
|
thread_create B test.db
|
||||||
|
thread_compile B {SELECT b FROM t1}
|
||||||
|
thread_step B
|
||||||
|
thread_result B
|
||||||
|
} SQLITE_ROW
|
||||||
|
do_test thread1-2.3 {
|
||||||
|
thread_create C test.db
|
||||||
|
thread_compile C {INSERT INTO t2 VALUES(98,99)}
|
||||||
|
thread_step C
|
||||||
|
thread_result C
|
||||||
|
} SQLITE_BUSY
|
||||||
|
do_test thread1-2.4 {
|
||||||
|
execsql {SELECT * FROM t2}
|
||||||
|
} {}
|
||||||
|
do_test thread1-2.5 {
|
||||||
|
thread_finalize A
|
||||||
|
thread_result A
|
||||||
|
} SQLITE_OK
|
||||||
|
do_test thread1-2.6 {
|
||||||
|
thread_step C
|
||||||
|
thread_result C
|
||||||
|
} SQLITE_BUSY
|
||||||
|
do_test thread1-2.7 {
|
||||||
|
execsql {SELECT * FROM t2}
|
||||||
|
} {}
|
||||||
|
do_test thread1-2.8 {
|
||||||
|
thread_finalize B
|
||||||
|
thread_result B
|
||||||
|
} SQLITE_OK
|
||||||
|
do_test thread1-2.9 {
|
||||||
|
thread_step C
|
||||||
|
thread_result C
|
||||||
|
} SQLITE_DONE
|
||||||
|
do_test thread1-2.10 {
|
||||||
|
execsql {SELECT * FROM t2}
|
||||||
|
} {98 99}
|
||||||
|
do_test thread1-2.11 {
|
||||||
|
thread_finalize C
|
||||||
|
thread_result C
|
||||||
|
} SQLITE_OK
|
||||||
|
|
||||||
thread_halt *
|
thread_halt *
|
||||||
finish_test
|
finish_test
|
||||||
|
Reference in New Issue
Block a user