mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Do not call the xDisconnect method on a virtual table while xUpdate is
pending. Instead, defer the xDisconnect until after xUpdate completes. (CVS 3387) FossilOrigin-Name: 61148f4c36255c4ed3552f888fa75252b300589d
This commit is contained in:
37
src/vtab.c
37
src/vtab.c
@@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** This file contains code used to help implement virtual tables.
|
||||
**
|
||||
** $Id: vtab.c,v 1.30 2006/09/02 14:17:00 drh Exp $
|
||||
** $Id: vtab.c,v 1.31 2006/09/02 20:57:52 drh Exp $
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
#include "sqliteInt.h"
|
||||
@@ -40,6 +40,29 @@ int sqlite3_create_module(
|
||||
return sqlite3ApiExit(db, SQLITE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
** Lock the virtual table so that it cannot be disconnected.
|
||||
** Locks nest. Every lock should have a corresponding unlock.
|
||||
** If an unlock is omitted, resources leaks will occur.
|
||||
**
|
||||
** If a disconnect is attempted while a virtual table is locked,
|
||||
** the disconnect is deferred until all locks have been removed.
|
||||
*/
|
||||
void sqlite3VtabLock(sqlite3_vtab *pVtab){
|
||||
pVtab->nRef++;
|
||||
}
|
||||
|
||||
/*
|
||||
** Unlock a virtual table. When the last lock is removed,
|
||||
** disconnect the virtual table.
|
||||
*/
|
||||
void sqlite3VtabUnlock(sqlite3_vtab *pVtab){
|
||||
pVtab->nRef--;
|
||||
if( pVtab->nRef==0 ){
|
||||
pVtab->pModule->xDisconnect(pVtab);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Clear any and all virtual-table information from the Table record.
|
||||
** This routine is called, for example, just before deleting the Table
|
||||
@@ -49,10 +72,7 @@ void sqlite3VtabClear(Table *p){
|
||||
sqlite3_vtab *pVtab = p->pVtab;
|
||||
if( pVtab ){
|
||||
assert( p->pMod && p->pMod->pModule );
|
||||
pVtab->nRef--;
|
||||
if( pVtab->nRef==0 ){
|
||||
pVtab->pModule->xDisconnect(pVtab);
|
||||
}
|
||||
sqlite3VtabUnlock(pVtab);
|
||||
p->pVtab = 0;
|
||||
}
|
||||
if( p->azModuleArg ){
|
||||
@@ -359,7 +379,7 @@ static int addToVTrans(sqlite3 *db, sqlite3_vtab *pVtab){
|
||||
|
||||
/* Add pVtab to the end of sqlite3.aVTrans */
|
||||
db->aVTrans[db->nVTrans++] = pVtab;
|
||||
pVtab->nRef++;
|
||||
sqlite3VtabLock(pVtab);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -492,10 +512,7 @@ static void callFinaliser(sqlite3 *db, int offset){
|
||||
int (*x)(sqlite3_vtab *);
|
||||
x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset);
|
||||
if( x ) x(pVtab);
|
||||
pVtab->nRef--;
|
||||
if( pVtab->nRef==0 ){
|
||||
pVtab->pModule->xDisconnect(pVtab);
|
||||
}
|
||||
sqlite3VtabUnlock(pVtab);
|
||||
}
|
||||
sqliteFree(db->aVTrans);
|
||||
db->nVTrans = 0;
|
||||
|
Reference in New Issue
Block a user