1 // This module exists because there is code run by signal handlers that allocate memory. Most 2 // notably `job_waitsafe()`. They need to know if it is safe to do so. So we wrap the malloc family 3 // of functions. See issue #563. 4 // 5 // TODO: Refactor those signal handlers so they only use async safe functions. Then remove this 6 // code. 7 // 8 #define NO_MALLOC_WRAPPERS 1 9 #include "config_ast.h" 10 11 #include <stdbool.h> 12 13 #if _hdr_stdlib 14 #include <stdlib.h> 15 #elif _hdr_malloc 16 #include <malloc.h> 17 #endif 18 19 #include "ast_assert.h" 20 21 volatile bool vmbusy_flag = false; 22 ast_malloc(size_t size)23void *ast_malloc(size_t size) { 24 vmbusy_flag = true; 25 void *p = malloc(size); 26 vmbusy_flag = false; 27 return p; 28 } 29 ast_calloc(size_t count,size_t size)30void *ast_calloc(size_t count, size_t size) { 31 vmbusy_flag = true; 32 void *p = calloc(count, size); 33 vmbusy_flag = false; 34 assert(p); 35 return p; 36 } 37 ast_realloc(void * ptr,size_t size)38void *ast_realloc(void *ptr, size_t size) { 39 vmbusy_flag = true; 40 void *p = realloc(ptr, size); 41 vmbusy_flag = false; 42 // On platforms like FreeBSD realloc with size == 0 frees the buffer and returns NULL. On other 43 // platforms a size of zero gets you a minimally sized block (typically four or eight bytes). 44 assert(!size || p); 45 return p; 46 } 47 ast_free(void * ptr)48void ast_free(void *ptr) { 49 vmbusy_flag = true; 50 free(ptr); 51 vmbusy_flag = false; 52 } 53