Added test code to check for file descriptor leaks. All regression tests pass
now on both win2k and linux. (CVS 868)
FossilOrigin-Name: 75ba78280f7ab6b6acce5878859312f3223ee898
diff --git a/src/main.c b/src/main.c
index c17c2f1..8fa81d8 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.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 @@
*/
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);
diff --git a/src/os.c b/src/os.c
index a071679..d0b50dc 100644
--- a/src/os.c
+++ b/src/os.c
@@ -225,6 +225,16 @@
#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 @@
}
id->locked = 0;
TRACE3("OPEN %-3d %s\n", id->fd, zFilename);
+ OpenCounter(+1);
return SQLITE_OK;
#endif
#if OS_WIN
@@ -325,6 +336,7 @@
}
id->h = h;
id->locked = 0;
+ OpenCounter(+1);
return SQLITE_OK;
#endif
#if OS_MAC
@@ -374,6 +386,7 @@
}
id->locked = 0;
id->delOnClose = 0;
+ OpenCounter(+1);
return SQLITE_OK;
#endif
}
@@ -415,6 +428,7 @@
unlink(zFilename);
}
TRACE3("OPEN-EX %-3d %s\n", id->fd, zFilename);
+ OpenCounter(+1);
return SQLITE_OK;
#endif
#if OS_WIN
@@ -439,6 +453,7 @@
}
id->h = h;
id->locked = 0;
+ OpenCounter(+1);
return SQLITE_OK;
#endif
#if OS_MAC
@@ -467,6 +482,7 @@
id->delOnClose = delFlag;
if (delFlag)
id->pathToDel = sqliteOsFullPathname(zFilename);
+ OpenCounter(+1);
return SQLITE_OK;
#endif
}
@@ -493,6 +509,7 @@
}
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 @@
}
id->h = h;
id->locked = 0;
+ OpenCounter(+1);
return SQLITE_OK;
#endif
#if OS_MAC
@@ -534,6 +552,7 @@
}
id->locked = 0;
id->delOnClose = 0;
+ OpenCounter(+1);
return SQLITE_OK;
#endif
}
@@ -651,10 +670,12 @@
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 @@
unlink(id->pathToDel);
sqliteFree(id->pathToDel);
}
+ OpenCounter(-1);
+ return SQLITE_OK;
#endif
}
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index e434543..e8f1682 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -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 @@
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 */
diff --git a/src/test1.c b/src/test1.c
index 232259f..402b2c2 100644
--- a/src/test1.c
+++ b/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 @@
** 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 @@
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 @@
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 @@
*/
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 @@
}
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;
}
diff --git a/src/util.c b/src/util.c
index 26e7afc..8231e98 100644
--- a/src/util.c
+++ b/src/util.c
@@ -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 @@
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 @@
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;
}
diff --git a/src/vdbe.c b/src/vdbe.c
index 67c7fdb..07819c1 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -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 @@
#endif
rc = p->rc;
sqliteVdbeDelete(p);
+ if( db->want_to_close && db->pVdbe==0 ){
+ sqlite_close(db);
+ }
return rc;
}