@@ -196,40 +196,45 @@ else
196
196
end
197
197
function uv_prepare (src:: Ptr{Void} ,timeout:: Ptr{Cint} )
198
198
global expiration, uv_pollfd
199
- local tmout_ms:: Cint , tmout_min :: Cint = (uv_pollfd :: _GPollFD ) . fd == - 1 ? 100 : 5000
199
+ local tmout_ms:: Cint
200
200
evt = Base. eventloop ()
201
- if ccall (:uv_loop_alive ,Cint,(Ptr{Void},),evt) == 0
202
- tmout_ms = tmout_min
203
- elseif uv_pollfd. revents != 0
201
+ if ! isempty_workqueue ()
204
202
tmout_ms = 0
205
- elseif ! isempty_workqueue ()
203
+ elseif ccall (:uv_loop_alive ,Cint,(Ptr{Void},),evt) == 0
204
+ tmout_ms = - 1
205
+ elseif uv_pollfd. revents != 0
206
206
tmout_ms = 0
207
+ elseif @windows ? (VERSION < v " 0.3-" ) : false # uv_backend_timeout broken on windows before Julia v0.3-rc2
208
+ tmout_ms = 10
207
209
else
208
210
tmout_ms = ccall (:uv_backend_timeout ,Cint,(Ptr{Void},),evt)
211
+ tmout_min:: Cint = (uv_pollfd:: _GPollFD ). fd == - 1 ? 100 : 5000
209
212
if tmout_ms < 0 || tmout_ms > tmout_min
210
213
tmout_ms = tmout_min
211
214
end
212
215
end
213
216
timeout != C_NULL && unsafe_store! (timeout, tmout_ms)
214
- if tmout_ms > 0
217
+ if tmout_ms < 0
218
+ expiration = typemax (Uint64)
219
+ elseif tmout_ms > 0
215
220
now = ccall ((:g_source_get_time ,GLib. libglib),Uint64,(Ptr{Void},),src)
216
221
expiration = convert (Uint64,now + tmout_ms* 1000 )
217
- else
222
+ else # tmout_ms == 0
218
223
expiration = uint64 (0 )
219
224
end
220
225
int32 (tmout_ms == 0 )
221
226
end
222
227
function uv_check (src:: Ptr{Void} )
223
228
global expiration
224
229
ex = expiration:: Uint64
225
- if ccall (:uv_loop_alive ,Cint,(Ptr{Void},),Base. eventloop ()) == 0
230
+ if ! isempty_workqueue ()
231
+ return int32 (1 )
232
+ elseif ccall (:uv_loop_alive ,Cint,(Ptr{Void},),Base. eventloop ()) == 0
226
233
return int32 (0 )
227
234
elseif ex == 0
228
235
return int32 (1 )
229
236
elseif uv_pollfd. revents != 0
230
237
return int32 (1 )
231
- elseif ! isempty_workqueue ()
232
- return int32 (1 )
233
238
else
234
239
now = ccall ((:g_source_get_time ,GLib. libglib),Uint64,(Ptr{Void},),src)
235
240
return int32 (ex <= now)
@@ -240,10 +245,33 @@ function uv_dispatch{T}(src::Ptr{Void},callback::Ptr{Void},data::T)
240
245
ret
241
246
end
242
247
248
+ yield_stack = Task[] # need to make sure we return to g_loop_run_run in the same order we were called
249
+ if VERSION < v " 0.3-"
250
+ function schedule_and_wait (task:: Task )
251
+ task. runnable || schedule (task)
252
+ wait ()
253
+ end
254
+ else
255
+ function schedule_and_wait (task:: Task )
256
+ # unfair scheduler version of Base.schedule_and_wait
257
+ if task. state == :runnable
258
+ yieldto (task)
259
+ else
260
+ wait ()
261
+ end
262
+ end
263
+ end
243
264
function g_yield (data)
265
+ global yield_stack
266
+ ct = current_task ()
267
+ push! (yield_stack, ct)
244
268
g_siginterruptible () do
245
269
yield ()
246
270
end
271
+ newtask = pop! (yield_stack)
272
+ if newtask != ct
273
+ schedule_and_wait (newtask)
274
+ end
247
275
int32 (true )
248
276
end
249
277
0 commit comments