]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
A better fix for ticket #530 - one that is likely to work on unix
authordrh <drh@noemail.net>
Fri, 19 Dec 2003 08:40:22 +0000 (08:40 +0000)
committerdrh <drh@noemail.net>
Fri, 19 Dec 2003 08:40:22 +0000 (08:40 +0000)
implementations in addition to linux.  Also more tests for multi-thread
locking added. (CVS 1138)

FossilOrigin-Name: 7dddbeb586504de30c64a1e61614da447f18c8ba

manifest
manifest.uuid
src/os.c
test/thread1.test

index 05c6df0f67bf2bbbca4e6c72831273a06f9dcd7a..a2b2430236dd74cfe815620a3e9d3eb6e3c29b49 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\snew\sthread-testing\scode\sand\sfix\slocking\sunder\sLinux\sthreads.\s\sTicket\s#530.\s(CVS\s1137)
-D 2003-12-19T02:52:06
+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-19T08:40:23
 F Makefile.in 5cb273b7d0e945d47ee8b9ad1c2a04ce79927d2d
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -38,7 +38,7 @@ F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
 F src/insert.c 01f66866f35c986eab4a57373ca689a3255ef2df
 F src/main.c 3dd3cae00bade294011da5a3cf9ff660a610c545
 F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
-F src/os.c 000b62b95cad6e3518cb7b71ba9376be192b19dc
+F src/os.c 3460bc83541eb276a69723d8babb533559b09344
 F src/os.h 729395fefcca4b81ae056aa9ff67b72bb40dd9e0
 F src/pager.c ca24fced1ca4c2b8ea519d5fe8ec69a2d846276f
 F src/pager.h 5da62c83443f26b1792cfd72c96c422f91aadd31
@@ -130,7 +130,7 @@ F test/tableapi.test d881e787779a175238b72f55b5e50d3a85ab47a6
 F test/tclsqlite.test f141303e0f2e9a616b551813e2b21bd38c5dca50
 F test/temptable.test c82bd6f800f10e8cf96921af6315e5f1c21e2692
 F test/tester.tcl 2671536d3650c29e7c105219f277568b0884cb58
-F test/thread1.test e98de6574910978017a621d0851fda13e257763d
+F test/thread1.test 0c1fcc2f9bdd887225e56f48db8ddfbb3d0794ba
 F test/trans.test 75e7a171b5d2d94ee56766459113e2ad0e5f809d
 F test/trigger1.test 3fe06daecf8334df840025e154e95fd4727600d7
 F test/trigger2.test 0767ab30cb5a2c8402c8524f3d566b410b6f5263
@@ -179,7 +179,7 @@ F www/speed.tcl 2f6b1155b99d39adb185f900456d1d592c4832b3
 F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
 F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
-P 80b1e277123c07b2db7441a9e600dd69ef55a0da
-R ea1fab6d3d994f942c20af002987010c
+P b36a4bb61094d539273c21a9e4042384f10a7806
+R de39b8252b64bbe001153a824a71610f
 U drh
-Z b3907cc74f1a3c0fe5cfc79f0eafa427
+Z 22268d4d15b83af3c4ce1b4c3335ae45
index aa294d8158dc1198d0b29f3cc79219b1b8f38021..ba2ecc6085befad97426bd36bad56a5cec0de0de 100644 (file)
@@ -1 +1 @@
-b36a4bb61094d539273c21a9e4042384f10a7806
\ No newline at end of file
+7dddbeb586504de30c64a1e61614da447f18c8ba
\ No newline at end of file
index 60928161f21a0c6161c8ad955b599678fb403c89..d68a12f156202efd0aa4bad334107a6604b93509 100644 (file)
--- a/src/os.c
+++ b/src/os.c
@@ -168,14 +168,15 @@ static unsigned int elapse;
 
 /*
 ** 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 */
   ino_t ino;   /* Inode number */
-#ifdef SQLITE_UNIX_THREADS
-  pthread_t thread_id;   /* Which thread are we */
-#endif
+  pid_t pid;   /* Process ID */
 };
 
 /*
@@ -185,13 +186,13 @@ struct inodeKey {
 ** object keeps a count of the number of OsFiles pointing to it.
 */
 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 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.
 */
 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){
   int rc;
-  struct inodeKey key;
+  struct lockKey key;
   struct stat statbuf;
   struct lockInfo *pInfo;
   rc = fstat(fd, &statbuf);
@@ -211,9 +212,7 @@ static struct lockInfo *findLockInfo(int fd){
   memset(&key, 0, sizeof(key));
   key.dev = statbuf.st_dev;
   key.ino = statbuf.st_ino;
-#ifdef SQLITE_UNIX_THREADS
-  key.thread_id = pthread_self();
-#endif
+  key.pid = getpid();
   pInfo = (struct lockInfo*)sqliteHashFind(&lockHash, &key, sizeof(key));
   if( pInfo==0 ){
     struct lockInfo *pOld;
index 8dd1bb7f2a6a2eea6f5f35182b94b96c14c662ac..598ba4c555b4bea818dd487f163fbc1d4456a935 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # 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]
@@ -38,7 +38,15 @@ do_test thread1-1.1 {
 } {8 64}
 
 # 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 {
   thread_create A test.db
@@ -82,7 +90,69 @@ do_test thread1-1.11 {
   thread_finalize C
   thread_result C
 } 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 *   
 finish_test