Return-Path: Delivered-To: apmail-apache-cvs-archive@apache.org Received: (qmail 92732 invoked by uid 500); 1 Dec 2000 00:46:48 -0000 Mailing-List: contact apache-cvs-help@apache.org; run by ezmlm Precedence: bulk Reply-To: new-httpd@apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list apache-cvs@apache.org Received: (qmail 92715 invoked by uid 500); 1 Dec 2000 00:46:48 -0000 Delivered-To: apmail-apache-2.0-cvs@apache.org Date: 1 Dec 2000 00:46:48 -0000 Message-ID: <20001201004648.92701.qmail@locus.apache.org> From: gstein@locus.apache.org To: apache-2.0-cvs@apache.org Subject: cvs commit: apache-2.0/src/lib/sdbm sdbm.c sdbm_private.h gstein 00/11/30 16:46:47 Modified: src/lib/sdbm sdbm.c sdbm_private.h Log: Allocate the SDBM structure using malloc/free rather than a pool. register a pool cleanup as a backup, but allow "early freeing" via sdbm_close. Concept from Ryan Bloom. Revision Changes Path 1.11 +78 -51 apache-2.0/src/lib/sdbm/sdbm.c Index: sdbm.c =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/sdbm/sdbm.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -u -r1.10 -r1.11 --- sdbm.c 2000/11/29 10:51:17 1.10 +++ sdbm.c 2000/12/01 00:46:47 1.11 @@ -72,6 +72,7 @@ #include "apr_errno.h" #include /* for memset() */ +#include /* for malloc() and free() */ /* * forward @@ -111,6 +112,18 @@ const sdbm_datum sdbm_nullitem = { NULL, 0 }; +static apr_status_t database_cleanup(void *data) +{ + SDBM *db = data; + + (void) apr_close(db->dirf); + (void) sdbm_unlock(db); + (void) apr_close(db->pagf); + free(db); + + return APR_SUCCESS; +} + apr_status_t sdbm_open(SDBM **db, const char *file, apr_int32_t flags, apr_fileperms_t perms, apr_pool_t *p) { @@ -121,71 +134,85 @@ } apr_status_t -sdbm_prep(SDBM **db, const char *dirname, const char *pagname, +sdbm_prep(SDBM **pdb, const char *dirname, const char *pagname, apr_int32_t flags, apr_fileperms_t perms, apr_pool_t *p) { - struct apr_finfo_t finfo; + SDBM *db; + apr_finfo_t finfo; apr_status_t status; - *db = (SDBM *) apr_pcalloc(p, sizeof(SDBM)); - -/* - * adjust user flags so that WRONLY becomes RDWR, - * as required by this package. Also set our internal - * flag for RDONLY if needed. - */ + *pdb = NULL; + + db = malloc(sizeof(*db)); + memset(db, 0, sizeof(*db)); + + db->pool = p; + + /* + * adjust user flags so that WRONLY becomes RDWR, + * as required by this package. Also set our internal + * flag for RDONLY if needed. + */ if (!(flags & APR_WRITE)) { - (*db)->flags = SDBM_RDONLY; + db->flags = SDBM_RDONLY; } flags |= APR_BINARY | APR_READ; - -/* - * open the files in sequence, and stat the dirfile. - * If we fail anywhere, undo everything, return NULL. - */ - if ((status = apr_open(&(*db)->pagf, pagname, flags, perms, p)) - == APR_SUCCESS) { - if ((status = sdbm_lock(*db)) == APR_SUCCESS) { - if ((status = apr_open(&(*db)->dirf, dirname, flags, perms, p)) - == APR_SUCCESS) { -/* - * need the dirfile size to establish max bit number. - */ - if ((status = apr_getfileinfo(&finfo, (*db)->dirf)) - == APR_SUCCESS) { -/* - * zero size: either a fresh database, or one with a single, - * unsplit data page: dirpage is all zeros. - */ - (*db)->dirbno = (!finfo.size) ? 0 : -1; - (*db)->pagbno = -1; - (*db)->maxbno = finfo.size * BYTESIZ; - - /* (apr_pcalloc will zero the buffers) */ - /* - * success - */ - return APR_SUCCESS; - } - (void) apr_close((*db)->dirf); - } - (void) sdbm_unlock(*db); - } - (void) apr_close((*db)->pagf); - } - - *db = NULL; - return status; + /* + * open the files in sequence, and stat the dirfile. + * If we fail anywhere, undo everything, return NULL. + */ + + if ((status = apr_open(&db->pagf, pagname, flags, perms, p)) + != APR_SUCCESS) + goto error; + + if ((status = sdbm_lock(db)) != APR_SUCCESS) + goto error; + + if ((status = apr_open(&db->dirf, dirname, flags, perms, p)) + != APR_SUCCESS) + goto error; + + /* + * need the dirfile size to establish max bit number. + */ + if ((status = apr_getfileinfo(&finfo, db->dirf)) != APR_SUCCESS) + goto error; + + /* + * zero size: either a fresh database, or one with a single, + * unsplit data page: dirpage is all zeros. + */ + db->dirbno = (!finfo.size) ? 0 : -1; + db->pagbno = -1; + db->maxbno = finfo.size * BYTESIZ; + + /* (apr_pcalloc zeroed the buffers) */ + + /* make sure that we close the database at some point */ + apr_register_cleanup(p, db, database_cleanup, apr_null_cleanup); + + /* Done! */ + *pdb = db; + return APR_SUCCESS; + + error: + if (db->dirf != NULL) + (void) apr_close(db->dirf); + if (db->pagf != NULL) { + (void) sdbm_unlock(db); + (void) apr_close(db->dirf); + } + free(db); + return status; } void sdbm_close(SDBM *db) { - (void) apr_close(db->dirf); - (void) sdbm_unlock(db); - (void) apr_close(db->pagf); + (void) apr_run_cleanup(db->pool, db, database_cleanup); } sdbm_datum 1.4 +4 -0 apache-2.0/src/lib/sdbm/sdbm_private.h Index: sdbm_private.h =================================================================== RCS file: /home/cvs/apache-2.0/src/lib/sdbm/sdbm_private.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -u -r1.3 -r1.4 --- sdbm_private.h 2000/11/29 10:51:18 1.3 +++ sdbm_private.h 2000/12/01 00:46:47 1.4 @@ -61,6 +61,9 @@ #ifndef SDBM_PRIVATE_H #define SDBM_PRIVATE_H +#include "apr.h" +#include "apr_pools.h" +#include "apr_file_io.h" #include "apr_errno.h" /* for apr_status_t */ /* increase the block/page size and what can be inserted */ @@ -80,6 +83,7 @@ #define SDBM_RDONLY 0x1 /* data base open read-only */ /* for a single insertion */ struct SDBM { + apr_pool_t *pool; apr_file_t *dirf; /* directory file descriptor */ apr_file_t *pagf; /* page file descriptor */ apr_int32_t flags; /* status/error flags, see below */