Merge "Add support for std::set_new_handler in Gabi++"
diff --git a/sources/cxx-stl/gabi++/include/new b/sources/cxx-stl/gabi++/include/new
index 7687c9b..d66fef7 100644
--- a/sources/cxx-stl/gabi++/include/new
+++ b/sources/cxx-stl/gabi++/include/new
@@ -48,6 +48,9 @@
virtual const char* what() const throw();
};
+typedef void (*new_handler)();
+new_handler set_new_handler(new_handler) throw();
+
}
void* operator new(std::size_t size) throw(std::bad_alloc);
diff --git a/sources/cxx-stl/gabi++/src/new.cc b/sources/cxx-stl/gabi++/src/new.cc
index 8148556..f65a291 100644
--- a/sources/cxx-stl/gabi++/src/new.cc
+++ b/sources/cxx-stl/gabi++/src/new.cc
@@ -29,6 +29,11 @@
#include <stdlib.h>
#include <new>
+using std::new_handler;
+namespace {
+ new_handler cur_handler;
+}
+
namespace std {
#if !defined(GABIXX_LIBCXX)
@@ -45,21 +50,37 @@
return "std::bad_alloc";
}
+ new_handler set_new_handler(new_handler next_handler) throw() {
+ new_handler old_handler = cur_handler;
+ cur_handler = next_handler;
+ return old_handler;
+ }
+
} // namespace std
__attribute__ ((weak))
void* operator new(std::size_t size) throw(std::bad_alloc) {
- void* space = ::operator new(size, std::nothrow_t());
- if (space) {
- return space;
- } else {
- throw std::bad_alloc();
- }
+ void* space;
+ do {
+ space = malloc(size);
+ if (space) {
+ return space;
+ }
+ new_handler handler = cur_handler;
+ if (handler == NULL) {
+ throw std::bad_alloc();
+ }
+ handler();
+ } while (space == 0);
}
__attribute__ ((weak))
void* operator new(std::size_t size, const std::nothrow_t& no) throw() {
- return malloc(size);
+ try {
+ ::operator new(size);
+ } catch (const std::bad_alloc&) {
+ return 0;
+ }
}
__attribute__ ((weak))