From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Lr1ur-0006rO-M2 for qemu-devel@nongnu.org; Mon, 06 Apr 2009 23:24:01 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Lr1um-0006mz-JZ for qemu-devel@nongnu.org; Mon, 06 Apr 2009 23:24:00 -0400 Received: from [199.232.76.173] (port=34418 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Lr1um-0006mw-Fv for qemu-devel@nongnu.org; Mon, 06 Apr 2009 23:23:56 -0400 Received: from mail2.shareable.org ([80.68.89.115]:40880) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1Lr1um-000708-31 for qemu-devel@nongnu.org; Mon, 06 Apr 2009 23:23:56 -0400 Date: Tue, 7 Apr 2009 04:23:52 +0100 From: Jamie Lokier Subject: Re: [Qemu-devel] [patch 04/10] qemu: introduce main_loop_break Message-ID: <20090407032352.GA12553@shareable.org> References: <20090325224714.853788328@amt.cnet> <20090325225438.990466524@amt.cnet> <20090326122717.GB20866@shareable.org> <20090402233621.GA4599@amt.cnet> <49D54FB4.9000606@codemonkey.ws> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <49D54FB4.9000606@codemonkey.ws> Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Anthony Liguori Cc: qemu-devel@nongnu.org Anthony Liguori wrote: > Marcelo Tosatti wrote: > >I didnt know. Anthony wrote this code, so I'll let him comment. > > > Is this guaranteed by Posix and reliable across Unixes? In general, I > think it's better to be conservative with this sort of thing. All the changes I suggested don't depend on pipe atomicity. (My mistake for bringing it up). As long as you're only writing 1 byte, write atomicity isn't relevant. (If the current code actually did anything with its 8 byte chunks it writes, _that_ would depend on atomicity.) The trick of reading 2 bytes and assuming the pipe is emptied if you only get 1 byte doesn't dependent on read atomicity, because in the unlikely event there is another byte, that's ok: the select() will return immediately and you'll read again anyway. That can happen even with atomicity due to parallelism. So reading 2 bytes is just a heuristic trick to avoid an unnecessary system call in most cases. So here's the signal-safe, thread-safe self-pipe trick as I see it: - Set both ends of the pipe to non-blocking. - Write 1 byte in signal handler, other threads etc. Don't care if you get EAGAIN; it just means the pipe is full, which is fine. (As an optimisation you can set a flag and avoid writing a second time when you know the pipe is non-empty. But to do this right, you have to be careful with memory ordering etc. Maybe this is not worth it.) - Read 2 or more bytes in the select() handler for the read side. If you get all the bytes you asked for, loop doing it again. The loop is to drain the pipe, avoiding spurious select() wakeups. When you get fewer bytes than you asked for, the pipe is probably empty, but if it isn't that's fine. -- Jamie