I ran into this strategy in a C program and I'm posting it here to get it on record.
The idea is to create a pipe when a process starts up and give the write end to a global signal-handling function. When a signal that is not ignored or defaulted is received, a packet describing the signal is written into the pipe with write(2), a known signal-safe operation, to the pipe. The handler then returns.
The packet sent into the pipe could be just the signal number (an int) or a full siginfo_t object (see <signal.h> and its man page). It shouldn't hold so much junk that you might get anywhere near PIPE_BUF (4K), which is not the maximum size of the pipe (64K-1MB on Linux), but the guaranteed-atomic size above which writes might be interspersed.
The read end of this pipe is examined by the Great Big Select or similar multiplexer (which is needed anyway to fake blocking I/O without actually blocking other threads), and if it contains anything its contents are read and the appropriate Scheme-level signal handler is called.
This will not work on Windows, of course, where one needs to use the appropriate intraprocess queueing mechanism involving application-specific window messages or what not.