@@ -227,7 +227,7 @@ async def serve(rd, wr):
227
227
228
228
(s_rd , s_wr ) = await fut
229
229
230
- # Limit the socket buffers so we can reliably overfill them
230
+ # Limit the socket buffers so we can more reliably overfill them
231
231
s_sock = s_wr .get_extra_info ('socket' )
232
232
s_sock .setsockopt (socket .SOL_SOCKET , socket .SO_SNDBUF , 65536 )
233
233
c_sock = c_wr .get_extra_info ('socket' )
@@ -242,10 +242,18 @@ async def serve(rd, wr):
242
242
await asyncio .sleep (0 )
243
243
244
244
# Get the writer in a waiting state by sending data until the
245
- # socket buffers are full on both server and client sockets and
246
- # the kernel stops accepting more data
247
- s_wr .write (b'a' * c_sock .getsockopt (socket .SOL_SOCKET , socket .SO_RCVBUF ))
248
- s_wr .write (b'a' * s_sock .getsockopt (socket .SOL_SOCKET , socket .SO_SNDBUF ))
245
+ # kernel stops accepting more data in the send buffer.
246
+ # gh-122136: getsockopt() does not reliably report the buffer size
247
+ # available for message content.
248
+ # We loop until we start filling up the asyncio buffer.
249
+ # To avoid an infinite loop we cap at 10 times the expected value
250
+ c_bufsize = c_sock .getsockopt (socket .SOL_SOCKET , socket .SO_RCVBUF )
251
+ s_bufsize = s_sock .getsockopt (socket .SOL_SOCKET , socket .SO_SNDBUF )
252
+ for i in range (10 ):
253
+ s_wr .write (b'a' * c_bufsize )
254
+ s_wr .write (b'a' * s_bufsize )
255
+ if s_wr .transport .get_write_buffer_size () > 0 :
256
+ break
249
257
self .assertNotEqual (s_wr .transport .get_write_buffer_size (), 0 )
250
258
251
259
task = asyncio .create_task (srv .wait_closed ())
0 commit comments