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;
