Patches respoted.
(previous were without -u option :( )

Amit Athavale wrote:
Here is initial patch:

- only for unix, if this OK I will write for other platforms
- Tested on linux RH 8.0 and solaris 9
- New test case added in testshm.c

Please review it so I can provide patch for other platforms ASAP.

Thanks
Amit

Joe Orton wrote:
On Fri, May 28, 2004 at 12:31:37PM +0530, Amit Athavale wrote:
  
It would be very useful for programmers. They could simply do one of the
following to avoid headaches of admins :)

- call apr_shm_remove right before apr_shm_create()
- detect unclean shutdown case and call apr_shm_remove()

I could prepare a patch for this if people are happy with this idea ;)
    

Great, yes please!

joe

  

Index: apr_shm.h
===================================================================
RCS file: /home/cvspublic/apr/include/apr_shm.h,v
retrieving revision 1.5.2.1
diff -u -r1.5.2.1 apr_shm.h
--- apr_shm.h   13 Feb 2004 09:33:45 -0000      1.5.2.1
+++ apr_shm.h   28 May 2004 11:40:46 -0000
@@ -69,6 +69,21 @@
                                          const char *filename,
                                          apr_pool_t *pool);
 
+
+/**
+ * Remove shared memory segment associated with a file.
+ * @param filename The file associated with shared-memory segment which
+ *        needs to be removed
+ * @param pool To be used for file operations
+ * @remark This function is only supported for name-based shared 
+ *         memory segments. This function will return APR_ENOTIMPL if 
+ *         anonymous shared memory is prefered over name-based shared memory.
+ *         
+ */
+APR_DECLARE(apr_status_t) apr_shm_remove(const char *filename,
+                                         apr_pool_t *pool);
+
+
 /**
  * Destroy a shared memory segment and associated memory.
  * @param m The shared memory segment structure to destroy.
Index: shm.c
===================================================================
RCS file: /home/cvspublic/apr/shmem/unix/shm.c,v
retrieving revision 1.21.2.2
diff -u -r1.21.2.2 shm.c
--- shm.c       26 Feb 2004 21:18:01 -0000      1.21.2.2
+++ shm.c       28 May 2004 11:21:23 -0000
@@ -377,6 +377,70 @@
     return APR_ENOTIMPL;
 }
 
+APR_DECLARE(apr_status_t) apr_shm_remove(const char *filename,
+                                         apr_pool_t *pool)
+{
+    apr_status_t rv;
+#if APR_USE_SHMEM_SHMGET
+    apr_status_t status;
+    apr_file_t *file;  
+    key_t shmkey;
+    int shmid;
+#endif
+
+#if APR_USE_SHMEM_MMAP_TMP
+    rv = apr_file_remove(filename, pool);
+    if (rv != APR_SUCCESS) {
+        return rv;
+    }
+    return APR_SUCCESS;
+#endif
+#if APR_USE_SHMEM_MMAP_SHM
+    if (shm_unlink(filename) == -1) {
+        return errno;
+    }
+    return APR_SUCCESS;
+#endif
+#if APR_USE_SHMEM_SHMGET
+    /* At this point we don't know whether file exists or not
+     * so opening it with only CREATE flag i.e. without EXCL
+    */
+    status = apr_file_open(&file, filename,
+                           APR_WRITE | APR_CREATE,
+                           APR_OS_DEFAULT, pool);
+    if (status != APR_SUCCESS) {
+        return status;
+    }
+
+    /* ftok() (on solaris at least) requires that the file actually
+     * exist before calling ftok(). */
+    shmkey = ftok(filename, 1);
+    if (shmkey == (key_t)-1) {
+        return errno;
+    }
+
+    if ((shmid = shmget(shmkey, 0, SHM_R | SHM_W)) < 0) {
+        return errno;
+    }
+
+    /* 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(shmid, IPC_RMID, NULL) == -1) {
+        return errno;
+    }
+    rv = apr_file_remove(filename, pool);
+    if (rv != APR_SUCCESS) {
+        return rv;
+    }
+    return APR_SUCCESS;
+#endif
+
+    /* No support for anonymous shm */
+    return APR_ENOTIMPL;
+} 
+                                         
+
 APR_DECLARE(apr_status_t) apr_shm_destroy(apr_shm_t *m)
 {
     return apr_pool_cleanup_run(m->pool, m, shm_cleanup_owner);
Index: testshm.c
===================================================================
RCS file: /home/cvspublic/apr/test/testshm.c,v
retrieving revision 1.8.2.1
diff -u -r1.8.2.1 testshm.c
--- testshm.c   13 Feb 2004 09:33:52 -0000      1.8.2.1
+++ testshm.c   28 May 2004 11:40:15 -0000
@@ -245,6 +245,56 @@
     return APR_SUCCESS;
 }
 
+static apr_status_t test_named_remove(apr_pool_t *parpool)
+{
+    apr_status_t rv;
+    apr_pool_t *pool;
+    apr_shm_t *shm;
+    int exit_int;
+
+    rv = apr_pool_create(&pool, parpool);
+    if (rv != APR_SUCCESS) {
+        fprintf(stderr, "Error creating child pool\n");
+        return rv;
+    }
+
+    printf("Creating named shared memory block first time(%"
+           APR_SIZE_T_FMT " bytes)........", SHARED_SIZE);
+    rv = apr_shm_create(&shm, SHARED_SIZE, SHARED_FILENAME, pool);
+    if (rv != APR_SUCCESS) {
+        fprintf(stderr, "Error allocating shared memory block\n");
+        return rv;
+    }
+    fprintf(stdout, "OK\n");
+
+    printf("Removing named shared memory block...");
+    rv = apr_shm_remove(SHARED_FILENAME, pool);
+    if (rv != APR_SUCCESS) {
+        fprintf(stderr, "Error removing shared memory block\n");
+        return rv;
+    }
+    fprintf(stdout, "OK\n");
+
+    printf("Creating named shared memory block second time(%"
+           APR_SIZE_T_FMT " bytes)........", SHARED_SIZE);
+    rv = apr_shm_create(&shm, SHARED_SIZE, SHARED_FILENAME, pool);
+    if (rv != APR_SUCCESS) {
+        fprintf(stderr, "Error allocating shared memory block\n");
+        return rv;
+    }
+    fprintf(stdout, "OK\n");
+
+    printf("Destroying shared memory segment...");
+    rv = apr_shm_destroy(shm);
+    if (rv != APR_SUCCESS) {
+        printf("FAILED\n");
+        return rv;
+    }
+    printf("OK\n");
+    
+    return APR_SUCCESS; 
+}
+
 int main(void)
 {
     apr_status_t rv;
@@ -282,6 +332,13 @@
         exit(-3);
     }
     printf("Named shared memory test passed!\n");
+
+    if ((rv = test_named_remove(pool)) != APR_SUCCESS) {
+        printf("Name-based shared memory remove test FAILED: [%d] %s \n",
+               rv, apr_strerror(rv, errmsg, sizeof(errmsg)));
+        exit(-3);
+    }
+    printf("Named shared memory removal test passed!\n");
 
     return 0;
 }

Reply via email to