diff options
-rw-r--r-- | CHANGES | 5 | ||||
-rw-r--r-- | include/apr_mmap.h | 15 | ||||
-rw-r--r-- | mmap/unix/mmap.c | 32 | ||||
-rw-r--r-- | mmap/win32/mmap.c | 32 |
4 files changed, 84 insertions, 0 deletions
@@ -1,4 +1,9 @@ Changes with APR b1 + *) New function apr_mmap_dup. This is called in the mmap_setaside + [Brain Pane <bpane@pacbell.net>] + + *) speed up the apr_hash_t implementation's handling of APR_HASH_KEY_STRING. + [Brain Pane <bpane@pacbell.net>] *) Tweak apr_gethostname() so that it detects truncation of the name and returns an error. [Jeff Trawick] diff --git a/include/apr_mmap.h b/include/apr_mmap.h index 6edceaa0d..17cbab343 100644 --- a/include/apr_mmap.h +++ b/include/apr_mmap.h @@ -111,6 +111,8 @@ struct apr_mmap_t { void *mm; /** The amount of data in the mmap */ apr_size_t size; + /** Whether this object is reponsible for doing the munmap */ + int is_owner; }; #if APR_HAS_MMAP || defined(DOXYGEN) @@ -136,6 +138,19 @@ APR_DECLARE(apr_status_t) apr_mmap_create(apr_mmap_t **newmmap, apr_pool_t *cntxt); /** + * Duplicate the specified MMAP. + * @param new_mmap The structure to duplicate into. + * @param old_mmap The file to duplicate. + * @param p The pool to use for the new file. + * @param transfer_ownership Whether responsibility for destroying + * the memory-mapped segment is transferred from old_mmap to new_mmap + */ +APR_DECLARE(apr_status_t) apr_mmap_dup(apr_mmap_t **new_mmap, + apr_mmap_t *old_mmap, + apr_pool_t *p, + int transfer_ownership); + +/** * Remove a mmap'ed. * @param mmap The mmap'ed file. */ diff --git a/mmap/unix/mmap.c b/mmap/unix/mmap.c index ae8f22935..1f915bdb5 100644 --- a/mmap/unix/mmap.c +++ b/mmap/unix/mmap.c @@ -83,6 +83,11 @@ static apr_status_t mmap_cleanup(void *themmap) { apr_mmap_t *mm = themmap; int rv; + + if (!mm->is_owner) { + return APR_SUCCESS; + } + #ifdef BEOS rv = delete_area(mm->area); @@ -159,6 +164,7 @@ APR_DECLARE(apr_status_t) apr_mmap_create(apr_mmap_t **new, (*new)->mm = mm; (*new)->size = size; (*new)->cntxt = cont; + (*new)->is_owner = 1; /* register the cleanup... */ apr_pool_cleanup_register((*new)->cntxt, (void*)(*new), mmap_cleanup, @@ -166,6 +172,32 @@ APR_DECLARE(apr_status_t) apr_mmap_create(apr_mmap_t **new, return APR_SUCCESS; } +APR_DECLARE(apr_status_t) apr_mmap_dup(apr_mmap_t **new_mmap, + apr_mmap_t *old_mmap, + apr_pool_t *p, + int transfer_ownership) +{ + *new_mmap = (apr_mmap_t *)apr_pmemdup(p, old_mmap, sizeof(apr_mmap_t)); + (*new_mmap)->cntxt = p; + + /* The old_mmap can transfer ownership only if the old_mmap itself + * is an owner of the mmap'ed segment. + */ + if (old_mmap->is_owner) { + if (transfer_ownership) { + (*new_mmap)->is_owner = 1; + old_mmap->is_owner = 0; + apr_pool_cleanup_kill(old_mmap->cntxt, old_mmap, mmap_cleanup); + } + else { + (*new_mmap)->is_owner = 0; + } + apr_pool_cleanup_register(p, *new_mmap, mmap_cleanup, + apr_pool_cleanup_null); + } + return APR_SUCCESS; +} + APR_DECLARE(apr_status_t) apr_mmap_delete(apr_mmap_t *mmap) { apr_status_t rv; diff --git a/mmap/win32/mmap.c b/mmap/win32/mmap.c index 8a27618ee..428e4c91c 100644 --- a/mmap/win32/mmap.c +++ b/mmap/win32/mmap.c @@ -66,6 +66,11 @@ static apr_status_t mmap_cleanup(void *themmap) { apr_mmap_t *mm = themmap; apr_status_t rv = 0; + + if (!mm->is_owner) { + return APR_SUCCESS; + } + if (mm->mv) { if (!UnmapViewOfFile(mm->mv)) { @@ -155,6 +160,7 @@ APR_DECLARE(apr_status_t) apr_mmap_create(apr_mmap_t **new, apr_file_t *file, (*new)->mm = (char*)((*new)->mv) + offset; (*new)->size = size; (*new)->cntxt = cont; + (*new)->is_owner = 1; /* register the cleanup... */ apr_pool_cleanup_register((*new)->cntxt, (void*)(*new), mmap_cleanup, @@ -162,6 +168,32 @@ APR_DECLARE(apr_status_t) apr_mmap_create(apr_mmap_t **new, apr_file_t *file, return APR_SUCCESS; } +APR_DECLARE(apr_status_t) apr_mmap_dup(apr_mmap_t **new_mmap, + apr_mmap_t *old_mmap, + apr_pool_t *p, + int transfer_ownership) +{ + *new_mmap = (apr_mmap_t *)apr_pmemdup(p, old_mmap, sizeof(apr_mmap_t)); + (*new_mmap)->cntxt = p; + + /* The old_mmap can transfer ownership only if the old_mmap itself + * is an owner of the mmap'ed segment. + */ + if (old_mmap->is_owner) { + if (transfer_ownership) { + (*new_mmap)->is_owner = 1; + old_mmap->is_owner = 0; + apr_pool_cleanup_kill(old_mmap->cntxt, old_mmap, mmap_cleanup); + } + else { + (*new_mmap)->is_owner = 0; + } + apr_pool_cleanup_register(p, *new_mmap, mmap_cleanup, + apr_pool_cleanup_null); + } + return APR_SUCCESS; +} + APR_DECLARE(apr_status_t) apr_mmap_delete(apr_mmap_t *mmap) { apr_status_t rv; |