Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Nov 2003 23:25:43 +0200
From:      Alexey Zelkin <phantom@freebsd.org>
To:        java@freebsd.org
Subject:   Re: jdk14 fork() problem fix
Message-ID:  <20031105232543.A99393@phantom.cris.net>
In-Reply-To: <20031023122839.A75570@phantom.cris.net>; from phantom@FreeBSD.org.ua on Thu, Oct 23, 2003 at 12:28:39PM %2B0300
References:  <20031023122839.A75570@phantom.cris.net>

next in thread | previous in thread | raw e-mail | index | archive | help
hi,

Though patch is working it has some limitations.  Under high load
java applications which utilize many parallel fork()'s may hang.

It's reproducible with testcase then least 5 threads calling Runtime.exec()

After finding a reason I had to rethink logic of 'critical section'
while calling to fork.  We can't use pthread_{suspend,resume}_all_np()
in order to not to create race conditions.

Updated version of patch to this fork problem is attached.

On Thu, Oct 23, 2003 at 12:28:39PM +0300, Alexey Zelkin wrote:
> hi,
> 
> This is an intermediate version of fix of jdk fork problem (i.e.
> Runtime.getRuntime().exec() and friends).
> 
> It does affect only people who use libc_r (kse and thr should not
> be affected).
> 
> Please try this one and report me if it fixes problems for you.
> 
> PS: If you are rebuilding already built jdk (i.e. object files are
> already compiled) remove 'control/build/bsd-i586/tmp/java/java.lang' directory
> before restarting of build.

Index: UNIXProcess_md.c.bsd
===================================================================
RCS file: /home/jdk14-cvs/jdk142-src/j2se/src/solaris/native/java/lang/UNIXProcess_md.c.bsd,v
retrieving revision 1.2
retrieving revision 1.4
diff -u -u -r1.2 -r1.4
--- UNIXProcess_md.c.bsd	15 Oct 2003 15:49:39 -0000	1.2
+++ UNIXProcess_md.c.bsd	5 Nov 2003 22:48:47 -0000	1.4
@@ -22,6 +22,12 @@
 #include <errno.h>
 #include <unistd.h>
 
+#if defined(__FreeBSD__)
+#include <dlfcn.h>
+#include <pthread.h>
+#include <pthread_np.h>
+#endif
+
 /* path in the environment */
 static char **PATH = 0;
 /* effective uid */
@@ -228,6 +234,58 @@
     }
 }
 
+#if defined(__FreeBSD__)
+
+extern pid_t   __sys_fork(void);
+
+static pid_t
+jdk_fork_wrapper()
+{
+    pid_t resultPid;
+    typedef void (*void_func)();
+    static void_func func_defer = NULL;
+    static void_func func_undefer = NULL;
+    static int is_libc_r = -1;
+
+    if (is_libc_r == -1) {
+
+	/*
+         * BSDNOTE: Check for loaded symbols.
+         *
+         * If "_thread_kern_sig_defer" symbol is found assume we are
+	 * libc_r
+         *
+         * If libc_r is loaded, use fork system call drectly to avoid
+         * problems with using protected pages. 
+         *
+         * --phantom
+	 */
+	func_defer =
+		(void_func)dlsym(RTLD_DEFAULT, "_thread_kern_sig_defer");
+	func_undefer =
+		(void_func)dlsym(RTLD_DEFAULT, "_thread_kern_sig_undefer");
+	if (func_defer != NULL)
+	    is_libc_r = 1;
+	else {
+	    is_libc_r = 0;
+	}
+    }
+
+    if (is_libc_r == 0) {
+	/* Not a libc_r */
+	resultPid = fork();
+    } else {
+        (*func_defer)();		/* call _thread_kern_sig_defer() */
+        resultPid = __sys_fork();
+        if (resultPid != 0)
+ 	    (*func_undefer)();		/* call _thread_kern_sig_undefer() */
+	/* leave child with signals disabled, but reenable in parent */
+    }
+
+    return resultPid;
+}
+#endif /* __FreeBSD__ */
+
 JNIEXPORT jint JNICALL
 Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env,
 				       jobject process,
@@ -335,8 +393,12 @@
     if (path != NULL) {
         cwd = (char *)JNU_GetStringPlatformChars(env, path, NULL);
     }
- 
+
+#if defined(__FreeBSD__)
+    resultPid = jdk_fork_wrapper();
+#else
     resultPid = fork();
+#endif
 
     if (resultPid < 0) {
 	char errmsg[128];



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20031105232543.A99393>