-C Untested\supdates\sto\ssupport\satomic\smulti-file\stransactions\s(CVS\s1526)
-D 2004-06-03T16:08:41
+C Move\sthe\s'busy-callback'\slogic\sto\sthe\spager\slayer.\s(CVS\s1527)
+D 2004-06-04T06:22:01
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
F src/attach.c c315c58cb16fd6e913b3bfa6412aedecb4567fa5
F src/auth.c 5c2f0bea4729c98c2be3b69d6b466fc51448fe79
-F src/btree.c 3cf513520d5b6fe54cc4c5fb44ce5c6231f1a535
-F src/btree.h 7b682341772eb1199de3f9c29ce5e34f96836d17
+F src/btree.c 39dfc3954a7af77be42ef7fb19ab22c1fa644a83
+F src/btree.h 589427ac13bb544d298cd99726e2572a6fe4bdaa
F src/build.c e12e602f06e37a0fbcb49af17cba68ad85e101b6
F src/date.c 8e6fa3173386fb29fdef012ee08a853c1e9908b2
F src/delete.c b30f08250c9ed53a25a13c7c04599c1e8753992d
F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
F src/insert.c 4268d9e3959cc845ea243fb4ec7507269404dad9
F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f
-F src/main.c d2a7632f459e9c270bb6e313e10916fc840f4a6e
+F src/main.c 4e8e5c96e5a9460e71b97c83cb30cb3ad44db259
F src/md5.c 4302e84ae516c616bb079c4e6d038c0addb33481
F src/os.h cc2fd62b2e8e11103701913871908ff77532af58
F src/os_common.h 744286a27de55c52f1b18921e8d17abbf7fafc0f
F src/os_unix.h 7999f2246c6347707e98f7078871ea8ca605df3f
F src/os_win.c 92b51a38437b98d8aa3ac05b57c71e1d1092e5be
F src/os_win.h 5d41af24caaef6c13a2d8e2399caa1c57d45c84d
-F src/pager.c 1619b6a0338cefa3b4d8be54afbbe1c46e85e64e
-F src/pager.h ade5bee4a0771adf82180fd702f170cb0031d811
+F src/pager.c 00fabe423729e8d8a4c5e8f9602341b69a5a21b5
+F src/pager.h 0c7b5ac45c69e690c45d160d03bdc8fbd2d4657b
F src/parse.y 27c1ce09f9d309be91f9e537df2fb00892990af4
F src/pragma.c 1b58d852b84b36a8b84e2245dd29b63c377414ec
F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53
F src/select.c 0297717eb7331604687c2e29c147d3a311359df1
F src/shell.c a9e2ad8f6c1d39b04bad61a0ec655e9a3a360b50
F src/sqlite.h.in 8236db65bc6d8f5f47dc5a5e86c4a9bce42f2adf
-F src/sqliteInt.h 1aa9f7d5f88d13442d39c1bc9216c73e9b6c5191
+F src/sqliteInt.h 99f2b4ff4ed28123890a0c71359fec3d2c5901c9
F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
F src/tclsqlite.c 3db6b868bd844bfb71720c8e573f4c9b0d536bd5
F src/test1.c 4a3cc1b628a29f24c0a43227a035d0f2a96eb634
-F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872
-F src/test3.c b3f331bda440ae21b6cab5171f28ddb402001f26
+F src/test2.c ae18537d8a85e5028c955837797f9da461b908b8
+F src/test3.c beafd0ccf7b9ae784744be1b1e66ffe8f64c25da
F src/test4.c caf675e443460ec76b04d78e1688986c17c82cec
-F src/test5.c e731274b902eaad09b195cfbac06768dfefba93e
+F src/test5.c 44178ce85c3afd2004ab4eeb5cfd7487116ce366
F src/tokenize.c 183c5d7da11affab5d70d903d33409c8c0ce6c5b
F src/trigger.c 04b2c310d0d056b213609cab6df5fff03d5eaf88
F src/update.c 259f06e7b22c684b2d3dda54a18185892d6e9573
F src/utf.c c8be20ecdcb10659e23c43e35d835460e964d248
F src/util.c d3d2f62ec94160db3cb2b092267405ba99122152
F src/vacuum.c b921eb778842592e1fb48a9d4cef7e861103878f
-F src/vdbe.c 2cf1376f23e2f8ddd1a55143ea9e0e289095504d
+F src/vdbe.c e1e62347215a8dbe0ec72c155e4a042e81c6aa71
F src/vdbe.h e73f890e0f2a6c42b183d7d6937947930fe4fdeb
F src/vdbeInt.h 9f5df0a21474be02fe870cbb0a414d09b66eb31a
F src/vdbeapi.c 77d2e681a992ef189032cd9c1b7bf922f01ebe3e
F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 51348b82c4d5801091537b80059d770410774905
-R 0e06f4b108dd74f5024eb81017752495
+P d57e5252c8baaf615c2cd218a33356ea5d95a5e2
+R 2d675c6973e7ef6b1853da4802084a3d
U danielk1977
-Z 4a23c8e1ebb05080684ee0992bb72463
+Z bb8854c6d118151a9229d93a5653a12b
-d57e5252c8baaf615c2cd218a33356ea5d95a5e2
\ No newline at end of file
+ff70b6d2b60c143e3ada0606ceff97571998c7e3
\ No newline at end of file
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.156 2004/06/03 16:08:41 danielk1977 Exp $
+** $Id: btree.c,v 1.157 2004/06/04 06:22:01 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
const char *zFilename, /* Name of the file containing the BTree database */
Btree **ppBtree, /* Pointer to new Btree object written here */
int nCache, /* Number of cache pages */
- int flags /* Options */
+ int flags, /* Options */
+ void *pBusyHandler /* Busy callback info passed to pager layer */
){
Btree *pBt;
int rc;
}
if( nCache<10 ) nCache = 10;
rc = sqlite3pager_open(&pBt->pPager, zFilename, nCache, EXTRA_SIZE,
- (flags & BTREE_OMIT_JOURNAL)==0);
+ (flags & BTREE_OMIT_JOURNAL)==0, pBusyHandler);
if( rc!=SQLITE_OK ){
if( pBt->pPager ) sqlite3pager_close(pBt->pPager);
sqliteFree(pBt);
** subsystem. See comments in the source code for a detailed description
** of what each interface routine does.
**
-** @(#) $Id: btree.h,v 1.52 2004/06/03 16:08:41 danielk1977 Exp $
+** @(#) $Id: btree.h,v 1.53 2004/06/04 06:22:01 danielk1977 Exp $
*/
#ifndef _BTREE_H_
#define _BTREE_H_
typedef struct BtCursor BtCursor;
-int sqlite3BtreeOpen(const char *zFilename, Btree **, int nCache, int flags);
+int sqlite3BtreeOpen(
+ const char *zFilename,
+ Btree **,
+ int nCache,
+ int flags,
+ void *pBusyHandler
+);
/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
** following values.
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.203 2004/06/02 00:41:09 drh Exp $
+** $Id: main.c,v 1.204 2004/06/04 06:22:01 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
int (*xBusy)(void*,const char*,int),
void *pArg
){
- db->xBusyCallback = xBusy;
- db->pBusyArg = pArg;
+ db->busyHandler.xFunc = xBusy;
+ db->busyHandler.pArg = pArg;
}
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
btree_flags |= BTREE_MEMORY;
}
- return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags);
+ return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags,
+ &db->busyHandler);
}
/*
if( !db->init.busy ){
if( (db->flags & SQLITE_Initialized)==0 ){
int cnt = 1;
- while( (rc = sqlite3Init(db, &zErrMsg))==SQLITE_BUSY
- && db->xBusyCallback
- && db->xBusyCallback(db->pBusyArg, "", cnt++)!=0 ){}
+ rc = sqlite3Init(db, &zErrMsg);
if( rc!=SQLITE_OK ){
goto prepare_out;
}
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.110 2004/06/03 16:08:42 danielk1977 Exp $
+** @(#) $Id: pager.c,v 1.111 2004/06/04 06:22:01 danielk1977 Exp $
*/
#include "os.h" /* Must be first to enable large file support */
#include "sqliteInt.h"
PgHdr *pStmt; /* List of pages in the statement subjournal */
PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number of PgHdr */
int nMaster; /* Number of bytes to reserve for master j.p */
+ BusyHandler *pBusyHandler; /* Pointer to sqlite.busyHandler */
};
/*
const char *zFilename, /* Name of the database file to open */
int mxPage, /* Max number of in-memory cache pages */
int nExtra, /* Extra bytes append to each in-memory page */
- int useJournal /* TRUE to use a rollback journal on this file */
+ int useJournal, /* TRUE to use a rollback journal on this file */
+ void *pBusyHandler /* Busy callback */
){
Pager *pPager;
char *zFullPathname;
pPager->pFirstSynced = 0;
pPager->pLast = 0;
pPager->nExtra = nExtra;
+ pPager->pBusyHandler = (BusyHandler *)pBusyHandler;
memset(pPager->aHash, 0, sizeof(pPager->aHash));
*ppPager = pPager;
return SQLITE_OK;
** on the database file.
*/
if( pPager->nRef==0 && !pPager->memDb ){
- rc = sqlite3OsReadLock(&pPager->fd);
- if( rc!=SQLITE_OK ){
- return rc;
+ int busy = 1;
+ while( busy ){
+ rc = sqlite3OsReadLock(&pPager->fd);
+ if( rc==SQLITE_BUSY &&
+ pPager->pBusyHandler &&
+ pPager->pBusyHandler->xFunc &&
+ pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, "", busy++)
+ ){
+ rc = SQLITE_OK;
+ }else{
+ busy = 0;
+ }
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
}
pPager->state = SQLITE_READLOCK;
pPager->state = SQLITE_WRITELOCK;
pPager->origDbSize = pPager->dbSize;
}else{
- rc = sqlite3OsWriteLock(&pPager->fd);
- if( rc!=SQLITE_OK ){
- return rc;
+ int busy = 1;
+ while( busy ){
+ rc = sqlite3OsWriteLock(&pPager->fd);
+ if( rc==SQLITE_BUSY &&
+ pPager->pBusyHandler &&
+ pPager->pBusyHandler->xFunc &&
+ pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, "", busy++)
+ ){
+ rc = SQLITE_OK;
+ }else{
+ busy = 0;
+ }
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
}
pPager->nMaster = nMaster;
pPager->state = SQLITE_WRITELOCK;
** subsystem. The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
-** @(#) $Id: pager.h,v 1.30 2004/06/03 16:08:42 danielk1977 Exp $
+** @(#) $Id: pager.h,v 1.31 2004/06/04 06:22:02 danielk1977 Exp $
*/
/*
** routines:
*/
int sqlite3pager_open(Pager **ppPager, const char *zFilename,
- int nPage, int nExtra, int useJournal);
+ int nPage, int nExtra, int useJournal,
+ void *pBusyHandler);
void sqlite3pager_set_destructor(Pager*, void(*)(void*,int));
void sqlite3pager_set_cachesize(Pager*, int);
int sqlite3pager_close(Pager *pPager);
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.267 2004/06/02 00:41:09 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.268 2004/06/04 06:22:02 danielk1977 Exp $
*/
#include "config.h"
#include "sqlite3.h"
typedef struct KeyClass KeyClass;
typedef struct CollSeq CollSeq;
typedef struct KeyInfo KeyInfo;
+typedef struct BusyHandler BusyHandler;
/*
#define TEXT_Utf16be 3
#define TEXT_Utf16 (SQLITE_BIGENDIAN?TEXT_Utf16be:TEXT_Utf16le)
+/*
+** An instance of the following structure is used to store the busy-handler
+** callback for a given sqlite handle.
+**
+** The sqlite.busyHandler member of the sqlite struct contains the busy
+** callback for the database handle. Each pager opened via the sqlite
+** handle is passed a pointer to sqlite.busyHandler. The busy-handler
+** callback is currently invoked only from within pager.c.
+*/
+struct BusyHandler {
+ int (*xFunc)(void *,const char*,int); /* The busy callback */
+ void *pArg; /* First arg to busy callback */
+};
+
/*
** Each database is an instance of the following structure.
**
int next_cookie; /* Next value of aDb[0].schema_cookie */
int cache_size; /* Number of pages to use in the cache */
int nTable; /* Number of tables in the database */
- void *pBusyArg; /* 1st Argument to the busy callback */
- int (*xBusyCallback)(void *,const char*,int); /* The busy callback */
+ BusyHandler busyHandler; /* Busy callback */
void *pCommitArg; /* Argument to xCommitCallback() */
int (*xCommitCallback)(void*);/* Invoked at every commit. */
Hash aFunc; /* All functions that can be in SQL exprs */
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
-** $Id: test2.c,v 1.19 2004/05/10 10:34:53 danielk1977 Exp $
+** $Id: test2.c,v 1.20 2004/06/04 06:22:02 danielk1977 Exp $
*/
#include "os.h"
#include "sqliteInt.h"
return TCL_ERROR;
}
if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR;
- rc = sqlite3pager_open(&pPager, argv[1], nPage, 0, 1);
+ rc = sqlite3pager_open(&pPager, argv[1], nPage, 0, 1, 0);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
return TCL_ERROR;
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
-** $Id: test3.c,v 1.42 2004/06/03 16:08:42 danielk1977 Exp $
+** $Id: test3.c,v 1.43 2004/06/04 06:22:02 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
}
if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR;
if( Tcl_GetInt(interp, argv[3], &flags) ) return TCL_ERROR;
- rc = sqlite3BtreeOpen(argv[1], &pBt, nCache, flags);
+ rc = sqlite3BtreeOpen(argv[1], &pBt, nCache, flags, 0);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, errorName(rc), 0);
return TCL_ERROR;
** is used for testing the SQLite routines for converting between
** the various supported unicode encodings.
**
-** $Id: test5.c,v 1.7 2004/06/02 00:41:10 drh Exp $
+** $Id: test5.c,v 1.8 2004/06/04 06:22:02 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h" /* to get SQLITE_BIGENDIAN */
{ "sqlite_utf8to16be", (Tcl_ObjCmdProc*)sqlite_utf8to16be },
{ "sqlite_utf16to16le", (Tcl_ObjCmdProc*)sqlite_utf16to16le },
{ "sqlite_utf16to16be", (Tcl_ObjCmdProc*)sqlite_utf16to16be },
- { "binarize", (Tcl_ObjCmdProc*)binarize }
+ { "binarize", (Tcl_ObjCmdProc*)binarize },
};
int i;
for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
** 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.356 2004/06/03 16:08:42 danielk1977 Exp $
+** $Id: vdbe.c,v 1.357 2004/06/04 06:22:02 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
** If P2 is zero, then a read-lock is obtained on the database file.
*/
case OP_Transaction: {
- int busy = 1;
int i = pOp->p1;
Btree *pBt;
assert( i>=0 && i<db->nDb );
pBt = db->aDb[i].pBt;
- while( pBt && busy ){
+ if( pBt ){
int nMaster = strlen(sqlite3BtreeGetFilename(db->aDb[0].pBt))+11;
- rc = sqlite3BtreeBeginTrans(db->aDb[i].pBt, pOp->p2, nMaster);
- switch( rc ){
- case SQLITE_BUSY: {
- if( db->xBusyCallback==0 ){
+ rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, nMaster);
+ if( rc==SQLITE_BUSY ){
+ if( db->busyHandler.xFunc==0 ){
p->pc = pc;
p->rc = SQLITE_BUSY;
p->pTos = pTos;
return SQLITE_BUSY;
- }else if( (*db->xBusyCallback)(db->pBusyArg, "", busy++)==0 ){
+ }else{
sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
- busy = 0;
}
- break;
- }
- case SQLITE_READONLY: {
- rc = SQLITE_OK;
- /* Fall thru into the next case */
- }
- case SQLITE_OK: {
- busy = 0;
- break;
- }
- default: {
- goto abort_due_to_error;
- }
+ }
+ if( rc!=SQLITE_OK && rc!=SQLITE_READONLY && rc!=SQLITE_BUSY ){
+ goto abort_due_to_error;
}
}
break;
*/
case OP_OpenRead:
case OP_OpenWrite: {
- int busy = 0;
int i = pOp->p1;
int p2 = pOp->p2;
int wrFlag;
sqlite3VdbeCleanupCursor(pCur);
pCur->nullRow = 1;
if( pX==0 ) break;
- do{
- /* We always provide a key comparison function. If the table being
- ** opened is of type INTKEY, the comparision function will be ignored. */
- rc = sqlite3BtreeCursor(pX, p2, wrFlag,
- sqlite3VdbeRecordCompare, pOp->p3,
- &pCur->pCursor);
- pCur->pKeyInfo = (KeyInfo*)pOp->p3;
- if( pCur->pKeyInfo ){
- pCur->pIncrKey = &pCur->pKeyInfo->incrKey;
- pCur->pKeyInfo->enc = p->db->enc;
- }else{
- pCur->pIncrKey = &pCur->bogusIncrKey;
- }
- switch( rc ){
- case SQLITE_BUSY: {
- if( db->xBusyCallback==0 ){
- p->pc = pc;
- p->rc = SQLITE_BUSY;
- p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */
- return SQLITE_BUSY;
- }else if( (*db->xBusyCallback)(db->pBusyArg, pOp->p3, ++busy)==0 ){
- sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
- busy = 0;
- }
- break;
- }
- case SQLITE_OK: {
- int flags = sqlite3BtreeFlags(pCur->pCursor);
- pCur->intKey = (flags & BTREE_INTKEY)!=0;
- pCur->zeroData = (flags & BTREE_ZERODATA)!=0;
- busy = 0;
- break;
- }
- case SQLITE_EMPTY: {
- rc = SQLITE_OK;
- busy = 0;
- break;
- }
- default: {
- goto abort_due_to_error;
+ /* We always provide a key comparison function. If the table being
+ ** opened is of type INTKEY, the comparision function will be ignored. */
+ rc = sqlite3BtreeCursor(pX, p2, wrFlag,
+ sqlite3VdbeRecordCompare, pOp->p3,
+ &pCur->pCursor);
+ pCur->pKeyInfo = (KeyInfo*)pOp->p3;
+ if( pCur->pKeyInfo ){
+ pCur->pIncrKey = &pCur->pKeyInfo->incrKey;
+ pCur->pKeyInfo->enc = p->db->enc;
+ }else{
+ pCur->pIncrKey = &pCur->bogusIncrKey;
+ }
+ switch( rc ){
+ case SQLITE_BUSY: {
+ if( db->busyHandler.xFunc ){
+ p->pc = pc;
+ p->rc = SQLITE_BUSY;
+ p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */
+ return SQLITE_BUSY;
+ }else{
+ sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
}
+ break;
}
- }while( busy );
+ case SQLITE_OK: {
+ int flags = sqlite3BtreeFlags(pCur->pCursor);
+ pCur->intKey = (flags & BTREE_INTKEY)!=0;
+ pCur->zeroData = (flags & BTREE_ZERODATA)!=0;
+ break;
+ }
+ case SQLITE_EMPTY: {
+ rc = SQLITE_OK;
+ break;
+ }
+ default: {
+ goto abort_due_to_error;
+ }
+ }
break;
}