Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Testing of the automatic TSD deallocation logic. The sqlite3_thread_cleanup() API is documented. This should close ticket #1601. (CVS 2920) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
fb518b0ce4ddd4aaca5cccf61e651f17 |
User & Date: | drh 2006-01-11 23:40:33.000 |
Context
2006-01-12
| ||
01:25 | Improve performance by about 10% by avoiding excess calls to get the thread-specific data. (CVS 2921) (check-in: a8c74febec user: drh tags: trunk) | |
2006-01-11
| ||
23:40 | Testing of the automatic TSD deallocation logic. The sqlite3_thread_cleanup() API is documented. This should close ticket #1601. (CVS 2920) (check-in: fb518b0ce4 user: drh tags: trunk) | |
21:41 | Automatically deallocate thread-specific data when it is no longer being used. Ticket #1601. Also implemented the suggestion of ticket #1603. Memory management is now off by default at compile-time. The sqlite3_enable_memory_management() API has been removed. (CVS 2919) (check-in: 5d9c6aa964 user: drh tags: trunk) | |
Changes
Changes to src/os_unix.c.
︙ | ︙ | |||
1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 | /* ** Return TRUE if we are currently within the mutex and FALSE if not. */ int sqlite3UnixInMutex(){ return inMutex; } /* ** If called with allocateFlag==1, then return a pointer to thread ** specific data for the current thread. Allocate and zero the ** thread-specific data if it does not already exist necessary. ** ** If called with allocateFlag==0, then check the current thread | > > > > > > > > > > > > > > > > > > > > > | 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 | /* ** Return TRUE if we are currently within the mutex and FALSE if not. */ int sqlite3UnixInMutex(){ return inMutex; } /* ** Remember the number of thread-specific-data blocks allocated. ** Use this to verify that we are not leaking thread-specific-data. ** Ticket #1601 */ #ifdef SQLITE_TEST int sqlite3_tsd_count = 0; # ifdef SQLITE_UNIX_THREADS static pthread_mutex_t tsd_counter_mutex = PTHREAD_MUTEX_INITIALIZER; # define TSD_COUNTER(N) \ pthread_mutex_lock(&tsd_counter_mutex); \ sqlite3_tsd_count += N; \ pthread_mutex_unlock(&tsd_counter_mutex); # else # define TSD_COUNTER(N) sqlite3_tsd_count += N # endif #else # define TSD_COUNTER(N) /* no-op */ #endif /* ** If called with allocateFlag==1, then return a pointer to thread ** specific data for the current thread. Allocate and zero the ** thread-specific data if it does not already exist necessary. ** ** If called with allocateFlag==0, then check the current thread |
︙ | ︙ | |||
1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 | pTsd = pthread_getspecific(key); if( allocateFlag ){ if( pTsd==0 ){ pTsd = sqlite3OsMalloc(sizeof(zeroData)); if( pTsd ){ *pTsd = zeroData; pthread_setspecific(key, pTsd); } } }else if( pTsd!=0 && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){ sqlite3OsFree(pTsd); pthread_setspecific(key, 0); pTsd = 0; } return pTsd; #else static ThreadData *pTsd = 0; if( allocateFlag ){ if( pTsd==0 ){ pTsd = sqlite3OsMalloc( sizeof(zeroData) ); if( pTsd ){ *pTsd = zeroData; } } }else if( pTsd!=0 && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){ sqlite3OsFree(pTsd); pTsd = 0; } return pTsd; #endif } /* | > > > > | 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 | pTsd = pthread_getspecific(key); if( allocateFlag ){ if( pTsd==0 ){ pTsd = sqlite3OsMalloc(sizeof(zeroData)); if( pTsd ){ *pTsd = zeroData; pthread_setspecific(key, pTsd); TSD_COUNTER(+1); } } }else if( pTsd!=0 && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){ sqlite3OsFree(pTsd); pthread_setspecific(key, 0); TSD_COUNTER(-1); pTsd = 0; } return pTsd; #else static ThreadData *pTsd = 0; if( allocateFlag ){ if( pTsd==0 ){ pTsd = sqlite3OsMalloc( sizeof(zeroData) ); if( pTsd ){ *pTsd = zeroData; TSD_COUNTER(+1); } } }else if( pTsd!=0 && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){ sqlite3OsFree(pTsd); TSD_COUNTER(-1); pTsd = 0; } return pTsd; #endif } /* |
︙ | ︙ |
Changes to src/os_win.c.
︙ | ︙ | |||
1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 | #ifdef SQLITE_TEST if( sqlite3_current_time ){ *prNow = sqlite3_current_time/86400.0 + 2440587.5; } #endif return 0; } /* ** If called with allocateFlag==1, then return a pointer to thread ** specific data for the current thread. Allocate and zero the ** thread-specific data if it does not already exist necessary. ** ** If called with allocateFlag==0, then check the current thread ** specific data. If it exists and is all zeros, then deallocate it. ** Return a pointer to the thread specific data or NULL if it is ** unallocated. */ | > > > > > > > > > > > > > > > > | < > | > > | 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 | #ifdef SQLITE_TEST if( sqlite3_current_time ){ *prNow = sqlite3_current_time/86400.0 + 2440587.5; } #endif return 0; } /* ** Remember the number of thread-specific-data blocks allocated. ** Use this to verify that we are not leaking thread-specific-data. ** Ticket #1601 */ #ifdef SQLITE_TEST int sqlite3_tsd_count = 0; # define TSD_COUNTER_INCR InterlockedIncrement(&sqlite3_tsd_count) # define TSD_COUNTER_DECR InterlockedDecrement(&sqlite3_tsd_count) #else # define TSD_COUNTER_INCR /* no-op */ # define TSD_COUNTER_DECR /* no-op */ #endif /* ** If called with allocateFlag==1, then return a pointer to thread ** specific data for the current thread. Allocate and zero the ** thread-specific data if it does not already exist necessary. ** ** If called with allocateFlag==0, then check the current thread ** specific data. If it exists and is all zeros, then deallocate it. ** Return a pointer to the thread specific data or NULL if it is ** unallocated. */ ThreadData *sqlite3WinThreadSpecificData(int allocateFlag){ static int key; static int keyInit = 0; static const ThreadData zeroData; ThreadData *pTsd; if( !keyInit ){ sqlite3OsEnterMutex(); if( !keyInit ){ key = TlsAlloc(); if( key==0xffffffff ){ sqlite3OsLeaveMutex(); return 0; } keyInit = 1; } sqlite3OsLeaveMutex(); } pTsd = TlsGetValue(key); if( allocateFlag ){ if( !pTsd ){ pTsd = sqlite3OsMalloc( sizeof(zeroData) ); if( pTsd ){ *pTsd = zeroData; TlsSetValue(key, pTsd); TSD_COUNTER_INCR; } } }else if( pTsd!=0 && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){ sqlite3OsFree(pTsd); TlsSetValue(key, 0); TSD_COUNTER_DECR; pTsd = 0; } return pTsd; } #endif /* OS_WIN */ |
Changes to src/server.c.
︙ | ︙ | |||
328 329 330 331 332 333 334 335 336 337 338 339 340 341 | ** on this procedure. See the sqlite3_server_start() routine below ** for an example. This procedure loops until g.serverHalt becomes ** true. */ void *sqlite3_server(void *NotUsed){ sqlite3_enable_shared_cache(1); if( pthread_mutex_trylock(&g.serverMutex) ){ return 0; /* Another server is already running */ } while( !g.serverHalt ){ SqlMessage *pMsg; /* Remove the last message from the message queue. */ | > | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | ** on this procedure. See the sqlite3_server_start() routine below ** for an example. This procedure loops until g.serverHalt becomes ** true. */ void *sqlite3_server(void *NotUsed){ sqlite3_enable_shared_cache(1); if( pthread_mutex_trylock(&g.serverMutex) ){ sqlite3_enable_shared_cache(0); return 0; /* Another server is already running */ } while( !g.serverHalt ){ SqlMessage *pMsg; /* Remove the last message from the message queue. */ |
︙ | ︙ | |||
389 390 391 392 393 394 395 396 397 398 399 400 401 402 | /* Signal the client that the message has been processed. */ pMsg->op = MSG_Done; pthread_mutex_unlock(&pMsg->clientMutex); pthread_cond_signal(&pMsg->clientWakeup); } pthread_mutex_unlock(&g.serverMutex); return 0; } /* ** Start a server thread if one is not already running. If there ** is aleady a server thread running, the new thread will quickly ** die and this routine is effectively a no-op. | > | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 | /* Signal the client that the message has been processed. */ pMsg->op = MSG_Done; pthread_mutex_unlock(&pMsg->clientMutex); pthread_cond_signal(&pMsg->clientWakeup); } pthread_mutex_unlock(&g.serverMutex); sqlite3_thread_cleanup(); return 0; } /* ** Start a server thread if one is not already running. If there ** is aleady a server thread running, the new thread will quickly ** die and this routine is effectively a no-op. |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.189 2006/01/11 23:40:34 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 | if( Tcl_GetIntFromObj(interp, objv[1], &N) ) return TCL_ERROR; sqlite3_soft_heap_limit(N); } Tcl_SetObjResult(interp, Tcl_NewIntObj(amt)); #endif return TCL_OK; } /* ** This routine sets entries in the global ::sqlite_options() array variable ** according to the compile-time configuration of the database. Test ** procedures use this to determine when tests should be omitted. */ static void set_options(Tcl_Interp *interp){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 | if( Tcl_GetIntFromObj(interp, objv[1], &N) ) return TCL_ERROR; sqlite3_soft_heap_limit(N); } Tcl_SetObjResult(interp, Tcl_NewIntObj(amt)); #endif return TCL_OK; } /* ** Usage: sqlite3_clear_tsd_memdebug ** ** Clear all of the MEMDEBUG information out of thread-specific data. ** This will allow it to be deallocated. */ static int test_clear_tsd_memdebug( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ #if defined(SQLITE_MEMDEBUG) ThreadData *pTd = sqlite3ThreadData(); pTd->nMaxAlloc = 0; pTd->zFile = 0; pTd->iLine = 0; #endif return TCL_OK; } /* ** Usage: sqlite3_tsd_release ** ** Call sqlite3ReleaseThreadData. */ static int test_tsd_release( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ #if defined(SQLITE_MEMDEBUG) sqlite3ReleaseThreadData(); #endif return TCL_OK; } /* ** Usage: sqlite3_thread_cleanup ** ** Call the sqlite3_thread_cleanup API. */ static int test_thread_cleanup( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ sqlite3_thread_cleanup(); return TCL_OK; } /* ** This routine sets entries in the global ::sqlite_options() array variable ** according to the compile-time configuration of the database. Test ** procedures use this to determine when tests should be omitted. */ static void set_options(Tcl_Interp *interp){ |
︙ | ︙ | |||
3368 3369 3370 3371 3372 3373 3374 | { "sqlite3_finalize", test_finalize ,0 }, { "sqlite3_reset", test_reset ,0 }, { "sqlite3_expired", test_expired ,0 }, { "sqlite3_transfer_bindings", test_transfer_bind ,0 }, { "sqlite3_changes", test_changes ,0 }, { "sqlite3_step", test_step ,0 }, | | | > > > | 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 | { "sqlite3_finalize", test_finalize ,0 }, { "sqlite3_reset", test_reset ,0 }, { "sqlite3_expired", test_expired ,0 }, { "sqlite3_transfer_bindings", test_transfer_bind ,0 }, { "sqlite3_changes", test_changes ,0 }, { "sqlite3_step", test_step ,0 }, { "sqlite3_release_memory", test_release_memory, 0}, { "sqlite3_soft_heap_limit", test_soft_heap_limit, 0}, { "sqlite3_clear_tsd_memdebug", test_clear_tsd_memdebug, 0}, { "sqlite3_tsd_release", test_tsd_release, 0}, { "sqlite3_thread_cleanup", test_thread_cleanup, 0}, /* sqlite3_column_*() API */ { "sqlite3_column_count", test_column_count ,0 }, { "sqlite3_data_count", test_data_count ,0 }, { "sqlite3_column_type", test_column_type ,0 }, { "sqlite3_column_blob", test_column_blob ,0 }, { "sqlite3_column_double", test_column_double ,0 }, |
︙ | ︙ | |||
3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 | extern int sqlite3_where_trace; extern int sqlite3_sync_count, sqlite3_fullsync_count; extern int sqlite3_opentemp_count; extern int sqlite3_memUsed; extern int sqlite3_malloc_id; extern int sqlite3_memMax; extern int sqlite3_like_count; #if OS_WIN extern int sqlite3_os_type; #endif #ifdef SQLITE_DEBUG extern int sqlite3_vdbe_addop_trace; #endif #ifdef SQLITE_TEST | > | 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 | extern int sqlite3_where_trace; extern int sqlite3_sync_count, sqlite3_fullsync_count; extern int sqlite3_opentemp_count; extern int sqlite3_memUsed; extern int sqlite3_malloc_id; extern int sqlite3_memMax; extern int sqlite3_like_count; extern int sqlite3_tsd_count; #if OS_WIN extern int sqlite3_os_type; #endif #ifdef SQLITE_DEBUG extern int sqlite3_vdbe_addop_trace; #endif #ifdef SQLITE_TEST |
︙ | ︙ | |||
3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 | (char*)&sqlite3_interrupt_count, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_open_file_count", (char*)&sqlite3_open_file_count, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_current_time", (char*)&sqlite3_current_time, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_os_trace", (char*)&sqlite3_os_trace, TCL_LINK_INT); #ifndef SQLITE_OMIT_UTF16 Tcl_LinkVar(interp, "sqlite_last_needed_collation", (char*)&pzNeededCollation, TCL_LINK_STRING|TCL_LINK_READ_ONLY); #endif #ifdef SQLITE_MEMDEBUG Tcl_LinkVar(interp, "sqlite_malloc_id", (char*)&sqlite3_malloc_id, TCL_LINK_STRING); | > > | 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 | (char*)&sqlite3_interrupt_count, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_open_file_count", (char*)&sqlite3_open_file_count, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_current_time", (char*)&sqlite3_current_time, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_os_trace", (char*)&sqlite3_os_trace, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite3_tsd_count", (char*)&sqlite3_tsd_count, TCL_LINK_INT); #ifndef SQLITE_OMIT_UTF16 Tcl_LinkVar(interp, "sqlite_last_needed_collation", (char*)&pzNeededCollation, TCL_LINK_STRING|TCL_LINK_READ_ONLY); #endif #ifdef SQLITE_MEMDEBUG Tcl_LinkVar(interp, "sqlite_malloc_id", (char*)&sqlite3_malloc_id, TCL_LINK_STRING); |
︙ | ︙ | |||
3503 3504 3505 3506 3507 3508 3509 | Tcl_LinkVar(interp, "sqlite_sync_count", (char*)&sqlite3_sync_count, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_fullsync_count", (char*)&sqlite3_fullsync_count, TCL_LINK_INT); #endif /* OS_UNIX */ set_options(interp); | > | > | | > | 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 | Tcl_LinkVar(interp, "sqlite_sync_count", (char*)&sqlite3_sync_count, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_fullsync_count", (char*)&sqlite3_fullsync_count, TCL_LINK_INT); #endif /* OS_UNIX */ set_options(interp); { extern int sqlite3_shared_cache_report(void *, Tcl_Interp *, int, Tcl_Obj *CONST[]); Tcl_CreateObjCommand(interp, "sqlite_shared_cache_report", sqlite3_shared_cache_report, 0, 0); } return TCL_OK; } |
Changes to src/test4.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 December 18 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the the SQLite library in a multithreaded environment. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2003 December 18 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the the SQLite library in a multithreaded environment. ** ** $Id: test4.c,v 1.14 2006/01/11 23:40:34 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #if defined(OS_UNIX) && OS_UNIX==1 && defined(THREADSAFE) && THREADSAFE==1 #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
93 94 95 96 97 98 99 100 101 102 103 104 105 106 | p->db = 0; } if( p->zErr && p->zErr!=p->zStaticErr ){ sqlite3_free(p->zErr); p->zErr = 0; } p->completed++; return 0; } /* ** Get a thread ID which is an upper case letter. Return the index. ** If the argument is not a valid thread ID put an error message in ** the interpreter and return -1. | > | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | p->db = 0; } if( p->zErr && p->zErr!=p->zStaticErr ){ sqlite3_free(p->zErr); p->zErr = 0; } p->completed++; sqlite3_thread_cleanup(); return 0; } /* ** Get a thread ID which is an upper case letter. Return the index. ** If the argument is not a valid thread ID put an error message in ** the interpreter and return -1. |
︙ | ︙ |
Changes to src/test7.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the client/server version of the SQLite library. ** Derived from test4.c. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the client/server version of the SQLite library. ** Derived from test4.c. ** ** $Id: test7.c,v 1.2 2006/01/11 23:40:34 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" /* ** This test only works on UNIX with a THREADSAFE build that includes |
︙ | ︙ | |||
114 115 116 117 118 119 120 121 122 123 124 125 126 127 | p->db = 0; } if( p->zErr && p->zErr!=p->zStaticErr ){ sqlite3_free(p->zErr); p->zErr = 0; } p->completed++; return 0; } /* ** Get a thread ID which is an upper case letter. Return the index. ** If the argument is not a valid thread ID put an error message in ** the interpreter and return -1. | > | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | p->db = 0; } if( p->zErr && p->zErr!=p->zStaticErr ){ sqlite3_free(p->zErr); p->zErr = 0; } p->completed++; sqlite3_thread_cleanup(); return 0; } /* ** Get a thread ID which is an upper case letter. Return the index. ** If the argument is not a valid thread ID put an error message in ** the interpreter and return -1. |
︙ | ︙ |
Changes to test/tester.tcl.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements some common TCL routines used for regression # testing the SQLite library # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements some common TCL routines used for regression # testing the SQLite library # # $Id: tester.tcl,v 1.59 2006/01/11 23:40:34 drh Exp $ # Make sure tclsqlite3 was compiled correctly. Abort now with an # error message if not. # if {[sqlite3 -tcl-uses-utf]} { if {"\u1234"=="u1234"} { puts stderr "***** BUILD PROBLEM *****" |
︙ | ︙ | |||
145 146 147 148 149 150 151 | catch {db close} catch {db2 close} catch {db3 close} catch { pp_check_for_leaks } | > > > > > > > > | > | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | catch {db close} catch {db2 close} catch {db3 close} catch { pp_check_for_leaks } sqlite3 db {} sqlite3_clear_tsd_memdebug db close if {$::sqlite3_tsd_count} { puts "Thread-specific data leak: $::sqlite3_tsd_count instances" incr nErr } else { puts "Thread-specific data deallocated properly" } incr nTest puts "$nErr errors out of $nTest tests" puts "Failures on these tests: $::failList" if {$nProb>0} { puts "$nProb probabilistic tests also failed, but this does" puts "not necessarily indicate a malfunction." } if 0 { |
︙ | ︙ |
Changes to www/capi3ref.tcl.
|
| | | 1 2 3 4 5 6 7 8 | set rcsid {$Id: capi3ref.tcl,v 1.28 2006/01/11 23:40:34 drh Exp $} source common.tcl header {C/C++ Interface For SQLite Version 3} puts { <h2>C/C++ Interface For SQLite Version 3</h2> } proc api {name prototype desc {notused x}} { |
︙ | ︙ | |||
1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 | Cache sharing is enabled and disabled on a thread-by-thread basis. Each call to this routine enables or disables cache sharing only for connections created in the same thread in which this routine is called. There is no mechanism for sharing cache between database connections running in different threads. This routine must not be called when any database connections are active in the current thread. Enabling or disabling shared cache while there are active database connections will result in memory corruption. For any given database connection, SQLite requires that the following routines always be called from the same thread: | > > > > | 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 | Cache sharing is enabled and disabled on a thread-by-thread basis. Each call to this routine enables or disables cache sharing only for connections created in the same thread in which this routine is called. There is no mechanism for sharing cache between database connections running in different threads. Sharing must be disabled prior to shutting down a thread or else the thread will leak memory. Call this routine with an argument of 0 to turn of sharing. Or use the sqlite3_thread_cleanup() API. This routine must not be called when any database connections are active in the current thread. Enabling or disabling shared cache while there are active database connections will result in memory corruption. For any given database connection, SQLite requires that the following routines always be called from the same thread: |
︙ | ︙ | |||
1260 1261 1262 1263 1264 1265 1266 | enabled or disabled successfully. An error code is returned otherwise. Shared cache is disabled by default for backward compatibility. } api {} { | | < < < | < | < < | < < < < < < | < < < < < < | | < < < < < < < < | < < < < | | < < | < < < < > | | < < | | | | | > | 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 | enabled or disabled successfully. An error code is returned otherwise. Shared cache is disabled by default for backward compatibility. } api {} { void sqlite3_thread_cleanup(void); } { This routine makes sure that all thread local storage used by SQLite in the current thread has been deallocated. A thread can call this routine prior to terminating in order to make sure there are no memory leaks. This routine is not strictly necessary. If cache sharing has been disabled using sqlite3_enable_shared_cache() and if all database connections have been closed and if SQLITE_ENABLE_MEMORY_MANAGMENT is on and all memory has been freed, then the thread local storage will already have been automatically deallocated. This routine is provided as a convenience to the program who just wants to make sure that there are no leaks. } api {} { int sqlite3_release_memory(int N); } { This routine attempts to free at least N bytes of memory from the caches of database connecions that were created in the same thread from which this routine is called. The value returned is the number of bytes actually freed. This routine is only available if memory management has been enabled by compiling with the SQLITE_ENABLE_MEMORY_MANAGMENT macro. } api {} { void sqlite3_soft_heap_limit(int N); } { This routine sets the soft heap limit for the current thread to N. If the total heap usage by SQLite in the current thread exceeds N, then sqlite3_release_memory() is called to try to reduce the memory usage below the soft limit. A negative or zero value for N means that there is no soft heap limit and sqlite3_release_memory() will only be called when memory is exhaused. The default value for the soft heap limit is zero. SQLite makes a best effort to honor the soft heap limit. But if it is unable to reduce memory usage below the soft limit, execution will continue without error or notification. This is why the limit is called a "soft" limit. It is advisory only. This routine is only available if memory management has been enabled by compiling with the SQLITE_ENABLE_MEMORY_MANAGMENT macro. } set n 0 set i 0 foreach item $apilist { set namelist [lindex $item 0] foreach name $namelist { |
︙ | ︙ |