-C Allow\sthe\sIN\soperator\sto\stake\sa\slist\sof\sarbitrary\sexpressions\son\sits\nright-hand\sside.\s\sThe\sexpressions\sno\slonger\sneed\sto\sbe\sconstant.\s\sThe\ncurrent\simplementation\sseems\sto\swork\sbut\sneeds\smore\stesting\sand\soptimization.\s(CVS\s2542)
-D 2005-07-08T18:25:26
+C Make\ssure\sthere\sis\sonly\sone\sbusy\scounter.\s\sTicket\s#1315.\s(CVS\s2543)
+D 2005-07-09T02:16:03
F Makefile.in 3c10cd7bc3ecbd60fe4d5a5c0f59bfa7fb217a66
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
F src/analyze.c 2f770b39f9d77353ac36db1861319e6323772f82
F src/attach.c 3615dbe960cbee4aa5ea300b8a213dad36527b0f
F src/auth.c 18c5a0befe20f3a58a41e3ddd78f372faeeefe1f
-F src/btree.c a167f412cf5b269bffba925ac55a1c0a2f749e29
+F src/btree.c ec55bd70052cdd0958f3a0e79ad58d93561acb20
F src/btree.h 41a71ce027db9ddee72cb43df2316bbe3a1d92af
F src/build.c 1f40c07a11e0a4eed1cef1ad4e52cf3f9770f220
F src/callback.c 0910b611e0c158f107ee3ff86f8a371654971e2b
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
F src/insert.c c4533240451b73ead88098b5d819cb70fa0880bd
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
-F src/main.c 7d0293d9520688d47092ff48c1ed5254cd3c4474
+F src/main.c fcf2fc29a32cdfa69994e411618664d421aa64bd
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
F src/os.h c4b34bd4d6fea51a420f337468b907f4edecb161
F src/os_common.h 0e7f428ba0a6c40a61bc56c4e96f493231301b73
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
F src/os_win.c fe7b99cfcfb61d9bf54493ddf5857885a657fb89
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
-F src/pager.c 841a2cdddd4275de36cda26ed9dc54ae942660ce
+F src/pager.c ee3bbc4cd590a0266c791b4ed537cbd9a9d03566
F src/pager.h 0d9153d6269d60d04af3dd84a0cc0a96253cf4a4
F src/parse.y d57cdd2adc0923762b40314f08683c836a2e0c90
F src/pragma.c dea86dad2f0e872b29632ae9fba526e539a4ddd8
F src/select.c c611471052773b94af771693686bd5bcdbbb0dba
F src/shell.c 25b3217d7c64e6497225439d261a253a23efff26
F src/sqlite.h.in e06d5774e9cfa5962376ae988300a9f114a3e3d7
-F src/sqliteInt.h f1804025f8ff45825ae2a2efa01c0be8a95738e8
+F src/sqliteInt.h af65e8fac1fe8f6f78a65551081bafd49f6e0650
F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
F src/tclsqlite.c cccaf6b78c290d824cf8ea089b8b27377e545830
F src/test1.c 83ead44dead55033adff61ce69a1e2fc3e72935e
F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c
F src/util.c 1acbe299cbe51f45176ac1e48ded9bea206c3c23
F src/vacuum.c 829d9e1a6d7c094b80e0899686670932eafd768c
-F src/vdbe.c 971e08e91848e0afcdf5c7312c7f10b5fc6e7cd4
+F src/vdbe.c 7b41a1979d3421dbbe34a3a48970b4e75fb1d634
F src/vdbe.h 75e466d84d362b0c4498978a9d6b1e6bd32ecf3b
F src/vdbeInt.h 9be9a6c43d38124bd03cc5cf05715605b1789fd9
F src/vdbeapi.c 7f392f0792d1258c958083d7de9eae7c3530c9a6
F test/btree5.test 8e5ff32c02e685d36516c6499add9375fe1377f2
F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027
F test/btree7.test a6d3b842db22af97dd14b989e90a2fd96066b72f
+F test/busy.test e355bee7d32aae35ccb3786f7a6470b73559d0f9
F test/capi2.test f897209386fb21cfdc9267595e0c667ebaca9164
F test/capi3.test 4d848cc55ad6e5f68cf2712716e9fc1fa55d7635
F test/capi3b.test 5b6a66f9f295f79f443b5d3f33187fa5ef6cf336
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b
-P 3bb9ce5f20d0a6bc19df31df9b8e82044c3e6004
-R 1efa9cdd449acebde300ce2385775e19
+P ba56478dd8bc2135749966ff55831fd497883781
+R aec210f9b01657445bd9205f6677dd15
U drh
-Z 5c326e79427e109a129a76bef3edf05e
+Z 3974f28046fc5173c599027244194a4a
-ba56478dd8bc2135749966ff55831fd497883781
\ No newline at end of file
+af2a0ba4a38abf208db1ff6f018cf756de2afd5b
\ No newline at end of file
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.262 2005/06/14 16:04:06 drh Exp $
+** $Id: btree.c,v 1.263 2005/07/09 02:16:03 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
*/
int sqlite3BtreeBeginTrans(Btree *pBt, int wrflag){
int rc = SQLITE_OK;
- int busy = 0;
- BusyHandler *pH;
/* If the btree is already in a write-transaction, or it
** is already in a read-transaction and a read-transaction
unlockBtreeIfUnused(pBt);
}
}while( rc==SQLITE_BUSY && pBt->inTrans==TRANS_NONE &&
- (pH = pBt->pBusyHandler)!=0 &&
- pH->xFunc && pH->xFunc(pH->pArg, busy++)
- );
+ sqlite3InvokeBusyHandler(pBt->pBusyHandler) );
return rc;
}
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.294 2005/06/14 02:24:32 drh Exp $
+** $Id: main.c,v 1.295 2005/07/09 02:16:03 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#endif
}
+/*
+** Invoke the given busy handler.
+**
+** This routine is called when an operation failed with a lock.
+** If this routine returns non-zero, the lock is retried. If it
+** returns 0, the operation aborts with an SQLITE_BUSY error.
+*/
+int sqlite3InvokeBusyHandler(BusyHandler *p){
+ int rc;
+ if( p==0 || p->xFunc==0 || p->nBusy<0 ) return 0;
+ rc = p->xFunc(p->pArg, p->nBusy);
+ if( rc==0 ){
+ p->nBusy = -1;
+ }else{
+ p->nBusy++;
+ }
+ return rc;
+}
+
/*
** This routine sets the busy callback for an Sqlite database to the
** given callback function with the given argument.
}
db->busyHandler.xFunc = xBusy;
db->busyHandler.pArg = pArg;
+ db->busyHandler.nBusy = 0;
return SQLITE_OK;
}
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.207 2005/06/07 02:12:30 drh Exp $
+** @(#) $Id: pager.c,v 1.208 2005/07/09 02:16:03 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
/*
** Try to obtain a lock on a file. Invoke the busy callback if the lock
-** is currently not available. Repeate until the busy callback returns
+** is currently not available. Repeat until the busy callback returns
** false or until the lock succeeds.
**
** Return SQLITE_OK on success and an error code if we cannot obtain
if( pPager->state>=locktype ){
rc = SQLITE_OK;
}else{
- int busy = 1;
- BusyHandler *pH;
do {
rc = sqlite3OsLock(&pPager->fd, locktype);
- }while( rc==SQLITE_BUSY &&
- (pH = pPager->pBusyHandler)!=0 &&
- pH->xFunc && pH->xFunc(pH->pArg, busy++)
- );
+ }while( rc==SQLITE_BUSY && sqlite3InvokeBusyHandler(pPager->pBusyHandler) );
if( rc==SQLITE_OK ){
pPager->state = locktype;
}
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.392 2005/07/08 17:13:47 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.393 2005/07/09 02:16:03 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
struct BusyHandler {
int (*xFunc)(void *,int); /* The busy callback */
void *pArg; /* First arg to busy callback */
+ int nBusy; /* Incremented with each busy call */
};
/*
CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char *, int);
char sqlite3AffinityType(const Token*);
void sqlite3Analyze(Parse*, Token*, Token*);
+int sqlite3InvokeBusyHandler(BusyHandler*);
#ifdef SQLITE_SSE
#include "sseInt.h"
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
-** $Id: vdbe.c,v 1.474 2005/07/08 17:13:47 drh Exp $
+** $Id: vdbe.c,v 1.475 2005/07/09 02:16:03 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
p->popStack = 0;
}
p->resOnStack = 0;
+ db->busyHandler.nBusy = 0;
CHECK_FOR_INTERRUPT;
for(pc=p->pc; rc==SQLITE_OK; pc++){
assert( pc>=0 && pc<p->nOp );
--- /dev/null
+# 2005 july 8
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file test the busy handler
+#
+# $Id: busy.test,v 1.1 2005/07/09 02:16:03 drh Exp $
+
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+do_test busy-1.1 {
+ sqlite3 db2 test.db
+ execsql {
+ CREATE TABLE t1(x);
+ INSERT INTO t1 VALUES(1);
+ SELECT * FROM t1
+ }
+} 1
+proc busy x {
+ lappend ::busyargs $x
+ if {$x>2} {return 1}
+ return 0
+}
+do_test busy-1.2 {
+ db busy busy
+ db2 eval {begin exclusive}
+ catchsql {begin immediate}
+} {1 {database is locked}}
+do_test busy-1.3 {
+ set busyargs
+} {0 1 2 3}
+
+db2 close
+
+finish_test