From 24162fe668d3b1592a151c36bb7f4d1e69a19bf2 Mon Sep 17 00:00:00 2001 From: danielk1977 Date: Fri, 4 Jun 2004 06:22:00 +0000 Subject: [PATCH] Move the 'busy-callback' logic to the pager layer. (CVS 1527) FossilOrigin-Name: ff70b6d2b60c143e3ada0606ceff97571998c7e3 --- manifest | 30 ++++++------- manifest.uuid | 2 +- src/btree.c | 7 ++-- src/btree.h | 10 ++++- src/main.c | 13 +++--- src/pager.c | 43 +++++++++++++++---- src/pager.h | 5 ++- src/sqliteInt.h | 20 +++++++-- src/test2.c | 4 +- src/test3.c | 4 +- src/test5.c | 4 +- src/vdbe.c | 109 ++++++++++++++++++++---------------------------- 12 files changed, 140 insertions(+), 111 deletions(-) diff --git a/manifest b/manifest index e4b12f275e..bb4ad21f51 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 @@ -25,8 +25,8 @@ F sqlite.def fc4f5734786fe4743cfe2aa98eb2da4b089edb5f 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 @@ -37,7 +37,7 @@ F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f 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 @@ -47,8 +47,8 @@ F src/os_unix.c 3175540f8d1c820dab7a470c50875c221c3a98cd 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 @@ -56,21 +56,21 @@ F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 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 @@ -214,7 +214,7 @@ F www/support.tcl 1801397edd271cc39a2aadd54e701184b5181248 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 diff --git a/manifest.uuid b/manifest.uuid index 91ad00296f..2108920713 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d57e5252c8baaf615c2cd218a33356ea5d95a5e2 \ No newline at end of file +ff70b6d2b60c143e3ada0606ceff97571998c7e3 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 07ebaa9d57..c112b55921 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.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 @@ -977,7 +977,8 @@ int sqlite3BtreeOpen( 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; @@ -1002,7 +1003,7 @@ int sqlite3BtreeOpen( } 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); diff --git a/src/btree.h b/src/btree.h index 472fd90529..48ba97e0df 100644 --- a/src/btree.h +++ b/src/btree.h @@ -13,7 +13,7 @@ ** 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_ @@ -30,7 +30,13 @@ typedef struct Btree Btree; 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. diff --git a/src/main.c b/src/main.c index 57d6b0170e..ce93f2eff2 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.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" @@ -570,8 +570,8 @@ void sqlite3_busy_handler( 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 @@ -762,7 +762,8 @@ int sqlite3BtreeFactory( btree_flags |= BTREE_MEMORY; } - return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags); + return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags, + &db->busyHandler); } /* @@ -847,9 +848,7 @@ int sqlite3_prepare( 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; } diff --git a/src/pager.c b/src/pager.c index 7068df7861..1f95e72e6a 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.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" @@ -213,6 +213,7 @@ struct Pager { 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 */ }; /* @@ -1080,7 +1081,8 @@ int sqlite3pager_open( 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; @@ -1161,6 +1163,7 @@ int sqlite3pager_open( 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; @@ -1603,9 +1606,21 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ ** 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; @@ -2004,9 +2019,21 @@ int sqlite3pager_begin(void *pData, int nMaster){ 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; diff --git a/src/pager.h b/src/pager.h index 132989d76b..5ae27167e9 100644 --- a/src/pager.h +++ b/src/pager.h @@ -13,7 +13,7 @@ ** 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 $ */ /* @@ -70,7 +70,8 @@ typedef struct Pager Pager; ** 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); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d00210c583..aa95275db5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** 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" @@ -264,6 +264,7 @@ typedef struct AuthContext AuthContext; typedef struct KeyClass KeyClass; typedef struct CollSeq CollSeq; typedef struct KeyInfo KeyInfo; +typedef struct BusyHandler BusyHandler; /* @@ -326,6 +327,20 @@ struct Db { #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. ** @@ -369,8 +384,7 @@ struct sqlite { 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 */ diff --git a/src/test2.c b/src/test2.c index 72b68c56b8..177043f025 100644 --- a/src/test2.c +++ b/src/test2.c @@ -13,7 +13,7 @@ ** 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" @@ -76,7 +76,7 @@ static int pager_open( 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; diff --git a/src/test3.c b/src/test3.c index a5e5f92a23..2c2ab86b2d 100644 --- a/src/test3.c +++ b/src/test3.c @@ -13,7 +13,7 @@ ** 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" @@ -70,7 +70,7 @@ static int btree_open( } 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; diff --git a/src/test5.c b/src/test5.c index f288d3052b..ff3fa6f553 100644 --- a/src/test5.c +++ b/src/test5.c @@ -15,7 +15,7 @@ ** 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 */ @@ -248,7 +248,7 @@ int Sqlitetest5_Init(Tcl_Interp *interp){ { "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; ip1; Btree *pBt; assert( i>=0 && inDb ); 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; @@ -2445,7 +2432,6 @@ case OP_VerifyCookie: { */ case OP_OpenRead: case OP_OpenWrite: { - int busy = 0; int i = pOp->p1; int p2 = pOp->p2; int wrFlag; @@ -2478,49 +2464,44 @@ case OP_OpenWrite: { 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; + /* 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; } - 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; - } + case SQLITE_OK: { + int flags = sqlite3BtreeFlags(pCur->pCursor); + pCur->intKey = (flags & BTREE_INTKEY)!=0; + pCur->zeroData = (flags & BTREE_ZERODATA)!=0; + break; } - }while( busy ); + case SQLITE_EMPTY: { + rc = SQLITE_OK; + break; + } + default: { + goto abort_due_to_error; + } + } break; }