--- parser3/src/targets/cgi/Attic/pool_storage.h 2001/10/24 16:20:39 1.2 +++ parser3/src/targets/cgi/Attic/pool_storage.h 2001/12/13 11:29:22 1.6 @@ -1,10 +1,10 @@ /** @file - Parser: CGI: pool storage class decl. + Parser: ISAPI: pool storage class decl. Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) - Author: Alexander Petrosyan (http://design.ru/paf) + Author: Alexander Petrosyan (http://paf.design.ru) - $Id: pool_storage.h,v 1.2 2001/10/24 16:20:39 parser Exp $ + $Id: pool_storage.h,v 1.6 2001/12/13 11:29:22 paf Exp $ */ #ifndef PA_POOL_STORAGE_H @@ -17,56 +17,64 @@ @todo implement at least simple suballocations */ +template class List { +public: + List(int preallocate) : + items((T *)::malloc(preallocate*sizeof(T))), + allocated(0), + used(0) { + if(items) // successfully preallocated? + allocated=preallocate; + } -class Pool_storage; + ~List() { + if(items) + ::free(items); + items=0; + used=0; + } - template class List { - friend Pool_storage; - public: - List(int preallocate) : - items((T *)::malloc(preallocate*sizeof(T))), - allocated(0), - used(0) { - if(items) // successfully preallocated? - allocated=preallocate; - } + bool add(T item) { + if(full()) + if(!expand()) + return false; - ~List() { - ::free(items); - } + items[used++]=item; + return true; + } - bool add(T item) { - if(full()) - if(!expand()) - return false; + void for_each_reverse(void (*callback)(T& info)) { + size_t top; - items[used++]=item; - return true; - } + for(top=used; top; ) + callback(items[--top]); + } - private: +size_t size() { return used; } +private: - bool full() { return used==allocated; } - bool expand() { - size_t new_allocated=allocated*3/2; - T *new_items=(T *)::realloc(items, new_allocated*sizeof(T)); - if(new_items) { - items=new_items; - allocated=new_allocated; - return true; - } else - return false; - } + bool full() { return used==allocated; } + bool expand() { + size_t new_allocated=allocated*3/2; + T *new_items=(T *)::realloc(items, new_allocated*sizeof(T)); + if(new_items) { + items=new_items; + allocated=new_allocated; + return true; + } else + return false; + } - private: +private: - T *items; - size_t allocated; - size_t used; + T *items; + size_t allocated; + size_t used; - }; +}; class Pool_storage { + struct Cleanup_struct { void (*cleanup) (void *); void *data; @@ -76,7 +84,24 @@ class Pool_storage { public: Pool_storage() : - cleanups(100) { + cleanups(100), + allocations(10*0x400) { + } + + void *malloc(size_t size) { +//fprintf(stderr, "malloc: %d\n", size); + void *result=::malloc(size); + if(result && !allocations.add(result)) { + ::free(result); result=0; + } + return result; + } + void *calloc(size_t size) { + void *result=::calloc(size, 1); + if(result && !allocations.add(result)) { + ::free(result); result=0; + } + return result; } bool register_cleanup(void (*cleanup) (void *), void *data) { @@ -84,20 +109,29 @@ public: return cleanups.add(item)!=0; } - ~Pool_storage() { - size_t top; + static void cleanup(Cleanup_struct& item) { + item.cleanup(item.data); + } + static void free(void *& item) { + ::free(item); item=0; + } + + ~Pool_storage() { +// __asm__("int3"); +//fprintf(stderr, "cleanups: %d\n", cleanups.size()); // cleanups first, because they use some object's memory pointers - // Cleanup_structs - for(top=cleanups.used; top; ) { - Cleanup_struct& item=cleanups.items[--top]; - item.cleanup(item.data); - } + cleanups.for_each_reverse(cleanup); + +//fprintf(stderr, "allocs: %d\n", allocations.size()); + // allocations + allocations.for_each_reverse(free); } private: List cleanups; + List allocations; };