15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2008 June 18
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code.  In place of
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing:
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you do good and not evil.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you find forgiveness for yourself and forgive others.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you share freely, never taking more than you give.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*************************************************************************
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This file contains test logic for the sqlite3_mutex interfaces.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tcl.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqlite3.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqliteInt.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h>
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* defined in test1.c */
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char *sqlite3TestErrorName(int);
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* A countable mutex */
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct sqlite3_mutex {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex *pReal;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int eType;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* State variables */
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct test_mutex_globals {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int isInstalled;              /* True if installed */
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int disableInit;              /* True to cause sqlite3_initalize() to fail */
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int disableTry;               /* True to force sqlite3_mutex_try() to fail */
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int isInit;                   /* True if initialized */
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex_methods m;      /* Interface to "real" mutex system */
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int aCounter[8];              /* Number of grabs of each type of mutex */
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex aStatic[6];     /* The six static mutexes */
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} g = {0};
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return true if the countable mutex is currently held */
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int counterMutexHeld(sqlite3_mutex *p){
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g.m.xMutexHeld(p->pReal);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Return true if the countable mutex is not currently held */
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int counterMutexNotheld(sqlite3_mutex *p){
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g.m.xMutexNotheld(p->pReal);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Initialize the countable mutex interface
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Or, if g.disableInit is non-zero, then do not initialize but instead
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** return the value of g.disableInit as the result code.  This can be used
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to simulate an initialization failure.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int counterMutexInit(void){
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( g.disableInit ) return g.disableInit;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = g.m.xMutexInit();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g.isInit = 1;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rc;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Uninitialize the mutex subsystem
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int counterMutexEnd(void){
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g.isInit = 0;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g.m.xMutexEnd();
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Allocate a countable mutex
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sqlite3_mutex *counterMutexAlloc(int eType){
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex *pReal;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex *pRet = 0;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( g.isInit );
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(eType<8 && eType>=0);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pReal = g.m.xMutexAlloc(eType);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( !pReal ) return 0;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( eType==SQLITE_MUTEX_FAST || eType==SQLITE_MUTEX_RECURSIVE ){
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pRet = (sqlite3_mutex *)malloc(sizeof(sqlite3_mutex));
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pRet = &g.aStatic[eType-2];
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pRet->eType = eType;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pRet->pReal = pReal;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pRet;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Free a countable mutex
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void counterMutexFree(sqlite3_mutex *p){
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( g.isInit );
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g.m.xMutexFree(p->pReal);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( p->eType==SQLITE_MUTEX_FAST || p->eType==SQLITE_MUTEX_RECURSIVE ){
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    free(p);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Enter a countable mutex.  Block until entry is safe.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void counterMutexEnter(sqlite3_mutex *p){
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( g.isInit );
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g.aCounter[p->eType]++;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g.m.xMutexEnter(p->pReal);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Try to enter a mutex.  Return true on success.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int counterMutexTry(sqlite3_mutex *p){
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( g.isInit );
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g.aCounter[p->eType]++;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( g.disableTry ) return SQLITE_BUSY;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g.m.xMutexTry(p->pReal);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Leave a mutex
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void counterMutexLeave(sqlite3_mutex *p){
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( g.isInit );
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g.m.xMutexLeave(p->pReal);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite3_shutdown
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_shutdown(
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=1 ){
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "");
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_shutdown();
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite3_initialize
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_initialize(
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=1 ){
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "");
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_initialize();
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** install_mutex_counters BOOLEAN
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_install_mutex_counters(
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc = SQLITE_OK;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int isInstall;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex_methods counter_methods = {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    counterMutexInit,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    counterMutexEnd,
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    counterMutexAlloc,
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    counterMutexFree,
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    counterMutexEnter,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    counterMutexTry,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    counterMutexLeave,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    counterMutexHeld,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    counterMutexNotheld
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=2 ){
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN");
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[1], &isInstall) ){
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(isInstall==0 || isInstall==1);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(g.isInstalled==0 || g.isInstalled==1);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( isInstall==g.isInstalled ){
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "mutex counters are ", 0);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, isInstall?"already installed":"not installed", 0);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( isInstall ){
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert( g.m.xMutexAlloc==0 );
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3_config(SQLITE_CONFIG_GETMUTEX, &g.m);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( rc==SQLITE_OK ){
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3_config(SQLITE_CONFIG_MUTEX, &counter_methods);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g.disableTry = 0;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert( g.m.xMutexAlloc );
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3_config(SQLITE_CONFIG_MUTEX, &g.m);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(&g.m, 0, sizeof(sqlite3_mutex_methods));
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc==SQLITE_OK ){
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g.isInstalled = isInstall;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** read_mutex_counters
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_read_mutex_counters(
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *pRet;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ii;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *aName[8] = {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "fast",        "recursive",   "static_master", "static_mem",
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "static_open", "static_prng", "static_lru",    "static_pmem"
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=1 ){
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "");
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pRet = Tcl_NewObj();
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_IncrRefCount(pRet);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(ii=0; ii<8; ii++){
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(aName[ii], -1));
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(g.aCounter[ii]));
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp, pRet);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_DecrRefCount(pRet);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** clear_mutex_counters
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_clear_mutex_counters(
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int ii;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=1 ){
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "");
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(ii=0; ii<8; ii++){
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g.aCounter[ii] = 0;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Create and free a mutex.  Return the mutex pointer.  The pointer
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** will be invalid since the mutex has already been freed.  The
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** return pointer just checks to see if the mutex really was allocated.
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_alloc_mutex(
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if SQLITE_THREADSAFE
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex *p = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char zBuf[100];
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex_free(p);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_snprintf(sizeof(zBuf), zBuf, "%p", p);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_AppendResult(interp, zBuf, (char*)0);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite3_config OPTION
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** OPTION can be either one of the keywords:
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**            SQLITE_CONFIG_SINGLETHREAD
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**            SQLITE_CONFIG_MULTITHREAD
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**            SQLITE_CONFIG_SERIALIZED
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Or OPTION can be an raw integer.
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_config(
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct ConfigOption {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *zName;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int iValue;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } aOpt[] = {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"singlethread", SQLITE_CONFIG_SINGLETHREAD},
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"multithread",  SQLITE_CONFIG_MULTITHREAD},
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {"serialized",   SQLITE_CONFIG_SERIALIZED},
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {0, 0}
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int s = sizeof(struct ConfigOption);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=2 ){
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "");
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetIndexFromObjStruct(interp, objv[1], aOpt, s, "flag", 0, &i) ){
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( Tcl_GetIntFromObj(interp, objv[1], &i) ){
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return TCL_ERROR;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    i = aOpt[i].iValue;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_config(i);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sqlite3 *getDbPointer(Tcl_Interp *pInterp, Tcl_Obj *pObj){
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_CmdInfo info;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zCmd = Tcl_GetString(pObj);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetCommandInfo(pInterp, zCmd, &info) ){
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    db = *((sqlite3 **)info.objClientData);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    db = (sqlite3*)sqlite3TestTextToPtr(zCmd);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( db );
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return db;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_enter_db_mutex(
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=2 ){
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "DB");
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db = getDbPointer(interp, objv[1]);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( !db ){
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex_enter(sqlite3_db_mutex(db));
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_leave_db_mutex(
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( objc!=2 ){
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_WrongNumArgs(interp, 1, objv, "DB");
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db = getDbPointer(interp, objv[1]);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( !db ){
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex_leave(sqlite3_db_mutex(db));
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Sqlitetest_mutex_Init(Tcl_Interp *interp){
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static struct {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *zName;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_ObjCmdProc *xProc;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } aCmd[] = {
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "sqlite3_shutdown",        (Tcl_ObjCmdProc*)test_shutdown },
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "sqlite3_initialize",      (Tcl_ObjCmdProc*)test_initialize },
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "sqlite3_config",          (Tcl_ObjCmdProc*)test_config },
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "enter_db_mutex",          (Tcl_ObjCmdProc*)test_enter_db_mutex },
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "leave_db_mutex",          (Tcl_ObjCmdProc*)test_leave_db_mutex },
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "alloc_dealloc_mutex",     (Tcl_ObjCmdProc*)test_alloc_mutex },
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "install_mutex_counters",  (Tcl_ObjCmdProc*)test_install_mutex_counters },
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "read_mutex_counters",     (Tcl_ObjCmdProc*)test_read_mutex_counters },
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "clear_mutex_counters",    (Tcl_ObjCmdProc*)test_clear_mutex_counters },
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_LinkVar(interp, "disable_mutex_init",
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              (char*)&g.disableInit, TCL_LINK_INT);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_LinkVar(interp, "disable_mutex_try",
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              (char*)&g.disableTry, TCL_LINK_INT);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SQLITE_OK;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
440