xref: /sqlite-3.40.0/src/fault.c (revision 78f82d1e)
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 */
92