mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-06 15:49:35 +03:00
Fix the sqlite3_unlock_notify() interface so that when the callback is NULL
it simply cancels any outstanding callbacks. (CVS 6467) FossilOrigin-Name: 9ccfcb760745df28b04e746355b1b6dec49a93de
This commit is contained in:
16
manifest
16
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Remove\stwo\sunused\stests\sfrom\sthe\sintegrity_check\spragma\slogic.\s(CVS\s6466)
|
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:05:43
|
D 2009-04-07T22:06:57
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
|
F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -136,7 +136,7 @@ F src/mutex_noop.c f5a07671f25a1a9bd7c10ad7107bc2585446200f
|
|||||||
F src/mutex_os2.c 6b5a74f812082a8483c3df05b47bbaac2424b9a0
|
F src/mutex_os2.c 6b5a74f812082a8483c3df05b47bbaac2424b9a0
|
||||||
F src/mutex_unix.c 2f936339dfef1a4c142db290d575a3509b77315f
|
F src/mutex_unix.c 2f936339dfef1a4c142db290d575a3509b77315f
|
||||||
F src/mutex_w32.c f4b6a4a48f1dfff7f0089cba9b5a371691f17b8b
|
F src/mutex_w32.c f4b6a4a48f1dfff7f0089cba9b5a371691f17b8b
|
||||||
F src/notify.c da6f6b999dce9203d24280fa01b4ffbd2d9ba79b
|
F src/notify.c 0127121816d8a861deb0dfd111b495346bf233db
|
||||||
F src/os.c c2aa4a7d8bb845222e5c37f56cde377b20c3b087
|
F src/os.c c2aa4a7d8bb845222e5c37f56cde377b20c3b087
|
||||||
F src/os.h fa3f4aa0119ff721a2da4b47ffd74406ac864c05
|
F src/os.h fa3f4aa0119ff721a2da4b47ffd74406ac864c05
|
||||||
F src/os_common.h 8c61457df58f1a4bd5f5adc3e90e01b37bf7afbc
|
F src/os_common.h 8c61457df58f1a4bd5f5adc3e90e01b37bf7afbc
|
||||||
@@ -159,7 +159,7 @@ F src/select.c 462d9671e91accd983110fa38674be0d2a3daa66
|
|||||||
F src/shell.c 0a11f831603f17fea20ca97133c0f64e716af4a7
|
F src/shell.c 0a11f831603f17fea20ca97133c0f64e716af4a7
|
||||||
F src/sqlite.h.in 718a026b4cf3c766fc7ac5ff582faa60324b116c
|
F src/sqlite.h.in 718a026b4cf3c766fc7ac5ff582faa60324b116c
|
||||||
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
||||||
F src/sqliteInt.h 3754c3c7f8549db259909882d3484250d77488cb
|
F src/sqliteInt.h 7b341ab7d570b271e8566e7e7ed6993453f84964
|
||||||
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
|
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
|
||||||
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
||||||
F src/table.c 332ab0ea691e63862e2a8bdfe2c0617ee61062a3
|
F src/table.c 332ab0ea691e63862e2a8bdfe2c0617ee61062a3
|
||||||
@@ -479,7 +479,7 @@ F test/misuse.test 30b3a458e5a70c31e74c291937b6c82204c59f33
|
|||||||
F test/mutex1.test ebd54720401fafe854799dc86b7bf60b75631935
|
F test/mutex1.test ebd54720401fafe854799dc86b7bf60b75631935
|
||||||
F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660
|
F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660
|
||||||
F test/nan.test c627d79b3d36ea892563fd67584b3e8a18f0618a
|
F test/nan.test c627d79b3d36ea892563fd67584b3e8a18f0618a
|
||||||
F test/notify1.test 099191b6f450a7cc3208bdf826532572bdd9a204
|
F test/notify1.test 533cf60a81f59c1c88a99ce46b1c14f47d14c32c
|
||||||
F test/notify2.test 195a467e021f74197be2c4fb02d6dee644b8d8db
|
F test/notify2.test 195a467e021f74197be2c4fb02d6dee644b8d8db
|
||||||
F test/notnull.test 44d600f916b770def8b095a9962dbe3be5a70d82
|
F test/notnull.test 44d600f916b770def8b095a9962dbe3be5a70d82
|
||||||
F test/null.test a8b09b8ed87852742343b33441a9240022108993
|
F test/null.test a8b09b8ed87852742343b33441a9240022108993
|
||||||
@@ -715,7 +715,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
P 2c1f59834ab7a16066ee12cb8a8342d438c23ce9
|
P 22999d31418aa9ecb17ab5d135b206b967889614
|
||||||
R da69fda516423dc915653709b87d09f0
|
R 8662e3a26c19cc89676dfbf43f445945
|
||||||
U drh
|
U drh
|
||||||
Z 1ffc7b542098adaaa0308f19da4f52e8
|
Z 7764f7e6b16bc4d3ac70136f1d1dcce8
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
22999d31418aa9ecb17ab5d135b206b967889614
|
9ccfcb760745df28b04e746355b1b6dec49a93de
|
||||||
40
src/notify.c
40
src/notify.c
@@ -13,7 +13,7 @@
|
|||||||
** This file contains the implementation of the sqlite3_unlock_notify()
|
** This file contains the implementation of the sqlite3_unlock_notify()
|
||||||
** API method and its associated functionality.
|
** 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 "sqliteInt.h"
|
||||||
#include "btreeInt.h"
|
#include "btreeInt.h"
|
||||||
@@ -128,6 +128,24 @@ static void leaveMutex(void){
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** Register an unlock-notify callback.
|
** 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(
|
int sqlite3_unlock_notify(
|
||||||
sqlite3 *db,
|
sqlite3 *db,
|
||||||
@@ -139,7 +157,12 @@ int sqlite3_unlock_notify(
|
|||||||
sqlite3_mutex_enter(db->mutex);
|
sqlite3_mutex_enter(db->mutex);
|
||||||
enterMutex();
|
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
|
/* The blocking transaction has been concluded. Or there never was a
|
||||||
** blocking transaction. In either case, invoke the notify callback
|
** blocking transaction. In either case, invoke the notify callback
|
||||||
** immediately.
|
** immediately.
|
||||||
@@ -148,7 +171,7 @@ int sqlite3_unlock_notify(
|
|||||||
}else{
|
}else{
|
||||||
sqlite3 *p;
|
sqlite3 *p;
|
||||||
|
|
||||||
for(p=db->pBlockingConnection; p && p!=db; p=p->pUnlockConnection);
|
for(p=db->pBlockingConnection; p && p!=db; p=p->pUnlockConnection){}
|
||||||
if( p ){
|
if( p ){
|
||||||
rc = SQLITE_LOCKED; /* Deadlock detected. */
|
rc = SQLITE_LOCKED; /* Deadlock detected. */
|
||||||
}else{
|
}else{
|
||||||
@@ -183,7 +206,8 @@ void sqlite3ConnectionBlocked(sqlite3 *db, sqlite3 *pBlocker){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** 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.
|
** by database connection db have been released.
|
||||||
**
|
**
|
||||||
** This function loops through each entry in the blocked connections
|
** This function loops through each entry in the blocked connections
|
||||||
@@ -204,11 +228,11 @@ void sqlite3ConnectionUnlocked(sqlite3 *db){
|
|||||||
void (*xUnlockNotify)(void **, int) = 0; /* Unlock-notify cb to invoke */
|
void (*xUnlockNotify)(void **, int) = 0; /* Unlock-notify cb to invoke */
|
||||||
int nArg = 0; /* Number of entries in aArg[] */
|
int nArg = 0; /* Number of entries in aArg[] */
|
||||||
sqlite3 **pp; /* Iterator variable */
|
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];
|
aArg = aStatic;
|
||||||
void **aArg = aStatic;
|
|
||||||
void **aDyn = 0;
|
|
||||||
|
|
||||||
enterMutex(); /* Enter STATIC_MASTER mutex */
|
enterMutex(); /* Enter STATIC_MASTER mutex */
|
||||||
|
|
||||||
/* This loop runs once for each entry in the blocked-connections list. */
|
/* This loop runs once for each entry in the blocked-connections list. */
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** 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_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@@ -836,6 +836,13 @@ struct sqlite3 {
|
|||||||
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
|
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
|
||||||
/* The following variables are all protected by the STATIC_MASTER
|
/* The following variables are all protected by the STATIC_MASTER
|
||||||
** mutex, not by sqlite3.mutex. They are used by code in notify.c.
|
** 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 *pBlockingConnection; /* Connection that caused SQLITE_LOCKED */
|
||||||
sqlite3 *pUnlockConnection; /* Connection to watch for unlock */
|
sqlite3 *pUnlockConnection; /* Connection to watch for unlock */
|
||||||
|
|||||||
@@ -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 file is testing the sqlite3_unlock_notify() API.
|
# 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]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -55,6 +55,38 @@ do_test notify1-1.5 {
|
|||||||
execsql { SELECT * FROM t1 }
|
execsql { SELECT * FROM t1 }
|
||||||
} {1 2 3 4}
|
} {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
|
# The following tests, notify1-2.*, test that deadlock is detected
|
||||||
# correctly.
|
# correctly.
|
||||||
|
|||||||
Reference in New Issue
Block a user