Annotation of parser3/src/targets/isapi/pool_storage.h, revision 1.19

1.1       paf         1: /** @file
                      2:        Parser: ISAPI: pool storage class decl.
                      3: 
1.19    ! paf         4:        Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com)
1.15      paf         5:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1       paf         6: */
                      7: 
                      8: #ifndef PA_POOL_STORAGE_H
                      9: #define PA_POOL_STORAGE_H
1.17      paf        10: 
1.19    ! paf        11: static const char* IDENT_POOL_STORAGE_H="$Date: 2002/08/01 11:41:21 $";
1.1       paf        12: 
                     13: #include "pa_config_includes.h"
                     14: 
                     15: /**
                     16:        Dumb pool allocations accounter
                     17:        
1.4       paf        18:        @todo implement at least simple suballocations
1.1       paf        19: */
1.12      parser     20: template<class T> class List {
                     21: public:
                     22:        List(int preallocate) : 
                     23:                items((T *)::malloc(preallocate*sizeof(T))),
                     24:                allocated(0),
                     25:                used(0) {
                     26:                if(items) // successfully preallocated?
                     27:                        allocated=preallocate;
                     28:        }
                     29: 
                     30:        ~List() {
                     31:                ::free(items);
                     32:        }
                     33: 
                     34:        bool add(T item) {
                     35:                if(full())
                     36:                        if(!expand())
                     37:                                return false;
                     38: 
                     39:                items[used++]=item;
                     40:                return true;
                     41:        }
1.6       parser     42: 
1.12      parser     43:        void for_each_reverse(void (*callback)(T& info)) {
                     44:                size_t top;
1.6       parser     45: 
1.12      parser     46:                for(top=used; top; )
                     47:                        callback(items[--top]);
                     48:        }
1.6       parser     49: 
1.12      parser     50: private:
1.6       parser     51: 
1.12      parser     52:        bool full() { return used==allocated; }
                     53:        bool expand() {
                     54:                size_t new_allocated=allocated*3/2;
                     55:                T *new_items=(T *)::realloc(items, new_allocated*sizeof(T));
                     56:                if(new_items) {
                     57:                        items=new_items;
                     58:                        allocated=new_allocated;
1.7       parser     59:                        return true;
1.12      parser     60:                } else
                     61:                        return false;                   
                     62:        }
1.6       parser     63: 
1.12      parser     64: private:
1.6       parser     65: 
1.12      parser     66:        T *items;
                     67:        size_t allocated;
                     68:        size_t used;
1.6       parser     69: 
1.12      parser     70: };
1.6       parser     71: 
1.12      parser     72: class Pool_storage {
1.6       parser     73: 
                     74:        struct Cleanup_struct {
                     75:                void (*cleanup) (void *);
                     76:                void *data;
                     77:        };
                     78: 
                     79: 
1.1       paf        80: public:
                     81: 
1.6       parser     82:        Pool_storage() : 
1.16      paf        83: #ifdef _DEBUG
                     84:                fbreak_on_alloc(false),
                     85: #endif
1.8       parser     86:                cleanups(100),
                     87:                allocations(10*0x400) {
1.1       paf        88:        }
                     89: 
1.16      paf        90:        void *malloc(size_t size) {
                     91: #ifdef _DEBUG
                     92:                if(fbreak_on_alloc)
                     93:                        _asm int 3;
                     94: #endif
1.7       parser     95:                void *result=::malloc(size);
                     96:                if(result && !allocations.add(result)) {
                     97:                        ::free(result); result=0;
                     98:                }
                     99:                return result;
                    100:        }
                    101:        void *calloc(size_t size) { 
1.16      paf       102: #ifdef _DEBUG
                    103:                if(fbreak_on_alloc)
                    104:                        _asm int 3;
                    105: #endif
1.7       parser    106:                void *result=::calloc(size, 1);
                    107:                if(result && !allocations.add(result)) {
                    108:                        ::free(result); result=0;
                    109:                }
                    110:                return result;
                    111:        }
1.1       paf       112: 
1.6       parser    113:        bool register_cleanup(void (*cleanup) (void *), void *data) {
                    114:                Cleanup_struct item={cleanup, data};
1.7       parser    115:                return cleanups.add(item)!=0;
1.1       paf       116:        }
                    117: 
1.12      parser    118:        static void cleanup(Cleanup_struct& item) {
                    119:                item.cleanup(item.data);
                    120:        }
                    121: 
                    122:        static void free(void *& item) {
                    123:                ::free(item);  item=0;
                    124:        }
                    125: 
1.6       parser    126:        ~Pool_storage() {
1.8       parser    127:                // cleanups first, because they use some object's memory pointers
1.12      parser    128:                cleanups.for_each_reverse(cleanup);
1.8       parser    129: 
                    130:                // allocations
1.12      parser    131:                allocations.for_each_reverse(free);
1.5       parser    132:        }
1.16      paf       133: 
                    134: #ifdef _DEBUG
                    135: public:
                    136:        bool fbreak_on_alloc;
                    137: #endif
1.5       parser    138: 
1.6       parser    139: private:
1.1       paf       140: 
1.8       parser    141:        List<Cleanup_struct> cleanups;
1.7       parser    142:        List<void *> allocations;
1.1       paf       143: 
                    144: };
                    145: 
                    146: 
                    147: #endif

E-mail: