mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Added test code to check for file descriptor leaks. All regression tests pass
now on both win2k and linux. (CVS 868) FossilOrigin-Name: 75ba78280f7ab6b6acce5878859312f3223ee898
This commit is contained in:
@ -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.113 2003/02/12 14:09:44 drh Exp $
|
||||
** $Id: main.c,v 1.114 2003/02/16 22:21:32 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@ -457,7 +457,11 @@ int sqlite_changes(sqlite *db){
|
||||
*/
|
||||
void sqlite_close(sqlite *db){
|
||||
HashElem *i;
|
||||
if( sqliteSafetyCheck(db) || sqliteSafetyOn(db) ){ return; }
|
||||
db->want_to_close = 1;
|
||||
if( sqliteSafetyCheck(db) || sqliteSafetyOn(db) ){
|
||||
/* printf("DID NOT CLOSE\n"); fflush(stdout); */
|
||||
return;
|
||||
}
|
||||
db->magic = SQLITE_MAGIC_CLOSED;
|
||||
sqliteBtreeClose(db->pBe);
|
||||
sqliteResetInternalSchema(db);
|
||||
|
23
src/os.c
23
src/os.c
@ -225,6 +225,16 @@ static void local_ioerr(){
|
||||
#define SimulateIOError(A)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** When testing, keep a count of the number of open files.
|
||||
*/
|
||||
#ifdef SQLITE_TEST
|
||||
int sqlite_open_file_count = 0;
|
||||
#define OpenCounter(X) sqlite_open_file_count+=(X)
|
||||
#else
|
||||
#define OpenCounter(X)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** Delete the named file
|
||||
@ -296,6 +306,7 @@ int sqliteOsOpenReadWrite(
|
||||
}
|
||||
id->locked = 0;
|
||||
TRACE3("OPEN %-3d %s\n", id->fd, zFilename);
|
||||
OpenCounter(+1);
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
#if OS_WIN
|
||||
@ -325,6 +336,7 @@ int sqliteOsOpenReadWrite(
|
||||
}
|
||||
id->h = h;
|
||||
id->locked = 0;
|
||||
OpenCounter(+1);
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
#if OS_MAC
|
||||
@ -374,6 +386,7 @@ int sqliteOsOpenReadWrite(
|
||||
}
|
||||
id->locked = 0;
|
||||
id->delOnClose = 0;
|
||||
OpenCounter(+1);
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
}
|
||||
@ -415,6 +428,7 @@ int sqliteOsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
|
||||
unlink(zFilename);
|
||||
}
|
||||
TRACE3("OPEN-EX %-3d %s\n", id->fd, zFilename);
|
||||
OpenCounter(+1);
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
#if OS_WIN
|
||||
@ -439,6 +453,7 @@ int sqliteOsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
|
||||
}
|
||||
id->h = h;
|
||||
id->locked = 0;
|
||||
OpenCounter(+1);
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
#if OS_MAC
|
||||
@ -467,6 +482,7 @@ int sqliteOsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
|
||||
id->delOnClose = delFlag;
|
||||
if (delFlag)
|
||||
id->pathToDel = sqliteOsFullPathname(zFilename);
|
||||
OpenCounter(+1);
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
}
|
||||
@ -493,6 +509,7 @@ int sqliteOsOpenReadOnly(const char *zFilename, OsFile *id){
|
||||
}
|
||||
id->locked = 0;
|
||||
TRACE3("OPEN-RO %-3d %s\n", id->fd, zFilename);
|
||||
OpenCounter(+1);
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
#if OS_WIN
|
||||
@ -509,6 +526,7 @@ int sqliteOsOpenReadOnly(const char *zFilename, OsFile *id){
|
||||
}
|
||||
id->h = h;
|
||||
id->locked = 0;
|
||||
OpenCounter(+1);
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
#if OS_MAC
|
||||
@ -534,6 +552,7 @@ int sqliteOsOpenReadOnly(const char *zFilename, OsFile *id){
|
||||
}
|
||||
id->locked = 0;
|
||||
id->delOnClose = 0;
|
||||
OpenCounter(+1);
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
}
|
||||
@ -651,10 +670,12 @@ int sqliteOsClose(OsFile *id){
|
||||
releaseLockInfo(id->pLock);
|
||||
sqliteOsLeaveMutex();
|
||||
TRACE2("CLOSE %-3d\n", id->fd);
|
||||
OpenCounter(-1);
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
#if OS_WIN
|
||||
CloseHandle(id->h);
|
||||
OpenCounter(-1);
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
#if OS_MAC
|
||||
@ -669,6 +690,8 @@ int sqliteOsClose(OsFile *id){
|
||||
unlink(id->pathToDel);
|
||||
sqliteFree(id->pathToDel);
|
||||
}
|
||||
OpenCounter(-1);
|
||||
return SQLITE_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.161 2003/02/12 14:09:44 drh Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.162 2003/02/16 22:21:32 drh Exp $
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "sqlite.h"
|
||||
@ -209,6 +209,7 @@ struct sqlite {
|
||||
int flags; /* Miscellanous flags. See below */
|
||||
u8 file_format; /* What file format version is this database? */
|
||||
u8 safety_level; /* How aggressive at synching data to disk */
|
||||
u8 want_to_close; /* Close after all VDBEs are deallocated */
|
||||
int schema_cookie; /* Magic number that changes with the schema */
|
||||
int next_cookie; /* Value of schema_cookie after commit */
|
||||
int cache_size; /* Number of pages to use in the cache */
|
||||
|
20
src/test1.c
20
src/test1.c
@ -13,18 +13,25 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** testing of the SQLite library.
|
||||
**
|
||||
** $Id: test1.c,v 1.21 2003/02/16 19:13:37 drh Exp $
|
||||
** $Id: test1.c,v 1.22 2003/02/16 22:21:32 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
#include "os.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if OS_WIN
|
||||
# define PTR_FMT "%x"
|
||||
#else
|
||||
# define PTR_FMT "%p"
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Decode a pointer to an sqlite object.
|
||||
*/
|
||||
static int getDbPointer(Tcl_Interp *interp, const char *zArg, sqlite **ppDb){
|
||||
if( sscanf(zArg, "%p", (void**)ppDb)!=1 ){
|
||||
if( sscanf(zArg, PTR_FMT, (void**)ppDb)!=1 ){
|
||||
Tcl_AppendResult(interp, "\"", zArg, "\" is not a valid pointer value", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@ -35,7 +42,7 @@ static int getDbPointer(Tcl_Interp *interp, const char *zArg, sqlite **ppDb){
|
||||
** Decode a pointer to an sqlite_vm object.
|
||||
*/
|
||||
static int getVmPointer(Tcl_Interp *interp, const char *zArg, sqlite_vm **ppVm){
|
||||
if( sscanf(zArg, "%p", (void**)ppVm)!=1 ){
|
||||
if( sscanf(zArg, PTR_FMT, (void**)ppVm)!=1 ){
|
||||
Tcl_AppendResult(interp, "\"", zArg, "\" is not a valid pointer value", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@ -67,7 +74,7 @@ static int sqlite_test_open(
|
||||
free(zErr);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
sprintf(zBuf,"%p", db);
|
||||
sprintf(zBuf,PTR_FMT, db);
|
||||
Tcl_AppendResult(interp, zBuf, 0);
|
||||
return TCL_OK;
|
||||
}
|
||||
@ -735,7 +742,7 @@ static int test_compile(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( vm ){
|
||||
sprintf(zBuf, "%p", vm);
|
||||
sprintf(zBuf, PTR_FMT, vm);
|
||||
Tcl_AppendResult(interp, zBuf, 0);
|
||||
}
|
||||
return TCL_OK;
|
||||
@ -853,6 +860,7 @@ static int test_breakpoint(
|
||||
*/
|
||||
int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
extern int sqlite_search_count;
|
||||
extern int sqlite_open_file_count;
|
||||
static struct {
|
||||
char *zName;
|
||||
Tcl_CmdProc *xProc;
|
||||
@ -889,5 +897,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
}
|
||||
Tcl_LinkVar(interp, "sqlite_search_count",
|
||||
(char*)&sqlite_search_count, TCL_LINK_INT);
|
||||
Tcl_LinkVar(interp, "sqlite_open_file_count",
|
||||
(char*)&sqlite_open_file_count, TCL_LINK_INT);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
** This file contains functions for allocating memory, comparing
|
||||
** strings, and stuff like that.
|
||||
**
|
||||
** $Id: util.c,v 1.57 2003/01/29 14:06:09 drh Exp $
|
||||
** $Id: util.c,v 1.58 2003/02/16 22:21:32 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <stdarg.h>
|
||||
@ -1163,7 +1163,8 @@ int sqliteSafetyOn(sqlite *db){
|
||||
if( db->magic==SQLITE_MAGIC_OPEN ){
|
||||
db->magic = SQLITE_MAGIC_BUSY;
|
||||
return 0;
|
||||
}else if( db->magic==SQLITE_MAGIC_BUSY || db->magic==SQLITE_MAGIC_ERROR ){
|
||||
}else if( db->magic==SQLITE_MAGIC_BUSY || db->magic==SQLITE_MAGIC_ERROR
|
||||
|| db->want_to_close ){
|
||||
db->magic = SQLITE_MAGIC_ERROR;
|
||||
db->flags |= SQLITE_Interrupt;
|
||||
}
|
||||
@ -1179,7 +1180,8 @@ int sqliteSafetyOff(sqlite *db){
|
||||
if( db->magic==SQLITE_MAGIC_BUSY ){
|
||||
db->magic = SQLITE_MAGIC_OPEN;
|
||||
return 0;
|
||||
}else if( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ERROR ){
|
||||
}else if( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ERROR
|
||||
|| db->want_to_close ){
|
||||
db->magic = SQLITE_MAGIC_ERROR;
|
||||
db->flags |= SQLITE_Interrupt;
|
||||
}
|
||||
|
@ -36,7 +36,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.203 2003/01/29 22:58:26 drh Exp $
|
||||
** $Id: vdbe.c,v 1.204 2003/02/16 22:21:32 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -5741,5 +5741,8 @@ int sqliteVdbeFinalize(Vdbe *p, char **pzErrMsg){
|
||||
#endif
|
||||
rc = p->rc;
|
||||
sqliteVdbeDelete(p);
|
||||
if( db->want_to_close && db->pVdbe==0 ){
|
||||
sqlite_close(db);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
Reference in New Issue
Block a user