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