test_init.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. ** 2009 August 17
  3. **
  4. ** The author disclaims copyright to this source code. In place of
  5. ** a legal notice, here is a blessing:
  6. **
  7. ** May you do good and not evil.
  8. ** May you find forgiveness for yourself and forgive others.
  9. ** May you share freely, never taking more than you give.
  10. **
  11. *************************************************************************
  12. **
  13. ** The code in this file is used for testing SQLite. It is not part of
  14. ** the source code used in production systems.
  15. **
  16. ** Specifically, this file tests the effect of errors while initializing
  17. ** the various pluggable sub-systems from within sqlite3_initialize().
  18. ** If an error occurs in sqlite3_initialize() the following should be
  19. ** true:
  20. **
  21. ** 1) An error code is returned to the user, and
  22. ** 2) A subsequent call to sqlite3_shutdown() calls the shutdown method
  23. ** of those subsystems that were initialized, and
  24. ** 3) A subsequent call to sqlite3_initialize() attempts to initialize
  25. ** the remaining, uninitialized, subsystems.
  26. */
  27. #include "sqliteInt.h"
  28. #include <string.h>
  29. #include <tcl.h>
  30. static struct Wrapped {
  31. sqlite3_pcache_methods2 pcache;
  32. sqlite3_mem_methods mem;
  33. sqlite3_mutex_methods mutex;
  34. int mem_init; /* True if mem subsystem is initalized */
  35. int mem_fail; /* True to fail mem subsystem inialization */
  36. int mutex_init; /* True if mutex subsystem is initalized */
  37. int mutex_fail; /* True to fail mutex subsystem inialization */
  38. int pcache_init; /* True if pcache subsystem is initalized */
  39. int pcache_fail; /* True to fail pcache subsystem inialization */
  40. } wrapped;
  41. static int wrMemInit(void *pAppData){
  42. int rc;
  43. if( wrapped.mem_fail ){
  44. rc = SQLITE_ERROR;
  45. }else{
  46. rc = wrapped.mem.xInit(wrapped.mem.pAppData);
  47. }
  48. if( rc==SQLITE_OK ){
  49. wrapped.mem_init = 1;
  50. }
  51. return rc;
  52. }
  53. static void wrMemShutdown(void *pAppData){
  54. wrapped.mem.xShutdown(wrapped.mem.pAppData);
  55. wrapped.mem_init = 0;
  56. }
  57. static void *wrMemMalloc(int n) {return wrapped.mem.xMalloc(n);}
  58. static void wrMemFree(void *p) {wrapped.mem.xFree(p);}
  59. static void *wrMemRealloc(void *p, int n) {return wrapped.mem.xRealloc(p, n);}
  60. static int wrMemSize(void *p) {return wrapped.mem.xSize(p);}
  61. static int wrMemRoundup(int n) {return wrapped.mem.xRoundup(n);}
  62. static int wrMutexInit(void){
  63. int rc;
  64. if( wrapped.mutex_fail ){
  65. rc = SQLITE_ERROR;
  66. }else{
  67. rc = wrapped.mutex.xMutexInit();
  68. }
  69. if( rc==SQLITE_OK ){
  70. wrapped.mutex_init = 1;
  71. }
  72. return rc;
  73. }
  74. static int wrMutexEnd(void){
  75. wrapped.mutex.xMutexEnd();
  76. wrapped.mutex_init = 0;
  77. return SQLITE_OK;
  78. }
  79. static sqlite3_mutex *wrMutexAlloc(int e){
  80. return wrapped.mutex.xMutexAlloc(e);
  81. }
  82. static void wrMutexFree(sqlite3_mutex *p){
  83. wrapped.mutex.xMutexFree(p);
  84. }
  85. static void wrMutexEnter(sqlite3_mutex *p){
  86. wrapped.mutex.xMutexEnter(p);
  87. }
  88. static int wrMutexTry(sqlite3_mutex *p){
  89. return wrapped.mutex.xMutexTry(p);
  90. }
  91. static void wrMutexLeave(sqlite3_mutex *p){
  92. wrapped.mutex.xMutexLeave(p);
  93. }
  94. static int wrMutexHeld(sqlite3_mutex *p){
  95. return wrapped.mutex.xMutexHeld(p);
  96. }
  97. static int wrMutexNotheld(sqlite3_mutex *p){
  98. return wrapped.mutex.xMutexNotheld(p);
  99. }
  100. static int wrPCacheInit(void *pArg){
  101. int rc;
  102. if( wrapped.pcache_fail ){
  103. rc = SQLITE_ERROR;
  104. }else{
  105. rc = wrapped.pcache.xInit(wrapped.pcache.pArg);
  106. }
  107. if( rc==SQLITE_OK ){
  108. wrapped.pcache_init = 1;
  109. }
  110. return rc;
  111. }
  112. static void wrPCacheShutdown(void *pArg){
  113. wrapped.pcache.xShutdown(wrapped.pcache.pArg);
  114. wrapped.pcache_init = 0;
  115. }
  116. static sqlite3_pcache *wrPCacheCreate(int a, int b, int c){
  117. return wrapped.pcache.xCreate(a, b, c);
  118. }
  119. static void wrPCacheCachesize(sqlite3_pcache *p, int n){
  120. wrapped.pcache.xCachesize(p, n);
  121. }
  122. static int wrPCachePagecount(sqlite3_pcache *p){
  123. return wrapped.pcache.xPagecount(p);
  124. }
  125. static sqlite3_pcache_page *wrPCacheFetch(sqlite3_pcache *p, unsigned a, int b){
  126. return wrapped.pcache.xFetch(p, a, b);
  127. }
  128. static void wrPCacheUnpin(sqlite3_pcache *p, sqlite3_pcache_page *a, int b){
  129. wrapped.pcache.xUnpin(p, a, b);
  130. }
  131. static void wrPCacheRekey(
  132. sqlite3_pcache *p,
  133. sqlite3_pcache_page *a,
  134. unsigned b,
  135. unsigned c
  136. ){
  137. wrapped.pcache.xRekey(p, a, b, c);
  138. }
  139. static void wrPCacheTruncate(sqlite3_pcache *p, unsigned a){
  140. wrapped.pcache.xTruncate(p, a);
  141. }
  142. static void wrPCacheDestroy(sqlite3_pcache *p){
  143. wrapped.pcache.xDestroy(p);
  144. }
  145. static void installInitWrappers(void){
  146. sqlite3_mutex_methods mutexmethods = {
  147. wrMutexInit, wrMutexEnd, wrMutexAlloc,
  148. wrMutexFree, wrMutexEnter, wrMutexTry,
  149. wrMutexLeave, wrMutexHeld, wrMutexNotheld
  150. };
  151. sqlite3_pcache_methods2 pcachemethods = {
  152. 1, 0,
  153. wrPCacheInit, wrPCacheShutdown, wrPCacheCreate,
  154. wrPCacheCachesize, wrPCachePagecount, wrPCacheFetch,
  155. wrPCacheUnpin, wrPCacheRekey, wrPCacheTruncate,
  156. wrPCacheDestroy
  157. };
  158. sqlite3_mem_methods memmethods = {
  159. wrMemMalloc, wrMemFree, wrMemRealloc,
  160. wrMemSize, wrMemRoundup, wrMemInit,
  161. wrMemShutdown,
  162. 0
  163. };
  164. memset(&wrapped, 0, sizeof(wrapped));
  165. sqlite3_shutdown();
  166. sqlite3_config(SQLITE_CONFIG_GETMUTEX, &wrapped.mutex);
  167. sqlite3_config(SQLITE_CONFIG_GETMALLOC, &wrapped.mem);
  168. sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &wrapped.pcache);
  169. sqlite3_config(SQLITE_CONFIG_MUTEX, &mutexmethods);
  170. sqlite3_config(SQLITE_CONFIG_MALLOC, &memmethods);
  171. sqlite3_config(SQLITE_CONFIG_PCACHE2, &pcachemethods);
  172. }
  173. static int init_wrapper_install(
  174. ClientData clientData, /* Unused */
  175. Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
  176. int objc, /* Number of arguments */
  177. Tcl_Obj *CONST objv[] /* Command arguments */
  178. ){
  179. int i;
  180. installInitWrappers();
  181. for(i=1; i<objc; i++){
  182. char *z = Tcl_GetString(objv[i]);
  183. if( strcmp(z, "mem")==0 ){
  184. wrapped.mem_fail = 1;
  185. }else if( strcmp(z, "mutex")==0 ){
  186. wrapped.mutex_fail = 1;
  187. }else if( strcmp(z, "pcache")==0 ){
  188. wrapped.pcache_fail = 1;
  189. }else{
  190. Tcl_AppendResult(interp, "Unknown argument: \"", z, "\"");
  191. return TCL_ERROR;
  192. }
  193. }
  194. return TCL_OK;
  195. }
  196. static int init_wrapper_uninstall(
  197. ClientData clientData, /* Unused */
  198. Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
  199. int objc, /* Number of arguments */
  200. Tcl_Obj *CONST objv[] /* Command arguments */
  201. ){
  202. if( objc!=1 ){
  203. Tcl_WrongNumArgs(interp, 1, objv, "");
  204. return TCL_ERROR;
  205. }
  206. sqlite3_shutdown();
  207. sqlite3_config(SQLITE_CONFIG_MUTEX, &wrapped.mutex);
  208. sqlite3_config(SQLITE_CONFIG_MALLOC, &wrapped.mem);
  209. sqlite3_config(SQLITE_CONFIG_PCACHE2, &wrapped.pcache);
  210. return TCL_OK;
  211. }
  212. static int init_wrapper_clear(
  213. ClientData clientData, /* Unused */
  214. Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
  215. int objc, /* Number of arguments */
  216. Tcl_Obj *CONST objv[] /* Command arguments */
  217. ){
  218. if( objc!=1 ){
  219. Tcl_WrongNumArgs(interp, 1, objv, "");
  220. return TCL_ERROR;
  221. }
  222. wrapped.mem_fail = 0;
  223. wrapped.mutex_fail = 0;
  224. wrapped.pcache_fail = 0;
  225. return TCL_OK;
  226. }
  227. static int init_wrapper_query(
  228. ClientData clientData, /* Unused */
  229. Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
  230. int objc, /* Number of arguments */
  231. Tcl_Obj *CONST objv[] /* Command arguments */
  232. ){
  233. Tcl_Obj *pRet;
  234. if( objc!=1 ){
  235. Tcl_WrongNumArgs(interp, 1, objv, "");
  236. return TCL_ERROR;
  237. }
  238. pRet = Tcl_NewObj();
  239. if( wrapped.mutex_init ){
  240. Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("mutex", -1));
  241. }
  242. if( wrapped.mem_init ){
  243. Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("mem", -1));
  244. }
  245. if( wrapped.pcache_init ){
  246. Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("pcache", -1));
  247. }
  248. Tcl_SetObjResult(interp, pRet);
  249. return TCL_OK;
  250. }
  251. int Sqlitetest_init_Init(Tcl_Interp *interp){
  252. static struct {
  253. char *zName;
  254. Tcl_ObjCmdProc *xProc;
  255. } aObjCmd[] = {
  256. {"init_wrapper_install", init_wrapper_install},
  257. {"init_wrapper_query", init_wrapper_query },
  258. {"init_wrapper_uninstall", init_wrapper_uninstall},
  259. {"init_wrapper_clear", init_wrapper_clear}
  260. };
  261. int i;
  262. for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
  263. Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
  264. }
  265. return TCL_OK;
  266. }