Line | Exclusive | Inclusive | Code |
---|---|---|---|
1 | # This file is a part of Julia. License is MIT: https://julialang.org/license | ||
2 | |||
3 | # Core definitions for interacting with the libuv library from Julia | ||
4 | |||
5 | include(string(length(Core.ARGS) >= 2 ? Core.ARGS[2] : "", "uv_constants.jl")) # include($BUILDROOT/base/uv_constants.jl) | ||
6 | |||
7 | # convert UV handle data to julia object, checking for null | ||
8 | function uv_sizeof_handle(handle) | ||
9 | if !(UV_UNKNOWN_HANDLE < handle < UV_HANDLE_TYPE_MAX) | ||
10 | throw(DomainError(handle)) | ||
11 | end | ||
12 | ccall(:uv_handle_size,Csize_t,(Int32,),handle) | ||
13 | end | ||
14 | |||
15 | function uv_sizeof_req(req) | ||
16 | if !(UV_UNKNOWN_REQ < req < UV_REQ_TYPE_MAX) | ||
17 | throw(DomainError(req)) | ||
18 | end | ||
19 | ccall(:uv_req_size,Csize_t,(Int32,),req) | ||
20 | end | ||
21 | |||
22 | for h in uv_handle_types | ||
23 | @eval const $(Symbol("_sizeof_",lowercase(string(h)))) = uv_sizeof_handle($h) | ||
24 | end | ||
25 | for r in uv_req_types | ||
26 | @eval const $(Symbol("_sizeof_",lowercase(string(r)))) = uv_sizeof_req($r) | ||
27 | end | ||
28 | |||
29 | uv_handle_data(handle) = ccall(:jl_uv_handle_data,Ptr{Cvoid},(Ptr{Cvoid},),handle) | ||
30 | uv_req_data(handle) = ccall(:jl_uv_req_data,Ptr{Cvoid},(Ptr{Cvoid},),handle) | ||
31 | uv_req_set_data(req,data) = ccall(:jl_uv_req_set_data,Cvoid,(Ptr{Cvoid},Any),req,data) | ||
32 | uv_req_set_data(req,data::Ptr{Cvoid}) = ccall(:jl_uv_req_set_data,Cvoid,(Ptr{Cvoid},Ptr{Cvoid}),req,data) | ||
33 | |||
34 | macro handle_as(hand, typ) | ||
35 | quote | ||
36 | data = uv_handle_data($(esc(hand))) | ||
37 | data == C_NULL && return | ||
38 | unsafe_pointer_to_objref(data)::($(esc(typ))) | ||
39 | end | ||
40 | end | ||
41 | |||
42 | associate_julia_struct(handle::Ptr{Cvoid}, @nospecialize(jlobj)) = | ||
43 | ccall(:jl_uv_associate_julia_struct, Cvoid, (Ptr{Cvoid}, Any), handle, jlobj) | ||
44 | disassociate_julia_struct(uv) = disassociate_julia_struct(uv.handle) | ||
45 | disassociate_julia_struct(handle::Ptr{Cvoid}) = | ||
46 | handle != C_NULL && ccall(:jl_uv_disassociate_julia_struct, Cvoid, (Ptr{Cvoid},), handle) | ||
47 | |||
48 | # A dict of all libuv handles that are being waited on somewhere in the system | ||
49 | # and should thus not be garbage collected | ||
50 | const uvhandles = IdDict() | ||
51 | function preserve_handle(x) | ||
52 | v = get(uvhandles, x, 0)::Int | ||
53 | uvhandles[x] = v + 1 | ||
54 | nothing | ||
55 | end | ||
56 | function unpreserve_handle(x) | ||
57 | v = uvhandles[x]::Int | ||
58 | if v == 1 | ||
59 | pop!(uvhandles, x) | ||
60 | else | ||
61 | uvhandles[x] = v - 1 | ||
62 | end | ||
63 | nothing | ||
64 | end | ||
65 | |||
66 | ## Libuv error handling ## | ||
67 | |||
68 | struct IOError <: Exception | ||
69 | msg::AbstractString | ||
70 | code::Int32 | ||
71 | IOError(msg::AbstractString, code::Integer) = new(msg, code) | ||
72 | end | ||
73 | |||
74 | showerror(io::IO, e::IOError) = print(io, "IOError: ", e.msg) | ||
75 | |||
76 | function _UVError(pfx::AbstractString, code::Integer) | ||
77 | code = Int32(code) | ||
78 | IOError(string(pfx, ": ", struverror(code), " (", uverrorname(code), ")"), code) | ||
79 | end | ||
80 | |||
81 | struverror(err::Int32) = unsafe_string(ccall(:uv_strerror,Cstring,(Int32,),err)) | ||
82 | uverrorname(err::Int32) = unsafe_string(ccall(:uv_err_name,Cstring,(Int32,),err)) | ||
83 | |||
84 | uv_error(prefix::Symbol, c::Integer) = uv_error(string(prefix),c) | ||
85 | uv_error(prefix::AbstractString, c::Integer) = c < 0 ? throw(_UVError(prefix,c)) : nothing | ||
86 | |||
87 | ## event loop ## | ||
88 | |||
89 | eventloop() = uv_eventloop::Ptr{Cvoid} | ||
90 | #mkNewEventLoop() = ccall(:jl_new_event_loop,Ptr{Cvoid},()) # this would probably be fine, but is nowhere supported | ||
91 | |||
92 | function run_event_loop() | ||
93 | ccall(:jl_run_event_loop,Cvoid,(Ptr{Cvoid},),eventloop()) | ||
94 | end | ||
95 | function process_events(block::Bool) | ||
96 | loop = eventloop() | ||
97 | if block | ||
98 | 3 (7.14%) | 3 (7.14%) |
3 (7.14%) samples spent in process_events
return ccall(:jl_run_once,Int32,(Ptr{Cvoid},),loop)
3 (100.00%) (ex.), 3 (100.00%) (incl.) when called from wait line 246 |
99 | else | ||
100 | return ccall(:jl_process_events,Int32,(Ptr{Cvoid},),loop) | ||
101 | end | ||
102 | end | ||
103 | |||
104 | function uv_alloc_buf end | ||
105 | function uv_readcb end | ||
106 | function uv_writecb_task end | ||
107 | function uv_return_spawn end | ||
108 | function uv_asynccb end | ||
109 | function uv_timercb end | ||
110 | |||
111 | function reinit_stdio() | ||
112 | global uv_jl_alloc_buf = @cfunction(uv_alloc_buf, Cvoid, (Ptr{Cvoid}, Csize_t, Ptr{Cvoid})) | ||
113 | global uv_jl_readcb = @cfunction(uv_readcb, Cvoid, (Ptr{Cvoid}, Cssize_t, Ptr{Cvoid})) | ||
114 | global uv_jl_writecb_task = @cfunction(uv_writecb_task, Cvoid, (Ptr{Cvoid}, Cint)) | ||
115 | global uv_jl_return_spawn = @cfunction(uv_return_spawn, Cvoid, (Ptr{Cvoid}, Int64, Int32)) | ||
116 | global uv_jl_asynccb = @cfunction(uv_asynccb, Cvoid, (Ptr{Cvoid},)) | ||
117 | global uv_jl_timercb = @cfunction(uv_timercb, Cvoid, (Ptr{Cvoid},)) | ||
118 | |||
119 | global uv_eventloop = ccall(:jl_global_event_loop, Ptr{Cvoid}, ()) | ||
120 | global stdin = init_stdio(ccall(:jl_stdin_stream, Ptr{Cvoid}, ())) | ||
121 | global stdout = init_stdio(ccall(:jl_stdout_stream, Ptr{Cvoid}, ())) | ||
122 | global stderr = init_stdio(ccall(:jl_stderr_stream, Ptr{Cvoid}, ())) | ||
123 | end | ||
124 | |||
125 | """ | ||
126 | stdin | ||
127 | |||
128 | Global variable referring to the standard input stream. | ||
129 | """ | ||
130 | :stdin | ||
131 | |||
132 | """ | ||
133 | stdout | ||
134 | |||
135 | Global variable referring to the standard out stream. | ||
136 | """ | ||
137 | :stdout | ||
138 | |||
139 | """ | ||
140 | stderr | ||
141 | |||
142 | Global variable referring to the standard error stream. | ||
143 | """ | ||
144 | :stderr |