jli  Linuxx86_641.10.3v1.10.30b4590a5507d3f3046e5bafc007cacbbfc9b310bwZMQQ})# K5CRC32c\y.jmуj K5 FileWatchingXzsy`{,zmуh& K5LibdluVW59˗,mу-" K5LoggingT{VhUXM=mуrU" K5MmapP~:xg,Omу|' K5NetworkOptionsC0YW,mуʠ, K5SHAQ<$!<%mу1 K5 Serialization [)*k1mу-G K5Sockets1V$ bdސݗmуYBY K5UnicodeP>I>Nrmуeszo K5 LinearAlgebraSm7̏mуuux K5 OpenBLAS_jll[(Śb6EcQ FmуDux K5libblastrampoline_jllLSۆ }lxӠmу^} K5MarkdownZPn7z`smу/Ed~ K5Printfg^cX׸QDmу;h K5Random_ɢ?\Ymу? K5TarOi>աmу!t, K5DatesEY8pj2 mуX K5FuturebS;3{I xVMmуsD K5InteractiveUtilsWL ~@'ZmуVg K5LibGit2Z[&RPTv3EКRmу8J K5 LibGit2_jll YXg}]$mуD K5 MbedTLS_jllAX 3ȡ_mу- K5 LibSSH2_jlloTZk)߆ 255 throw(StateError("option value too large")) end rc = ccall((:zmq_setsockopt, libzmq), Cint, (Ptr{Cvoid}, Cint, Ptr{UInt8}, Csize_t), socket, $k, option_val, sizeof(option_val)) if rc != 0 throw(StateError(jl_zmq_error_str())) end end @eval ($fset)(socket::Socket, option_val::AbstractString) = $fset(socket, String(option_val)) end if fget != nothing @eval function ($fget)(socket::Socket) buf = Base.StringVector(255) len = Ref{Csize_t}(sizeof(buf)) rc = ccall((:zmq_getsockopt, libzmq), Cint, (Ptr{Cvoid}, Cint, Ptr{UInt8}, Ref{Csize_t}), socket, $k, buf, len) if rc != 0 throw(StateError(jl_zmq_error_str())) end return String(resize!(buf, len[])) end end end @deprecate get_identity(socket::Socket) getproperty(socket, :routing_id) @deprecate set_identity(socket::Socket, val) setproperty!(socket, :routing_id, val) # getproperty/setproperty API for socket properties const sockprops = (:affinity, :type, :linger, :reconnect_ivl, :backlog, :reconnect_ivl_max, :rate, :recovery_ivl, :sndbuf, :rcvbuf, :rcvmore, :events, :maxmsgsize, :sndhwm, :rcvhwm, :multicast_hops, :ipv4only, :tcp_keepalive, :tcp_keepalive_idle, :tcp_keepalive_cnt, :tcp_keepalive_intvl, :rcvtimeo, :sndtimeo, :fd, :routing_id, :last_endpoint, :immediate, :conflate) Base.propertynames(::Socket) = sockprops @eval function Base.getproperty(value::Socket, name::Symbol) $(propexpression(filter!(p -> isdefined(@__MODULE__, Symbol("_get_", p)), collect(sockprops))) do p :($(Symbol("_get_", p))(value)) end) end @eval function Base.setproperty!(value::Socket, name::Symbol, x) $(propexpression(filter!(p -> isdefined(@__MODULE__, Symbol("_set_", p)), collect(sockprops))) do p :($(Symbol("_set_", p))(value, x)) end) return x end ,/opt/julia/packages/ZMQ/4Jw8C/src/message.jl include("_message.jl") # in order to support zero-copy messages that share data with Julia # arrays, we need to hold a reference to the Julia object in a dictionary # until zeromq is done with the data, to prevent it from being garbage # collected. The gc_protect dictionary is keyed by a uv_async_t* pointer, # used in uv_async_send to tell Julia to when zeromq is done with the data. const gc_protect = Dict{Ptr{Cvoid},Any}() # callback argument for AsyncCondition gc_protect_cb(work) = (pop!(gc_protect, work.handle, nothing); Base.close(work)) function gc_protect_handle(obj::Any) work = Base.AsyncCondition(gc_protect_cb) gc_protect[work.handle] = (work,obj) work.handle end # Thread-safe zeromq callback when data is freed, passed to zmq_msg_init_data. # The hint parameter will be a uv_async_t* pointer. function gc_free_fn(data::Ptr{Cvoid}, hint::Ptr{Cvoid}) ccall(:uv_async_send,Cint,(Ptr{Cvoid},),hint) end """ High-level Message object for sending/receiving ZMQ messages in shared buffers. Message() Create an empty message (for receive). --- Message(len::Integer) Create a message with a given buffer size (for send). --- Message(origin::Any, m::Ptr{T}, len::Integer) where {T} Low-level function to create a message (for send) with an existing data buffer, without making a copy. The origin parameter should be the Julia object that is the origin of the data, so that we can hold a reference to it until ZMQ is done with the buffer. --- Message(m::String) Create a message with a string as a buffer (for send). Note: the Message now "owns" the string, it must not be resized, or even written to after the message is sent. --- Message(p::SubString{String}) Create a message with a sub-string as a buffer (for send). Note: the same ownership semantics as for [`Message(m::String)`](@ref) apply. --- Message(a::Array) Create a message with an array as a buffer (for send). Note: the same ownership semantics as for [`Message(m::String)`](@ref) apply. --- Message(io::IOBuffer) Create a message with an [`IOBuffer`](https://docs.julialang.org/en/v1/base/io-network/#Base.IOBuffer) as a buffer (for send). Note: the same ownership semantics as for [`Message(m::String)`](@ref) apply. """ mutable struct Message <: AbstractArray{UInt8,1} # Matching the declaration in the header: char _[64]; w_padding::_Message handle::Ptr{Cvoid} # index into gc_protect, if any """ Message() Create an empty message (for receive). """ function Message() zmsg = new() setfield!(zmsg, :handle, C_NULL) rc = ccall((:zmq_msg_init, libzmq), Cint, (Ref{Message},), zmsg) if rc != 0 throw(StateError(jl_zmq_error_str())) end finalizer(close, zmsg) return zmsg end """ Message(len::Integer) Create a message with a given buffer size (for send). """ function Message(len::Integer) zmsg = new() setfield!(zmsg, :handle, C_NULL) rc = ccall((:zmq_msg_init_size, libzmq), Cint, (Ref{Message}, Csize_t), zmsg, len) if rc != 0 throw(StateError(jl_zmq_error_str())) end finalizer(close, zmsg) return zmsg end """ Message(origin::Any, m::Ptr{T}, len::Integer) where {T} Low-level function to create a message (for send) with an existing data buffer, without making a copy. The origin parameter should be the Julia object that is the origin of the data, so that we can hold a reference to it until ZMQ is done with the buffer. """ function Message(origin::Any, m::Ptr{T}, len::Integer) where {T} zmsg = new() setfield!(zmsg, :handle, gc_protect_handle(origin)) gc_free_fn_c = @cfunction(gc_free_fn, Cint, (Ptr{Cvoid}, Ptr{Cvoid})) rc = ccall((:zmq_msg_init_data, libzmq), Cint, (Ref{Message}, Ptr{T}, Csize_t, Ptr{Cvoid}, Ptr{Cvoid}), zmsg, m, len, gc_free_fn_c, getfield(zmsg, :handle)) if rc != 0 gc_free_fn(C_NULL, getfield(zmsg, :handle)) # don't leak memory on error throw(StateError(jl_zmq_error_str())) end finalizer(close, zmsg) return zmsg end """ Message(m::String) Create a message with a string as a buffer (for send). Note: the Message now "owns" the string, it must not be resized, or even written to after the message is sent. """ Message(m::String) = Message(m, pointer(m), sizeof(m)) """ Message(p::SubString{String}) Create a message with a sub-string as a buffer (for send). Note: the same ownership semantics as for [`Message(m::String)`](@ref) apply. """ Message(p::SubString{String}) = Message(p, pointer(p.string)+p.offset, sizeof(p)) """ Message(a::Array) Create a message with an array as a buffer (for send). Note: the same ownership semantics as for [`Message(m::String)`](@ref) apply. """ Message(a::Array) = Message(a, pointer(a), sizeof(a)) """ Message(io::IOBuffer) Create a message with an [`IOBuffer`](https://docs.julialang.org/en/v1/base/io-network/#Base.IOBuffer) as a buffer (for send). Note: the same ownership semantics as for [`Message(m::String)`](@ref) apply. """ function Message(io::IOBuffer) if !io.readable || !io.seekable error("byte read failed") end Message(io.data) end end # check whether zeromq has called our free-function, i.e. whether # we are save to reclaim ownership of any buffer object isfreed(m::Message) = haskey(gc_protect, getfield(m, :handle)) # AbstractArray behaviors: Base.similar(a::Message, ::Type{T}, dims::Dims) where {T} = Array{T}(undef, dims) # ? Base.length(zmsg::Message) = Int(ccall((:zmq_msg_size, libzmq), Csize_t, (Ref{Message},), zmsg)) Base.size(zmsg::Message) = (length(zmsg),) Base.unsafe_convert(::Type{Ptr{UInt8}}, zmsg::Message) = ccall((:zmq_msg_data, libzmq), Ptr{UInt8}, (Ref{Message},), zmsg) function Base.getindex(a::Message, i::Integer) @boundscheck if i < 1 || i > length(a) throw(BoundsError()) end @preserve a unsafe_load(pointer(a), i) end function Base.setindex!(a::Message, v, i::Integer) @boundscheck if i < 1 || i > length(a) throw(BoundsError()) end @preserve a unsafe_store!(pointer(a), v, i) return v end # Convert message to string (copies data) Base.unsafe_string(zmsg::Message) = @preserve zmsg unsafe_string(pointer(zmsg), length(zmsg)) Base.elsize(::Message) = 1 Base.strides(::Message) = (1,) # Build an IOStream from a message # Copies the data function Base.convert(::Type{IOStream}, zmsg::Message) s = IOBuffer() write(s, zmsg) return s end # Close a message. You should not need to call this manually (let the # finalizer do it). function Base.close(zmsg::Message) rc = ccall((:zmq_msg_close, libzmq), Cint, (Ref{Message},), zmsg) if rc != 0 throw(StateError(jl_zmq_error_str())) end return nothing end function _get(zmsg::Message, property::Integer) val = ccall((:zmq_msg_get, libzmq), Cint, (Ref{Message}, Cint), zmsg, property) if val < 0 throw(StateError(jl_zmq_error_str())) end val end function _set(zmsg::Message, property::Integer, value::Integer) rc = ccall((:zmq_msg_set, libzmq), Cint, (Ref{Message}, Cint, Cint), zmsg, property, value) if rc < 0 throw(StateError(jl_zmq_error_str())) end end Base.propertynames(zmsg::Message) = (:more,) function Base.getproperty(zmsg::Message, name::Symbol) if name === :more return _get(zmsg, MORE) else error("Message has no field $name") end end function Base.setproperty!(zmsg::Message, name::Symbol, value::Integer) # Currently the zmq_msg_set() function does not support any property names error("Message has no writable field $name") end function Base.get(zmsg::Message, option::Integer) Base.depwarn("get(zmsg, option) is deprecated; use zmsg.option instead", :get) return _get(zmsg, option) end @deprecate set(zmsg::Message, property::Integer, value::Integer) _set(zmsg, property, value) -/opt/julia/packages/ZMQ/4Jw8C/src/_message.jl ## Low-level _Message type for sending/receiving small ZMQ messages directly, without the complications ## and overhead of the Message object for sharing buffers between Julia and libzmq. # Low-level message type, matching the declaration of # zmq_msg_t in the header: char _[64]; primitive type _Message 64 * 8 end const _MessageOrRef = Union{_Message,Base.RefValue{_Message}} function msg_init() zmsg = Ref{_Message}() rc = ccall((:zmq_msg_init, libzmq), Cint, (Ref{_Message},), zmsg) rc != 0 && throw(StateError(jl_zmq_error_str())) return zmsg end function msg_init(nbytes::Int) zmsg = Ref{_Message}() rc = ccall((:zmq_msg_init_size, libzmq), Cint, (Ref{_Message}, Csize_t), zmsg, nbytes % Csize_t) rc != 0 && throw(StateError(jl_zmq_error_str())) return zmsg end # note: no finalizer for _Message, so we need to call close manually! function Base.close(zmsg::_MessageOrRef) rc = ccall((:zmq_msg_close, libzmq), Cint, (Ref{_Message},), zmsg) rc != 0 && throw(StateError(jl_zmq_error_str())) return nothing end Base.length(zmsg::_MessageOrRef) = ccall((:zmq_msg_size, libzmq), Csize_t, (Ref{_Message},), zmsg) % Int Base.unsafe_convert(::Type{Ptr{UInt8}}, zmsg::_MessageOrRef) = ccall((:zmq_msg_data, libzmq), Ptr{UInt8}, (Ref{_Message},), zmsg) # isbits data, vectors thereof, and strings can be converted to/from _Message function _MessageRef(x::T) where {T} isbitstype(T) || throw(MethodError(_MessageRef, (x,))) n = sizeof(x) zmsg = msg_init(n) @preserve zmsg unsafe_store!(Ptr{T}(Base.unsafe_convert(Ptr{UInt8}, zmsg)), x) return zmsg end function _MessageRef(x::Vector{T}) where {T} isbitstype(T) || throw(MethodError(_MessageRef, (x,))) n = sizeof(x) zmsg = msg_init(n) ccall(:memcpy, Ptr{Cvoid}, (Ptr{UInt8}, Ptr{T}, Csize_t), zmsg, x, n) return zmsg end function _MessageRef(x::String) n = sizeof(x) zmsg = msg_init(n) ccall(:memcpy, Ptr{Cvoid}, (Ptr{UInt8}, Ptr{UInt8}, Csize_t), zmsg, x, n) return zmsg end function unsafe_copy(::Type{Vector{T}}, zmsg::_MessageOrRef) where {T} isbitstype(T) || throw(MethodError(unsafe_copy, (T, zmsg,))) n = length(zmsg) len, remainder = divrem(n, sizeof(T)) iszero(remainder) || error("message length $n not a multiple of sizeof($T)") a = Array{T}(undef, len) ccall(:memcpy, Ptr{Cvoid}, (Ptr{T}, Ptr{UInt8}, Csize_t), a, zmsg, n) return a end function unsafe_copy(::Type{T}, zmsg::_MessageOrRef) where {T} isbitstype(T) || throw(MethodError(unsafe_copy, (T, zmsg,))) n = length(zmsg) n == sizeof(T) || error("message length $n ≠ sizeof($T)") return @preserve zmsg unsafe_load(Ptr{T}(Base.unsafe_convert(Ptr{UInt8}, zmsg))) end function unsafe_copy(::Type{String}, zmsg::_MessageOrRef) n = length(zmsg) return @preserve zmsg unsafe_string(Base.unsafe_convert(Ptr{UInt8}, zmsg), n) end unsafe_copy(::Type{IOBuffer}, zmsg::_MessageOrRef) = IOBuffer(unsafe_copy(Vector{UInt8}, zmsg)) )/opt/julia/packages/ZMQ/4Jw8C/src/comm.jl ## Send/receive messages. ############################################################################ msg_send(socket::Socket, zmsg::_MessageOrRef, flags::Integer) = ccall((:zmq_msg_send, libzmq), Cint, (Ref{_Message}, Ptr{Cvoid}, Cint), zmsg, socket, flags) msg_send(socket::Socket, zmsg::Message, flags::Integer) = ccall((:zmq_msg_send, libzmq), Cint, (Ref{Message}, Ptr{Cvoid}, Cint), zmsg, socket, flags) function _send(socket::Socket, zmsg, more::Bool=false) while true if -1 == msg_send(socket, zmsg, (ZMQ_SNDMORE*more) | ZMQ_DONTWAIT) zmq_errno() == EAGAIN || throw(StateError(jl_zmq_error_str())) while (socket.events & POLLOUT) == 0 wait(socket) end else notify_is_expensive = !isempty(getfield(socket,:pollfd).notify.waitq) if notify_is_expensive socket.events != 0 && notify(socket) end break end end end # By default, we send using _Message objects, which are optimized for # small messages and copy the data. If the caller wants zero-copy communications, # then should explicitly create a Message() object, a more heavyweight object # that allows zero-copy access. """ send(socket::Socket, data; more=false) Send `data` over `socket`. A `more=true` keyword argument can be passed to indicate that `data` is a portion of a larger multipart message. `data` can be any `isbits` type, a `Vector` of `isbits` elements, a `String`, or a [`Message`](@ref) object to perform zero-copy sends of large arrays. """ function Sockets.send(socket::Socket, data; more::Bool=false) zmsg = _MessageRef(data) try _send(socket, zmsg, more) finally close(zmsg) end end """ send(socket::Socket, zmsg::Message; more::Bool=false) Zero-copy version of [`Sockets.send(socket, data)`](@ref) using a user-allocated [`Message`](@ref). """ Sockets.send(socket::Socket, zmsg::Message; more::Bool=false) = _send(socket, zmsg, more) import Sockets: send @deprecate send(socket::Socket, data, more::Bool) send(socket, data; more=more) function Sockets.send(f::Function, socket::Socket; more::Bool=false) io = IOBuffer() f(io) send(socket, take!(io); more=more) end ############################################################################ msg_recv(socket::Socket, zmsg::_MessageOrRef, flags::Integer) = ccall((:zmq_msg_recv, libzmq), Cint, (Ref{_Message}, Ptr{Cvoid}, Cint), zmsg, socket, flags) msg_recv(socket::Socket, zmsg::Message, flags::Integer) = ccall((:zmq_msg_recv, libzmq), Cint, (Ref{Message}, Ptr{Cvoid}, Cint), zmsg, socket, flags) function _recv!(socket::Socket, zmsg) while true if -1 == msg_recv(socket, zmsg, ZMQ_DONTWAIT) zmq_errno() == EAGAIN || throw(StateError(jl_zmq_error_str())) while socket.events & POLLIN== 0 wait(socket) end else notify_is_expensive = !isempty(getfield(socket,:pollfd).notify.waitq) if notify_is_expensive socket.events != 0 && notify(socket) end break end end return zmsg end """ recv(socket::Socket) Return a `Message` object representing a message received from a ZMQ `Socket` (without making a copy of the message data). """ Sockets.recv(socket::Socket) = _recv!(socket, Message()) """ recv(socket::Socket, ::Type{T}) Receive a message of type `T` (typically a `String`, `Vector{UInt8}`, or [`isbits`](https://docs.julialang.org/en/v1/base/base/#Base.isbits) type) from a ZMQ [`Socket`](@ref). (Makes a copy of the message data; you can alternatively use [`recv(socket)`](@ref) to work with zero-copy bytearray-like representation for large messages.) """ function Sockets.recv(socket::Socket, ::Type{T}) where {T} zmsg = msg_init() try _recv!(socket, zmsg) return unsafe_copy(T, zmsg) finally close(zmsg) end end