[Python-Dev] PEP 446: Add new parameters to configure the inherance of files and for non-blocking sockets

Cameron Simpson cs at zip.com.au
Fri Jul 5 11:15:59 CEST 2013


On 05Jul2013 08:24, Victor Stinner <victor.stinner at gmail.com> wrote:
| 2013/7/5 Cameron Simpson <cs at zip.com.au>:
| > You might want to make clear that the "blocking" parameter refers
| > only to the file creation calls (eg socket.socket) and not to the
| > file descriptor itself, and is not to be confused with the UNIX
| > O_NONBLOCK file descriptor flag (and whatever equivalent flag may
| > apply on Windows).
| 
| The two following codes are the same:
| 
| s = socket.socket(..., blocking=False)
| and
| s = socket.socket(...)
| s.setblocking(False)
| 
| Both set O_NONBLOCK flag (UNIX)

Oh, how embarassing.

| or clear HANDLE_FLAG_INHERIT (Windows)
| on the socket (which is a file descriptor).
| 
| socket.socket(..., blocking=False) cannot fail with EAGAIN or
| EWOULDBLOCK (at least on Linux according to the manual page).

Fair enough.

| > This is deducable from your PEP, but I was at first confused, and
| > initially expected get_blocking/set_blocking functions in New
| > Functions.
| 
| socket objects already have get_blocking() and set_blocking() methods.

Ah, ok then. As far as it goes. Shouldn't there be a general purpose
os.get_blocking() and os.set_blocking() functions that operate on
any file descriptor, paralleling os.get_cloexec() and os.set_cloexec()?
They're not socket specific operations in principle, merely commonly
used with sockets.

| If we supported the blocking flag on any file descriptor, it would
| make sense to add such function to the os module. But I explained in
| the "Add blocking parameter for file descriptors and Windows
| overlapped I/O" section why I only want to set/clear the blocking file
| on sockets.

But WHY? I think socket file decriptors should be treated little
differently from other file descriptors. Certainly a stream socket
connection is outstanding like other unseekable file descriptors
in many respects. Just "only wanting it on sockets" seems a bit
special purpose.

If you're going address O_NONBLOCK in this proposal in addition to
the close-on-exec flag, it should be general purpose.

Otherwise, I think it should be separated out into a separate
proposal if you're proposing it just for sockets; make this proposal
just close-on-exec and forget the blocking stuff for this specific
PEP.

| > I would expect Popen and friends to need to both clear the flag to
| > get the descriptors across the fork() call, and _possibly_ to set
| > the flag again after the fork. Naively, I would expect the the flag
| > to be as it was before the Popen call, after the call.
| 
| As explained in the "Inheritance of file descriptors" section, the
| close-on-exec flag has no effect on fork:
| 
| "The flag has no effect on fork(), all file descriptors are inherited
| by the child process."

Agreed, see my second post where I explained I'd misthought it.
However, as stated there, I think the side effects should be fairly
overtly stated in the docuemntation.

| The close-on-exec flag is cleared after the fork and before the
| exec(). Pseudo-code for Popen:
| 
| pid = os.fork()
| if pid:
|   return pid
| # child process
| for fd in pass_fds: os.set_cloexec(fd, False)
| os.execv(...)

Fine. No state restore is fine with me. I think it should be as
clear as possible in the doco.

Cheers,
-- 
Cameron Simpson <cs at zip.com.au>

Experience is what you have got after you needed it.


More information about the Python-Dev mailing list