Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interrupting Select to add another socket to watch in Python

I'm implementing peer-to-peer IPC using TCP in a Windows XP application.

I'm using the select and socket modules in Python 2.6.6.

I have three TCP threads, a reading thread that typically is blocking on select(), a writing thread that is typically waiting on an event (the event indicates there is stuff to write to TCP) and a listening thread that accepts connections.

If I start a new connection or close a current one then I need to interrupt the read select and restart it so it listens to the newly accepted socket as well.

Under winsock I can call WSACancelBlockingCall which will interrupt the select gracefully.

So my question is this: is it possible to do all this in a pythonic way without resorting to using poll()?

Many thx

--DM

like image 324
DangerMouse Avatar asked Feb 25 '23 10:02

DangerMouse


2 Answers

You could try adding an extra file descriptor to your set that you use as a signaling mechanism. You can then write to that descriptor a dummy value to cause select to exit. For example:

my_pipe = os.pipe()
...
while True:
    ready_fds = select.select(my_read_fds + [my_pipe[0]],
                              my_write_fds, my_except_fds, timeout)
    if my_pipe[0] in ready_fds[0]:
        # Add another fd to my_read_fds, etc.
        os.read(my_pipe[0], 1)
    ...

# To interrupt the current select call and add a new fd, write to the pipe:
os.write(my_pipe[1], 'x')
like image 101
Adam Rosenfield Avatar answered Apr 27 '23 09:04

Adam Rosenfield


I am not able to add comments, so I'm adding this as an answer.

Don't use WSACancelBlockingCall. You should use the approach from Adam Rosenfield's answer. Just make a pair of dummy sockets one connected to another, instead of a dummy file descriptor. Include one of that sockets in your select() call. When you need to interrupt the call - just write a byte into the second dummy socket.

Oh, and don't forget to read that byte back from the first socket when select() will return.

like image 29
torvin Avatar answered Apr 27 '23 11:04

torvin