diff options
| author | frsyuki <frsyuki@users.sourceforge.jp> | 2009-03-01 15:49:24 +0900 |
|---|---|---|
| committer | frsyuki <frsyuki@users.sourceforge.jp> | 2009-03-01 15:49:24 +0900 |
| commit | 21040d9cd3b03ee27248b39a6b657948fdac5f9d (patch) | |
| tree | 77a26af7b379b07eae9ccc06d04349e9cc9e2566 /cpp | |
| parent | 319838e51757b59a9aa9e017491139602bcc1e68 (diff) | |
| download | msgpack-python-21040d9cd3b03ee27248b39a6b657948fdac5f9d.tar.gz | |
zone::push_finalizer reverts memory allocation on exception
Diffstat (limited to 'cpp')
| -rw-r--r-- | cpp/zone.hpp.erb | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/cpp/zone.hpp.erb b/cpp/zone.hpp.erb index 930c8e8..874c900 100644 --- a/cpp/zone.hpp.erb +++ b/cpp/zone.hpp.erb @@ -45,6 +45,8 @@ public: <%}%> private: + void undo_malloc(size_t s); + template <typename T> static void object_destructor(void* obj); @@ -91,14 +93,29 @@ void zone::object_destructor(void* obj) reinterpret_cast<T*>(obj)->~T(); } +inline void zone::undo_malloc(size_t s) +{ + msgpack_zone_chunk* chunk = chunk_array.tail; + chunk->ptr -= s; + chunk->free += s; +} + <%0.upto(GENERATION_LIMIT) {|i|%> template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> T* zone::allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>) { void* x = malloc(sizeof(T)); - push_finalizer(&zone::object_destructor<T>, x); - try { return new (x) T(<%=(1..i).map{|j|"a#{j}"}.join(', ')%>); } - catch (...) { --finalizer_array.tail; throw; } + if(!msgpack_zone_push_finalizer(this, &zone::object_destructor<T>, x)) { + undo_malloc(sizeof(T)); + throw std::bad_alloc(); + } + try { + return new (x) T(<%=(1..i).map{|j|"a#{j}"}.join(', ')%>); + } catch (...) { + --finalizer_array.tail; + undo_malloc(sizeof(T)); + throw; + } } <%}%> |
