Skip to content

Commit 0682d76

Browse files
committed
Make sock_sendall & sock_recv another 30% faster.
1 parent 666ee49 commit 0682d76

File tree

3 files changed

+72
-56
lines changed

3 files changed

+72
-56
lines changed

uvloop/cbhandles.pyx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,6 @@ cdef new_MethodHandle1(Loop loop, str name, method1_t *callback,
240240

241241
return handle
242242

243-
# The below code is currently unused.
244-
'''
245243
cdef new_MethodHandle2(Loop loop, str name, method2_t *callback, object ctx,
246244
object arg1, object arg2):
247245

@@ -258,7 +256,6 @@ cdef new_MethodHandle2(Loop loop, str name, method2_t *callback, object ctx,
258256
handle.arg3 = arg2
259257

260258
return handle
261-
'''
262259

263260
cdef new_MethodHandle3(Loop loop, str name, method3_t *callback, object ctx,
264261
object arg1, object arg2, object arg3):

uvloop/loop.pxd

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ cdef class Loop:
108108
readonly uint64_t _poll_write_events_total
109109
readonly uint64_t _poll_write_cb_errors_total
110110

111-
readonly uint64_t _sock_try_read_total
112111
readonly uint64_t _sock_try_write_total
113112

114113
readonly uint64_t _debug_exception_handler_cnt
@@ -152,9 +151,9 @@ cdef class Loop:
152151
cdef _add_writer(self, fd, Handle handle)
153152
cdef _remove_writer(self, fd)
154153

155-
cdef _sock_recv(self, fut, int registered, sock, n)
156-
cdef _sock_sendall(self, fut, int registered, sock, data)
157-
cdef _sock_accept(self, fut, int registered, sock)
154+
cdef _sock_recv(self, fut, sock, n)
155+
cdef _sock_sendall(self, fut, sock, data)
156+
cdef _sock_accept(self, fut, sock)
158157

159158
cdef _sock_connect(self, fut, sock, address)
160159
cdef _sock_connect_cb(self, fut, sock, address)

uvloop/loop.pyx

Lines changed: 69 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ cdef class Loop:
117117
self._poll_write_events_total = 0
118118
self._poll_write_cb_errors_total = 0
119119

120-
self._sock_try_read_total = 0
121120
self._sock_try_write_total = 0
122121

123122
self._debug_exception_handler_cnt = 0
@@ -548,49 +547,43 @@ cdef class Loop:
548547
nr.query(addr, flags)
549548
return fut
550549

551-
cdef _sock_recv(self, fut, int registered, sock, n):
552-
# _sock_recv() can add itself as an I/O callback if the operation can't
553-
# be done immediately. Don't use it directly, call sock_recv().
550+
cdef _sock_recv(self, fut, sock, n):
554551
cdef:
555552
Handle handle
553+
int fd
556554

557555
fd = sock.fileno()
558556
if fut.cancelled():
559-
if registered:
560-
self._remove_reader(fd)
557+
self._remove_reader(fd)
561558
return
559+
562560
try:
563561
data = sock.recv(n)
564562
except (BlockingIOError, InterruptedError):
565-
handle = new_MethodHandle4(
563+
handle = new_MethodHandle3(
566564
self,
567565
"Loop._sock_recv",
568-
<method4_t*>&self._sock_recv,
566+
<method3_t*>&self._sock_recv,
569567
self,
570-
fut, 1, sock, n)
571-
568+
fut, sock, n)
572569
self._add_reader(fd, handle)
573570
except Exception as exc:
574571
fut.set_exception(exc)
575-
if registered:
576-
self._remove_reader(fd)
572+
self._remove_reader(fd)
577573
else:
578-
IF DEBUG:
579-
if not registered:
580-
self._sock_try_read_total += 1
581574
fut.set_result(data)
582-
if registered:
583-
self._remove_reader(fd)
575+
self._remove_reader(fd)
584576

585-
cdef _sock_sendall(self, fut, int registered, sock, data):
577+
cdef _sock_sendall(self, fut, sock, data):
586578
cdef:
587579
Handle handle
580+
int n
581+
int fd
588582

589583
fd = sock.fileno()
590584

591585
if fut.cancelled():
592-
if registered:
593-
self._remove_writer(fd)
586+
self._remove_writer(fd)
594587
return
595588

596589
try:
@@ -599,60 +592,50 @@ cdef class Loop:
599592
n = 0
600593
except Exception as exc:
601594
fut.set_exception(exc)
602-
if registered:
603-
self._remove_writer(fd)
595+
self._remove_writer(fd)
604596
return
605-
else:
606-
IF DEBUG:
607-
if not registered:
608-
# This can be a partial success, i.e. only part
609-
# of the data was sent
610-
self._sock_try_write_total += 1
611597

612598
if n == len(data):
613599
fut.set_result(None)
614-
if registered:
615-
self._remove_writer(fd)
600+
self._remove_writer(fd)
616601
else:
617602
if n:
618603
if not isinstance(data, memoryview):
619604
data = memoryview(data)
620605
data = data[n:]
621606

622-
handle = new_MethodHandle4(
607+
handle = new_MethodHandle3(
623608
self,
624609
"Loop._sock_sendall",
625-
<method4_t*>&self._sock_sendall,
610+
<method3_t*>&self._sock_sendall,
626611
self,
627-
fut, 1, sock, data)
612+
fut, sock, data)
628613

629614
self._add_writer(fd, handle)
630615

631-
cdef _sock_accept(self, fut, int registered, sock):
616+
cdef _sock_accept(self, fut, sock):
632617
cdef:
633618
Handle handle
634619

635620
fd = sock.fileno()
636-
if registered:
637-
self._remove_reader(fd)
621+
638622
if fut.cancelled():
623+
self._remove_reader(fd)
639624
return
625+
640626
try:
641627
conn, address = sock.accept()
642628
conn.setblocking(False)
643629
except (BlockingIOError, InterruptedError):
644-
handle = new_MethodHandle3(
645-
self,
646-
"Loop._sock_accept",
647-
<method3_t*>&self._sock_accept,
648-
self,
649-
fut, 1, sock)
650-
651-
self._add_reader(fd, handle)
630+
# There is an active reader for _sock_accept, so
631+
# do nothing, it will be called again.
632+
pass
652633
except Exception as exc:
653634
fut.set_exception(exc)
635+
self._remove_reader(fd)
654636
else:
655637
fut.set_result((conn, address))
638+
self._remove_reader(fd)
656639

657640
cdef _sock_connect(self, fut, sock, address):
658641
cdef:
@@ -823,8 +806,6 @@ cdef class Loop:
823806
print()
824807

825808
print('--- Sock ops successfull on 1st try: ---')
826-
print('Socket try-reads: {}'.format(
827-
self._sock_try_read_total))
828809
print('Socket try-writes: {}'.format(
829810
self._sock_try_write_total))
830811

@@ -1629,10 +1610,23 @@ cdef class Loop:
16291610
16301611
This method is a coroutine.
16311612
"""
1613+
cdef:
1614+
Handle handle
1615+
int fd
1616+
16321617
if self._debug and sock.gettimeout() != 0:
16331618
raise ValueError("the socket must be non-blocking")
1619+
16341620
fut = self._new_future()
1635-
self._sock_recv(fut, 0, sock, n)
1621+
handle = new_MethodHandle3(
1622+
self,
1623+
"Loop._sock_recv",
1624+
<method3_t*>&self._sock_recv,
1625+
self,
1626+
fut, sock, n)
1627+
1628+
fd = sock.fileno()
1629+
self._add_reader(fd, handle)
16361630
return fut
16371631

16381632
async def sock_sendall(self, sock, data):
@@ -1646,6 +1640,11 @@ cdef class Loop:
16461640
16471641
This method is a coroutine.
16481642
"""
1643+
cdef:
1644+
Handle handle
1645+
int n
1646+
int fd
1647+
16491648
if self._debug and sock.gettimeout() != 0:
16501649
raise ValueError("the socket must be non-blocking")
16511650

@@ -1669,7 +1668,15 @@ cdef class Loop:
16691668
data = data[n:]
16701669

16711670
fut = self._new_future()
1672-
self._sock_sendall(fut, 0, sock, data)
1671+
handle = new_MethodHandle3(
1672+
self,
1673+
"Loop._sock_sendall",
1674+
<method3_t*>&self._sock_sendall,
1675+
self,
1676+
fut, sock, data)
1677+
1678+
fd = sock.fileno()
1679+
self._add_writer(fd, handle)
16731680
return await fut
16741681

16751682
def sock_accept(self, sock):
@@ -1682,10 +1689,23 @@ cdef class Loop:
16821689
16831690
This method is a coroutine.
16841691
"""
1692+
cdef:
1693+
Handle handle
1694+
int fd
1695+
16851696
if self._debug and sock.gettimeout() != 0:
16861697
raise ValueError("the socket must be non-blocking")
1698+
16871699
fut = self._new_future()
1688-
self._sock_accept(fut, 0, sock)
1700+
handle = new_MethodHandle2(
1701+
self,
1702+
"Loop._sock_accept",
1703+
<method2_t*>&self._sock_accept,
1704+
self,
1705+
fut, sock)
1706+
1707+
fd = sock.fileno()
1708+
self._add_reader(fd, handle)
16891709
return fut
16901710

16911711
def sock_connect(self, sock, address):

0 commit comments

Comments
 (0)