summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES5
-rw-r--r--include/apr_mmap.h15
-rw-r--r--mmap/unix/mmap.c32
-rw-r--r--mmap/win32/mmap.c32
4 files changed, 84 insertions, 0 deletions
diff --git a/CHANGES b/CHANGES
index f1c337b3b..4560643d3 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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;