[Python-3000] socket GC worries

roudkerk r.m.oudkerk at gmail.com
Wed Oct 31 19:19:05 CET 2007


Guido van Rossum <guido <at> python.org> writes:
> 
> 2007/10/29, Greg Ewing <greg.ewing <at> canterbury.ac.nz>:
> > I don't see what's so difficult about this. Each file
> > descriptor should be owned by exactly one object. If
> > two objects need to share a fd, then you dup() it so
> > that each one has its own fd. When the object is
> > close()d or GCed, it closes its fd.
> 
> On Windows you can't dup() a fd.
> 

You can use os.dup() on an fd.  But with sockets you must 
use DuplicateHandle() instead because socket.fileno() returns 
a handle not an fd.

socket.py has this comment:

#
# These classes are used by the socket() defined on Windows and BeOS
# platforms to provide a best-effort implementation of the cleanup
# semantics needed when sockets can't be dup()ed.
#
# These are not actually used on other platforms.
#

I don't know whether BeOS still matters to anyone...  I would just
implement _socket.socket.dup() on Windows using DuplicateHandle().

Example of DuplicateHandle():


import ctypes, socket
from _subprocess import *

# send a message to a socket object 'conn'
listener = socket.socket()
listener.bind(('localhost', 0))
listener.listen(1)
client = socket.socket()
client.connect(listener.getsockname())
conn, addr = listener.accept()
client.sendall('hello world')

# duplicate handle
handle = conn.fileno()
duphandle = DuplicateHandle(
    GetCurrentProcess(), handle, GetCurrentProcess(), 
    0, False, DUPLICATE_SAME_ACCESS
    ).Detach()

# use duplicate handle to read the message
buffer = ctypes.c_buffer(20)
ctypes.windll.ws2_32.recv(duphandle, buffer, 20, 0)
print handle, duphandle, buffer.value


BTW.  On Windows can we please have a socket.fromfd() 
function (or maybe that should be socket.fromhandle()).




More information about the Python-3000 mailing list