Brad King wrote:
> Markus Duft wrote:
>> Brad King wrote:
>>> Can you print out the state of signal masks?
>> how can i do that? i'm not really into that topic that much :) but i'll
>> read some man pages to figure it out.
> 
> Look at "sigprocmask" docs.

ok - this was a dead end - not a single signal is blocked. it would have
surprised me if one was, actually. but better check, right? :)

> 
>> it seems that i'm not hit by the select problem, as there is already a
>> "select has lied" path somewhere in that code path that catches exactly
>> my select() problem.
> 
> Actually, if the select() path works other than the signal pipe
> you can probably get away with a minimal hack for this platform.
> Set a SIGALRM handler that wakes up every few milliseconds and
> writes to the signal pipes just like the SIGCHLD handler does.
> This code can be kept separate from the main select loop and
> activated only for this platform.

i implemented this, by effectively doing the same as already done for
SIGCHLD (i'm also using the same signal handler function, is this a
problem?). i'm setting the alarm right after i setup the signal handler,
and unsetting it right before removing the handler again.

i set the alarm to three seconds, which i guess is a little too long,
because the process hangs quite often sitting there for two seconds -
i'll reduce that to 1 second (is this too much overhead?). however this
seems to fix the problem

so thanks for the great idea :)


so now i have two patches to make it work - which one should i prefer?
(i guess the alarm one?). i attached both FYI.

thanks for the help.

Cheers, Markus

> 
> -Brad

reported upstream: 
http://www.cmake.org/pipermail/cmake/2010-February/035186.html

diff -ru cmake-2.6.4.orig/Source/kwsys/ProcessUNIX.c 
cmake-2.6.4/Source/kwsys/ProcessUNIX.c
--- cmake-2.6.4.orig/Source/kwsys/ProcessUNIX.c 2010-02-17 14:39:20 +0100
+++ cmake-2.6.4/Source/kwsys/ProcessUNIX.c      2010-02-17 15:52:30 +0100
@@ -1018,6 +1018,9 @@
   int numReady = 0;
   int max = -1;
   kwsysProcessTimeNative* timeout = 0;
+#ifdef __INTERIX
+  int is_sig_only = 0;
+#endif
 
   /* Check for any open pipes with data reported ready by the last
      call to select.  According to "man select_tut" we must deal
@@ -1125,9 +1128,65 @@
 
   /* Run select to block until data are available.  Repeat call
      until it is not interrupted.  */
+#ifdef __INTERIX
+  /* hack around broken sh** ... */
+  is_sig_only = 1;
+  for(i=0; i < KWSYSPE_PIPE_COUNT; ++i) {
+       if(cp->PipeReadEnds[i] >= 0) {
+               if(i != KWSYSPE_PIPE_SIGNAL)
+                       is_sig_only = 0;
+       } else {
+               if(i == KWSYSPE_PIPE_SIGNAL)
+                       is_sig_only = 0;
+       }
+  }
+
+  if(is_sig_only && !timeout) {
+       static kwsysProcessTimeNative _tmp = { 1,0 };
+       timeout = &_tmp;
+  }
+
+  while(1) {
+#endif
+
   while(((numReady = select(max+1, &cp->PipeSet, 0, 0, timeout)) < 0) &&
         (errno == EINTR));
 
+#ifdef __INTERIX
+       if(!is_sig_only)
+               break;
+       
+       if(numReady != 0)
+               break;
+               
+       /* only signal pipe left over, and nothing waiting ...
+        * we'll just wait() for the process to see whether it still exists.
+        * if it does, we continue to select, otherwise we return 0. no need
+        * to modify the PipeSet as the pipe will be set in there anyway then. 
*/
+       for(i=0; i < cp->NumberOfCommands; ++i)
+    {
+    if(cp->ForkPIDs[i])
+      {
+      int result;
+      while(((result = waitpid(cp->ForkPIDs[i],
+                               &cp->CommandExitCodes[i], WNOHANG)) < 0) &&
+            (errno == EINTR));
+      if(result == cp->ForkPIDs[i])
+        {
+                       /* uh ... process terminated, SIGCHLD got lost?
+                        * what should i DO here? */
+
+                       /* Set the pipe in a signalled state.  */
+                       kwsysProcessCleanupDescriptor(&cp->SignalPipe);
+                       return 1;
+        }
+      }
+    }
+       /* no process terminated, nothing select()ed. */
+       continue;
+  }
+#endif
+
   /* Check result of select.  */
   if(numReady == 0)
     {
@@ -1215,12 +1274,16 @@
     return 1;
     }
 
+/* errr.... this looks wrong, and is not done for the select() part above.
+ * (the kwsysProcessGetTimeoutLeft part from above is in both code paths).  */
+#if 0
   if((timeoutLength.tv_sec == 0) && (timeoutLength.tv_usec == 0))
     {
     /* Timeout has already expired.  */
     wd->Expired = 1;
     return 1;
     }
+#endif
 
   /* Sleep a little, try again. */
   {
diff -ru cmake-2.6.4.orig/Source/kwsys/ProcessUNIX.c 
cmake-2.6.4/Source/kwsys/ProcessUNIX.c
--- cmake-2.6.4.orig/Source/kwsys/ProcessUNIX.c 2010-02-18 08:47:44 +0100
+++ cmake-2.6.4/Source/kwsys/ProcessUNIX.c      2010-02-18 09:19:25 +0100
@@ -2444,6 +2444,9 @@
 
 /* The old SIGCHLD handler.  */
 static struct sigaction kwsysProcessesOldSigChldAction;
+#ifdef __INTERIX
+static struct sigaction kwsysProcessesOldSigAlrmAction;
+#endif
 
 /*--------------------------------------------------------------------------*/
 static void kwsysProcessesUpdate(kwsysProcessInstances* newProcesses)
@@ -2561,6 +2564,14 @@
     while((sigaction(SIGCHLD, &newSigChldAction,
                      &kwsysProcessesOldSigChldAction) < 0) &&
           (errno == EINTR));
+
+#ifdef __INTERIX
+       while((sigaction(SIGALRM, &newSigChldAction,
+                                        &kwsysProcessesOldSigAlrmAction) < 0) 
&&
+                 (errno == EINTR));
+       
+       alarm(1);
+#endif
     }
   }
 
@@ -2599,6 +2610,13 @@
       while((sigaction(SIGCHLD, &kwsysProcessesOldSigChldAction, 0) < 0) &&
             (errno == EINTR));
 
+#ifdef __INTERIX
+         alarm(0);
+
+      while((sigaction(SIGALRM, &kwsysProcessesOldSigAlrmAction, 0) < 0) &&
+            (errno == EINTR));
+#endif
+
       /* Free the table of process pointers since it is now empty.
          This is safe because the signal handler has been removed.  */
       newProcesses.Size = 0;
@@ -2653,6 +2671,11 @@
   while((sigaction(SIGCHLD, &newSigChldAction,
                    &kwsysProcessesOldSigChldAction) < 0) &&
         (errno == EINTR));
+#ifdef __INTERIX
+  while((sigaction(SIGALRM, &newSigChldAction,
+                   &kwsysProcessesOldSigAlrmAction) < 0) &&
+        (errno == EINTR));
+#endif
   }
 #endif
 }
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake

Reply via email to