Annotation of parser3/src/targets/cgi/pool_storage.h, revision 1.6

1.1       parser      1: /** @file
1.6     ! paf         2:        Parser: ISAPI: pool storage class decl.
1.1       parser      3: 
                      4:        Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
1.5       paf         5:        Author: Alexander Petrosyan <paf@design.ru> (http://paf.design.ru)
1.1       parser      6: 
1.6     ! paf         7:        $Id: pool_storage.h,v 1.13 2001/11/05 11:46:31 paf Exp $
1.1       parser      8: */
                      9: 
                     10: #ifndef PA_POOL_STORAGE_H
                     11: #define PA_POOL_STORAGE_H
                     12: 
                     13: #include "pa_config_includes.h"
                     14: 
                     15: /**
                     16:        Dumb pool allocations accounter
                     17:        
                     18:        @todo implement at least simple suballocations
                     19: */
1.4       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:        }
1.2       parser     29: 
1.4       parser     30:        ~List() {
1.6     ! paf        31:                if(items)
        !            32:                    ::free(items);
        !            33:                items=0;
        !            34:                used=0;
1.4       parser     35:        }
1.1       parser     36: 
1.4       parser     37:        bool add(T item) {
                     38:                if(full())
                     39:                        if(!expand())
                     40:                                return false;
                     41: 
                     42:                items[used++]=item;
                     43:                return true;
                     44:        }
                     45: 
                     46:        void for_each_reverse(void (*callback)(T& info)) {
                     47:                size_t top;
                     48: 
                     49:                for(top=used; top; )
                     50:                        callback(items[--top]);
                     51:        }
                     52: 
1.6     ! paf        53: size_t size() { return used; }
1.4       parser     54: private:
                     55: 
                     56:        bool full() { return used==allocated; }
                     57:        bool expand() {
                     58:                size_t new_allocated=allocated*3/2;
                     59:                T *new_items=(T *)::realloc(items, new_allocated*sizeof(T));
                     60:                if(new_items) {
                     61:                        items=new_items;
                     62:                        allocated=new_allocated;
1.1       parser     63:                        return true;
1.4       parser     64:                } else
                     65:                        return false;                   
                     66:        }
1.1       parser     67: 
1.4       parser     68: private:
1.1       parser     69: 
1.4       parser     70:        T *items;
                     71:        size_t allocated;
                     72:        size_t used;
1.1       parser     73: 
1.4       parser     74: };
1.1       parser     75: 
1.2       parser     76: class Pool_storage {
1.6     ! paf        77: 
1.1       parser     78:        struct Cleanup_struct {
                     79:                void (*cleanup) (void *);
                     80:                void *data;
                     81:        };
                     82: 
                     83: 
                     84: public:
                     85: 
                     86:        Pool_storage() : 
1.6     ! paf        87:                cleanups(100),
        !            88:                allocations(10*0x400) {
        !            89:        }
        !            90: 
        !            91:        void *malloc(size_t size) { 
        !            92: //fprintf(stderr, "malloc: %d\n", size);
        !            93:                void *result=::malloc(size);
        !            94:                if(result && !allocations.add(result)) {
        !            95:                        ::free(result); result=0;
        !            96:                }
        !            97:                return result;
        !            98:        }
        !            99:        void *calloc(size_t size) { 
        !           100:                void *result=::calloc(size, 1);
        !           101:                if(result && !allocations.add(result)) {
        !           102:                        ::free(result); result=0;
        !           103:                }
        !           104:                return result;
1.1       parser    105:        }
                    106: 
                    107:        bool register_cleanup(void (*cleanup) (void *), void *data) {
                    108:                Cleanup_struct item={cleanup, data};
                    109:                return cleanups.add(item)!=0;
                    110:        }
                    111: 
1.4       parser    112:        static void cleanup(Cleanup_struct& item) {
                    113:                item.cleanup(item.data);
                    114:        }
                    115: 
1.6     ! paf       116:        static void free(void *& item) {
        !           117:                ::free(item);  item=0;
        !           118:        }
        !           119: 
1.1       parser    120:        ~Pool_storage() {
1.6     ! paf       121: //     __asm__("int3");
        !           122: //fprintf(stderr, "cleanups: %d\n", cleanups.size());
1.1       parser    123:                // cleanups first, because they use some object's memory pointers
1.4       parser    124:                cleanups.for_each_reverse(cleanup);
1.6     ! paf       125:                
        !           126: //fprintf(stderr, "allocs: %d\n", allocations.size());
        !           127:                // allocations
        !           128:                allocations.for_each_reverse(free);
1.1       parser    129:        }
                    130: 
                    131: private:
                    132: 
                    133:        List<Cleanup_struct> cleanups;
1.6     ! paf       134:        List<void *> allocations;
1.1       parser    135: 
                    136: };
                    137: 
                    138: 
                    139: #endif

E-mail: