Attached are revised patches (diff against HEAD and changes suggested by Joe)

Regarding other platforms(beos, win32, os2), I have a simple question ;)
Do we need to implement apr_shm_remove ? (or just return APR_ENOTIMPL)

Frankly speaking I have very little knowledge about beos and os2.
Just looking at APIs, I don't think there should be case of orphan segments and
if it is there, I didn't find a way to remove that segment just on the basis of
filename like we do in shm_xxx API.

Win32 has same case AFAIK. You can call "OpenFileMapping", but there is
no way to *destroy* file mapping which was created by some other process
which has died.

Suggestions ?

Thanks
Amit



Joe Orton wrote:
On Fri, May 28, 2004 at 05:08:17PM +0530, 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.
    

Looks good, thanks a lot Amit... patch against APR HEAD would be
preferred though.  There's no need for apr_shm_remove() to have an
APR_ENOTIMPL case: the caller knows not to call this function for an
anonymous segment.

You can collapse:

  rv = apr_file_remove();
  if (rv) return rv;
  return APR_SUCCESS;

into just "return apr_file_remove();"

joe

  
Index: include/apr_shm.h
===================================================================
RCS file: /home/cvspublic/apr/include/apr_shm.h,v
retrieving revision 1.6
diff -u -r1.6 apr_shm.h
--- include/apr_shm.h   13 Feb 2004 09:38:28 -0000      1.6
+++ include/apr_shm.h   31 May 2004 13:17:19 -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: shmem/unix/shm.c
===================================================================
RCS file: /home/cvspublic/apr/shmem/unix/shm.c,v
retrieving revision 1.26
diff -u -r1.26 shm.c
--- shmem/unix/shm.c    27 May 2004 16:00:05 -0000      1.26
+++ shmem/unix/shm.c    31 May 2004 13:17:06 -0000
@@ -354,6 +354,66 @@
     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;
+    }
+    return apr_file_remove(filename, pool);
+#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: test/testshm.c
===================================================================
RCS file: /home/cvspublic/apr/test/testshm.c,v
retrieving revision 1.16
diff -u -r1.16 testshm.c
--- test/testshm.c      15 May 2004 19:51:50 -0000      1.16
+++ test/testshm.c      31 May 2004 13:16:44 -0000
@@ -214,6 +214,42 @@
     ABTS_INT_EQUAL(tc, sent, received);
 
 }
+static void test_named_remove(abts_case *tc, void *data)
+{
+    apr_status_t rv;
+    apr_shm_t *shm;
+    int exit_int;
+
+    rv = apr_shm_create(&shm, SHARED_SIZE, SHARED_FILENAME, p);
+    apr_assert_success(tc, "Error allocating shared memory block", rv);
+    if (rv != APR_SUCCESS) {
+        return;
+    }
+    ABTS_PTR_NOTNULL(tc, shm);
+
+    rv = apr_shm_remove(SHARED_FILENAME, p);
+    apr_assert_success(tc, "Error removing shared memory block", rv);
+    if (rv != APR_SUCCESS) {
+        return ;
+    }
+
+    rv = apr_shm_create(&shm, SHARED_SIZE, SHARED_FILENAME, p);
+    apr_assert_success(tc, "Error allocating shared memory block", rv);
+    if (rv != APR_SUCCESS) {
+        return;
+    }
+    ABTS_PTR_NOTNULL(tc, shm);
+
+    rv = apr_shm_destroy(shm);
+    apr_assert_success(tc, "Error destroying shared memory block", rv);
+    if (rv != APR_SUCCESS) {
+        return;
+    }
+
+    return;
+}
+
+
 #endif
 
 abts_suite *testshm(abts_suite *suite)
@@ -228,6 +264,7 @@
     abts_run_test(suite, test_anon, NULL);
 #endif
     abts_run_test(suite, test_named, NULL); 
+    abts_run_test(suite, test_named_remove, NULL); 
 #endif
 
     return suite;

Reply via email to