Move the 'busy-callback' logic to the pager layer. (CVS 1527)
FossilOrigin-Name: ff70b6d2b60c143e3ada0606ceff97571998c7e3
This commit is contained in:
parent
13adf8a071
commit
24162fe668
30
manifest
30
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
|
||||
|
@ -1 +1 @@
|
||||
d57e5252c8baaf615c2cd218a33356ea5d95a5e2
|
||||
ff70b6d2b60c143e3ada0606ceff97571998c7e3
|
@ -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);
|
||||
|
10
src/btree.h
10
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.
|
||||
|
13
src/main.c
13
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;
|
||||
}
|
||||
|
31
src/pager.c
31
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,10 +1606,22 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
|
||||
** on the database file.
|
||||
*/
|
||||
if( pPager->nRef==0 && !pPager->memDb ){
|
||||
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;
|
||||
|
||||
/* If a journal file exists, and there is no RESERVED lock on the
|
||||
@ -2004,10 +2019,22 @@ int sqlite3pager_begin(void *pData, int nMaster){
|
||||
pPager->state = SQLITE_WRITELOCK;
|
||||
pPager->origDbSize = pPager->dbSize;
|
||||
}else{
|
||||
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;
|
||||
pPager->dirtyFile = 0;
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
|
||||
|
37
src/vdbe.c
37
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.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"
|
||||
@ -2281,42 +2281,29 @@ case OP_AutoCommit: {
|
||||
** 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: {
|
||||
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,7 +2464,6 @@ 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,
|
||||
@ -2493,14 +2478,13 @@ case OP_OpenWrite: {
|
||||
}
|
||||
switch( rc ){
|
||||
case SQLITE_BUSY: {
|
||||
if( db->xBusyCallback==0 ){
|
||||
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 if( (*db->xBusyCallback)(db->pBusyArg, pOp->p3, ++busy)==0 ){
|
||||
}else{
|
||||
sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
|
||||
busy = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2508,19 +2492,16 @@ case OP_OpenWrite: {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}while( busy );
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user