Compare commits

...

3 Commits

Author SHA1 Message Date
d4c9d31068 Oops, we were being overzealous about calling nowrite().
We were doing it as soon as the other end was shut_read, but we didn't
confirm first that the other end's read buffer had been totally emptied.
This caused problems on twitter.com, at least, where they create a zillion
short-lived connections.

I don't actually need these lines at all, as it turns out, because we were
already calling nowrite() correctly on the other end after a buffer got
emptied.
2011-01-12 09:33:56 -08:00
38bb7f3c21 If we get EPIPE on uwrite(), don't close, just do nowrite().
EPIPE doesn't mean the whole socket is dead, it just means we can't write to
it.  Maybe there's still data waiting to be read, though.
2011-01-12 09:19:43 -08:00
b7f1530aef Remember which syscall got a particular stream-killing error. 2011-01-12 09:18:46 -08:00

View File

@ -151,7 +151,7 @@ class SockWrapper:
try:
self.wsock.shutdown(SHUT_WR)
except socket.error, e:
self.seterr(e)
self.seterr('nowrite: %s' % e)
def too_full(self):
return False # fullness is determined by the socket's select() state
@ -163,9 +163,14 @@ class SockWrapper:
try:
return _nb_clean(os.write, self.wsock.fileno(), buf)
except OSError, e:
# unexpected error... stream is dead
self.seterr(e)
return 0
if e.errno == errno.EPIPE:
debug1('%r: uwrite: got EPIPE\n' % self)
self.nowrite()
return 0
else:
# unexpected error... stream is dead
self.seterr('uwrite: %s' % e)
return 0
def write(self, buf):
assert(buf)
@ -180,7 +185,7 @@ class SockWrapper:
try:
return _nb_clean(os.read, self.rsock.fileno(), 65536)
except OSError, e:
self.seterr(e)
self.seterr('uread: %s' % e)
return '' # unexpected error... we'll call it EOF
def fill(self):
@ -232,9 +237,7 @@ class Proxy(Handler):
self.wrap2 = wrap2
def pre_select(self, r, w, x):
if self.wrap1.shut_read: self.wrap2.nowrite()
if self.wrap1.shut_write: self.wrap2.noread()
if self.wrap2.shut_read: self.wrap1.nowrite()
if self.wrap2.shut_write: self.wrap1.noread()
if self.wrap1.connect_to: