Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Eoghan Glynn committed Mar 14, 2012
1 parent 1615a1f commit 51a06aa
Showing 1 changed file with 18 additions and 4 deletions.
22 changes: 18 additions & 4 deletions glance/common/client.py
Expand Up @@ -25,6 +25,7 @@
import httplib
import logging
import os
import select
import urllib
import urlparse

Expand Down Expand Up @@ -129,10 +130,23 @@ def __len__(self):
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)
Expand Down

0 comments on commit 51a06aa

Please sign in to comment.