aaron 02/01/28 17:16:11
Modified: shmem/unix shm.c
Log:
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).
Revision Changes Path
1.11 +98 -66 apr/shmem/unix/shm.c
Index: shm.c
===================================================================
RCS file: /home/cvs/apr/shmem/unix/shm.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- shm.c 25 Jan 2002 07:16:01 -0000 1.10
+++ shm.c 29 Jan 2002 01:16:11 -0000 1.11
@@ -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 @@
/* 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 @@
/* 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 @@
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 @@
/* 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 @@
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_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 @@
/* 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 @@
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_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)