Retry sendfile on EAGAIN or EBUSY
Addresses bug 954430 The sendfile call is redriven after a blocking select() to ensure the socket is now writeable. Change-Id: I68242c76593405f78e30324c2913cead63463c77
This commit is contained in:
parent
1615a1fc57
commit
51a06aab1c
@ -25,6 +25,7 @@ import functools
|
||||
import httplib
|
||||
import logging
|
||||
import os
|
||||
import select
|
||||
import urllib
|
||||
import urlparse
|
||||
|
||||
@ -129,10 +130,23 @@ class SendFileIterator:
|
||||
return self.len
|
||||
|
||||
while self.sending:
|
||||
sent = sendfile.sendfile(self.connection.sock.fileno(),
|
||||
self.body.fileno(),
|
||||
self.offset,
|
||||
CHUNKSIZE)
|
||||
try:
|
||||
sent = sendfile.sendfile(self.connection.sock.fileno(),
|
||||
self.body.fileno(),
|
||||
self.offset,
|
||||
CHUNKSIZE)
|
||||
except OSError as e:
|
||||
# suprisingly, sendfile may fail transiently instead of
|
||||
# blocking, in which case we select on the socket in order
|
||||
# to wait on its return to a writeable state before resuming
|
||||
# the send loop
|
||||
if e.errno in (errno.EAGAIN, errno.EBUSY):
|
||||
wlist = [self.connection.sock.fileno()]
|
||||
rfds, wfds, efds = select.select([], wlist, [])
|
||||
if wfds:
|
||||
continue
|
||||
raise
|
||||
|
||||
self.sending = (sent != 0)
|
||||
self.offset += sent
|
||||
yield OfLength(sent)
|
||||
|
Loading…
Reference in New Issue
Block a user