⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test_mutex.c

📁 最新的sqlite3.6.2源代码
💻 C
字号:
/*** 2008 June 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.***************************************************************************** ** $Id: test_mutex.c,v 1.11 2008/07/19 13:43:24 danielk1977 Exp $*/#include "tcl.h"#include "sqlite3.h"#include "sqliteInt.h"#include <stdlib.h>#include <assert.h>#include <string.h>/* defined in test1.c */const char *sqlite3TestErrorName(int);/* A countable mutex */struct sqlite3_mutex {  sqlite3_mutex *pReal;  int eType;};/* State variables */static struct test_mutex_globals {  int isInstalled;              /* True if installed */  int disableInit;              /* True to cause sqlite3_initalize() to fail */  int disableTry;               /* True to force sqlite3_mutex_try() to fail */  int isInit;                   /* True if initialized */  sqlite3_mutex_methods m;      /* Interface to "real" mutex system */  int aCounter[8];              /* Number of grabs of each type of mutex */  sqlite3_mutex aStatic[6];     /* The six static mutexes */} g;/* Return true if the countable mutex is currently held */static int counterMutexHeld(sqlite3_mutex *p){  return g.m.xMutexHeld(p->pReal);}/* Return true if the countable mutex is not currently held */static int counterMutexNotheld(sqlite3_mutex *p){  return g.m.xMutexNotheld(p->pReal);}/* Initialize the countable mutex interface** Or, if g.disableInit is non-zero, then do not initialize but instead** return the value of g.disableInit as the result code.  This can be used** to simulate an initialization failure.*/static int counterMutexInit(void){   int rc;  if( g.disableInit ) return g.disableInit;  rc = g.m.xMutexInit();  g.isInit = 1;  return rc;}/*** Uninitialize the mutex subsystem*/static int counterMutexEnd(void){   g.isInit = 0;  return g.m.xMutexEnd();}/*** Allocate a countable mutex*/static sqlite3_mutex *counterMutexAlloc(int eType){  sqlite3_mutex *pReal;  sqlite3_mutex *pRet = 0;  assert( g.isInit );  assert(eType<8 && eType>=0);  pReal = g.m.xMutexAlloc(eType);  if( !pReal ) return 0;  if( eType==SQLITE_MUTEX_FAST || eType==SQLITE_MUTEX_RECURSIVE ){    pRet = (sqlite3_mutex *)malloc(sizeof(sqlite3_mutex));  }else{    pRet = &g.aStatic[eType-2];  }  pRet->eType = eType;  pRet->pReal = pReal;  return pRet;}/*** Free a countable mutex*/static void counterMutexFree(sqlite3_mutex *p){  assert( g.isInit );  g.m.xMutexFree(p->pReal);  if( p->eType==SQLITE_MUTEX_FAST || p->eType==SQLITE_MUTEX_RECURSIVE ){    free(p);  }}/*** Enter a countable mutex.  Block until entry is safe.*/static void counterMutexEnter(sqlite3_mutex *p){  assert( g.isInit );  g.aCounter[p->eType]++;  g.m.xMutexEnter(p->pReal);}/*** Try to enter a mutex.  Return true on success.*/static int counterMutexTry(sqlite3_mutex *p){  assert( g.isInit );  g.aCounter[p->eType]++;  if( g.disableTry ) return SQLITE_BUSY;  return g.m.xMutexTry(p->pReal);}/* Leave a mutex*/static void counterMutexLeave(sqlite3_mutex *p){  assert( g.isInit );  g.m.xMutexLeave(p->pReal);}/*** sqlite3_shutdown*/static int test_shutdown(  void * clientData,  Tcl_Interp *interp,  int objc,  Tcl_Obj *CONST objv[]){  int rc;  if( objc!=1 ){    Tcl_WrongNumArgs(interp, 1, objv, "");    return TCL_ERROR;  }  rc = sqlite3_shutdown();  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);  return TCL_OK;}/*** sqlite3_initialize*/static int test_initialize(  void * clientData,  Tcl_Interp *interp,  int objc,  Tcl_Obj *CONST objv[]){  int rc;  if( objc!=1 ){    Tcl_WrongNumArgs(interp, 1, objv, "");    return TCL_ERROR;  }  rc = sqlite3_initialize();  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);  return TCL_OK;}/*** install_mutex_counters BOOLEAN*/static int test_install_mutex_counters(  void * clientData,  Tcl_Interp *interp,  int objc,  Tcl_Obj *CONST objv[]){  int rc = SQLITE_OK;  int isInstall;  sqlite3_mutex_methods counter_methods = {    counterMutexInit,    counterMutexEnd,    counterMutexAlloc,    counterMutexFree,    counterMutexEnter,    counterMutexTry,    counterMutexLeave,    counterMutexHeld,    counterMutexNotheld  };  if( objc!=2 ){    Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN");    return TCL_ERROR;  }  if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[1], &isInstall) ){    return TCL_ERROR;  }  assert(isInstall==0 || isInstall==1);  assert(g.isInstalled==0 || g.isInstalled==1);  if( isInstall==g.isInstalled ){    Tcl_AppendResult(interp, "mutex counters are ", 0);    Tcl_AppendResult(interp, isInstall?"already installed":"not installed", 0);    return TCL_ERROR;  }  if( isInstall ){    assert( g.m.xMutexAlloc==0 );    rc = sqlite3_config(SQLITE_CONFIG_GETMUTEX, &g.m);    if( rc==SQLITE_OK ){      sqlite3_config(SQLITE_CONFIG_MUTEX, &counter_methods);    }    g.disableTry = 0;  }else{    assert( g.m.xMutexAlloc );    rc = sqlite3_config(SQLITE_CONFIG_MUTEX, &g.m);    memset(&g.m, 0, sizeof(sqlite3_mutex_methods));  }  if( rc==SQLITE_OK ){    g.isInstalled = isInstall;  }  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);  return TCL_OK;}/*** read_mutex_counters*/static int test_read_mutex_counters(  void * clientData,  Tcl_Interp *interp,  int objc,  Tcl_Obj *CONST objv[]){  Tcl_Obj *pRet;  int ii;  char *aName[8] = {    "fast",        "recursive",   "static_master", "static_mem",     "static_mem2", "static_prng", "static_lru",    "static_lru2"  };  if( objc!=1 ){    Tcl_WrongNumArgs(interp, 1, objv, "");    return TCL_ERROR;  }  pRet = Tcl_NewObj();  Tcl_IncrRefCount(pRet);  for(ii=0; ii<8; ii++){    Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(aName[ii], -1));    Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(g.aCounter[ii]));  }  Tcl_SetObjResult(interp, pRet);  Tcl_DecrRefCount(pRet);  return TCL_OK;}/*** clear_mutex_counters*/static int test_clear_mutex_counters(  void * clientData,  Tcl_Interp *interp,  int objc,  Tcl_Obj *CONST objv[]){  int ii;  if( objc!=1 ){    Tcl_WrongNumArgs(interp, 1, objv, "");    return TCL_ERROR;  }  for(ii=0; ii<8; ii++){    g.aCounter[ii] = 0;  }  return TCL_OK;}/*** Create and free a mutex.  Return the mutex pointer.  The pointer** will be invalid since the mutex has already been freed.  The** return pointer just checks to see if the mutex really was allocated.*/static int test_alloc_mutex(  void * clientData,  Tcl_Interp *interp,  int objc,  Tcl_Obj *CONST objv[]){#if SQLITE_THREADSAFE  sqlite3_mutex *p = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);  char zBuf[100];  sqlite3_mutex_free(p);  sqlite3_snprintf(sizeof(zBuf), zBuf, "%p", p);  Tcl_AppendResult(interp, zBuf, (char*)0);#endif  return TCL_OK;}/*** sqlite3_config OPTION**** OPTION can be either one of the keywords:****            SQLITE_CONFIG_SINGLETHREAD**            SQLITE_CONFIG_MULTITHREAD**            SQLITE_CONFIG_SERIALIZED**** Or OPTION can be an raw integer.*/static int test_config(  void * clientData,  Tcl_Interp *interp,  int objc,  Tcl_Obj *CONST objv[]){  struct ConfigOption {    const char *zName;    int iValue;  } aOpt[] = {    {"singlethread", SQLITE_CONFIG_SINGLETHREAD},    {"multithread",  SQLITE_CONFIG_MULTITHREAD},    {"serialized",   SQLITE_CONFIG_SERIALIZED},    {0, 0}  };  int s = sizeof(struct ConfigOption);  int i;  int rc;  if( objc!=2 ){    Tcl_WrongNumArgs(interp, 1, objv, "");    return TCL_ERROR;  }  if( Tcl_GetIndexFromObjStruct(interp, objv[1], aOpt, s, "flag", 0, &i) ){    if( Tcl_GetIntFromObj(interp, objv[1], &i) ){      return TCL_ERROR;    }  }else{    i = aOpt[i].iValue;  }  rc = sqlite3_config(i);  Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_VOLATILE);  return TCL_OK;}int Sqlitetest_mutex_Init(Tcl_Interp *interp){  static struct {    char *zName;    Tcl_ObjCmdProc *xProc;  } aCmd[] = {    { "sqlite3_shutdown",        (Tcl_ObjCmdProc*)test_shutdown },    { "sqlite3_initialize",      (Tcl_ObjCmdProc*)test_initialize },    { "sqlite3_config",          (Tcl_ObjCmdProc*)test_config },    { "alloc_dealloc_mutex",     (Tcl_ObjCmdProc*)test_alloc_mutex },    { "install_mutex_counters",  (Tcl_ObjCmdProc*)test_install_mutex_counters },    { "read_mutex_counters",     (Tcl_ObjCmdProc*)test_read_mutex_counters },    { "clear_mutex_counters",    (Tcl_ObjCmdProc*)test_clear_mutex_counters },  };  int i;  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){    Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);  }  memset(&g, 0, sizeof(g));  Tcl_LinkVar(interp, "disable_mutex_init",               (char*)&g.disableInit, TCL_LINK_INT);  Tcl_LinkVar(interp, "disable_mutex_try",               (char*)&g.disableTry, TCL_LINK_INT);  return SQLITE_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -