|
|
| version 1.18, 2001/05/17 19:33:33 | version 1.67, 2023/09/26 20:49:10 |
|---|---|
| Line 1 | Line 1 |
| /** @file | /** @file |
| Parser: pool class. | Parser: pool class. |
| Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) | Copyright (c) 2000-2023 Art. Lebedev Studio (http://www.artlebedev.com) |
| Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru> | |
| Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf) | |
| $Id$ | |
| */ | */ |
| #include "pa_pool.h" | #include "pa_pool.h" |
| #include "pa_exception.h" | #include "pa_exception.h" |
| #include "pa_common.h" | |
| #include "pa_sapi.h" | |
| #include "pa_charset.h" | |
| volatile const char * IDENT_PA_POOL_C="$Id$" IDENT_PA_POOL_H; | |
| // Pool | |
| Pool::Pool(){} | |
| static void cleanup(Pool::Cleanup item, int) { | |
| if(item.cleanup) | |
| item.cleanup(item.data); | |
| } | |
| Pool::~Pool() { | |
| //__asm__("int3"); | |
| //_asm int 3; | |
| //fprintf(stderr, "cleanups: %d\n", cleanups.size()); | |
| // cleanups first, because they use some object's memory pointers | |
| cleanups.for_each(cleanup, 0); | |
| } | |
| void Pool::register_cleanup(void (*cleanup) (void *), void *data) { | |
| cleanups+=Cleanup(cleanup, data); | |
| } | |
| static void unregister_cleanup(Pool::Cleanup& item, void* cleanup_data) { | |
| if(item.data==cleanup_data) | |
| item.cleanup=0; | |
| } | |
| void Pool::unregister_cleanup(void *cleanup_data) { | |
| cleanups.for_each_ref(::unregister_cleanup, cleanup_data); | |
| } | |
| // Pooled | |
| static void cleanup(void *data) { | |
| static_cast<Pooled*>(data)->~Pooled(); | |
| } | |
| Pooled::Pooled(Pool& apool): fpool(apool) { | |
| fpool.register_cleanup(cleanup, this); | |
| } | |
| void Pool::fail(size_t size) const { | /// Sole: this got called automatically from Pool::~Pool() |
| fexception->_throw(0, 0, | Pooled::~Pooled() { |
| 0, | fpool.unregister_cleanup(this); |
| "failed to allocate %u bytes", size); | |
| } | } |