harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ge...@apache.org
Subject svn commit: r416412 - in /incubator/harmony/enhanced/classlib/trunk/native-src: linux.IA32/luni/procimpl.c shared/luni/process.c
Date Thu, 22 Jun 2006 16:32:07 GMT
Author: geirm
Date: Thu Jun 22 09:32:05 2006
New Revision: 416412

URL: http://svn.apache.org/viewvc?rev=416412&view=rev
Log:
fix to the problem reported in HARMONY-638

The problem was that fork() was failing due to 
what I can only assume was some kind of ulimit.
By running eclipse at the same time w/ a big 
heap, I can get this problem to show itself
on demand.

Problem was that execProgram() didn't check if
the fork() failed until after doing a blocking
read on a pipe to get a message from the child.
If the child was never created, it hung forever.

Now execProgram() returns 0 on success, and a
meaningful error code on failure, so that a 
nice Exception can be thrown.  The error codes
have to be split accross the platform impls of
this function.  I assume if people don't
reject this approach, we just put the error
codes into a common header.

Windows checkin will follow from other machine
after 1 svn update and smoke test.

We will need to find a regression test for
this and other stress-related maladies.


Modified:
    incubator/harmony/enhanced/classlib/trunk/native-src/linux.IA32/luni/procimpl.c
    incubator/harmony/enhanced/classlib/trunk/native-src/shared/luni/process.c

Modified: incubator/harmony/enhanced/classlib/trunk/native-src/linux.IA32/luni/procimpl.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/native-src/linux.IA32/luni/procimpl.c?rev=416412&r1=416411&r2=416412&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/native-src/linux.IA32/luni/procimpl.c (original)
+++ incubator/harmony/enhanced/classlib/trunk/native-src/linux.IA32/luni/procimpl.c Thu Jun
22 09:32:05 2006
@@ -86,6 +86,21 @@
   return StatusLocation;
 }
 
+
+/*
+ *  int execProgram()
+ * 
+ *  does a fork/execvp to launch the program
+ * 
+ *  returns :
+ *     0  successful
+ *     1001  fork failure errno = ENOMEM
+ *     1002 fork failure errno = EAGAIN
+ *     -1  error, unknown
+ * 
+ *   Note - there is one error code 'namespace' for execProgram
+ *          please coordinate w/ other platform impls
+ */
 int
 execProgram (JNIEnv * vmthread, jobject recv,
              char *command[], int commandLineLength,
@@ -97,7 +112,7 @@
    * the new thread  ==> make it a globalRef.
    */
 
-  char result;
+  int result = -1;
   char *cmd;
   int grdpid, rc = 0;
   int newFD[3][2];
@@ -114,7 +129,40 @@
   pipe (execvFailure);
 
   cmd = command[0];
+
   grdpid = fork ();
+
+  /*
+   *   if we fail, lets clean up and bail right here
+   */
+  
+    if (grdpid == -1) {
+
+	    int error = errno;
+	  	
+		close(newFD[0][0]);
+		close(newFD[0][1]);
+		close(newFD[1][0]);
+		close(newFD[1][1]);
+		close(newFD[2][0]);
+		close(newFD[2][1]);
+	
+		close(forkedChildIsRunning[0]);
+		close(forkedChildIsRunning[1]);
+		
+		close(execvFailure[0]);
+		close(execvFailure[1]);
+	
+		if (error == ENOMEM) {
+		    result = 1001;
+		}
+		else if (error = EAGAIN) { 
+		    result = 1002;
+		}
+	
+		return result;
+      }  
+
   if (grdpid == 0)
     {
       /* Redirect pipes so grand-child inherits new pipes */
@@ -122,17 +170,21 @@
       dup2 (newFD[0][0], 0);
       dup2 (newFD[1][1], 1);
       dup2 (newFD[2][1], 2);
+      
       /* tells the parent that that very process is running */
       write (forkedChildIsRunning[1], &dummy, 1);
 
-      if (dir)
+      if (dir) {
         chdir (dir);
-
+      }
+      
       /* ===try to perform the execv : on success, it does not return ===== */
-      if (envSize != 0)
+      if (envSize != 0) {
         environ = env;
+      }
 
       rc = execvp (cmd, command);
+
       /* ===================================================== */
 
       /* if we get here ==> tell the parent that the execv failed ! */
@@ -220,17 +272,12 @@
       close (execvFailure[0]);
       close (execvFailure[1]);
 
-      /* tells the parent what result it should return */
-      if ((grdpid < 0) || (rc == -1))
-        {
-          result = (char) 0;
-        }
-      else
-        {
-          result = (char) 1;
+        if (rc != -1) {
+            result = 0;
         }
     }
-  return (int) result;          /* 0 or 1 */
+
+  return result;
 }
 
 /* Stream handling support */

Modified: incubator/harmony/enhanced/classlib/trunk/native-src/shared/luni/process.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/native-src/shared/luni/process.c?rev=416412&r1=416411&r2=416412&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/native-src/shared/luni/process.c (original)
+++ incubator/harmony/enhanced/classlib/trunk/native-src/shared/luni/process.c Thu Jun 22
09:32:05 2006
@@ -105,6 +105,11 @@
         }
     }
 
+  /*
+   *  now call execProgram.  Any non-zero return code 
+   *  indicates some kind of failure
+   */
+   
   retVal = execProgram (env, recv,
       command, commandLineLength, envArray, envLength,
       workingDir, &pHandle, &inHandle, &outHandle,
@@ -115,14 +120,32 @@
       jclmem_free_memory (env, workingDir);
     }
 
-  if (!retVal)
+  if (retVal)
     {
-      /* Failed to exec program */
-      jclass exClass = (*env)->FindClass (env, "java/io/IOException");
-      (*env)->ThrowNew (env, exClass, "Unable to start program");
-      goto failed;
+        char errMsg[256];
+    	jclass exClass;
+
+        /* Failed to exec program */
+        
+        switch(retVal) {
+        case 1001 :
+            sprintf(errMsg, "Unable to start program : %s", "fork() failed with errno = EOMEM");
+            break;
+        case 1002 : 
+            sprintf(errMsg, "Unable to start program : %s", "fork() failed with errno = EAGAIN");
+            break;
+        default:
+            sprintf(errMsg, "Unable to start program : %s", "unknown");
+            break;
+        }
+
+        exClass = (*env)->FindClass (env, "java/io/IOException");
+        (*env)->ThrowNew (env, exClass, errMsg);
+        goto failed;
     }
+
   pVals = (*env)->NewLongArray (env, 4);
+
   if (pVals)
     {
       npVals[0] = (jlong) pHandle;



Mime
View raw message