|
1 /* |
|
2 ** 2008 Jan 22 |
|
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 ** $Id: fault.c,v 1.11 2008/09/02 00:52:52 drh Exp $ |
|
14 */ |
|
15 |
|
16 /* |
|
17 ** This file contains code to support the concept of "benign" |
|
18 ** malloc failures (when the xMalloc() or xRealloc() method of the |
|
19 ** sqlite3_mem_methods structure fails to allocate a block of memory |
|
20 ** and returns 0). |
|
21 ** |
|
22 ** Most malloc failures are non-benign. After they occur, SQLite |
|
23 ** abandons the current operation and returns an error code (usually |
|
24 ** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily |
|
25 ** fatal. For example, if a malloc fails while resizing a hash table, this |
|
26 ** is completely recoverable simply by not carrying out the resize. The |
|
27 ** hash table will continue to function normally. So a malloc failure |
|
28 ** during a hash table resize is a benign fault. |
|
29 */ |
|
30 |
|
31 #include "sqliteInt.h" |
|
32 |
|
33 #ifndef SQLITE_OMIT_BUILTIN_TEST |
|
34 |
|
35 /* |
|
36 ** Global variables. |
|
37 */ |
|
38 typedef struct BenignMallocHooks BenignMallocHooks; |
|
39 static SQLITE_WSD struct BenignMallocHooks { |
|
40 void (*xBenignBegin)(void); |
|
41 void (*xBenignEnd)(void); |
|
42 } sqlite3Hooks = { 0, 0 }; |
|
43 |
|
44 /* The "wsdHooks" macro will resolve to the appropriate BenignMallocHooks |
|
45 ** structure. If writable static data is unsupported on the target, |
|
46 ** we have to locate the state vector at run-time. In the more common |
|
47 ** case where writable static data is supported, wsdHooks can refer directly |
|
48 ** to the "sqlite3Hooks" state vector declared above. |
|
49 */ |
|
50 #ifdef SQLITE_OMIT_WSD |
|
51 # define wsdHooksInit \ |
|
52 BenignMallocHooks *x = &GLOBAL(BenignMallocHooks,sqlite3Hooks) |
|
53 # define wsdHooks x[0] |
|
54 #else |
|
55 # define wsdHooksInit |
|
56 # define wsdHooks sqlite3Hooks |
|
57 #endif |
|
58 |
|
59 |
|
60 /* |
|
61 ** Register hooks to call when sqlite3BeginBenignMalloc() and |
|
62 ** sqlite3EndBenignMalloc() are called, respectively. |
|
63 */ |
|
64 void sqlite3BenignMallocHooks( |
|
65 void (*xBenignBegin)(void), |
|
66 void (*xBenignEnd)(void) |
|
67 ){ |
|
68 wsdHooksInit; |
|
69 wsdHooks.xBenignBegin = xBenignBegin; |
|
70 wsdHooks.xBenignEnd = xBenignEnd; |
|
71 } |
|
72 |
|
73 /* |
|
74 ** This (sqlite3EndBenignMalloc()) is called by SQLite code to indicate that |
|
75 ** subsequent malloc failures are benign. A call to sqlite3EndBenignMalloc() |
|
76 ** indicates that subsequent malloc failures are non-benign. |
|
77 */ |
|
78 void sqlite3BeginBenignMalloc(void){ |
|
79 wsdHooksInit; |
|
80 if( wsdHooks.xBenignBegin ){ |
|
81 wsdHooks.xBenignBegin(); |
|
82 } |
|
83 } |
|
84 void sqlite3EndBenignMalloc(void){ |
|
85 wsdHooksInit; |
|
86 if( wsdHooks.xBenignEnd ){ |
|
87 wsdHooks.xBenignEnd(); |
|
88 } |
|
89 } |
|
90 |
|
91 #endif /* #ifndef SQLITE_OMIT_BUILTIN_TEST */ |