diff options
-rw-r--r-- | CHANGES | 6 | ||||
-rw-r--r-- | include/apr_mmap.h | 19 | ||||
-rw-r--r-- | mmap/unix/mmap.c | 37 | ||||
-rw-r--r-- | mmap/win32/mmap.c | 35 |
4 files changed, 47 insertions, 50 deletions
@@ -1,5 +1,11 @@ Changes with APR 0.9.2 + *) Changed apr_mmap_dup() and friends so that there's no longer any + is_owner concept on the mmaped region, but rather something more + along the lines of a reference count. This allows the old apr_mmap_t + to still be used safely when the new apr_mmap_t is in a disjoint pool. + [Cliff Woolley, Sander Striker] + *) Fix a bug in apr_hash_merge() which caused the last entry in the overlay hash to be lost. PR 10522 [Jeff Trawick] diff --git a/include/apr_mmap.h b/include/apr_mmap.h index 44e51be08..2c2278c99 100644 --- a/include/apr_mmap.h +++ b/include/apr_mmap.h @@ -58,6 +58,7 @@ #include "apr.h" #include "apr_pools.h" #include "apr_errno.h" +#include "apr_ring.h" #include "apr_file_io.h" /* for apr_file_t */ #ifdef BEOS @@ -115,8 +116,12 @@ 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; + /** @deprecated this field is no longer used and will be removed + * in APR 1.0 */ + int unused; + /** ring of apr_mmap_t's that reference the same + * mmap'ed region; acts in place of a reference count */ + APR_RING_ENTRY(apr_mmap_t) link; }; #if APR_HAS_MMAP || defined(DOXYGEN) @@ -174,8 +179,8 @@ APR_DECLARE(apr_status_t) apr_mmap_create(apr_mmap_t **newmmap, * @param new_mmap The structure to duplicate into. * @param old_mmap The mmap to duplicate. * @param p The pool to use for new_mmap. - * @param transfer_ownership Whether responsibility for destroying - * the memory-mapped segment is transferred from old_mmap to new_mmap + * @param transfer_ownership DEPRECATED: this param is now ignored + * and should be removed prior to APR 1.0 */ APR_DECLARE(apr_status_t) apr_mmap_dup(apr_mmap_t **new_mmap, apr_mmap_t *old_mmap, @@ -185,10 +190,11 @@ APR_DECLARE(apr_status_t) apr_mmap_dup(apr_mmap_t **new_mmap, #if defined(DOXYGEN) /** * Transfer the specified MMAP to a different pool - * @param new_mmap The structure to duplicate into. + * @param new_mmap The structure to duplicate into. * @param old_mmap The file to transfer. * @param p The pool to use for new_mmap. - * @remark After this call, old_mmap cannot be used + * @deprecated Just use apr_mmap_dup(). The transfer_ownership flag will + * go away soon anyway. */ APR_DECLARE(apr_status_t) apr_mmap_setaside(apr_mmap_t **new_mmap, apr_mmap_t *old_mmap, @@ -197,7 +203,6 @@ APR_DECLARE(apr_status_t) apr_mmap_setaside(apr_mmap_t **new_mmap, #define apr_mmap_setaside(new_mmap, old_mmap, p) apr_mmap_dup(new_mmap, old_mmap, p, 1) #endif /* DOXYGEN */ - /** * Remove a mmap'ed. * @param mm The mmap'ed file. diff --git a/mmap/unix/mmap.c b/mmap/unix/mmap.c index 4a54b860e..707702662 100644 --- a/mmap/unix/mmap.c +++ b/mmap/unix/mmap.c @@ -83,13 +83,17 @@ static apr_status_t mmap_cleanup(void *themmap) { apr_mmap_t *mm = themmap; - int rv; + apr_mmap_t *next = APR_RING_NEXT(mm,link); + int rv = 0; - if (!mm->is_owner) { - return APR_EINVAL; - } - else if (mm->mm == (void *)-1) { - return APR_ENOENT; + /* we no longer refer to the mmaped region */ + APR_RING_REMOVE(mm,link); + APR_RING_NEXT(mm,link) = NULL; + APR_RING_PREV(mm,link) = NULL; + + if (next != mm) { + /* more references exist, so we're done */ + return APR_SUCCESS; } #ifdef BEOS @@ -163,7 +167,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; + APR_RING_ELEM_INIT(*new, link); /* register the cleanup... */ apr_pool_cleanup_register((*new)->cntxt, (void*)(*new), mmap_cleanup, @@ -179,21 +183,10 @@ APR_DECLARE(apr_status_t) apr_mmap_dup(apr_mmap_t **new_mmap, *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); - apr_pool_cleanup_register(p, *new_mmap, mmap_cleanup, - apr_pool_cleanup_null); - } - else { - (*new_mmap)->is_owner = 0; - } - } + APR_RING_INSERT_AFTER(old_mmap, *new_mmap, link); + + apr_pool_cleanup_register(p, *new_mmap, mmap_cleanup, + apr_pool_cleanup_null); return APR_SUCCESS; } diff --git a/mmap/win32/mmap.c b/mmap/win32/mmap.c index a113ecfcf..4053ab868 100644 --- a/mmap/win32/mmap.c +++ b/mmap/win32/mmap.c @@ -66,13 +66,17 @@ static apr_status_t mmap_cleanup(void *themmap) { apr_mmap_t *mm = themmap; + apr_mmap_t *next = APR_RING_NEXT(mm,link); apr_status_t rv = 0; - if (!mm->is_owner) { - return APR_EINVAL; - } - else if (!mm->mhandle) { - return APR_ENOENT; + /* we no longer refer to the mmaped region */ + APR_RING_REMOVE(mm,link); + APR_RING_NEXT(mm,link) = NULL; + APR_RING_PREV(mm,link) = NULL; + + if (next != mm) { + /* more references exist, so we're done */ + return APR_SUCCESS; } if (mm->mv) { @@ -163,7 +167,7 @@ APR_DECLARE(apr_status_t) apr_mmap_create(apr_mmap_t **new, apr_file_t *file, (*new)->mm = (char*)((*new)->mv) + (*new)->poffset; (*new)->size = size; (*new)->cntxt = cont; - (*new)->is_owner = 1; + APR_RING_ELEM_INIT(*new, link); /* register the cleanup... */ apr_pool_cleanup_register((*new)->cntxt, (void*)(*new), mmap_cleanup, @@ -179,21 +183,10 @@ APR_DECLARE(apr_status_t) apr_mmap_dup(apr_mmap_t **new_mmap, *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); - apr_pool_cleanup_register(p, *new_mmap, mmap_cleanup, - apr_pool_cleanup_null); - } - else { - (*new_mmap)->is_owner = 0; - } - } + APR_RING_INSERT_AFTER(old_mmap, *new_mmap, link); + + apr_pool_cleanup_register(p, *new_mmap, mmap_cleanup, + apr_pool_cleanup_null); return APR_SUCCESS; } |