diff --git a/src/socket.jl b/src/socket.jl index ee884b2..58a9db5 100644 --- a/src/socket.jl +++ b/src/socket.jl @@ -3,6 +3,7 @@ A ZMQ socket. """ mutable struct Socket data::Ptr{Cvoid} + context::Context pollfd::FDWatcher @doc """ @@ -15,7 +16,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 63c2dac..cc79f7d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -14,7 +14,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)