-C Remove\stwo\sunused\stests\sfrom\sthe\sintegrity_check\spragma\slogic.\s(CVS\s6466)
-D 2009-04-07T22:05:43
+C Fix\sthe\ssqlite3_unlock_notify()\sinterface\sso\sthat\swhen\sthe\scallback\sis\sNULL\nit\ssimply\scancels\sany\soutstanding\scallbacks.\s(CVS\s6467)
+D 2009-04-07T22:06:57
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/mutex_os2.c 6b5a74f812082a8483c3df05b47bbaac2424b9a0
F src/mutex_unix.c 2f936339dfef1a4c142db290d575a3509b77315f
F src/mutex_w32.c f4b6a4a48f1dfff7f0089cba9b5a371691f17b8b
-F src/notify.c da6f6b999dce9203d24280fa01b4ffbd2d9ba79b
+F src/notify.c 0127121816d8a861deb0dfd111b495346bf233db
F src/os.c c2aa4a7d8bb845222e5c37f56cde377b20c3b087
F src/os.h fa3f4aa0119ff721a2da4b47ffd74406ac864c05
F src/os_common.h 8c61457df58f1a4bd5f5adc3e90e01b37bf7afbc
F src/shell.c 0a11f831603f17fea20ca97133c0f64e716af4a7
F src/sqlite.h.in 718a026b4cf3c766fc7ac5ff582faa60324b116c
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
-F src/sqliteInt.h 3754c3c7f8549db259909882d3484250d77488cb
+F src/sqliteInt.h 7b341ab7d570b271e8566e7e7ed6993453f84964
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
F src/table.c 332ab0ea691e63862e2a8bdfe2c0617ee61062a3
F test/mutex1.test ebd54720401fafe854799dc86b7bf60b75631935
F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660
F test/nan.test c627d79b3d36ea892563fd67584b3e8a18f0618a
-F test/notify1.test 099191b6f450a7cc3208bdf826532572bdd9a204
+F test/notify1.test 533cf60a81f59c1c88a99ce46b1c14f47d14c32c
F test/notify2.test 195a467e021f74197be2c4fb02d6dee644b8d8db
F test/notnull.test 44d600f916b770def8b095a9962dbe3be5a70d82
F test/null.test a8b09b8ed87852742343b33441a9240022108993
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P 2c1f59834ab7a16066ee12cb8a8342d438c23ce9
-R da69fda516423dc915653709b87d09f0
+P 22999d31418aa9ecb17ab5d135b206b967889614
+R 8662e3a26c19cc89676dfbf43f445945
U drh
-Z 1ffc7b542098adaaa0308f19da4f52e8
+Z 7764f7e6b16bc4d3ac70136f1d1dcce8
-22999d31418aa9ecb17ab5d135b206b967889614
\ No newline at end of file
+9ccfcb760745df28b04e746355b1b6dec49a93de
\ No newline at end of file
** This file contains the implementation of the sqlite3_unlock_notify()
** API method and its associated functionality.
**
-** $Id: notify.c,v 1.3 2009/04/07 11:21:29 danielk1977 Exp $
+** $Id: notify.c,v 1.4 2009/04/07 22:06:57 drh Exp $
*/
#include "sqliteInt.h"
#include "btreeInt.h"
/*
** Register an unlock-notify callback.
+**
+** This is called after connection "db" has attempted some operation
+** but has received an SQLITE_LOCKED error because another connection
+** (call it pOther) in the same process was busy using the same shared
+** cache. pOther is found by looking at db->pBlockingConnection.
+**
+** If there is no blocking connection, the callback is invoked immediately,
+** before this routine returns.
+**
+** If pOther is already blocked on db, then report SQLITE_LOCKED, to indicate
+** a deadlock.
+**
+** Otherwise, make arrangements to invoke xNotify when pOther drops
+** its locks.
+**
+** Each call to this routine overrides any prior callbacks registered
+** on the same "db". If xNotify==0 then any prior callbacks are immediately
+** cancelled.
*/
int sqlite3_unlock_notify(
sqlite3 *db,
sqlite3_mutex_enter(db->mutex);
enterMutex();
- if( 0==db->pBlockingConnection ){
+ if( xNotify==0 ){
+ removeFromBlockedList(db);
+ db->pUnlockConnection = 0;
+ db->xUnlockNotify = 0;
+ db->pUnlockArg = 0;
+ }else if( 0==db->pBlockingConnection ){
/* The blocking transaction has been concluded. Or there never was a
** blocking transaction. In either case, invoke the notify callback
** immediately.
}else{
sqlite3 *p;
- for(p=db->pBlockingConnection; p && p!=db; p=p->pUnlockConnection);
+ for(p=db->pBlockingConnection; p && p!=db; p=p->pUnlockConnection){}
if( p ){
rc = SQLITE_LOCKED; /* Deadlock detected. */
}else{
}
/*
-** The transaction opened by database db has just finished. Locks held
+** This function is called when
+** the transaction opened by database db has just finished. Locks held
** by database connection db have been released.
**
** This function loops through each entry in the blocked connections
void (*xUnlockNotify)(void **, int) = 0; /* Unlock-notify cb to invoke */
int nArg = 0; /* Number of entries in aArg[] */
sqlite3 **pp; /* Iterator variable */
+ void **aArg; /* Arguments to the unlock callback */
+ void **aDyn = 0; /* Dynamically allocated space for aArg[] */
+ void *aStatic[16]; /* Starter space for aArg[]. No malloc required */
- void *aStatic[16];
- void **aArg = aStatic;
- void **aDyn = 0;
-
+ aArg = aStatic;
enterMutex(); /* Enter STATIC_MASTER mutex */
/* This loop runs once for each entry in the blocked-connections list. */
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.852 2009/04/07 14:14:22 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.853 2009/04/07 22:06:57 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
/* The following variables are all protected by the STATIC_MASTER
** mutex, not by sqlite3.mutex. They are used by code in notify.c.
+ **
+ ** When X.pUnlockConnection==Y, that means that X is waiting for Y to
+ ** unlock so that it can proceed.
+ **
+ ** When X.pBlockingConnection==Y, that means that something that X tried
+ ** tried to do recently failed with an SQLITE_LOCKED error due to locks
+ ** held by Y.
*/
sqlite3 *pBlockingConnection; /* Connection that caused SQLITE_LOCKED */
sqlite3 *pUnlockConnection; /* Connection to watch for unlock */
# This file implements regression tests for SQLite library. The
# focus of this file is testing the sqlite3_unlock_notify() API.
#
-# $Id: notify1.test,v 1.2 2009/03/25 15:43:09 danielk1977 Exp $
+# $Id: notify1.test,v 1.3 2009/04/07 22:06:57 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
execsql { SELECT * FROM t1 }
} {1 2 3 4}
+#-------------------------------------------------------------------------
+# Verify that invoking the "unlock_notify" method with no arguments
+# (which is the equivalent of invoking sqlite3_unlock_notify() with
+# a NULL xNotify argument) cancels a pending notify callback.
+#
+do_test notify1-1.11 {
+ execsql { DROP TABLE t1; CREATE TABLE t1(a, b) }
+} {}
+do_test notify1-1.12 {
+ execsql {
+ BEGIN;
+ INSERT INTO t1 VALUES(1, 2);
+ }
+ catchsql { INSERT INTO t1 VALUES(3, 4) } db2
+} {1 {database table is locked}}
+do_test notify1-1.13 {
+ set zScript ""
+ db2 unlock_notify {
+ set zScript "db2 eval { INSERT INTO t1 VALUES(3, 4) }"
+ }
+ execsql { SELECT * FROM t1 }
+} {1 2}
+do_test notify1-1.14 {
+ set zScript
+} {}
+do_test notify1-1.15 {
+ db2 unlock_notify
+ execsql { COMMIT }
+ eval $zScript
+ execsql { SELECT * FROM t1 }
+} {1 2}
+
#-------------------------------------------------------------------------
# The following tests, notify1-2.*, test that deadlock is detected
# correctly.