![]() |
|
|
#1 |
|
May 2014
2116 Posts |
Two issues here:
1. Linux does not have SO_NOSIGPIPE defined, but has MSG_NOSIGNAL flag to send(2) that does similar thing. It's good to use it. (in primenet.c) While we have MSG_NOSIGNAL, it also becomes possible to handle SIGPIPE on stdout when mprime is piped to another program. (Test case:) $ mprime -t | tee log.txt $ pkill tee My suggestion for this case is to handle it like SIGTERM -- stop workers properly, but it might be fine to keep it running (albeit without output) and ignore SIGPIPE entirely. This behavior can be discussed further. (I'm just showing one suggestion in the patch; no need to apply that directly.) 2. SIGHUP handling. It should respect the default action as returned by signal(), so that we don't break "nohup" or like. I'm not sure mprime developers know this (when discussed in this forum thread: http://www.mersenneforum.org/showthread.php?t=21496), so I show one of the right way to handle it, here. (By the way, there is a Unix convention of SIGHUP for daemons (if mprime were to fully support running as daemon). When a daemon receives SIGHUP, it re-reads configuration files and maybe restarts itself. Just a note here.) Code:
diff -r -u p95v289-vanilla/linux/prime.c p95v289-new/linux/prime.c
--- p95v289-vanilla/linux/prime.c
+++ p95v289-new/linux/prime.c
@@ -11,6 +11,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/socket.h>
#include <sys/stat.h>
#include "prime.h"
@@ -135,6 +136,19 @@
(void)signal(SIGTERM, sigterm_handler);
(void)signal(SIGINT, sigterm_handler);
+ if (signal(SIGHUP, sigterm_handler) == SIG_DFL) {
+ /* If we are run through 'nohup', keep SIGHUP ignored. */
+ (void)signal(SIGHUP, SIG_DFL);
+ }
+#if !defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL)
+ (void)signal(SIGPIPE, SIG_IGN);
+#else
+ /* SIGPIPE might be generated when user pipes stdout to another */
+ /* program (e.g. `mprime | tee log.txt`), and that "tee" dies. */
+ /* Handle this to terminate when we're sure we never receive */
+ /* SIGPIPE from sockets. */
+ (void)signal(SIGPIPE, sigterm_handler);
+#endif
/* No buffering of output */
diff -r -u p95v289-vanilla/primenet.c p95v289-new/primenet.c
--- p95v289-vanilla/primenet.c
+++ p95v289-new/primenet.c
@@ -369,7 +369,7 @@
return (PRIMENET_ERROR_CONNECT_FAILED);
}
-/* Prevent SIGPIPE signals in Linux (and other) environments */
+/* Prevent SIGPIPE signals in OS X, BSD and other environments */
#ifdef SO_NOSIGPIPE
{
@@ -442,7 +442,11 @@
LogMsg (buf);
}
}
- res = send (s, szURL, (int) strlen (szURL), 0);
+ res = send (s, szURL, strlen (szURL), 0
+#ifdef MSG_NOSIGNAL /* Prevent SIGPIPE in Linux (and others) */
+ | MSG_NOSIGNAL
+#endif
+ );
if (res < 0) {
sprintf (buf, "Error in send call: %d\n",
getLastSocketError ());
|
|
|
|
|
|
#2 |
|
May 2014
1000012 Posts |
Sorry for double-posting. But I seems to have forgotten one more issue:
3. Regarding SIGINT handling. SIGINT may be ignored by default when an mprime instance is run asynchronously through the shell's '&' operator, and that the shell is not interactive. (Example is running mprime through a shell script or a subshell like this: `sh -c "mprime & some_other_command"`) For this case, the asynchronous process will also ignore SIGQUIT and, without explicit redirection, assigns /dev/null as stdin. (Processes created though shell's '&' operator are assumed to be out of the direct control of the terminal. For interactive shell, the process is put into a "background" process group (in which processes cannot listen to SIGINT, SIGQUIT and stdin directly from the terminal); without job control, the shell won't create process groups and ignores processes' SIGINT and SIGQUIT explicitly. That's why.) SIGINT should be kept ignored for mprime when this happens. By the way, there's no need to worry about when mprime is run interactively and in the background (the `sh -c "mprime -m & some_other_command"` case), the EOF on stdin shall be enough to terminate this mprime instance, without the need of a signal. Code:
diff -r -u p95v289-new/linux/prime.c p95v289-new-2/linux/prime.c
--- p95v289-new/linux/prime.c 2016-10-20 18:31:30.770254124 +0800
+++ p95v289-new-2/linux/prime.c 2016-10-21 08:27:35.476753411 +0800
@@ -135,7 +135,11 @@
/* catch termination signals */
(void)signal(SIGTERM, sigterm_handler);
- (void)signal(SIGINT, sigterm_handler);
+ if (signal(SIGINT, sigterm_handler) == SIG_DFL) {
+ /* If we are run asynchronously, keep SIGINT ignored. */
+ /* (e.g. `sh -c 'mprime & other_command'`) */
+ (void)signal(SIGHUP, SIG_DFL);
+ }
if (signal(SIGHUP, sigterm_handler) == SIG_DFL) {
/* If we are run through 'nohup', keep SIGHUP ignored. */
(void)signal(SIGHUP, SIG_DFL);
|
|
|
|
|
|
#3 |
|
P90 years forever!
Aug 2002
Yeehaw, FL
35·31 Posts |
I made the SIGINT and SIGHUP changes.
I changed primenet.c to not use SIGPIPE in sockets code. However, I doubt anyone is executing the sockets code (not sure it even works anymore). The sockets code was obsoleted by LIBCURL. As for handling the SIGPIPE signal I decided to do nothing (added your code but commented it out) because I don't know what LIBCURL's interaction is with SIGPIPE. I can uncomment the code should further discussion here conclude that it would be the best thing to do. |
|
|
|
![]() |
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| [Patch] CPU affinity prompt problem in mprime Linux / OS X build | Explorer09 | Software | 1 | 2017-03-01 02:34 |
| PFGW ABC file handling problem | carpetpool | Information & Answers | 19 | 2016-12-16 01:21 |
| mprime: signal handler, SIGHUP | rudi_m | Software | 21 | 2016-10-18 05:07 |
| mprime messages line wrap problem (with patch) | Explorer09 | Software | 5 | 2015-03-25 20:48 |
| Mprime's signal handling? | zukertort | Software | 1 | 2005-04-23 12:18 |