Fix a bug in the demo "superlock" code preventing locks from being released in some circumstances.
FossilOrigin-Name: 65c393793ff5fdb935d5acfe5bdc3bca052f7314
This commit is contained in:
parent
6568ffb14f
commit
c216eee7ce
26
manifest
26
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
|
||||
|
@ -1 +1 @@
|
||||
11c74c0dae0e302f248ec4af6dc8a9376203b034
|
||||
65c393793ff5fdb935d5acfe5bdc3bca052f7314
|
@ -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.
|
||||
**************************************************************************
|
||||
|
@ -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} {
|
||||
|
Loading…
Reference in New Issue
Block a user