1 // 2 // new_handler.cpp 3 // 4 // Copyright (c) Microsoft Corporation. All rights reserved. 5 // 6 // Implementation of the new handler and related functions.. 7 // 8 #include <corecrt_internal.h> 9 #include <new.h> 10 11 // The global new handler. This pointer should only be accessed via the 12 // functions defined in this source file. 13 static __crt_state_management::dual_state_global<_PNH> __acrt_new_handler; 14 15 16 17 // Initializes the new handler to the encoded nullptr value. 18 extern "C" void __cdecl __acrt_initialize_new_handler(void* const encoded_null) 19 { 20 __acrt_new_handler.initialize(reinterpret_cast<_PNH>(encoded_null)); 21 } 22 23 // Sets the new handler to the new new handler and returns the old handler. 24 _PNH __cdecl _set_new_handler(_PNH new_handler) 25 { 26 _PNH result = nullptr; 27 28 __acrt_lock(__acrt_heap_lock); 29 __try 30 { 31 result = __crt_fast_decode_pointer(__acrt_new_handler.value()); 32 __acrt_new_handler.value() = __crt_fast_encode_pointer(new_handler); 33 } 34 __finally 35 { 36 __acrt_unlock(__acrt_heap_lock); 37 } 38 __endtry 39 40 return result; 41 } 42 43 // Sets the new handler to nullptr and returns the old handler. The argument 44 // must be zero. This overload is used to enable a caller to pass nullptr. 45 _PNH __cdecl _set_new_handler(int const new_handler) 46 { 47 // This is referenced only in the Debug CRT build 48 UNREFERENCED_PARAMETER(new_handler); 49 50 _ASSERTE(new_handler == 0); 51 52 return _set_new_handler(__crt_fast_encode_pointer(nullptr)); 53 } 54 55 // Gets the current new handler. 56 _PNH __cdecl _query_new_handler() 57 { 58 _PNH result = nullptr; 59 60 __acrt_lock(__acrt_heap_lock); 61 __try 62 { 63 result = __crt_fast_decode_pointer(__acrt_new_handler.value()); 64 } 65 __finally 66 { 67 __acrt_unlock(__acrt_heap_lock); 68 } 69 __endtry 70 71 return result; 72 } 73 74 // Calls the currently registered new handler with the provided size. If the 75 // new handler succeeds, this function returns 1. This function returns 0 on 76 // failure. The new handler may throw std::bad_alloc. 77 extern "C" int __cdecl _callnewh(size_t const size) 78 { 79 _PNH const pnh = _query_new_handler(); 80 81 if (pnh == nullptr || (*pnh)(size) == 0) 82 return 0; 83 84 return 1; 85 } 86