Skip to content

Commit 69e6171

Browse files
committed
Use uv.try_write instead of socket.h/send
1 parent b28b30c commit 69e6171

File tree

3 files changed

+35
-37
lines changed

3 files changed

+35
-37
lines changed

uvloop/handles/stream.pyx

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -179,40 +179,45 @@ cdef class UVStream(UVBaseTransport):
179179

180180
cdef inline _try_write(self, object data):
181181
cdef:
182-
ssize_t written
183-
int fd
182+
int written
183+
bint used_buf = 0
184184
Py_buffer py_buf
185-
186-
fd = self._fileno()
185+
uv.uv_buf_t uv_buf
187186

188187
if PyBytes_CheckExact(data):
189-
written = system.send(fd, PyBytes_AS_STRING(data),
190-
Py_SIZE(data), 0)
191-
188+
uv_buf.base = PyBytes_AS_STRING(data)
189+
uv_buf.len = Py_SIZE(data)
192190
elif PyByteArray_CheckExact(data):
193-
written = system.send(fd, PyByteArray_AS_STRING(data),
194-
Py_SIZE(data), 0)
195-
191+
uv_buf.base = PyByteArray_AS_STRING(data)
192+
uv_buf.len = Py_SIZE(data)
196193
else:
197194
PyObject_GetBuffer(data, &py_buf, PyBUF_SIMPLE)
198-
written = system.send(fd, <char*>py_buf.buf, py_buf.len, 0)
195+
used_buf = 1
196+
uv_buf.base = <char*>py_buf.buf
197+
uv_buf.len = py_buf.len
198+
199+
written = uv.uv_try_write(
200+
<uv.uv_stream_t*>self._handle,
201+
&uv_buf, 1)
202+
203+
if used_buf:
199204
PyBuffer_Release(&py_buf)
200205

201206
if written < 0:
202-
if errno.errno not in (system.EINTR, system.EAGAIN,
203-
system.EWOULDBLOCK, system.EINPROGRESS,
204-
system.EALREADY,
205-
# If it's a wrong type of FD - let libuv
206-
# handle it, ignore the error:
207-
system.ENOTSOCK, system.EBADF,
208-
system.ENOSYS):
209-
exc = convert_error(-errno.errno)
207+
if written == uv.UV_EAGAIN:
208+
return -1
209+
else:
210+
exc = convert_error(written)
210211
self._fatal_error(exc, True)
212+
return
211213

212214
IF DEBUG:
213215
if written > 0:
214216
self._loop._debug_stream_write_tries += 1
215217

218+
if written == uv_buf.len:
219+
return 0
220+
216221
return written
217222

218223
cdef inline _write(self, object data):
@@ -224,9 +229,16 @@ cdef class UVStream(UVBaseTransport):
224229
# Try to write without polling only when there is
225230
# no data in write buffers.
226231
sent = self._try_write(data)
232+
if sent == 0:
233+
# All data was successfully written.
234+
return
227235
if sent > 0:
228-
if sent == len(data):
229-
return
236+
IF DEBUG:
237+
if sent == len(data):
238+
raise RuntimeError(
239+
'_try_write sent all data and returned non-zero')
240+
if not isinstance(data, memoryview):
241+
data = memoryview(data)
230242
data = data[sent:]
231243

232244
ctx = _StreamWriteContext.new(self, data)

uvloop/includes/system.pxd

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,5 @@ cdef extern from "sys/socket.h" nogil:
4141

4242
int socketpair(int domain, int type, int protocol, int socket_vector[2])
4343

44-
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
45-
4644
int setsockopt(int socket, int level, int option_name,
4745
const void *option_value, int option_len)
48-
49-
50-
cdef extern from "errno.h" nogil:
51-
52-
cdef:
53-
# cython.errno doesn't have EWOULDBLOCK defined.
54-
int EINTR
55-
int EAGAIN
56-
int EWOULDBLOCK
57-
int EINPROGRESS
58-
int EALREADY
59-
int ENOTSOCK
60-
int EBADF
61-
int ENOSYS

uvloop/includes/uv.pxd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,8 @@ cdef extern from "uv.h" nogil:
318318
int uv_write(uv_write_t* req, uv_stream_t* handle,
319319
uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb)
320320

321+
int uv_try_write(uv_stream_t* handle, uv_buf_t bufs[], unsigned int nbufs)
322+
321323
int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb)
322324

323325
int uv_is_readable(const uv_stream_t* handle)

0 commit comments

Comments
 (0)