windows-nt/Source/XPSP1/NT/base/crts/crtw32/heap/handler.cpp
2020-09-26 16:20:57 +08:00

162 lines
4.5 KiB
C++

/***
*handler.cpp - defines C++ setHandler routine
*
* Copyright (c) 1990-2001, Microsoft Corporation. All rights reserved.
*
*Purpose:
* Defines C++ setHandler routine.
*
*Revision History:
* 05-07-90 WAJ Initial version.
* 08-30-90 WAJ new now takes unsigned ints.
* 08-08-91 JCR call _halloc/_hfree, not halloc/hfree
* 08-13-91 KRS Change new.hxx to new.h. Fix copyright.
* 08-13-91 JCR ANSI-compatible _set_new_handler names
* 10-30-91 JCR Split new, delete, and handler into seperate sources
* 11-13-91 JCR 32-bit version
* 06-15-92 KRS Remove per-thread handler for multi-thread libs
* 03-02-94 SKS Add _query_new_handler(), remove commented out
* per-thread thread handler version of _set_new_h code.
* 04-01-94 GJF Made declaration of _pnhHeap conditional on ndef
* DLL_FOR_WIN32S.
* 05-03-94 CFW Add set_new_handler.
* 06-03-94 SKS Remove set_new_hander -- it does NOT conform to ANSI
* C++ working standard. We may implement it later.
* 09-21-94 SKS Fix typo: no leading _ on "DLL_FOR_WIN32S"
* 02-01-95 GJF Merged in common\handler.cxx (used for Mac).
* 02-01-95 GJF Comment out _query_new_handler for Mac builds
* (temporary).
* 04-13-95 CFW Add set_new_handler stub (asserts on non-NULL handler).
* 05-08-95 CFW Official ANSI C++ new handler added.
* 06-23-95 CFW ANSI new handler removed from build.
* 12-28-95 JWM set_new_handler() moved to setnewh.cpp for granularity.
* 10-02-96 GJF In _callnewh, use a local to hold the value of _pnhHeap
* instead of asserting _HEAP_LOCK.
* 09-22-97 JWM "OBSOLETE" warning removed from _set_new_handler().
* 05-13-99 PML Remove Win32s
*
*******************************************************************************/
#include <stddef.h>
#include <internal.h>
#include <cruntime.h>
#include <mtdll.h>
#include <process.h>
#include <new.h>
#include <dbgint.h>
/* pointer to old-style C++ new handler */
_PNH _pnhHeap;
/***
*_PNH _set_new_handler(_PNH pnh) - set the new handler
*
*Purpose:
* _set_new_handler is different from the ANSI C++ working standard definition
* of set_new_handler. Therefore it has a leading underscore in its name.
*
*Entry:
* Pointer to the new handler to be installed.
*
*Return:
* Previous new handler
*
*******************************************************************************/
_PNH __cdecl _set_new_handler(
_PNH pnh
)
{
_PNH pnhOld;
/* lock the heap */
_mlock(_HEAP_LOCK);
pnhOld = _pnhHeap;
_pnhHeap = pnh;
/* unlock the heap */
_munlock(_HEAP_LOCK);
return(pnhOld);
}
/***
*_PNH _query_new_handler(void) - query value of new handler
*
*Purpose:
* Obtain current new handler value.
*
*Entry:
* None
*
* WARNING: This function is OBSOLETE. Use _query_new_ansi_handler instead.
*
*Return:
* Currently installed new handler
*
*******************************************************************************/
_PNH __cdecl _query_new_handler (
void
)
{
return _pnhHeap;
}
/***
*int _callnewh - call the appropriate new handler
*
*Purpose:
* Call the appropriate new handler.
*
*Entry:
* None
*
*Return:
* 1 for success
* 0 for failure
* may throw bad_alloc
*
*******************************************************************************/
extern "C" int __cdecl _callnewh(size_t size)
{
#ifdef ANSI_NEW_HANDLER
/*
* if ANSI C++ new handler is activated but not installed, throw exception
*/
#ifdef _MT
_ptiddata ptd;
ptd = _getptd();
if (ptd->_newh == NULL)
throw bad_alloc();
#else
if (_defnewh == NULL)
throw bad_alloc();
#endif
/*
* if ANSI C++ new handler activated and installed, call it
* if it returns, the new handler was successful, retry allocation
*/
#ifdef _MT
if (ptd->_newh != _NO_ANSI_NEW_HANDLER)
(*(ptd->_newh))();
#else
if (_defnewh != _NO_ANSI_NEW_HANDLER)
(*_defnewh)();
#endif
/* ANSI C++ new handler is inactivated, call old handler if installed */
else
#endif /* ANSI_NEW_HANDLER */
{
_PNH pnh = _pnhHeap;
if ( (pnh == NULL) || ((*pnh)(size) == 0) )
return 0;
}
return 1;
}