4
4
5
5
import copy
6
6
import gc
7
- import sys
8
7
9
8
try :
10
9
from sys import getrefcount
18
17
import pytest
19
18
20
19
import zmq
20
+ from zmq .utils .garbage import gc as zmq_gc
21
21
from zmq_test_utils import PYPY , BaseZMQTestCase , SkipTest , skip_cpython_cffi , skip_pypy
22
22
23
23
# some useful constants:
30
30
view_rc = grc (x ) - rc0
31
31
32
32
33
- def await_gc (obj , rc ):
34
- """wait for refcount on an object to drop to an expected value
33
+ def await_gc (gc_key ):
34
+ """wait for zmq garbage collection
35
35
36
36
Necessary because of the zero-copy gc thread,
37
37
which can take some time to receive its DECREF message.
38
38
"""
39
- # count refs for this function
40
- if sys .version_info < (3 , 11 ):
41
- my_refs = 2
42
- else :
43
- my_refs = 1
44
- for i in range (50 ):
45
- # rc + 2 because of the refs in this function
46
- if grc (obj ) <= rc + my_refs :
39
+ deadline = time .monotonic () + 3
40
+ while time .monotonic () < deadline :
41
+ if gc_key in zmq_gc .refs :
42
+ time .sleep (0.05 )
43
+ else :
44
+ gc .collect ()
47
45
return
48
- time . sleep ( 0.05 )
46
+ raise TimeoutError ( "gc not collected" )
49
47
50
48
51
49
class TestFrame (BaseZMQTestCase ):
50
+ def setUp (self ):
51
+ super ().setUp ()
52
+ # make sure we are starting clean
53
+ assert not zmq_gc .refs
54
+
52
55
def tearDown (self ):
53
56
super ().tearDown ()
54
57
for i in range (3 ):
55
58
gc .collect ()
59
+ # make sure we left no refs
60
+ assert not zmq_gc .refs
56
61
57
62
@skip_pypy
58
63
def test_above_30 (self ):
@@ -61,9 +66,10 @@ def test_above_30(self):
61
66
s = (2 ** i ) * x
62
67
rc = grc (s )
63
68
m = zmq .Frame (s , copy = False )
69
+ _gc_ref = next (iter (zmq_gc .refs ))
64
70
assert grc (s ) == rc + 2
65
71
del m
66
- await_gc (s , rc )
72
+ await_gc (_gc_ref )
67
73
assert grc (s ) == rc
68
74
del s
69
75
@@ -116,6 +122,7 @@ def test_lifecycle1(self):
116
122
s = (2 ** i ) * x
117
123
rc = rc_0 = grc (s )
118
124
m = zmq .Frame (s , copy = False )
125
+ _gc_ref = next (iter (zmq_gc .refs ))
119
126
rc += 2
120
127
assert grc (s ) == rc
121
128
m2 = copy .copy (m )
@@ -137,7 +144,7 @@ def test_lifecycle1(self):
137
144
assert grc (s ) == rc
138
145
del m
139
146
rc -= 2
140
- await_gc (s , rc )
147
+ await_gc (_gc_ref )
141
148
assert grc (s ) == rc
142
149
assert rc == rc_0
143
150
del s
@@ -149,6 +156,7 @@ def test_lifecycle2(self):
149
156
s = (2 ** i ) * x
150
157
rc = rc_0 = grc (s )
151
158
m = zmq .Frame (s , copy = False )
159
+ _gc_ref = next (iter (zmq_gc .refs ))
152
160
rc += 2
153
161
assert grc (s ) == rc
154
162
m2 = copy .copy (m )
@@ -169,7 +177,7 @@ def test_lifecycle2(self):
169
177
assert grc (s ) == rc
170
178
del m2
171
179
rc -= 2
172
- await_gc (s , rc )
180
+ await_gc (_gc_ref )
173
181
assert grc (s ) == rc
174
182
assert rc == rc_0
175
183
del s
0 commit comments