On 03/14/2018 10:13 AM, Eric Blake wrote:
On 03/14/2018 10:04 AM, Tim Rühsen wrote:
Hi,
just stumbled upon nonintr_close() in spawn-pipe.c which has this loop:
do
retval = close (fd);
while (retval < 0 && errno == EINTR);
Regarding the man page of libc, this shouldn't be done on certain
systems. E.g. it says the Linux kernel closes the file descriptor even
on EINTR. With the effect of possible race conditions in multi-threaded
code.
What do the experts here say ?
Here's what POSIX has to say:
http://austingroupbugs.net/view.php?id=529#c1200
You are correct that retrying close (fd) is a bug in multi-threaded
programs. It is better to leak the fd (on the few implementations that
leave fd open on EINTR failure) than to risk corrupting multithreaded
state. If you are on a system that has posix_close() implemented (glibc
appears to not have done it yet, and I don't know if any other systems
have), then you are guaranteed that you can write race-free leak-free
code. But until then, it's better to err on the side of safety,
especially since it was only a minority of systems that leave fd open on
EINTR failure.
I didn't offer my conclusion: I think the existence of nonintr_close()
in gnulib is a bug, and should be removed. It's better to assume Linux
semantics (close ALWAYS destroys the fd, even when an error is reported)
which is safe for multithreaded apps, than to assume that EINTR leaves
the fd open (where assuming Linux semantics leaks on the few platforms
that leave the fd open, but a leak is safer than multithreaded
corruption when the wrong fd is closed on retry).
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org