Skip to content

Commit 945837c

Browse files
Fix thread safety of http writer (#11464)
1 parent 633dabc commit 945837c

File tree

4 files changed

+13
-12
lines changed

4 files changed

+13
-12
lines changed

CHANGES/11464.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Implemented support for free-threading builds of CPython -- by :user:`kumaraditya303`.

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ aiohttp/_find_header.c: $(call to-hash,aiohttp/hdrs.py ./tools/gen.py)
5959
# Special case for reader since we want to be able to disable
6060
# the extension with AIOHTTP_NO_EXTENSIONS
6161
aiohttp/_websocket/reader_c.c: aiohttp/_websocket/reader_c.py
62-
cython -3 -o $@ $< -I aiohttp -Werror
62+
cython -3 -X freethreading_compatible=True -o $@ $< -I aiohttp -Werror
6363

6464
# _find_headers generator creates _headers.pyi as well
6565
aiohttp/%.c: aiohttp/%.pyx $(call to-hash,$(CYS)) aiohttp/_find_header.c
66-
cython -3 -o $@ $< -I aiohttp -Werror
66+
cython -3 -X freethreading_compatible=True -o $@ $< -I aiohttp -Werror
6767

6868
aiohttp/_websocket/%.c: aiohttp/_websocket/%.pyx $(call to-hash,$(CYS))
69-
cython -3 -o $@ $< -I aiohttp -Werror
69+
cython -3 -X freethreading_compatible=True -o $@ $< -I aiohttp -Werror
7070

7171
vendor/llhttp/node_modules: vendor/llhttp/package.json
7272
cd vendor/llhttp; npm ci

aiohttp/_http_parser.pyx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#cython: language_level=3
2-
#
31
# Based on https://github.com/MagicStack/httptools
42
#
53

aiohttp/_http_writer.pyx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ from libc.string cimport memcpy
88
from multidict import istr
99

1010
DEF BUF_SIZE = 16 * 1024 # 16KiB
11-
cdef char BUFFER[BUF_SIZE]
1211

1312
cdef object _istr = istr
1413

@@ -19,16 +18,17 @@ cdef struct Writer:
1918
char *buf
2019
Py_ssize_t size
2120
Py_ssize_t pos
21+
bint heap_allocated
2222

23-
24-
cdef inline void _init_writer(Writer* writer):
25-
writer.buf = &BUFFER[0]
23+
cdef inline void _init_writer(Writer* writer, char *buf):
24+
writer.buf = buf
2625
writer.size = BUF_SIZE
2726
writer.pos = 0
27+
writer.heap_allocated = 0
2828

2929

3030
cdef inline void _release_writer(Writer* writer):
31-
if writer.buf != BUFFER:
31+
if writer.heap_allocated:
3232
PyMem_Free(writer.buf)
3333

3434

@@ -39,7 +39,7 @@ cdef inline int _write_byte(Writer* writer, uint8_t ch):
3939
if writer.pos == writer.size:
4040
# reallocate
4141
size = writer.size + BUF_SIZE
42-
if writer.buf == BUFFER:
42+
if not writer.heap_allocated:
4343
buf = <char*>PyMem_Malloc(size)
4444
if buf == NULL:
4545
PyErr_NoMemory()
@@ -52,6 +52,7 @@ cdef inline int _write_byte(Writer* writer, uint8_t ch):
5252
return -1
5353
writer.buf = buf
5454
writer.size = size
55+
writer.heap_allocated = 1
5556
writer.buf[writer.pos] = <char>ch
5657
writer.pos += 1
5758
return 0
@@ -125,8 +126,9 @@ def _serialize_headers(str status_line, headers):
125126
cdef Writer writer
126127
cdef object key
127128
cdef object val
129+
cdef char buf[BUF_SIZE]
128130

129-
_init_writer(&writer)
131+
_init_writer(&writer, buf)
130132

131133
try:
132134
if _write_str(&writer, status_line) < 0:

0 commit comments

Comments
 (0)