1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Bug fix: sqlite_exec() would sometimes return SQLITE_PROTOCOL when it

should have returned SQLITE_BUSY.  There was also a deadlock that the
previous bug was masking. (CVS 322)

FossilOrigin-Name: 585ed5ebf1c1afc8ae1d569b121208018d8ecd49
This commit is contained in:
drh
2001-12-05 00:21:20 +00:00
parent 6ff13859d5
commit b8ca307e7b
10 changed files with 101 additions and 61 deletions

View File

@@ -9,7 +9,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.41 2001/11/23 00:24:12 drh Exp $
** $Id: btree.c,v 1.42 2001/12/05 00:21:20 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
@@ -676,6 +676,24 @@ page1_init_failed:
return rc;
}
/*
** If there are no outstanding cursors and we are not in the middle
** of a transaction but there is a read lock on the database, then
** this routine unrefs the first page of the database file which
** has the effect of releasing the read lock.
**
** If there are any outstanding cursors, this routine is a no-op.
**
** If there is a transaction in progress, this routine is a no-op.
*/
static void unlockBtreeIfUnused(Btree *pBt){
if( pBt->inTrans==0 && pBt->pCursor==0 && pBt->page1!=0 ){
sqlitepager_unref(pBt->page1);
pBt->page1 = 0;
pBt->inTrans = 0;
}
}
/*
** Create a new database by initializing the first two pages of the
** file.
@@ -725,33 +743,19 @@ int sqliteBtreeBeginTrans(Btree *pBt){
return rc;
}
}
if( !sqlitepager_isreadonly(pBt->pPager) ){
rc = sqlitepager_write(pBt->page1);
if( rc!=SQLITE_OK ){
return rc;
}
if( sqlitepager_isreadonly(pBt->pPager) ){
return SQLITE_READONLY;
}
rc = sqlitepager_write(pBt->page1);
if( rc==SQLITE_OK ){
rc = newDatabase(pBt);
}
pBt->inTrans = 1;
return rc;
}
/*
** If there are no outstanding cursors and we are not in the middle
** of a transaction but there is a read lock on the database, then
** this routine unrefs the first page of the database file which
** has the effect of releasing the read lock.
**
** If there are any outstanding cursors, this routine is a no-op.
**
** If there is a transaction in progress, this routine is a no-op.
*/
static void unlockBtreeIfUnused(Btree *pBt){
if( pBt->inTrans==0 && pBt->pCursor==0 && pBt->page1!=0 ){
sqlitepager_unref(pBt->page1);
pBt->page1 = 0;
pBt->inTrans = 0;
if( rc==SQLITE_OK ){
pBt->inTrans = 1;
}else{
unlockBtreeIfUnused(pBt);
}
return rc;
}
/*

View File

@@ -25,7 +25,7 @@
** ROLLBACK
** PRAGMA
**
** $Id: build.c,v 1.57 2001/11/22 00:01:27 drh Exp $
** $Id: build.c,v 1.58 2001/12/05 00:21:20 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -553,7 +553,7 @@ void sqliteAddDefaultValue(Parse *pParse, Token *pVal, int minusFlag){
*/
static void changeCookie(sqlite *db){
if( db->next_cookie==db->schema_cookie ){
db->next_cookie = db->schema_cookie + sqliteRandomByte(db) + 1;
db->next_cookie = db->schema_cookie + sqliteRandomByte() + 1;
db->flags |= SQLITE_InternChanges;
}
}

View File

@@ -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.50 2001/11/23 00:24:12 drh Exp $
** $Id: main.c,v 1.51 2001/12/05 00:21:20 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -265,7 +265,7 @@ sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){
if( db==0 ) goto no_mem_on_open;
sqliteHashInit(&db->tblHash, SQLITE_HASH_STRING, 0);
sqliteHashInit(&db->idxHash, SQLITE_HASH_STRING, 0);
db->nextRowid = sqliteRandomInteger(db);
db->nextRowid = sqliteRandomInteger();
/* Open the backend database driver */
rc = sqliteBtreeOpen(zFilename, mode, MAX_PAGES, &db->pBe);

View File

@@ -59,8 +59,8 @@ int sqliteOsLock(OsFile, int wrlock);
int sqliteOsUnlock(OsFile);
int sqliteOsRandomSeed(char*);
int sqliteOsSleep(int ms);
void sqliteOsEnterMutex();
void sqliteOsLeaveMutex();
void sqliteOsEnterMutex(void);
void sqliteOsLeaveMutex(void);

View File

@@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.31 2001/11/22 00:01:27 drh Exp $
** @(#) $Id: pager.c,v 1.32 2001/12/05 00:21:20 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
@@ -955,13 +955,20 @@ int sqlitepager_write(void *pData){
}
sqliteOsUnlock(pPager->fd);
if( sqliteOsLock(pPager->fd, 1)!=SQLITE_OK ){
sqliteOsUnlock(pPager->fd);
rc = sqliteOsLock(pPager->fd, 0);
sqliteFree(pPager->aInJournal);
sqliteOsClose(pPager->jfd);
sqliteOsDelete(pPager->zJournal);
pPager->journalOpen = 0;
pPager->state = SQLITE_UNLOCK;
pPager->errMask |= PAGER_ERR_LOCK;
return SQLITE_PROTOCOL;
if( rc ){
pPager->state = SQLITE_UNLOCK;
pPager->errMask |= PAGER_ERR_LOCK;
return SQLITE_PROTOCOL;
}else{
pPager->state = SQLITE_READLOCK;
return SQLITE_BUSY;
}
}
pPager->state = SQLITE_WRITELOCK;
sqlitepager_pagecount(pPager);

View File

@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.71 2001/11/22 00:01:27 drh Exp $
** @(#) $Id: sqliteInt.h,v 1.72 2001/12/05 00:21:20 drh Exp $
*/
#include "sqlite.h"
#include "hash.h"
@@ -519,8 +519,8 @@ void sqliteExprResolveInSelect(Parse*, Expr*);
int sqliteExprAnalyzeAggregates(Parse*, Expr*);
void sqliteParseInfoReset(Parse*);
Vdbe *sqliteGetVdbe(Parse*);
int sqliteRandomByte();
int sqliteRandomInteger();
int sqliteRandomByte(void);
int sqliteRandomInteger(void);
void sqliteBeginTransaction(Parse*);
void sqliteCommitTransaction(Parse*);
void sqliteRollbackTransaction(Parse*);