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