1643167ffSdrh /*
2643167ffSdrh ** 2008 Jan 22
3643167ffSdrh **
4643167ffSdrh ** The author disclaims copyright to this source code. In place of
5643167ffSdrh ** a legal notice, here is a blessing:
6643167ffSdrh **
7643167ffSdrh ** May you do good and not evil.
8643167ffSdrh ** May you find forgiveness for yourself and forgive others.
9643167ffSdrh ** May you share freely, never taking more than you give.
10643167ffSdrh **
11643167ffSdrh *************************************************************************
12643167ffSdrh **
13ef05f2dfSdanielk1977 ** This file contains code to support the concept of "benign"
142d1d86fbSdanielk1977 ** malloc failures (when the xMalloc() or xRealloc() method of the
152d1d86fbSdanielk1977 ** sqlite3_mem_methods structure fails to allocate a block of memory
162d1d86fbSdanielk1977 ** and returns 0).
17643167ffSdrh **
182d1d86fbSdanielk1977 ** Most malloc failures are non-benign. After they occur, SQLite
192d1d86fbSdanielk1977 ** abandons the current operation and returns an error code (usually
202d1d86fbSdanielk1977 ** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily
212d1d86fbSdanielk1977 ** fatal. For example, if a malloc fails while resizing a hash table, this
222d1d86fbSdanielk1977 ** is completely recoverable simply by not carrying out the resize. The
232d1d86fbSdanielk1977 ** hash table will continue to function normally. So a malloc failure
242d1d86fbSdanielk1977 ** during a hash table resize is a benign fault.
25643167ffSdrh */
26ef05f2dfSdanielk1977
27643167ffSdrh #include "sqliteInt.h"
28643167ffSdrh
29*d12602a9Sdrh #ifndef SQLITE_UNTESTABLE
30ef05f2dfSdanielk1977
31643167ffSdrh /*
322d1d86fbSdanielk1977 ** Global variables.
33643167ffSdrh */
3478f82d1eSdrh typedef struct BenignMallocHooks BenignMallocHooks;
3578f82d1eSdrh static SQLITE_WSD struct BenignMallocHooks {
362d1d86fbSdanielk1977 void (*xBenignBegin)(void);
372d1d86fbSdanielk1977 void (*xBenignEnd)(void);
3878f82d1eSdrh } sqlite3Hooks = { 0, 0 };
3978f82d1eSdrh
4078f82d1eSdrh /* The "wsdHooks" macro will resolve to the appropriate BenignMallocHooks
4178f82d1eSdrh ** structure. If writable static data is unsupported on the target,
4278f82d1eSdrh ** we have to locate the state vector at run-time. In the more common
4378f82d1eSdrh ** case where writable static data is supported, wsdHooks can refer directly
4478f82d1eSdrh ** to the "sqlite3Hooks" state vector declared above.
4578f82d1eSdrh */
4678f82d1eSdrh #ifdef SQLITE_OMIT_WSD
4778f82d1eSdrh # define wsdHooksInit \
4878f82d1eSdrh BenignMallocHooks *x = &GLOBAL(BenignMallocHooks,sqlite3Hooks)
4978f82d1eSdrh # define wsdHooks x[0]
5078f82d1eSdrh #else
5178f82d1eSdrh # define wsdHooksInit
5278f82d1eSdrh # define wsdHooks sqlite3Hooks
5378f82d1eSdrh #endif
5478f82d1eSdrh
55d09414cdSdanielk1977
56d09414cdSdanielk1977 /*
572d1d86fbSdanielk1977 ** Register hooks to call when sqlite3BeginBenignMalloc() and
582d1d86fbSdanielk1977 ** sqlite3EndBenignMalloc() are called, respectively.
59d09414cdSdanielk1977 */
sqlite3BenignMallocHooks(void (* xBenignBegin)(void),void (* xBenignEnd)(void))602d1d86fbSdanielk1977 void sqlite3BenignMallocHooks(
612d1d86fbSdanielk1977 void (*xBenignBegin)(void),
622d1d86fbSdanielk1977 void (*xBenignEnd)(void)
632d1d86fbSdanielk1977 ){
6478f82d1eSdrh wsdHooksInit;
6578f82d1eSdrh wsdHooks.xBenignBegin = xBenignBegin;
6678f82d1eSdrh wsdHooks.xBenignEnd = xBenignEnd;
67d09414cdSdanielk1977 }
68d09414cdSdanielk1977
69d09414cdSdanielk1977 /*
702d1d86fbSdanielk1977 ** This (sqlite3EndBenignMalloc()) is called by SQLite code to indicate that
712d1d86fbSdanielk1977 ** subsequent malloc failures are benign. A call to sqlite3EndBenignMalloc()
722d1d86fbSdanielk1977 ** indicates that subsequent malloc failures are non-benign.
73643167ffSdrh */
sqlite3BeginBenignMalloc(void)742d1d86fbSdanielk1977 void sqlite3BeginBenignMalloc(void){
7578f82d1eSdrh wsdHooksInit;
7678f82d1eSdrh if( wsdHooks.xBenignBegin ){
7778f82d1eSdrh wsdHooks.xBenignBegin();
784873d5f6Sdrh }
792d1d86fbSdanielk1977 }
sqlite3EndBenignMalloc(void)802d1d86fbSdanielk1977 void sqlite3EndBenignMalloc(void){
8178f82d1eSdrh wsdHooksInit;
8278f82d1eSdrh if( wsdHooks.xBenignEnd ){
8378f82d1eSdrh wsdHooks.xBenignEnd();
842d1d86fbSdanielk1977 }
8519db9352Sdrh }
86643167ffSdrh
87*d12602a9Sdrh #endif /* #ifndef SQLITE_UNTESTABLE */
88