Hello, My question concerns asynchat in particular. With the following half- pseudo code in mind:
class Example(asynchat.async_chat): def readable(self): if foo: self.push_with_producer(ProducerA()) return asynchat.async_chat.readable(self) Now, asyncore will call the readable function just before a select(), and it is meant to determine whether or not to include that asyncore dispatcher in the select map for reading. The problem with this code is that it has the unexpected side-effect of _immediately_ trying to send, disregarding if the async_chat object is indeed writable or not. The asynchat.push_with_producer (and .push as well) call .initiate_send(), which in turn calls .send if there's data buffered. While this might seem logical, it isn't at all. Insinuate that when Example.readable is called, the socket has already been closed. There are two possible scenarios where it could be closed. a) The remote endpoint closed the connection, and b) the producer ProducerA somehow closed the connection (my case). Obviously, calling send on a socket that has been closed will result in an error - EBADF, "Bad file descriptor". So, my question is: Why does asynchat.push* call self.initiate_send? Nothing in the name "push" suggests that it'll transmit immediately, disregarding potential "closedness". Removing the two calls to .initiate_send() in the two push functions would still mean data is sent, but only when data can be sent - which is, IMO, what should be done. Thankful for insights, Ludvig. -- http://mail.python.org/mailman/listinfo/python-list