<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wikidot="http://www.wikidot.com/rss-namespace">

	<channel>
		<title>Comments for page &quot;EINTR and What It Is Good For&quot;</title>
		<link>http://250bpm.com/blog:12/comments/show</link>
		<description></description>
				<copyright></copyright>
		<lastBuildDate>Sat, 01 Aug 2015 21:43:12 +0000</lastBuildDate>
		
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-2154156</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-2154156</link>
				<description></description>
				<pubDate>Tue, 11 Nov 2014 16:07:39 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>True. As far as I know there is no guarantee that the operation haven't [partially] succeeded when EINTR is returned.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-2154094</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-2154094</link>
				<description></description>
				<pubDate>Tue, 11 Nov 2014 15:08:51 +0000</pubDate>
				<wikidot:authorName>Ulf Samuelsson</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Receive is the easy case.<br /> What happens if you have a protocol where you call &quot;write&quot;.</p> <p>Is there any guarantee that you cannot get EINTR if the packet has been transmitted?</p> <p>If you retry sending the packet, then it is sent TWICE, which may confuse the other end.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-2136360</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-2136360</link>
				<description></description>
				<pubDate>Tue, 21 Oct 2014 13:40:07 +0000</pubDate>
				<wikidot:authorName>Alex</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>On Windows this is done with SetConsoleCtrlHandler() call.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-1654888</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-1654888</link>
				<description></description>
				<pubDate>Sun, 16 Dec 2012 22:07:14 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Except that messing with signal handlers is not an option when you are implementing a library. Signal handlers are set by the main module and should not be changed randomly in the background by the libraries.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-1654886</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-1654886</link>
				<description></description>
				<pubDate>Sun, 16 Dec 2012 22:05:51 +0000</pubDate>
				<wikidot:authorName>Nico</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>FYI, this technique goes back a long time. It's used in OpenSSH, for example, and has been for many years now.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-1654884</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-1654884</link>
				<description></description>
				<pubDate>Sun, 16 Dec 2012 22:04:51 +0000</pubDate>
				<wikidot:authorName>Nico</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>write(2) a single byte to a pipe file descriptor from the signal handler and use whatever async I/O tech in your event loop (select(2), poll(2), libev, libevent, &#8230;.).</p> <p>Or give up on portability and use some API that solves this proble, like, say, Solaris event ports (just post an event from the handler, or put the port into alert mode from the handler).</p> <p>As for condition variables&#8230; if only pthread_mutex_lock() were async-signal-safe&#8230; then you could acquire the mutex, signal/broadcast on the cv, and drop the lock. But it's not, so you can't. What you can do is resort to having a thread waiting for events on a pipe written to by the signal handler (see above!) then have that thread signal/broadcast on you condition variable.</p> <p>See? The trick is to transmogrify async signals into events that you can wait for with traditional async I/O APIs.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-1608904</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-1608904</link>
				<description></description>
				<pubDate>Wed, 07 Nov 2012 12:58:05 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Nice! I wasn't aware of the trick. I'll mention it in the article.</p> <p>Still, it doesn't work for libraries. Unless, of course, ZeroMQ would expose zmq_precv (&#8230;, const sigset_t *sigmask) in addition to standard zmq_recv.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-1608898</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-1608898</link>
				<description></description>
				<pubDate>Wed, 07 Nov 2012 12:37:10 +0000</pubDate>
				<wikidot:authorName>Ambroz Bizjak</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>By &quot;check if signal is pending&quot; I mean check the flag, not some posix functions to get the pending signals mask&#8230;</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-1608896</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-1608896</link>
				<description></description>
				<pubDate>Wed, 07 Nov 2012 12:35:27 +0000</pubDate>
				<wikidot:authorName>Ambroz Bizjak</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I don't see a need to keep signals blocked outside zmq_recv(). When zmq_recv() is called:</p> <p>1. block signals<br /> 2. check if signal is pending (this is atomic because signals are blocked)<br /> 3. pselect()<br /> 5. recv()<br /> 6. if we need more data, goto 2 (yes, 2, so we don't miss a signal)<br /> 7. else unblock signals and return data to user</p> <p>It can never happen that a signal is received and we wait indefinitely in pselect().</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-1608891</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-1608891</link>
				<description></description>
				<pubDate>Wed, 07 Nov 2012 12:28:29 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Yes. In the tight event loop it would work OK.</p> <p>However, consider this example (pretty common ZeroMQ use case): User calls zmq_recv (a blocking function) to get some work. Then he processes the work. With the pselect solution, the program would be interruptible while waiting for a message (say 0.1 sec) but not interruptible while processing the work (say 1 hour).</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-1608889</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-1608889</link>
				<description></description>
				<pubDate>Wed, 07 Nov 2012 12:26:14 +0000</pubDate>
				<wikidot:authorName>Ambroz Bizjak</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>I think you're misinterpreting the meaning of &quot;blocked&quot;. If signals are blocked, and a signal happens, it is queued, not discarded. When you unblock it, the handler will execute.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-1608883</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-1608883</link>
				<description></description>
				<pubDate>Wed, 07 Nov 2012 12:23:27 +0000</pubDate>
				<wikidot:authorName>Ambroz Bizjak</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>The only blocking function here is pselect(). If you get Ctrl+C during a pselect(), it will immediately return (because you have unblocked signals with the sigmask argument to pselect). On the other hand, if you get Ctrl+C while you're not in pselect(), the signal handler will not run until you call pselect() (because signals are blocked), and when you finally call pselect(), it will run and pselect() will return.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-1608878</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-1608878</link>
				<description></description>
				<pubDate>Wed, 07 Nov 2012 12:16:22 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Yes, that would work if you are in control of the handler (send is in the POSIX list of signal-safe functions). Unfortunately, that's not the case for libraries.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-1608876</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-1608876</link>
				<description></description>
				<pubDate>Wed, 07 Nov 2012 12:12:58 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>As far as I understand, then the Ctrl+C would not work when we don't happen to be waiting in a blocking function. That seems even worse than doing it the other way round.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-1608861</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-1608861</link>
				<description></description>
				<pubDate>Wed, 07 Nov 2012 11:38:12 +0000</pubDate>
				<wikidot:authorName>Ambroz Bizjak</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>But this is of course only applicable to your Python problem if there is a way to change what the signal handler does. Or if you're very evil you can try to override the signal handler temporarily.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-1608860</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-1608860</link>
				<description></description>
				<pubDate>Wed, 07 Nov 2012 11:30:25 +0000</pubDate>
				<wikidot:authorName>Ambroz Bizjak</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>Another solution is to use the so-called &quot;self-pipe trick&quot; where you have the signal handler write a byte to a pipe. You use non-blocking sockets and in the select() you always monitor your sockets and the read end of the pipe. There is no race condition - when your signal happens, you very soon be able to read from this pipe (next time you call select, or immediately if select is being called). However, be sure to set both ends of the pipe to non-blocking. Otherwise the signal handler could block if the pipe buffer fills up and the program would deadlock.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-1608858</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-1608858</link>
				<description></description>
				<pubDate>Wed, 07 Nov 2012 11:23:35 +0000</pubDate>
				<wikidot:authorName>Ambroz Bizjak</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <p>From linux.die.ne t/man/2/pselect</p> <p>The reason that pselect() is needed is that if one wants to wait for either a signal or for a file descriptor to become ready, then an atomic test is needed to prevent race conditions. (Suppose the signal handler sets a global flag and returns. Then a test of this global flag followed by a call of select() could hang indefinitely if the signal arrived just after the test but just before the call. By contrast, pselect() allows one to first block signals, handle the signals that have come in, then call pselect() with the desired sigmask, avoiding the race.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-1608856</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-1608856</link>
				<description></description>
				<pubDate>Wed, 07 Nov 2012 11:18:59 +0000</pubDate>
				<wikidot:authorName>Ambroz Bizjak</wikidot:authorName>								<content:encoded>
					<![CDATA[
						 <div class="code"> <pre> <code>set file descriptor to non-blocking; sigprocmask() to block SIGINT; if (stop) { // handle it } while (1) { pselect() with sigmask argument which doesn't block SIGINT; if (stop) { // handle it } recv(); }</code> </pre></div> <p>The magic here is that signals are blocked except during the pselect(), and pselect() atomically unblocks them when it's called and blocks them when it returns. As a result, the signal handler can only execute during the pselect(), so it is safe to only check the flag after pselect() returns.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-1608831</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-1608831</link>
				<description></description>
				<pubDate>Wed, 07 Nov 2012 10:18:00 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>Ah, sorry. I've misunderstood you. Yes, you are right. SA_RESTART has to be set to 0 to get the EINTR behaviour. I'll make a note in the article.</p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://250bpm.com/blog:12/comments/show#post-1608822</guid>
				<title>(no title)</title>
				<link>http://250bpm.com/blog:12/comments/show#post-1608822</link>
				<description></description>
				<pubDate>Wed, 07 Nov 2012 09:58:20 +0000</pubDate>
				<wikidot:authorName>martin_sustrik</wikidot:authorName>				<wikidot:authorUserId>939</wikidot:authorUserId>				<content:encoded>
					<![CDATA[
						 <p>How exactly would you use it to deal with the Ctrl+C problem described in the article?</p> 
				 	]]>
				</content:encoded>							</item>
				</channel>
</rss>