Skip to content

Commit

Permalink
Add support for Message(::Memory) on Julia 1.11
Browse files Browse the repository at this point in the history
This is necessary because `IOBuffer.data` changed to being a `Memory` in
1.11. Also added a bunch of tests to cover the untested `Message`
constructors (which is how this wasn't caught earlier). Found with JET.jl.
  • Loading branch information
JamesWrigley committed Jul 8, 2024
1 parent 7f070fe commit 121292a
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 2 deletions.
6 changes: 6 additions & 0 deletions docs/src/_changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ CurrentModule = ZMQ
This documents notable changes in ZMQ.jl. The format is based on [Keep a
Changelog](https://keepachangelog.com).

## Unreleased

### Added
- Support for creating [`Message`](@ref)'s from the new `Memory` type in Julia
1.11 ([#244]).

## [v1.2.6] - 2024-06-13

### Added
Expand Down
7 changes: 5 additions & 2 deletions src/message.jl
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,15 @@ mutable struct Message <: AbstractArray{UInt8,1}
Message(p, pointer(p.string)+p.offset, sizeof(p))

@doc """
Message(a::Array)
Message(a::T) where T <: DenseVector
Create a message with an array as a buffer (for send). Note: the same
ownership semantics as for [`Message(m::String)`](@ref) apply.
Usually `a` will be a 1D `Array`/`Vector`, but on 1.11+ it can also be a
`Memory`.
"""
Message(a::Array) = Message(a, pointer(a), sizeof(a))
Message(a::T) where T <: DenseVector = Message(a, pointer(a), sizeof(a))

@doc """
Message(io::IOBuffer)
Expand Down
51 changes: 51 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,57 @@ end

# ZMQ.close(s1); ZMQ.close(s2) # should happen when context is closed
ZMQ.close(ZMQ._context) # immediately close global context rather than waiting for exit
@test !isopen(s1)
@test !isopen(s2)
end

# Test all the send constructors
@testset "Message" begin
s1 = Socket(PUB)
s2 = Socket(SUB)
ZMQ.subscribe(s2, "")
ZMQ.bind(s1, "tcp://*:5555")
ZMQ.connect(s2, "tcp://localhost:5555")

# Message(::Int) - construct from buffer size
data = rand(UInt8, 10)
m1 = Message(10)
copy!(m1, data)
ZMQ.send(s1, m1)
@test ZMQ.recv(s2) == data

# Message(::Any, ::Ptr, ::Int) - construct from pointer to existing data
buffer = rand(UInt8, 10)
m2 = Message(buffer, pointer(buffer), length(buffer))
ZMQ.send(s1, m2)
@test ZMQ.recv(s2) == buffer

# Message(::String)
str_msg = "foobar"
m3 = Message(str_msg)
ZMQ.send(s1, m3)
@test String(ZMQ.recv(s2)) == str_msg

# Message(::SubString)
m4 = Message(str_msg[1:3])
ZMQ.send(s1, m4)
@test String(ZMQ.recv(s2)) == str_msg[1:3]

# Message(::DenseVector) - construct from array
buffer2 = rand(UInt8, 10)
m5 = Message(buffer2)
ZMQ.send(s1, m5)
@test ZMQ.recv(s2) == buffer2

# Message(::IOBuffer)
buffer3 = rand(UInt8, 10)
iobuf = IOBuffer(buffer3)
m6 = Message(iobuf)
ZMQ.send(s1, m6)
@test ZMQ.recv(s2) == buffer3

close(s1)
close(s2)
end

@testset "ZMQ resource management" begin
Expand Down

0 comments on commit 121292a

Please sign in to comment.