You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by dr...@apache.org on 2004/06/29 18:35:57 UTC
cvs commit: apr/threadproc/beos .cvsignore proc.c
dreid 2004/06/29 09:35:57
Modified: threadproc/beos .cvsignore proc.c
Log:
Allow shared memory to work across forks in the way it was intended.
Revision Changes Path
1.4 +1 -0 apr/threadproc/beos/.cvsignore
Index: .cvsignore
===================================================================
RCS file: /home/cvs/apr/threadproc/beos/.cvsignore,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- .cvsignore 22 Apr 2002 01:25:53 -0000 1.3
+++ .cvsignore 29 Jun 2004 16:35:57 -0000 1.4
@@ -1,5 +1,6 @@
Makefile
apr_proc_stub
*.lo
+*.slo
.libs
.deps
1.54 +32 -0 apr/threadproc/beos/proc.c
Index: proc.c
===================================================================
RCS file: /home/cvs/apr/threadproc/beos/proc.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -r1.53 -r1.54
--- proc.c 28 Jun 2004 11:18:36 -0000 1.53
+++ proc.c 29 Jun 2004 16:35:57 -0000 1.54
@@ -149,6 +149,38 @@
return errno;
}
else if (pid == 0) {
+ /* This is really ugly...
+ * The semantics of BeOS's fork() are that areas (used for shared
+ * memory) get COW'd :-( The only way we can make shared memory
+ * work across fork() is therefore to find any areas that have
+ * been created and then clone them into our address space.
+ * Thankfully only COW'd areas have the lock variable set at
+ * anything but 0, so we can use that to find the areas we need to
+ * copy. Of course what makes it even worse is that the loop through
+ * the area's will go into an infinite loop, eating memory and then
+ * eventually segfault unless we know when we reach then end of the
+ * "original" areas and stop. Why? Well, we delete the area and then
+ * add another to the end of the list...
+ */
+ area_info ai;
+ int32 cookie = 0;
+ area_id highest = 0;
+
+ while (get_next_area_info(0, &cookie, &ai) == B_OK)
+ if (ai.area > highest)
+ highest = ai.area;
+ cookie = 0;
+ while (get_next_area_info(0, &cookie, &ai) == B_OK) {
+ if (ai.area > highest)
+ break;
+ if (ai.lock > 0) {
+ area_id original = find_area(ai.name);
+ delete_area(ai.area);
+ clone_area(ai.name, &ai.address, B_CLONE_ADDRESS,
+ ai.protection, original);
+ }
+ }
+
proc->pid = pid;
proc->in = NULL;
proc->out = NULL;