diff --git a/src/socket.jl b/src/socket.jl index 4680b16..3501761 100644 --- a/src/socket.jl +++ b/src/socket.jl @@ -19,6 +19,7 @@ Do-block constructor. """ mutable struct Socket data::Ptr{Cvoid} + context::Context pollfd::FDWatcher """ @@ -31,7 +32,7 @@ mutable struct Socket if p == C_NULL throw(StateError(jl_zmq_error_str())) end - socket = new(p) + socket = new(p, ctx) setfield!(socket, :pollfd, FDWatcher(fd(socket), #=readable=#true, #=writable=#false)) finalizer(close, socket) push!(getfield(ctx, :sockets), WeakRef(socket)) diff --git a/test/runtests.jl b/test/runtests.jl index f07d174..d7274f3 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -13,7 +13,23 @@ using ZMQ, Test @test_throws StateError Socket(ctx, PUB) end +# This test is in its own function to keep it simple and try to trick Julia into +# thinking it can safely GC the Context. +function context_gc_test() + ctx = Context() + s = Socket(ctx, PUB) + + # Force garbage collection to attempt to delete ctx + GC.gc() + + # But it shouldn't be garbage collected since the socket should have a + # reference to it, so the socket should still be open. + @test isopen(s) +end + @testset "ZMQ sockets" begin + context_gc_test() + s=Socket(PUB) @test s isa Socket ZMQ.close(s)