]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a bug in the demo "superlock" code preventing locks from being released in some...
authordan <dan@noemail.net>
Tue, 7 Dec 2010 16:39:25 +0000 (16:39 +0000)
committerdan <dan@noemail.net>
Tue, 7 Dec 2010 16:39:25 +0000 (16:39 +0000)
FossilOrigin-Name: 65c393793ff5fdb935d5acfe5bdc3bca052f7314

manifest
manifest.uuid
src/test_superlock.c
test/superlock.test

index 14f5ca866354137988afa6ed9d08c453885778d6..10f8555a8cca810072fd46570b0624a18323ec73 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,5 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-C Version\s3.7.4\srelease\scandidate\s3
-D 2010-12-07T14:59:22
+C Fix\sa\sbug\sin\sthe\sdemo\s"superlock"\scode\spreventing\slocks\sfrom\sbeing\sreleased\sin\ssome\scircumstances.
+D 2010-12-07T16:39:26
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 4547616ad2286053af6ccccefa242dc925e49bf0
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -220,7 +217,7 @@ F src/test_rtree.c 30c981837445a4e187ee850a49c4760d9642f7c3
 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
 F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6
 F src/test_stat.c f682704b5d1ba8e1d4e7e882a6d7922e2dcf066c
-F src/test_superlock.c c0c0b1f73254a0c4ad5aca69e627fe32f571f7f9
+F src/test_superlock.c aa91c01e42c8e1eef663b74bd1b9a762306f06b5
 F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
 F src/test_thread.c bedd05cad673dba53326f3aa468cc803038896c0
 F src/test_vfs.c e10fcca756cafa89438311b31522ac1f95bf784b
@@ -657,7 +654,7 @@ F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
 F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796
 F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
-F test/superlock.test 070e7fd9ccf91755b6f8e03ede27995a73220672
+F test/superlock.test 8468e057d8a5531ff99e504e77fcc585a0291bf2
 F test/sync.test ded6b39d8d8ca3c0c5518516c6371b3316d3e3a3
 F test/table.test 04ba066432430657712d167ebf28080fe878d305
 F test/tableapi.test 7262a8cbaa9965d429f1cbd2747edc185fa56516
@@ -897,14 +894,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P b0634d2f909fb192d20315e59fa31fcd8f316541
-R c899dedfcbfad993e519fd17027aa5c1
-U drh
-Z e558719848264f114302cf252022d7ad
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.6 (GNU/Linux)
-
-iD8DBQFM/kvQoxKgR168RlERAihjAJ483qru/mKHGZtSh1P4zl69jepBKwCfe11S
-MaOtcUGzrbyHLk/lC2rzkPk=
-=bBvs
------END PGP SIGNATURE-----
+P 11c74c0dae0e302f248ec4af6dc8a9376203b034
+R b4c637d07289308a3222d68447f4c6c3
+U dan
+Z 63bd98324f51b062689452a6abdd2cdc
index 281813f1d52cb0a1e1316ab32177a92788b1f898..63640be6f9fe70df2ee3464111b5fe73559b2f52 100644 (file)
@@ -1 +1 @@
-11c74c0dae0e302f248ec4af6dc8a9376203b034
\ No newline at end of file
+65c393793ff5fdb935d5acfe5bdc3bca052f7314
\ No newline at end of file
index 8a49188658d5640a3a813613a3a2ccc81c323e57..464da55076cedfd15779719e1cd1780a0b4465d7 100644 (file)
@@ -33,6 +33,17 @@ struct SuperlockBusy {
 };
 typedef struct SuperlockBusy SuperlockBusy;
 
+/*
+** An instance of the following structure is allocated for each active
+** superlock. The opaque handle returned by sqlite3demo_superlock() is
+** actually a pointer to an instance of this structure.
+*/
+struct Superlock {
+  sqlite3 *db;                    /* Database handle used to lock db */
+  int bWal;                       /* True if db is a WAL database */
+};
+typedef struct Superlock Superlock;
+
 /*
 ** The pCtx pointer passed to this function is actually a pointer to a
 ** SuperlockBusy structure. Invoke the busy-handler function encapsulated
@@ -53,18 +64,18 @@ static int superlockBusyHandler(void *pCtx, int UNUSED){
 ** If an error occurs, return an SQLite error code. The value of *pbWal
 ** is undefined in this case.
 */
-static int superlockIsWal(sqlite3 *db, int *pbWal){
+static int superlockIsWal(Superlock *pLock){
   int rc;                         /* Return Code */
   sqlite3_stmt *pStmt;            /* Compiled PRAGMA journal_mode statement */
 
-  rc = sqlite3_prepare(db, "PRAGMA main.journal_mode", -1, &pStmt, 0);
+  rc = sqlite3_prepare(pLock->db, "PRAGMA main.journal_mode", -1, &pStmt, 0);
   if( rc!=SQLITE_OK ) return rc;
 
-  *pbWal = 0;
+  pLock->bWal = 0;
   if( SQLITE_ROW==sqlite3_step(pStmt) ){
     const char *zMode = (const char *)sqlite3_column_text(pStmt, 0);
     if( zMode && strlen(zMode)==3 && sqlite3_strnicmp("wal", zMode, 3)==0 ){
-      *pbWal = 1;
+      pLock->bWal = 1;
     }
   }
 
@@ -132,6 +143,23 @@ static int superlockWalLock(
   return rc;
 }
 
+/*
+** Release a superlock held on a database file. The argument passed to 
+** this function must have been obtained from a successful call to
+** sqlite3demo_superlock().
+*/
+void sqlite3demo_superunlock(void *pLock){
+  Superlock *p = (Superlock *)pLock;
+  if( p->bWal ){
+    int flags = SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE;
+    sqlite3_file *fd = 0;
+    sqlite3_file_control(p->db, "main", SQLITE_FCNTL_FILE_POINTER, (void *)&fd);
+    fd->pMethods->xShmLock(fd, 2, SQLITE_SHM_NLOCK-2, flags);
+  }
+  sqlite3_close(p->db);
+  sqlite3_free(p);
+}
+
 /*
 ** Obtain a superlock on the database file identified by zPath, using the
 ** locking primitives provided by VFS zVfs. If successful, SQLITE_OK is
@@ -154,13 +182,17 @@ int sqlite3demo_superlock(
   void *pBusyArg,                 /* Context arg for busy handler */
   void **ppLock                   /* OUT: Context to pass to superunlock() */
 ){
-  sqlite3 *db = 0;                /* Database handle open on zPath */
   SuperlockBusy busy = {0, 0, 0}; /* Busy handler wrapper object */
   int rc;                         /* Return code */
+  Superlock *pLock;
+
+  pLock = sqlite3_malloc(sizeof(Superlock));
+  if( !pLock ) return SQLITE_NOMEM;
+  memset(pLock, 0, sizeof(Superlock));
 
   /* Open a database handle on the file to superlock. */
   rc = sqlite3_open_v2(
-      zPath, &db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs
+      zPath, &pLock->db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs
   );
 
   /* Install a busy-handler and execute a BEGIN EXCLUSIVE. If this is not
@@ -179,8 +211,8 @@ int sqlite3demo_superlock(
   if( rc==SQLITE_OK ){
     busy.xBusy = xBusy;
     busy.pBusyArg = pBusyArg;
-    sqlite3_busy_handler(db, superlockBusyHandler, (void *)&busy);
-    rc = sqlite3_exec(db, "BEGIN EXCLUSIVE", 0, 0, 0);
+    sqlite3_busy_handler(pLock->db, superlockBusyHandler, (void *)&busy);
+    rc = sqlite3_exec(pLock->db, "BEGIN EXCLUSIVE", 0, 0, 0);
   }
 
   /* If the BEGIN EXCLUSIVE was executed successfully and this is a WAL
@@ -193,34 +225,24 @@ int sqlite3demo_superlock(
   ** new WAL locks may conflict with the old.
   */
   if( rc==SQLITE_OK ){
-    int bWal;                     /* True for a WAL database, false otherwise */
-    if( SQLITE_OK==(rc = superlockIsWal(db, &bWal)) && bWal ){
-      rc = sqlite3_exec(db, "COMMIT", 0, 0, 0);
+    if( SQLITE_OK==(rc = superlockIsWal(pLock)) && pLock->bWal ){
+      rc = sqlite3_exec(pLock->db, "COMMIT", 0, 0, 0);
       if( rc==SQLITE_OK ){
-        rc = superlockWalLock(db, &busy);
+        rc = superlockWalLock(pLock->db, &busy);
       }
     }
   }
 
   if( rc!=SQLITE_OK ){
-    sqlite3_close(db);
+    sqlite3demo_superunlock(pLock);
     *ppLock = 0;
   }else{
-    *ppLock = (void *)db;
+    *ppLock = pLock;
   }
 
   return rc;
 }
 
-/*
-** Release a superlock held on a database file. The argument passed to 
-** this function must have been obtained from a successful call to
-** sqlite3demo_superlock().
-*/
-void sqlite3demo_superunlock(void *pLock){
-  sqlite3_close((sqlite3 *)pLock);
-}
-
 /*
 ** End of example code. Everything below here is the test harness.
 **************************************************************************
index c022d35c7875f386cb74813663187f57b2338752..41a55144a6378bdeab3a279bb6eb50145a6154fe 100644 (file)
@@ -143,6 +143,15 @@ do_multiclient_test tn {
     list [catch {sqlite3demo_superlock unlock test.db} msg] $msg
   } {0 unlock}
   unlock
+
+
+  do_test 5.$tn.13 { sql1 { SELECT * FROM t1 } } {1 2 3 4 5 6}
+  do_test 5.$tn.14 { sql2 { SELECT * FROM t1 } } {1 2 3 4 5 6}
+  do_test 5.$tn.15 { sqlite3demo_superlock unlock test.db } {unlock}
+  do_test 5.$tn.16 { unlock } {}
+  do_test 5.$tn.17 { sql2 { SELECT * FROM t1 } } {1 2 3 4 5 6}
+  do_test 5.$tn.18 { sql1 { SELECT * FROM t1 } } {1 2 3 4 5 6}
+  do_test 5.$tn.19 { sql2 { SELECT * FROM t1 } } {1 2 3 4 5 6}
 }
 
 proc read_content {file} {