blob: b36dd363019d38933db8f87fbbf370f7be5033fa [file] [log] [blame]
drh643167f2008-01-22 21:30:53 +00001/*
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*************************************************************************
drh643167f2008-01-22 21:30:53 +000012**
drh78f82d12008-09-02 00:52:52 +000013** $Id: fault.c,v 1.11 2008/09/02 00:52:52 drh Exp $
danielk19772d1d86f2008-06-20 14:59:51 +000014*/
15
16/*
danielk1977ef05f2d2008-06-20 11:05:37 +000017** This file contains code to support the concept of "benign"
danielk19772d1d86f2008-06-20 14:59:51 +000018** 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).
drh643167f2008-01-22 21:30:53 +000021**
danielk19772d1d86f2008-06-20 14:59:51 +000022** 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.
drh643167f2008-01-22 21:30:53 +000029*/
danielk1977ef05f2d2008-06-20 11:05:37 +000030
drh643167f2008-01-22 21:30:53 +000031#include "sqliteInt.h"
32
danielk1977ef05f2d2008-06-20 11:05:37 +000033#ifndef SQLITE_OMIT_BUILTIN_TEST
danielk1977d09414c2008-06-19 18:17:49 +000034
35/*
danielk19772d1d86f2008-06-20 14:59:51 +000036** Global variables.
danielk1977d09414c2008-06-19 18:17:49 +000037*/
drh78f82d12008-09-02 00:52:52 +000038typedef struct BenignMallocHooks BenignMallocHooks;
39static SQLITE_WSD struct BenignMallocHooks {
danielk19772d1d86f2008-06-20 14:59:51 +000040 void (*xBenignBegin)(void);
41 void (*xBenignEnd)(void);
drh78f82d12008-09-02 00:52:52 +000042} 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
danielk1977d09414c2008-06-19 18:17:49 +000059
60/*
danielk19772d1d86f2008-06-20 14:59:51 +000061** Register hooks to call when sqlite3BeginBenignMalloc() and
62** sqlite3EndBenignMalloc() are called, respectively.
danielk1977d09414c2008-06-19 18:17:49 +000063*/
danielk19772d1d86f2008-06-20 14:59:51 +000064void sqlite3BenignMallocHooks(
65 void (*xBenignBegin)(void),
66 void (*xBenignEnd)(void)
67){
drh78f82d12008-09-02 00:52:52 +000068 wsdHooksInit;
69 wsdHooks.xBenignBegin = xBenignBegin;
70 wsdHooks.xBenignEnd = xBenignEnd;
danielk1977d09414c2008-06-19 18:17:49 +000071}
72
danielk19772d1d86f2008-06-20 14:59:51 +000073/*
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.
drh643167f2008-01-22 21:30:53 +000077*/
danielk19772d1d86f2008-06-20 14:59:51 +000078void sqlite3BeginBenignMalloc(void){
drh78f82d12008-09-02 00:52:52 +000079 wsdHooksInit;
80 if( wsdHooks.xBenignBegin ){
81 wsdHooks.xBenignBegin();
danielk19772d1d86f2008-06-20 14:59:51 +000082 }
drh4873d5f2008-05-13 13:27:33 +000083}
danielk19772d1d86f2008-06-20 14:59:51 +000084void sqlite3EndBenignMalloc(void){
drh78f82d12008-09-02 00:52:52 +000085 wsdHooksInit;
86 if( wsdHooks.xBenignEnd ){
87 wsdHooks.xBenignEnd();
danielk19772d1d86f2008-06-20 14:59:51 +000088 }
drh643167f2008-01-22 21:30:53 +000089}
90
danielk1977ef05f2d2008-06-20 11:05:37 +000091#endif /* #ifndef SQLITE_OMIT_BUILTIN_TEST */