erickt / rust-zmq

Rust zeromq bindings.
Apache License 2.0
908 stars 193 forks source link

Dropping socket over which data has been sent (but no receiver has connected to) hangs. #382

Open david-boles opened 1 year ago

david-boles commented 1 year ago

Tested on zmq 0.10.0, Ubuntu 20.04 and 22.04.

Example:

use zmq::{Context, Error, SocketType::PUSH};

fn main() -> Result<(), Error> {
    let zmq_context = Context::new();
    let push_socket = zmq_context.socket(PUSH)?;
    push_socket.connect("tcp://localhost:1234")?;

    let bytes = vec![];
    push_socket.send(bytes, 0)?;

    println!("Sent! Now dropping...");

    drop(push_socket);

    println!("Dropped!"); // Never reached.

    Ok(())
}

Stacktrace:

#0  0x00007fe158318d7f in __GI___poll (fds=0x7ffd9dda6930, nfds=1, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
#1  0x00007fe150c1d930 in zmq::signaler_t::wait (this=0x808e278, timeout_=-1)
    at /home/csval/.cargo/registry/src/github.com-1ecc6299db9ec823/zeromq-src-0.2.5+4.3.4/vendor/src/signaler.cpp:246
#2  0x00007fe150c0b95d in zmq::mailbox_t::recv (this=0x808e210, cmd_=0x7ffd9dda6a40, timeout_=-1)
    at /home/csval/.cargo/registry/src/github.com-1ecc6299db9ec823/zeromq-src-0.2.5+4.3.4/vendor/src/mailbox.cpp:81
#3  0x00007fe150bfa219 in zmq::ctx_t::terminate (this=0x808e0e0)
    at /home/csval/.cargo/registry/src/github.com-1ecc6299db9ec823/zeromq-src-0.2.5+4.3.4/vendor/src/ctx.cpp:209
#4  0x00007fe150bf8198 in zmq_ctx_term (ctx_=0x808e0e0)
    at /home/csval/.cargo/registry/src/github.com-1ecc6299db9ec823/zeromq-src-0.2.5+4.3.4/vendor/src/zmq.cpp:157
#5  0x00007fe150bf0432 in zmq::RawContext::term (self=0x656fce0) at src/lib.rs:383
#6  0x00007fe150bf0472 in zmq::{impl#10}::drop (self=0x656fce0) at src/lib.rs:393
#7  0x00007fe150bf1fdb in core::ptr::drop_in_place<zmq::RawContext> ()
    at /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/core/src/ptr/mod.rs:490
#8  0x00007fe150bf5294 in alloc::sync::Arc<zmq::RawContext>::drop_slow<zmq::RawContext> (self=0x812aa70)
    at /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/alloc/src/sync.rs:1123
#9  0x00007fe150bf53ea in alloc::sync::{impl#27}::drop<zmq::RawContext> (self=0x812aa70)
    at /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/alloc/src/sync.rs:1745
#10 0x00007fe150bf226b in core::ptr::drop_in_place<alloc::sync::Arc<zmq::RawContext>> ()
    at /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/core/src/ptr/mod.rs:490
#11 0x00007fe150bf1fcb in core::ptr::drop_in_place<zmq::Context> ()
    at /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/core/src/ptr/mod.rs:490
#12 0x00007fe150bf22b6 in core::ptr::drop_in_place<core::option::Option<zmq::Context>> ()
    at /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/core/src/ptr/mod.rs:490
#13 0x00007fe150bf1f9c in core::ptr::drop_in_place<zmq::Socket> ()
    at /rustc/9eb3afe9ebe9c7d2b84b71002d44f4a0edac95e0/library/core/src/ptr/mod.rs:490

Let me know if there's anything else I can provide!

tsbernar commented 1 year ago

I ran into this problem too. After some digging in ZMQ docs, I think this is expected behavior (though it doesn't seem to be enforced in all languages).

http://api.zeromq.org/2-1:zmq-setsockopt

You'll have to set ZMQ_LINGER to something other than the default -1 for it to drop.

I don't think this is really a sensible default value, but it's at the libzmq api level, not at the rust binding implementation level.