diff --git a/manifest b/manifest index 0aa75fa69c..52b211fa72 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 @@ -31,7 +31,7 @@ F src/alter.c 03041f2464e22532601254f87cb49997fa21dcdf 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 @@ -44,7 +44,7 @@ F src/hash.c 2b1b13f7400e179631c83a1be0c664608c8f021f 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 @@ -54,7 +54,7 @@ F src/os_unix.c be8f327f9578a6bd1b1550ac3d083c427dfeb0f3 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 @@ -64,7 +64,7 @@ F src/random.c 90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4 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 @@ -78,7 +78,7 @@ F src/update.c 49a9c618c3ba1ca57038d9ce41f14e958442fe58 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 @@ -111,6 +111,7 @@ F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4 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 @@ -285,7 +286,7 @@ F www/tclsqlite.tcl 425be741b8ae664f55cb1ef2371aab0a75109cf9 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 diff --git a/manifest.uuid b/manifest.uuid index 59f3e90f89..3f7e2b30c8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ba56478dd8bc2135749966ff55831fd497883781 \ No newline at end of file +af2a0ba4a38abf208db1ff6f018cf756de2afd5b \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 8ab97dea83..bf08f6df2b 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** 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 @@ -1606,8 +1606,6 @@ static int newDatabase(Btree *pBt){ */ 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 @@ -1641,9 +1639,7 @@ int sqlite3BtreeBeginTrans(Btree *pBt, int wrflag){ 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; } diff --git a/src/main.c b/src/main.c index 8d3487194a..a143d78895 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ ** 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" @@ -307,6 +307,25 @@ static int sqliteDefaultBusyCallback( #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. @@ -321,6 +340,7 @@ int sqlite3_busy_handler( } db->busyHandler.xFunc = xBusy; db->busyHandler.pArg = pArg; + db->busyHandler.nBusy = 0; return SQLITE_OK; } diff --git a/src/pager.c b/src/pager.c index d1b5779d46..456bad012d 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** 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" @@ -1866,7 +1866,7 @@ static void memoryTruncate(Pager *pPager){ /* ** 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 @@ -1880,14 +1880,9 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){ 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; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index b0ee332ff0..a7a6cd2354 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** 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_ @@ -208,6 +208,7 @@ typedef struct BusyHandler BusyHandler; struct BusyHandler { int (*xFunc)(void *,int); /* The busy callback */ void *pArg; /* First arg to busy callback */ + int nBusy; /* Incremented with each busy call */ }; /* @@ -1567,6 +1568,7 @@ const char *sqlite3TestErrorName(int); 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" diff --git a/src/vdbe.c b/src/vdbe.c index ae4a3b4282..f6afbe027d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** 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" @@ -478,6 +478,7 @@ int sqlite3VdbeExec( p->popStack = 0; } p->resOnStack = 0; + db->busyHandler.nBusy = 0; CHECK_FOR_INTERRUPT; for(pc=p->pc; rc==SQLITE_OK; pc++){ assert( pc>=0 && pcnOp ); diff --git a/test/busy.test b/test/busy.test new file mode 100644 index 0000000000..cd13d5fd57 --- /dev/null +++ b/test/busy.test @@ -0,0 +1,43 @@ +# 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