Skip to content

Commit 83f2e06

Browse files
committed
Optimize stream send op -- try to send the data right away, w/o libuv
1 parent 0ff106f commit 83f2e06

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

uvloop/handles/stream.pxd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ cdef class UVStream(UVBaseTransport):
2020
cdef inline __reading_stopped(self)
2121

2222
cdef inline _write(self, object data)
23+
cdef inline _try_write(self, object data)
2324

2425
cdef _close(self)
2526

uvloop/handles/stream.pyx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,50 @@ cdef class UVStream(UVBaseTransport):
157157
else:
158158
self.__reading_stopped()
159159

160+
cdef inline _try_write(self, object data):
161+
if self._get_write_buffer_size():
162+
# Don't try to write anything as we already have some
163+
# data in the write buffers.
164+
return
165+
166+
cdef:
167+
ssize_t written
168+
int fd
169+
Py_buffer py_buf
170+
171+
# Let's try to send the data right away.
172+
173+
fd = self._fileno()
174+
PyObject_GetBuffer(data, &py_buf, PyBUF_SIMPLE)
175+
written = system.send(fd, <char*>py_buf.buf, py_buf.len, 0)
176+
PyBuffer_Release(&py_buf)
177+
if written < 0:
178+
if errno.errno not in (system.EINTR, system.EAGAIN,
179+
system.EWOULDBLOCK, system.EINPROGRESS,
180+
system.EALREADY,
181+
# If it's a wrong type of FD - let libuv
182+
# handle it, ignore the error:
183+
system.ENOTSOCK, system.EBADF,
184+
system.ENOSYS):
185+
exc = convert_error(-errno.errno)
186+
self._fatal_error(exc, True)
187+
188+
return written
189+
160190
cdef inline _write(self, object data):
161191
cdef:
162192
int err
193+
int sent
163194
_StreamWriteContext ctx
164195

165196
self._ensure_alive()
166197

198+
sent = self._try_write(data)
199+
if sent > 0:
200+
if sent == len(data):
201+
return
202+
data = data[sent:]
203+
167204
ctx = _StreamWriteContext.new(self, data)
168205

169206
err = uv.uv_write(&ctx.req,

uvloop/includes/system.pxd

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,19 @@ cdef extern from "sys/socket.h" nogil:
4040
const char *gai_strerror(int errcode)
4141

4242
int socketpair(int domain, int type, int protocol, int socket_vector[2])
43+
44+
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
45+
46+
47+
cdef extern from "errno.h" nogil:
48+
49+
cdef:
50+
# cython.errno doesn't have EWOULDBLOCK defined.
51+
int EINTR
52+
int EAGAIN
53+
int EWOULDBLOCK
54+
int EINPROGRESS
55+
int EALREADY
56+
int ENOTSOCK
57+
int EBADF
58+
int ENOSYS

0 commit comments

Comments
 (0)