summaryrefslogtreecommitdiff
path: root/shmem/unix
diff options
context:
space:
mode:
authorAaron Bannert <aaron@apache.org>2002-01-29 01:16:11 +0000
committerAaron Bannert <aaron@apache.org>2002-01-29 01:16:11 +0000
commitc70155eeb7ab99e354e281747fdd7b63b964f01d (patch)
treebfd37953ef53d3aa0aa8c79b040f0ef6f68e75eb /shmem/unix
parent5b9f7897ba77bd243acd37cc51b3ffb469754b62 (diff)
downloadapr-c70155eeb7ab99e354e281747fdd7b63b964f01d.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: https://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.c164
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)