Return-Path: Delivered-To: apmail-apr-dev-archive@www.apache.org Received: (qmail 3108 invoked from network); 4 Jun 2008 16:44:53 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 4 Jun 2008 16:44:53 -0000 Received: (qmail 85698 invoked by uid 500); 4 Jun 2008 16:44:55 -0000 Delivered-To: apmail-apr-dev-archive@apr.apache.org Received: (qmail 85653 invoked by uid 500); 4 Jun 2008 16:44:55 -0000 Mailing-List: contact dev-help@apr.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Id: Delivered-To: mailing list dev@apr.apache.org Delivered-To: moderator for dev@apr.apache.org Received: (qmail 43207 invoked by uid 99); 4 Jun 2008 16:21:45 -0000 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: local policy) Message-ID: <4846C11C.6010302@bee-ware.net> Date: Wed, 04 Jun 2008 18:21:48 +0200 From: Yann Lavictoire User-Agent: Mozilla-Thunderbird 2.0.0.14 (X11/20080509) MIME-Version: 1.0 To: Sander Striker CC: dev@apr.apache.org Subject: Re: Opaque apr_pool_t structure References: <48469699.9060203@bee-ware.net> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Checker-Version: SpamAssassin 3.2.3 (2007-08-08) on mail.bee-ware.net X-Virus-Scanned: ClamAV 0.93/7319/Mon Jun 2 02:37:30 2008 on mail.bee-ware.net X-Virus-Status: Clean X-Virus-Checked: Checked by ClamAV on apache.org X-Old-Spam-Status: No, score=-1.4 required=5.0 tests=ALL_TRUSTED autolearn=disabled version=3.2.3 >> I'm making a piece of software that recycles apr_sockets in sockets-pools. > > Have you looked at apr_reslist in apr-util? It looks very interesting, thank you for the hint, however it seems that I have to do the same trick to prevent a leak with my_socket (a stucture containing the apr_socket and other things associated with it). As the pool used to create the reslist is passed to the contructor for its own allocations (my_sockets here), I suppose I have to create a subpool in the constructor where my_socket will be allocated, and keep a reference to the subpool in my_socket to be able to release all that in the destructor. Without this, that is using the reslist pool directly, memory will leak as my_socket allocated fields or even the apr_socket internals (addr and like) will stay in the pool after destruction. Did I miss something ? > >> Each socket is allocated and created on its own pool (not a subpool, or >> exactly a subpool of the internal global pool only). >> I've read on svn programming pages that it is not recommanded to do this, >> but I find it very usefull, that's the power of pools, IMHO. > > The problem is the memory footprint that this brings with it. Each pool > will pre-allocate 8k of memory. Maybe a subpool doesn't pre-allocate memory, or the problem remain with reslists (and the method above I plan to use). > >> Anyway, to make the things clean, I need a way to attach/detach pools >> to/from others, whether the socket belongs to the socket-pool's pool or to >> the user's one. >> >> As the apr_pool_join() function is a noop (and I don't knwow if that's its >> purpose anyway), I used the apr_pool_cleanup_register()ing / >> apr_pool_cleanup_kill()ing mechanism to attach / detach pools between them. >> >> I create a small new API with my pools based on the APR ones, where I can >> attach/detach pools, as I said, but also malloc() and realloc() memories >> attached to a pool (with the same registering mechanism). >> >> My pool struct is like : >> >> struct my_pool_t { >> apr_pool_t pool; >> apr_pool_t *owner; >> }; >> >> And the functions : >> >> apr_status_t my_pool_create(my_pool_t **pool, void *owner); >> apr_status_t my_pool_attach(my_pool_t *pool, void *owner); >> apr_status_t my_pool_detach(my_pool_t *pool); >> >> apr_status_t my_pmalloc(void *pool, apr_size_t size); >> apr_status_t my_pzalloc(void *pool, apr_size_t size); >> apr_status_t my_prealloc(void *pool, void *ptr, apr_size_t size); >> void my_pfree(void *pool, void *ptr); >> >> As you can see with the first element of the struct which is an APR pool and >> 'void*' types used in functions, I expect the functions to be "compatible" >> with the APR ones, that is I can use my_pool_t and apr_pool_t pools >> indistinctly with them (where the type is void*) ... > > That's not the case, see below. > Hum, I see, the pool stands in an allocator node, see below. >> My problem is that I can't initialize my_pool because I haven't got the >> sizeof(apr_pool_t), an opaque structure ... >> >> I understand the advantages of opaque types, but is there a way an >> apr_pool_sizeof() function be added (and exported) in the APR, simply like : >> >> APR_DECLARE(apr_size_t) apr_pool_sizeof(void) >> { >> /* maybe the aligned SIZEOF_POOL_T should be used */ >> return sizeof(apr_pool_t); >> } >> >> With it, I could at least do : >> apr_pool_create(&p, NULL); >> memcpy(my_pool->pool, p, apr_pool_sizeof()) > > This would be a bad idea, as you'd be copying pointers and the like, which > would be off as soon as copied. Even if that were not the case, the apr_pool_t > struct instance lives in an allocated block of memory from which the pool > will hand out memory. This block in turn is managed by an allocator. > But the allocator node shouldn't be destroyed (or reused) while the pool isn't, so I don't see why a copy of the pool couldn't do the job as well. The copy of the pointers and the like still reference the allocator node, and it should work. However all this becomes cheat and I'd better look at apr_reslist. >> Or should I consider using my_p*() functions strictly with my_pools ? >> >> Thanks for your advices, answers. > > Cheers, > > Sander > Cheers, and thanks for your answers, Yann.