diff options
author | dan <dan@noemail.net> | 2009-09-09 18:46:52 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2009-09-09 18:46:52 +0000 |
commit | 11b3879b18d48d6a06f71fcbef0edca17ca31268 (patch) | |
tree | 93889995b770505e295c95068bb890f0b190b999 /src | |
parent | 3f022189dd7baca7c89c62f9c154067da2c389c0 (diff) | |
download | sqlite-11b3879b18d48d6a06f71fcbef0edca17ca31268.tar.gz sqlite-11b3879b18d48d6a06f71fcbef0edca17ca31268.zip |
Trying to open a transaction in one thread and close it in another is a misuse with LinuxThreads. Doing so may cause memory and file-descriptors to be leaked. Update an assert() and some test cases to account for this.
FossilOrigin-Name: ef99eb57c536d82e7c19fd3d990c17793cc64a3f
Diffstat (limited to 'src')
-rw-r--r-- | src/os_unix.c | 10 | ||||
-rw-r--r-- | src/test4.c | 31 |
2 files changed, 40 insertions, 1 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index 9b6afe537..a45aaa1d7 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -925,7 +925,15 @@ static void releaseOpenCnt(struct unixOpenCnt *pOpen){ assert( pOpen->pNext->pPrev==pOpen ); pOpen->pNext->pPrev = pOpen->pPrev; } - assert( !pOpen->pUnused ); + assert( !pOpen->pUnused || threadsOverrideEachOthersLocks==0 ); + + /* If pOpen->pUnused is not null, then memory and file-descriptors + ** are leaked. + ** + ** This will only happen if, under Linuxthreads, the user has opened + ** a transaction in one thread, then attempts to close the database + ** handle from another thread (without first unlocking the db file). + ** This is a misuse. */ sqlite3_free(pOpen); } } diff --git a/src/test4.c b/src/test4.c index c51d2a640..654b572db 100644 --- a/src/test4.c +++ b/src/test4.c @@ -651,6 +651,36 @@ static int tcl_thread_db_get( } /* +** Usage: thread_db_put ID DB +** +*/ +static int tcl_thread_db_put( + void *NotUsed, + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int argc, /* Number of arguments */ + const char **argv /* Text of each argument */ +){ + int i; + extern int sqlite3TestMakePointerStr(Tcl_Interp*, char*, void*); + extern void *sqlite3TestTextToPtr(const char *); + if( argc!=3 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " ID DB", 0); + return TCL_ERROR; + } + i = parse_thread_id(interp, argv[1]); + if( i<0 ) return TCL_ERROR; + if( !threadset[i].busy ){ + Tcl_AppendResult(interp, "no such thread", 0); + return TCL_ERROR; + } + thread_wait(&threadset[i]); + assert( !threadset[i].db ); + threadset[i].db = (sqlite3*)sqlite3TestTextToPtr(argv[2]); + return TCL_OK; +} + +/* ** Usage: thread_stmt_get ID ** ** Return the database stmt pointer for the given thread. Then @@ -704,6 +734,7 @@ int Sqlitetest4_Init(Tcl_Interp *interp){ { "thread_finalize", (Tcl_CmdProc*)tcl_thread_finalize }, { "thread_swap", (Tcl_CmdProc*)tcl_thread_swap }, { "thread_db_get", (Tcl_CmdProc*)tcl_thread_db_get }, + { "thread_db_put", (Tcl_CmdProc*)tcl_thread_db_put }, { "thread_stmt_get", (Tcl_CmdProc*)tcl_thread_stmt_get }, }; int i; |