[pypy-commit] pypy default: Like CPython 3, write a message to stderr if we can't write to wakeup_fd.
arigo
pypy.commits at gmail.com
Wed Feb 1 10:54:04 EST 2017
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r89890:f38fce96ddce
Date: 2017-02-01 16:49 +0100
http://bitbucket.org/pypy/pypy/changeset/f38fce96ddce/
Log: Like CPython 3, write a message to stderr if we can't write to
wakeup_fd. Unlike CPython, the message is sent to fileno 2, not back
through sys.stderr.
diff --git a/rpython/rlib/test/test_rsignal.py b/rpython/rlib/test/test_rsignal.py
--- a/rpython/rlib/test/test_rsignal.py
+++ b/rpython/rlib/test/test_rsignal.py
@@ -1,4 +1,4 @@
-import os, py
+import os, py, errno
from rpython.translator.c.test.test_genc import compile
from rpython.rlib import rsignal
@@ -37,3 +37,24 @@
def test_compile():
fn = compile(test_simple, [])
fn()
+
+def test_compile_wakeup_fd():
+ def fn():
+ rd, wr = os.pipe()
+ rsignal.pypysig_set_wakeup_fd(wr, False)
+ for i in range(3):
+ rsignal.pypysig_setflag(rsignal.SIGUSR1)
+ os.kill(os.getpid(), rsignal.SIGUSR1)
+ check(rsignal.SIGUSR1)
+ check(-1)
+ check(-1)
+ x = os.read(rd, 10)
+ assert x == chr(rsignal.SIGUSR1) * 3
+ #
+ rsignal.pypysig_set_wakeup_fd(rd, False) # can't write there
+ os.kill(os.getpid(), rsignal.SIGUSR1)
+
+ fn = compile(fn, [], return_stderr=True)
+ stderr = fn()
+ assert stderr.endswith('Exception ignored when trying to write to the '
+ 'signal wakeup fd: Errno %d\n' % errno.EBADF)
diff --git a/rpython/translator/c/src/signals.c b/rpython/translator/c/src/signals.c
--- a/rpython/translator/c/src/signals.c
+++ b/rpython/translator/c/src/signals.c
@@ -2,6 +2,7 @@
#include <limits.h>
#include <stdlib.h>
+#include <errno.h>
#ifdef _WIN32
#include <process.h>
#include <io.h>
@@ -82,27 +83,51 @@
}
}
+static void write_str(int fd, const char *p)
+{
+ int i = 0;
+ while (p[i] != '\x00')
+ i++;
+ (void)write(fd, p, i);
+}
+
static void signal_setflag_handler(int signum)
{
pypysig_pushback(signum);
- if (wakeup_fd != -1)
- {
+ /* Warning, this logic needs to be async-signal-safe */
+ if (wakeup_fd != -1) {
#ifndef _WIN32
ssize_t res;
#else
int res;
#endif
- if (wakeup_with_nul_byte)
- {
- res = write(wakeup_fd, "\0", 1);
- } else {
- unsigned char byte = (unsigned char)signum;
- res = write(wakeup_fd, &byte, 1);
- }
-
- /* the return value is ignored here */
- }
+ int old_errno = errno;
+ retry:
+ if (wakeup_with_nul_byte) {
+ res = write(wakeup_fd, "\0", 1);
+ } else {
+ unsigned char byte = (unsigned char)signum;
+ res = write(wakeup_fd, &byte, 1);
+ }
+ if (res < 0) {
+ unsigned int e = (unsigned int)errno;
+ char c[27], *p;
+ if (e == EINTR)
+ goto retry;
+ write_str(2, "Exception ignored when trying to write to the "
+ "signal wakeup fd: Errno ");
+ p = c + sizeof(c);
+ *--p = 0;
+ *--p = '\n';
+ do {
+ *--p = '0' + e % 10;
+ e /= 10;
+ } while (e != 0);
+ write_str(2, p);
+ }
+ errno = old_errno;
+ }
}
void pypysig_setflag(int signum)
More information about the pypy-commit
mailing list