Skip to content

Commit 71bf886

Browse files
authored
Merge pull request #55 from JuliaRobotics/tk/lcm_handle-allocs
Avoid allocation in onresponse using UnsafeArrays.
2 parents 081592f + 61447fd commit 71bf886

File tree

4 files changed

+31
-6
lines changed

4 files changed

+31
-6
lines changed

REQUIRE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ BinDeps 0.8
44
CMakeWrapper 0.2
55
StaticArrays 0.5
66
FastIOBuffers 0.0.1
7+
UnsafeArrays 0.2.0

src/LCMCore.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module LCMCore
22

33
using StaticArrays
44
using FastIOBuffers
5+
using UnsafeArrays
56

67
using Dates
78
using FileWatching: poll_fd

src/core.jl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,14 @@ end
146146

147147
function onresponse(rbuf::RecvBuf, channelptr::Ptr{UInt8}, opts::SubscriptionOptions{T}) where T
148148
check_channel_name(channelptr, opts)
149-
msgdata = unsafe_wrap(Vector{UInt8}, rbuf.data, rbuf.data_size)
150-
if T === Nothing
151-
opts.handler(opts.channel, msgdata)
152-
else
153-
msg = decode(msgdata, opts.msgtype)
154-
opts.handler(opts.channel, msg)
149+
GC.@preserve rbuf begin
150+
msgdata = UnsafeArray(rbuf.data, (Int(rbuf.data_size), ))
151+
if T === Nothing
152+
opts.handler(opts.channel, msgdata)
153+
else
154+
msg = decode(msgdata, opts.msgtype)
155+
opts.handler(opts.channel, msg)
156+
end
155157
end
156158
return nothing
157159
end

test/runtests.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,27 @@ end
214214
@test did_callback2
215215
end
216216

217+
@testset "lcm_handle allocations" begin
218+
data = UInt8[1,2,3,4,5]
219+
channel = "CHANNEL_1"
220+
221+
# start listening
222+
sublcm = LCM()
223+
sub = subscribe(sublcm, channel, (c, d) -> nothing)
224+
set_queue_capacity(sub, 2)
225+
226+
# publish two messages
227+
publcm = LCM()
228+
for _ = 1 : 2
229+
publish(publcm, channel, data)
230+
end
231+
232+
# check that handling doesn't allocate
233+
LCMCore.lcm_handle(sublcm)
234+
allocs = @allocated LCMCore.lcm_handle(sublcm)
235+
@test allocs == 0
236+
end
237+
217238
include("test_lcmtype.jl")
218239
include("test_readlog.jl")
219240

0 commit comments

Comments
 (0)