@@ -45,13 +45,22 @@ the async condition object itself.
45
45
"""
46
46
function AsyncCondition (cb:: Function )
47
47
async = AsyncCondition ()
48
- t = @task while _trywait (async)
49
- cb (async)
50
- isopen (async) || return
48
+ t = @task begin
49
+ unpreserve_handle (async)
50
+ while _trywait (async)
51
+ cb (async)
52
+ isopen (async) || return
53
+ end
54
+ end
55
+ # here we are mimicking parts of _trywait, in coordination with task `t`
56
+ preserve_handle (async)
57
+ @lock async. cond begin
58
+ if async. set
59
+ schedule (t)
60
+ else
61
+ _wait2 (async. cond, t)
62
+ end
51
63
end
52
- lock (async. cond)
53
- _wait2 (async. cond, t)
54
- unlock (async. cond)
55
64
return async
56
65
end
57
66
@@ -115,6 +124,7 @@ function _trywait(t::Union{Timer, AsyncCondition})
115
124
# full barrier now for AsyncCondition
116
125
t isa Timer || Core. Intrinsics. atomic_fence (:acquire_release )
117
126
else
127
+ t. isopen || return false
118
128
t. handle == C_NULL && return false
119
129
iolock_begin ()
120
130
set = t. set
@@ -123,14 +133,12 @@ function _trywait(t::Union{Timer, AsyncCondition})
123
133
lock (t. cond)
124
134
try
125
135
set = t. set
126
- if ! set
127
- if t. handle != C_NULL
128
- iolock_end ()
129
- set = wait (t. cond)
130
- unlock (t. cond)
131
- iolock_begin ()
132
- lock (t. cond)
133
- end
136
+ if ! set && t. isopen && t. handle != C_NULL
137
+ iolock_end ()
138
+ set = wait (t. cond)
139
+ unlock (t. cond)
140
+ iolock_begin ()
141
+ lock (t. cond)
134
142
end
135
143
finally
136
144
unlock (t. cond)
@@ -266,19 +274,28 @@ julia> begin
266
274
"""
267
275
function Timer (cb:: Function , timeout:: Real ; interval:: Real = 0.0 )
268
276
timer = Timer (timeout, interval= interval)
269
- t = @task while _trywait (timer)
270
- try
271
- cb (timer)
272
- catch err
273
- write (stderr , " Error in Timer:\n " )
274
- showerror (stderr , err, catch_backtrace ())
275
- return
277
+ t = @task begin
278
+ unpreserve_handle (timer)
279
+ while _trywait (timer)
280
+ try
281
+ cb (timer)
282
+ catch err
283
+ write (stderr , " Error in Timer:\n " )
284
+ showerror (stderr , err, catch_backtrace ())
285
+ return
286
+ end
287
+ isopen (timer) || return
288
+ end
289
+ end
290
+ # here we are mimicking parts of _trywait, in coordination with task `t`
291
+ preserve_handle (timer)
292
+ @lock timer. cond begin
293
+ if timer. set
294
+ schedule (t)
295
+ else
296
+ _wait2 (timer. cond, t)
276
297
end
277
- isopen (timer) || return
278
298
end
279
- lock (timer. cond)
280
- _wait2 (timer. cond, t)
281
- unlock (timer. cond)
282
299
return timer
283
300
end
284
301
0 commit comments