@@ -129,5 +129,45 @@ def test_popen(self):
129129 pass
130130
131131
132+ class OverlappedLeakTests (unittest .TestCase ):
133+ def _invalid_socket_handle (self ):
134+ return 0
135+
136+ def test_overlapped_wsasendto_failure_releases_user_buffer (self ):
137+ ov = _overlapped .Overlapped ()
138+ buf = bytearray (4096 )
139+ with self .assertRaises (OSError ):
140+ ov .WSASendTo (self ._invalid_socket_handle (),
141+ memoryview (buf ), 0 , ("127.0.0.1" , 1 ))
142+ # If the exported buffer is still held, this will raise BufferError.
143+ buf .append (1 )
144+
145+ def test_overlapped_wsarecvfrominto_failure_releases_user_buffer (self ):
146+ ov = _overlapped .Overlapped ()
147+ buf = bytearray (4096 )
148+ with self .assertRaises (OSError ):
149+ ov .WSARecvFromInto (self ._invalid_socket_handle (),
150+ memoryview (buf ), len (buf ), 0 )
151+ # If the exported buffer is still held, this will raise BufferError.
152+ buf .append (1 )
153+
154+ @support .refcount_test
155+ def test_overlapped_wsarecvfrom_failure_does_not_leak_allocated_buffer (self ):
156+ gettotalrefcount = support .get_attribute (sys , "gettotalrefcount" )
157+
158+ def run_once ():
159+ ov = _overlapped .Overlapped ()
160+ with self .assertRaises (OSError ):
161+ ov .WSARecvFrom (self ._invalid_socket_handle (), 4096 , 0 )
162+
163+ # Warm up
164+ run_once ()
165+ before = gettotalrefcount ()
166+ for _ in range (2000 ):
167+ run_once ()
168+ after = gettotalrefcount ()
169+ self .assertAlmostEqual (after - before , 0 , delta = 20 )
170+
171+
132172if __name__ == '__main__' :
133173 unittest .main ()
0 commit comments