| OLD | NEW |
| 1 /* | 1 /* |
| 2 ** 2008 June 18 | 2 ** 2008 June 18 |
| 3 ** | 3 ** |
| 4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
| 5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
| 6 ** | 6 ** |
| 7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
| 8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
| 9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
| 10 ** | 10 ** |
| 11 ************************************************************************* | 11 ************************************************************************* |
| 12 ** This file contains test logic for the sqlite3_mutex interfaces. | 12 ** This file contains test logic for the sqlite3_mutex interfaces. |
| 13 */ | 13 */ |
| 14 | 14 |
| 15 #include "tcl.h" | 15 #if defined(INCLUDE_SQLITE_TCL_H) |
| 16 # include "sqlite_tcl.h" |
| 17 #else |
| 18 # include "tcl.h" |
| 19 #endif |
| 16 #include "sqlite3.h" | 20 #include "sqlite3.h" |
| 17 #include "sqliteInt.h" | 21 #include "sqliteInt.h" |
| 18 #include <stdlib.h> | 22 #include <stdlib.h> |
| 19 #include <assert.h> | 23 #include <assert.h> |
| 20 #include <string.h> | 24 #include <string.h> |
| 21 | 25 |
| 22 #define MAX_MUTEXES (SQLITE_MUTEX_STATIC_VFS3+1) | 26 #define MAX_MUTEXES (SQLITE_MUTEX_STATIC_VFS3+1) |
| 23 #define STATIC_MUTEXES (MAX_MUTEXES-(SQLITE_MUTEX_RECURSIVE+1)) | 27 #define STATIC_MUTEXES (MAX_MUTEXES-(SQLITE_MUTEX_RECURSIVE+1)) |
| 24 | 28 |
| 25 /* defined in main.c */ | 29 /* defined in main.c */ |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 /* Leave a mutex | 149 /* Leave a mutex |
| 146 */ | 150 */ |
| 147 static void counterMutexLeave(sqlite3_mutex *p){ | 151 static void counterMutexLeave(sqlite3_mutex *p){ |
| 148 assert( g.isInit ); | 152 assert( g.isInit ); |
| 149 g.m.xMutexLeave(p->pReal); | 153 g.m.xMutexLeave(p->pReal); |
| 150 } | 154 } |
| 151 | 155 |
| 152 /* | 156 /* |
| 153 ** sqlite3_shutdown | 157 ** sqlite3_shutdown |
| 154 */ | 158 */ |
| 155 static int test_shutdown( | 159 static int SQLITE_TCLAPI test_shutdown( |
| 156 void * clientData, | 160 void * clientData, |
| 157 Tcl_Interp *interp, | 161 Tcl_Interp *interp, |
| 158 int objc, | 162 int objc, |
| 159 Tcl_Obj *CONST objv[] | 163 Tcl_Obj *CONST objv[] |
| 160 ){ | 164 ){ |
| 161 int rc; | 165 int rc; |
| 162 | 166 |
| 163 if( objc!=1 ){ | 167 if( objc!=1 ){ |
| 164 Tcl_WrongNumArgs(interp, 1, objv, ""); | 168 Tcl_WrongNumArgs(interp, 1, objv, ""); |
| 165 return TCL_ERROR; | 169 return TCL_ERROR; |
| 166 } | 170 } |
| 167 | 171 |
| 168 rc = sqlite3_shutdown(); | 172 rc = sqlite3_shutdown(); |
| 169 Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE); | 173 Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE); |
| 170 return TCL_OK; | 174 return TCL_OK; |
| 171 } | 175 } |
| 172 | 176 |
| 173 /* | 177 /* |
| 174 ** sqlite3_initialize | 178 ** sqlite3_initialize |
| 175 */ | 179 */ |
| 176 static int test_initialize( | 180 static int SQLITE_TCLAPI test_initialize( |
| 177 void * clientData, | 181 void * clientData, |
| 178 Tcl_Interp *interp, | 182 Tcl_Interp *interp, |
| 179 int objc, | 183 int objc, |
| 180 Tcl_Obj *CONST objv[] | 184 Tcl_Obj *CONST objv[] |
| 181 ){ | 185 ){ |
| 182 int rc; | 186 int rc; |
| 183 | 187 |
| 184 if( objc!=1 ){ | 188 if( objc!=1 ){ |
| 185 Tcl_WrongNumArgs(interp, 1, objv, ""); | 189 Tcl_WrongNumArgs(interp, 1, objv, ""); |
| 186 return TCL_ERROR; | 190 return TCL_ERROR; |
| 187 } | 191 } |
| 188 | 192 |
| 189 rc = sqlite3_initialize(); | 193 rc = sqlite3_initialize(); |
| 190 Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE); | 194 Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE); |
| 191 return TCL_OK; | 195 return TCL_OK; |
| 192 } | 196 } |
| 193 | 197 |
| 194 /* | 198 /* |
| 195 ** install_mutex_counters BOOLEAN | 199 ** install_mutex_counters BOOLEAN |
| 196 */ | 200 */ |
| 197 static int test_install_mutex_counters( | 201 static int SQLITE_TCLAPI test_install_mutex_counters( |
| 198 void * clientData, | 202 void * clientData, |
| 199 Tcl_Interp *interp, | 203 Tcl_Interp *interp, |
| 200 int objc, | 204 int objc, |
| 201 Tcl_Obj *CONST objv[] | 205 Tcl_Obj *CONST objv[] |
| 202 ){ | 206 ){ |
| 203 int rc = SQLITE_OK; | 207 int rc = SQLITE_OK; |
| 204 int isInstall; | 208 int isInstall; |
| 205 | 209 |
| 206 sqlite3_mutex_methods counter_methods = { | 210 sqlite3_mutex_methods counter_methods = { |
| 207 counterMutexInit, | 211 counterMutexInit, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 g.isInstalled = isInstall; | 252 g.isInstalled = isInstall; |
| 249 } | 253 } |
| 250 | 254 |
| 251 Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE); | 255 Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE); |
| 252 return TCL_OK; | 256 return TCL_OK; |
| 253 } | 257 } |
| 254 | 258 |
| 255 /* | 259 /* |
| 256 ** read_mutex_counters | 260 ** read_mutex_counters |
| 257 */ | 261 */ |
| 258 static int test_read_mutex_counters( | 262 static int SQLITE_TCLAPI test_read_mutex_counters( |
| 259 void * clientData, | 263 void * clientData, |
| 260 Tcl_Interp *interp, | 264 Tcl_Interp *interp, |
| 261 int objc, | 265 int objc, |
| 262 Tcl_Obj *CONST objv[] | 266 Tcl_Obj *CONST objv[] |
| 263 ){ | 267 ){ |
| 264 Tcl_Obj *pRet; | 268 Tcl_Obj *pRet; |
| 265 int ii; | 269 int ii; |
| 266 | 270 |
| 267 if( objc!=1 ){ | 271 if( objc!=1 ){ |
| 268 Tcl_WrongNumArgs(interp, 1, objv, ""); | 272 Tcl_WrongNumArgs(interp, 1, objv, ""); |
| 269 return TCL_ERROR; | 273 return TCL_ERROR; |
| 270 } | 274 } |
| 271 | 275 |
| 272 pRet = Tcl_NewObj(); | 276 pRet = Tcl_NewObj(); |
| 273 Tcl_IncrRefCount(pRet); | 277 Tcl_IncrRefCount(pRet); |
| 274 for(ii=0; ii<MAX_MUTEXES; ii++){ | 278 for(ii=0; ii<MAX_MUTEXES; ii++){ |
| 275 Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(aName[ii], -1)); | 279 Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(aName[ii], -1)); |
| 276 Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(g.aCounter[ii])); | 280 Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(g.aCounter[ii])); |
| 277 } | 281 } |
| 278 Tcl_SetObjResult(interp, pRet); | 282 Tcl_SetObjResult(interp, pRet); |
| 279 Tcl_DecrRefCount(pRet); | 283 Tcl_DecrRefCount(pRet); |
| 280 | 284 |
| 281 return TCL_OK; | 285 return TCL_OK; |
| 282 } | 286 } |
| 283 | 287 |
| 284 /* | 288 /* |
| 285 ** clear_mutex_counters | 289 ** clear_mutex_counters |
| 286 */ | 290 */ |
| 287 static int test_clear_mutex_counters( | 291 static int SQLITE_TCLAPI test_clear_mutex_counters( |
| 288 void * clientData, | 292 void * clientData, |
| 289 Tcl_Interp *interp, | 293 Tcl_Interp *interp, |
| 290 int objc, | 294 int objc, |
| 291 Tcl_Obj *CONST objv[] | 295 Tcl_Obj *CONST objv[] |
| 292 ){ | 296 ){ |
| 293 int ii; | 297 int ii; |
| 294 | 298 |
| 295 if( objc!=1 ){ | 299 if( objc!=1 ){ |
| 296 Tcl_WrongNumArgs(interp, 1, objv, ""); | 300 Tcl_WrongNumArgs(interp, 1, objv, ""); |
| 297 return TCL_ERROR; | 301 return TCL_ERROR; |
| 298 } | 302 } |
| 299 | 303 |
| 300 for(ii=0; ii<MAX_MUTEXES; ii++){ | 304 for(ii=0; ii<MAX_MUTEXES; ii++){ |
| 301 g.aCounter[ii] = 0; | 305 g.aCounter[ii] = 0; |
| 302 } | 306 } |
| 303 return TCL_OK; | 307 return TCL_OK; |
| 304 } | 308 } |
| 305 | 309 |
| 306 /* | 310 /* |
| 307 ** Create and free a mutex. Return the mutex pointer. The pointer | 311 ** Create and free a mutex. Return the mutex pointer. The pointer |
| 308 ** will be invalid since the mutex has already been freed. The | 312 ** will be invalid since the mutex has already been freed. The |
| 309 ** return pointer just checks to see if the mutex really was allocated. | 313 ** return pointer just checks to see if the mutex really was allocated. |
| 310 */ | 314 */ |
| 311 static int test_alloc_mutex( | 315 static int SQLITE_TCLAPI test_alloc_mutex( |
| 312 void * clientData, | 316 void * clientData, |
| 313 Tcl_Interp *interp, | 317 Tcl_Interp *interp, |
| 314 int objc, | 318 int objc, |
| 315 Tcl_Obj *CONST objv[] | 319 Tcl_Obj *CONST objv[] |
| 316 ){ | 320 ){ |
| 317 #if SQLITE_THREADSAFE | 321 #if SQLITE_THREADSAFE |
| 318 sqlite3_mutex *p = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); | 322 sqlite3_mutex *p = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); |
| 319 char zBuf[100]; | 323 char zBuf[100]; |
| 320 sqlite3_mutex_free(p); | 324 sqlite3_mutex_free(p); |
| 321 sqlite3_snprintf(sizeof(zBuf), zBuf, "%p", p); | 325 sqlite3_snprintf(sizeof(zBuf), zBuf, "%p", p); |
| 322 Tcl_AppendResult(interp, zBuf, (char*)0); | 326 Tcl_AppendResult(interp, zBuf, (char*)0); |
| 323 #endif | 327 #endif |
| 324 return TCL_OK; | 328 return TCL_OK; |
| 325 } | 329 } |
| 326 | 330 |
| 327 /* | 331 /* |
| 328 ** sqlite3_config OPTION | 332 ** sqlite3_config OPTION |
| 329 ** | 333 ** |
| 330 ** OPTION can be either one of the keywords: | 334 ** OPTION can be either one of the keywords: |
| 331 ** | 335 ** |
| 332 ** SQLITE_CONFIG_SINGLETHREAD | 336 ** SQLITE_CONFIG_SINGLETHREAD |
| 333 ** SQLITE_CONFIG_MULTITHREAD | 337 ** SQLITE_CONFIG_MULTITHREAD |
| 334 ** SQLITE_CONFIG_SERIALIZED | 338 ** SQLITE_CONFIG_SERIALIZED |
| 335 ** | 339 ** |
| 336 ** Or OPTION can be an raw integer. | 340 ** Or OPTION can be an raw integer. |
| 337 */ | 341 */ |
| 338 static int test_config( | 342 static int SQLITE_TCLAPI test_config( |
| 339 void * clientData, | 343 void * clientData, |
| 340 Tcl_Interp *interp, | 344 Tcl_Interp *interp, |
| 341 int objc, | 345 int objc, |
| 342 Tcl_Obj *CONST objv[] | 346 Tcl_Obj *CONST objv[] |
| 343 ){ | 347 ){ |
| 344 struct ConfigOption { | 348 struct ConfigOption { |
| 345 const char *zName; | 349 const char *zName; |
| 346 int iValue; | 350 int iValue; |
| 347 } aOpt[] = { | 351 } aOpt[] = { |
| 348 {"singlethread", SQLITE_CONFIG_SINGLETHREAD}, | 352 {"singlethread", SQLITE_CONFIG_SINGLETHREAD}, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 Tcl_Obj *pObj | 394 Tcl_Obj *pObj |
| 391 ){ | 395 ){ |
| 392 int iMutex; | 396 int iMutex; |
| 393 if( Tcl_GetIndexFromObj(pInterp, pObj, aName, "mutex name", 0, &iMutex) ){ | 397 if( Tcl_GetIndexFromObj(pInterp, pObj, aName, "mutex name", 0, &iMutex) ){ |
| 394 return 0; | 398 return 0; |
| 395 } | 399 } |
| 396 assert( iMutex!=SQLITE_MUTEX_FAST && iMutex!=SQLITE_MUTEX_RECURSIVE ); | 400 assert( iMutex!=SQLITE_MUTEX_FAST && iMutex!=SQLITE_MUTEX_RECURSIVE ); |
| 397 return counterMutexAlloc(iMutex); | 401 return counterMutexAlloc(iMutex); |
| 398 } | 402 } |
| 399 | 403 |
| 400 static int test_enter_static_mutex( | 404 static int SQLITE_TCLAPI test_enter_static_mutex( |
| 401 void * clientData, | 405 void * clientData, |
| 402 Tcl_Interp *interp, | 406 Tcl_Interp *interp, |
| 403 int objc, | 407 int objc, |
| 404 Tcl_Obj *CONST objv[] | 408 Tcl_Obj *CONST objv[] |
| 405 ){ | 409 ){ |
| 406 sqlite3_mutex *pMutex; | 410 sqlite3_mutex *pMutex; |
| 407 if( objc!=2 ){ | 411 if( objc!=2 ){ |
| 408 Tcl_WrongNumArgs(interp, 1, objv, "NAME"); | 412 Tcl_WrongNumArgs(interp, 1, objv, "NAME"); |
| 409 return TCL_ERROR; | 413 return TCL_ERROR; |
| 410 } | 414 } |
| 411 pMutex = getStaticMutexPointer(interp, objv[1]); | 415 pMutex = getStaticMutexPointer(interp, objv[1]); |
| 412 if( !pMutex ){ | 416 if( !pMutex ){ |
| 413 return TCL_ERROR; | 417 return TCL_ERROR; |
| 414 } | 418 } |
| 415 sqlite3_mutex_enter(pMutex); | 419 sqlite3_mutex_enter(pMutex); |
| 416 return TCL_OK; | 420 return TCL_OK; |
| 417 } | 421 } |
| 418 | 422 |
| 419 static int test_leave_static_mutex( | 423 static int SQLITE_TCLAPI test_leave_static_mutex( |
| 420 void * clientData, | 424 void * clientData, |
| 421 Tcl_Interp *interp, | 425 Tcl_Interp *interp, |
| 422 int objc, | 426 int objc, |
| 423 Tcl_Obj *CONST objv[] | 427 Tcl_Obj *CONST objv[] |
| 424 ){ | 428 ){ |
| 425 sqlite3_mutex *pMutex; | 429 sqlite3_mutex *pMutex; |
| 426 if( objc!=2 ){ | 430 if( objc!=2 ){ |
| 427 Tcl_WrongNumArgs(interp, 1, objv, "NAME"); | 431 Tcl_WrongNumArgs(interp, 1, objv, "NAME"); |
| 428 return TCL_ERROR; | 432 return TCL_ERROR; |
| 429 } | 433 } |
| 430 pMutex = getStaticMutexPointer(interp, objv[1]); | 434 pMutex = getStaticMutexPointer(interp, objv[1]); |
| 431 if( !pMutex ){ | 435 if( !pMutex ){ |
| 432 return TCL_ERROR; | 436 return TCL_ERROR; |
| 433 } | 437 } |
| 434 sqlite3_mutex_leave(pMutex); | 438 sqlite3_mutex_leave(pMutex); |
| 435 return TCL_OK; | 439 return TCL_OK; |
| 436 } | 440 } |
| 437 | 441 |
| 438 static int test_enter_db_mutex( | 442 static int SQLITE_TCLAPI test_enter_db_mutex( |
| 439 void * clientData, | 443 void * clientData, |
| 440 Tcl_Interp *interp, | 444 Tcl_Interp *interp, |
| 441 int objc, | 445 int objc, |
| 442 Tcl_Obj *CONST objv[] | 446 Tcl_Obj *CONST objv[] |
| 443 ){ | 447 ){ |
| 444 sqlite3 *db; | 448 sqlite3 *db; |
| 445 if( objc!=2 ){ | 449 if( objc!=2 ){ |
| 446 Tcl_WrongNumArgs(interp, 1, objv, "DB"); | 450 Tcl_WrongNumArgs(interp, 1, objv, "DB"); |
| 447 return TCL_ERROR; | 451 return TCL_ERROR; |
| 448 } | 452 } |
| 449 db = getDbPointer(interp, objv[1]); | 453 db = getDbPointer(interp, objv[1]); |
| 450 if( !db ){ | 454 if( !db ){ |
| 451 return TCL_ERROR; | 455 return TCL_ERROR; |
| 452 } | 456 } |
| 453 sqlite3_mutex_enter(sqlite3_db_mutex(db)); | 457 sqlite3_mutex_enter(sqlite3_db_mutex(db)); |
| 454 return TCL_OK; | 458 return TCL_OK; |
| 455 } | 459 } |
| 456 | 460 |
| 457 static int test_leave_db_mutex( | 461 static int SQLITE_TCLAPI test_leave_db_mutex( |
| 458 void * clientData, | 462 void * clientData, |
| 459 Tcl_Interp *interp, | 463 Tcl_Interp *interp, |
| 460 int objc, | 464 int objc, |
| 461 Tcl_Obj *CONST objv[] | 465 Tcl_Obj *CONST objv[] |
| 462 ){ | 466 ){ |
| 463 sqlite3 *db; | 467 sqlite3 *db; |
| 464 if( objc!=2 ){ | 468 if( objc!=2 ){ |
| 465 Tcl_WrongNumArgs(interp, 1, objv, "DB"); | 469 Tcl_WrongNumArgs(interp, 1, objv, "DB"); |
| 466 return TCL_ERROR; | 470 return TCL_ERROR; |
| 467 } | 471 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 497 for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ | 501 for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ |
| 498 Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); | 502 Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); |
| 499 } | 503 } |
| 500 | 504 |
| 501 Tcl_LinkVar(interp, "disable_mutex_init", | 505 Tcl_LinkVar(interp, "disable_mutex_init", |
| 502 (char*)&g.disableInit, TCL_LINK_INT); | 506 (char*)&g.disableInit, TCL_LINK_INT); |
| 503 Tcl_LinkVar(interp, "disable_mutex_try", | 507 Tcl_LinkVar(interp, "disable_mutex_try", |
| 504 (char*)&g.disableTry, TCL_LINK_INT); | 508 (char*)&g.disableTry, TCL_LINK_INT); |
| 505 return SQLITE_OK; | 509 return SQLITE_OK; |
| 506 } | 510 } |
| OLD | NEW |