4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
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.
11 *************************************************************************
13 ** The code in this file is used for testing SQLite. It is not part of
14 ** the source code used in production systems.
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
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.
28 #include "sqliteInt.h"
32 static struct Wrapped
{
33 sqlite3_pcache_methods2 pcache
;
34 sqlite3_mem_methods mem
;
35 sqlite3_mutex_methods mutex
;
37 int mem_init
; /* True if mem subsystem is initalized */
38 int mem_fail
; /* True to fail mem subsystem inialization */
39 int mutex_init
; /* True if mutex subsystem is initalized */
40 int mutex_fail
; /* True to fail mutex subsystem inialization */
41 int pcache_init
; /* True if pcache subsystem is initalized */
42 int pcache_fail
; /* True to fail pcache subsystem inialization */
45 static int wrMemInit(void *pAppData
){
47 if( wrapped
.mem_fail
){
50 rc
= wrapped
.mem
.xInit(wrapped
.mem
.pAppData
);
57 static void wrMemShutdown(void *pAppData
){
58 wrapped
.mem
.xShutdown(wrapped
.mem
.pAppData
);
61 static void *wrMemMalloc(int n
) {return wrapped
.mem
.xMalloc(n
);}
62 static void wrMemFree(void *p
) {wrapped
.mem
.xFree(p
);}
63 static void *wrMemRealloc(void *p
, int n
) {return wrapped
.mem
.xRealloc(p
, n
);}
64 static int wrMemSize(void *p
) {return wrapped
.mem
.xSize(p
);}
65 static int wrMemRoundup(int n
) {return wrapped
.mem
.xRoundup(n
);}
68 static int wrMutexInit(void){
70 if( wrapped
.mutex_fail
){
73 rc
= wrapped
.mutex
.xMutexInit();
76 wrapped
.mutex_init
= 1;
80 static int wrMutexEnd(void){
81 wrapped
.mutex
.xMutexEnd();
82 wrapped
.mutex_init
= 0;
85 static sqlite3_mutex
*wrMutexAlloc(int e
){
86 return wrapped
.mutex
.xMutexAlloc(e
);
88 static void wrMutexFree(sqlite3_mutex
*p
){
89 wrapped
.mutex
.xMutexFree(p
);
91 static void wrMutexEnter(sqlite3_mutex
*p
){
92 wrapped
.mutex
.xMutexEnter(p
);
94 static int wrMutexTry(sqlite3_mutex
*p
){
95 return wrapped
.mutex
.xMutexTry(p
);
97 static void wrMutexLeave(sqlite3_mutex
*p
){
98 wrapped
.mutex
.xMutexLeave(p
);
100 static int wrMutexHeld(sqlite3_mutex
*p
){
101 return wrapped
.mutex
.xMutexHeld(p
);
103 static int wrMutexNotheld(sqlite3_mutex
*p
){
104 return wrapped
.mutex
.xMutexNotheld(p
);
109 static int wrPCacheInit(void *pArg
){
111 if( wrapped
.pcache_fail
){
114 rc
= wrapped
.pcache
.xInit(wrapped
.pcache
.pArg
);
117 wrapped
.pcache_init
= 1;
121 static void wrPCacheShutdown(void *pArg
){
122 wrapped
.pcache
.xShutdown(wrapped
.pcache
.pArg
);
123 wrapped
.pcache_init
= 0;
126 static sqlite3_pcache
*wrPCacheCreate(int a
, int b
, int c
){
127 return wrapped
.pcache
.xCreate(a
, b
, c
);
129 static void wrPCacheCachesize(sqlite3_pcache
*p
, int n
){
130 wrapped
.pcache
.xCachesize(p
, n
);
132 static int wrPCachePagecount(sqlite3_pcache
*p
){
133 return wrapped
.pcache
.xPagecount(p
);
135 static sqlite3_pcache_page
*wrPCacheFetch(sqlite3_pcache
*p
, unsigned a
, int b
){
136 return wrapped
.pcache
.xFetch(p
, a
, b
);
138 static void wrPCacheUnpin(sqlite3_pcache
*p
, sqlite3_pcache_page
*a
, int b
){
139 wrapped
.pcache
.xUnpin(p
, a
, b
);
141 static void wrPCacheRekey(
143 sqlite3_pcache_page
*a
,
147 wrapped
.pcache
.xRekey(p
, a
, b
, c
);
149 static void wrPCacheTruncate(sqlite3_pcache
*p
, unsigned a
){
150 wrapped
.pcache
.xTruncate(p
, a
);
152 static void wrPCacheDestroy(sqlite3_pcache
*p
){
153 wrapped
.pcache
.xDestroy(p
);
156 static void installInitWrappers(void){
157 sqlite3_mutex_methods mutexmethods
= {
158 wrMutexInit
, wrMutexEnd
, wrMutexAlloc
,
159 wrMutexFree
, wrMutexEnter
, wrMutexTry
,
160 wrMutexLeave
, wrMutexHeld
, wrMutexNotheld
162 sqlite3_pcache_methods2 pcachemethods
= {
164 wrPCacheInit
, wrPCacheShutdown
, wrPCacheCreate
,
165 wrPCacheCachesize
, wrPCachePagecount
, wrPCacheFetch
,
166 wrPCacheUnpin
, wrPCacheRekey
, wrPCacheTruncate
,
169 sqlite3_mem_methods memmethods
= {
170 wrMemMalloc
, wrMemFree
, wrMemRealloc
,
171 wrMemSize
, wrMemRoundup
, wrMemInit
,
176 memset(&wrapped
, 0, sizeof(wrapped
));
179 sqlite3_config(SQLITE_CONFIG_GETMUTEX
, &wrapped
.mutex
);
180 sqlite3_config(SQLITE_CONFIG_GETMALLOC
, &wrapped
.mem
);
181 sqlite3_config(SQLITE_CONFIG_GETPCACHE2
, &wrapped
.pcache
);
182 sqlite3_config(SQLITE_CONFIG_MUTEX
, &mutexmethods
);
183 sqlite3_config(SQLITE_CONFIG_MALLOC
, &memmethods
);
184 sqlite3_config(SQLITE_CONFIG_PCACHE2
, &pcachemethods
);
187 static int init_wrapper_install(
188 ClientData clientData
, /* Unused */
189 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
190 int objc
, /* Number of arguments */
191 Tcl_Obj
*CONST objv
[] /* Command arguments */
194 installInitWrappers();
195 for(i
=1; i
<objc
; i
++){
196 char *z
= Tcl_GetString(objv
[i
]);
197 if( strcmp(z
, "mem")==0 ){
198 wrapped
.mem_fail
= 1;
199 }else if( strcmp(z
, "mutex")==0 ){
200 wrapped
.mutex_fail
= 1;
201 }else if( strcmp(z
, "pcache")==0 ){
202 wrapped
.pcache_fail
= 1;
204 Tcl_AppendResult(interp
, "Unknown argument: \"", z
, "\"");
211 static int init_wrapper_uninstall(
212 ClientData clientData
, /* Unused */
213 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
214 int objc
, /* Number of arguments */
215 Tcl_Obj
*CONST objv
[] /* Command arguments */
218 Tcl_WrongNumArgs(interp
, 1, objv
, "");
223 sqlite3_config(SQLITE_CONFIG_MUTEX
, &wrapped
.mutex
);
224 sqlite3_config(SQLITE_CONFIG_MALLOC
, &wrapped
.mem
);
225 sqlite3_config(SQLITE_CONFIG_PCACHE2
, &wrapped
.pcache
);
229 static int init_wrapper_clear(
230 ClientData clientData
, /* Unused */
231 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
232 int objc
, /* Number of arguments */
233 Tcl_Obj
*CONST objv
[] /* Command arguments */
236 Tcl_WrongNumArgs(interp
, 1, objv
, "");
240 wrapped
.mem_fail
= 0;
241 wrapped
.mutex_fail
= 0;
242 wrapped
.pcache_fail
= 0;
246 static int init_wrapper_query(
247 ClientData clientData
, /* Unused */
248 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
249 int objc
, /* Number of arguments */
250 Tcl_Obj
*CONST objv
[] /* Command arguments */
255 Tcl_WrongNumArgs(interp
, 1, objv
, "");
260 if( wrapped
.mutex_init
){
261 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewStringObj("mutex", -1));
263 if( wrapped
.mem_init
){
264 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewStringObj("mem", -1));
266 if( wrapped
.pcache_init
){
267 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewStringObj("pcache", -1));
270 Tcl_SetObjResult(interp
, pRet
);
274 int Sqlitetest_init_Init(Tcl_Interp
*interp
){
277 Tcl_ObjCmdProc
*xProc
;
279 {"init_wrapper_install", init_wrapper_install
},
280 {"init_wrapper_query", init_wrapper_query
},
281 {"init_wrapper_uninstall", init_wrapper_uninstall
},
282 {"init_wrapper_clear", init_wrapper_clear
}
286 for(i
=0; i
<sizeof(aObjCmd
)/sizeof(aObjCmd
[0]); i
++){
287 Tcl_CreateObjCommand(interp
, aObjCmd
[i
].zName
, aObjCmd
[i
].xProc
, 0, 0);