diff options
author | aaron <aaron@13f79535-47bb-0310-9956-ffa450edef68> | 2002-01-29 01:16:11 +0000 |
---|---|---|
committer | aaron <aaron@13f79535-47bb-0310-9956-ffa450edef68> | 2002-01-29 01:16:11 +0000 |
commit | 92345f2fbb5b53db4ff77fae41a3436c2ffe1464 (patch) | |
tree | bfd37953ef53d3aa0aa8c79b040f0ef6f68e75eb /shmem/unix | |
parent | 952120083ca72f0918772cbb3572e3246115d38c (diff) | |
download | libapr-92345f2fbb5b53db4ff77fae41a3436c2ffe1464.tar.gz |
Implement shared memory cleanup handlers on Unix for both the original
creating process' pool (cleans up after apr_shm_create) and an attaching
process' pool (cleans up after apr_shm_attach).
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@62848 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'shmem/unix')
-rw-r--r-- | shmem/unix/shm.c | 164 |
1 files changed, 98 insertions, 66 deletions
diff --git a/shmem/unix/shm.c b/shmem/unix/shm.c index f965e9dae..c493bdc7c 100644 --- a/shmem/unix/shm.c +++ b/shmem/unix/shm.c @@ -59,6 +59,74 @@ #include "apr_user.h" #include "apr_strings.h" +static apr_status_t shm_cleanup_owner(void *m_) +{ + apr_shm_t *m = (apr_shm_t *)m_; + + /* anonymous shared memory */ + if (m->filename == NULL) { +#if APR_USE_SHMEM_MMAP_ZERO || APR_USE_SHMEM_MMAP_ANON + if (munmap(m->base, m->realsize) == -1) { + return errno; + } + return APR_SUCCESS; +#endif +#if APR_USE_SHMEM_SHMGET_ANON + if (shmdt(m->base) == -1) { + return errno; + } + /* This segment will automatically remove itself after all + * references have detached. */ + return APR_SUCCESS; +#endif + } + + /* name-based shared memory */ + else { +#if APR_USE_SHMEM_MMAP_TMP + apr_status_t rv; + + if (munmap(m->base, m->realsize) == -1) { + return errno; + } + rv = apr_file_remove(m->filename, m->pool); + if (rv != APR_SUCCESS) { + return rv; + } + return APR_SUCCESS; +#endif +#if APR_USE_SHMEM_MMAP_SHM + if (munmap(m->base, m->realsize) == -1) { + return errno; + } + if (shm_unlink(m->filename) == -1) { + return errno; + } + return APR_SUCCESS; +#endif +#if APR_USE_SHMEM_SHMGET + apr_status_t rv; + + /* Indicate that the segment is to be destroyed as soon + * as all processes have detached. This also disallows any + * new attachments to the segment. */ + if (shmctl(m->shmid, IPC_RMID, NULL) == -1) { + return errno; + } + if (shmdt(m->base) == -1) { + return errno; + } + rv = apr_file_remove(m->filename, m->pool); + if (rv != APR_SUCCESS) { + return rv; + } + return APR_SUCCESS; +#endif + } + + return APR_ENOTIMPL; +} + APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m, apr_size_t reqsize, const char *filename, @@ -126,6 +194,8 @@ APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m, /* metadata isn't usable */ new_m->usable = new_m->base + sizeof(apr_size_t); + apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_owner, + apr_pool_cleanup_null); *m = new_m; return APR_SUCCESS; @@ -141,6 +211,8 @@ APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m, /* metadata isn't usable */ new_m->usable = (char *)new_m->base + sizeof(apr_size_t); + apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_owner, + apr_pool_cleanup_null); *m = new_m; return APR_SUCCESS; @@ -185,6 +257,8 @@ APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m, return errno; } + apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_owner, + apr_pool_cleanup_null); *m = new_m; return APR_SUCCESS; #endif /* APR_USE_SHMEM_SHMGET_ANON */ @@ -276,6 +350,8 @@ APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m, /* metadata isn't usable */ new_m->usable = new_m->base + sizeof(apr_size_t); + apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_owner, + apr_pool_cleanup_null); *m = new_m; return APR_SUCCESS; @@ -330,6 +406,8 @@ APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m, return status; } + apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_owner, + apr_pool_cleanup_null); *m = new_m; return APR_SUCCESS; @@ -341,63 +419,30 @@ APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m, APR_DECLARE(apr_status_t) apr_shm_destroy(apr_shm_t *m) { - /* anonymous shared memory */ + apr_status_t rv = shm_cleanup_owner(m); + apr_pool_cleanup_kill(m->pool, m, shm_cleanup_owner); + return rv; +} + +static apr_status_t shm_cleanup_attach(void *m_) +{ + apr_shm_t *m = (apr_shm_t *)m_; + if (m->filename == NULL) { -#if APR_USE_SHMEM_MMAP_ZERO || APR_USE_SHMEM_MMAP_ANON - if (munmap(m->base, m->realsize) == -1) { - return errno; - } - return APR_SUCCESS; -#endif -#if APR_USE_SHMEM_SHMGET_ANON - if (shmdt(m->base) == -1) { - return errno; - } - /* This segment will automatically remove itself after all - * references have detached. */ - return APR_SUCCESS; -#endif + /* It doesn't make sense to detach from an anonymous memory segment. */ + return APR_EINVAL; } - - /* name-based shared memory */ else { -#if APR_USE_SHMEM_MMAP_TMP - apr_status_t rv; - - if (munmap(m->base, m->realsize) == -1) { - return errno; - } - rv = apr_file_remove(m->filename, m->pool); - if (rv != APR_SUCCESS) { - return rv; - } - return APR_SUCCESS; -#endif -#if APR_USE_SHMEM_MMAP_SHM +#if APR_USE_SHMEM_MMAP_TMP || APR_USE_SHMEM_MMAP_SHM if (munmap(m->base, m->realsize) == -1) { return errno; } - if (shm_unlink(m->filename) == -1) { - return errno; - } return APR_SUCCESS; -#endif +#endif /* APR_USE_SHMEM_MMAP_TMP || APR_USE_SHMEM_MMAP_SHM */ #if APR_USE_SHMEM_SHMGET - apr_status_t rv; - - /* Indicate that the segment is to be destroyed as soon - * as all processes have detached. This also disallows any - * new attachments to the segment. */ - if (shmctl(m->shmid, IPC_RMID, NULL) == -1) { - return errno; - } if (shmdt(m->base) == -1) { return errno; } - rv = apr_file_remove(m->filename, m->pool); - if (rv != APR_SUCCESS) { - return rv; - } return APR_SUCCESS; #endif } @@ -470,6 +515,8 @@ APR_DECLARE(apr_status_t) apr_shm_attach(apr_shm_t **m, /* metadata isn't usable */ new_m->usable = new_m->base + sizeof(apr_size_t); + apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_attach, + apr_pool_cleanup_null); *m = new_m; return APR_SUCCESS; @@ -519,6 +566,8 @@ APR_DECLARE(apr_status_t) apr_shm_attach(apr_shm_t **m, new_m->usable = new_m->base; new_m->realsize = new_m->reqsize; + apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_attach, + apr_pool_cleanup_null); *m = new_m; return APR_SUCCESS; @@ -530,26 +579,9 @@ APR_DECLARE(apr_status_t) apr_shm_attach(apr_shm_t **m, APR_DECLARE(apr_status_t) apr_shm_detach(apr_shm_t *m) { - if (m->filename == NULL) { - /* It doesn't make sense to detach from an anonymous memory segment. */ - return APR_EINVAL; - } - else { -#if APR_USE_SHMEM_MMAP_TMP || APR_USE_SHMEM_MMAP_SHM - if (munmap(m->base, m->realsize) == -1) { - return errno; - } - return APR_SUCCESS; -#endif /* APR_USE_SHMEM_MMAP_TMP || APR_USE_SHMEM_MMAP_SHM */ -#if APR_USE_SHMEM_SHMGET - if (shmdt(m->base) == -1) { - return errno; - } - return APR_SUCCESS; -#endif - } - - return APR_ENOTIMPL; + apr_status_t rv = shm_cleanup_attach(m); + apr_pool_cleanup_kill(m->pool, m, shm_cleanup_attach); + return rv; } APR_DECLARE(void *) apr_shm_baseaddr_get(const apr_shm_t *m) |