Code Monkey home page Code Monkey logo

cppzmq's Issues

Missing FindZeroMQ.cmake

Attempting to build on Ubuntu 16.04 after installing ZeroMQ 4.2.1

CMake Error at CMakeLists.txt:4 (find_package):
By not providing "FindZeroMQ.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "ZeroMQ", but
CMake did not find one.

Could not find a package configuration file provided by "ZeroMQ" with any
of the following names:

ZeroMQConfig.cmake
zeromq-config.cmake

Add the installation prefix of "ZeroMQ" to CMAKE_PREFIX_PATH or set
"ZeroMQ_DIR" to a directory containing one of the above files. If "ZeroMQ"
provides a separate development package or SDK, be sure it has been
installed.

-- Configuring incomplete, errors occurred!

Am i invoking cmake incorrectly?

Memory leak in monitor_t?

The while loop (in monitor_t::monitor() method) can be aborted at line 700 and 717. If that happens the zmq_msg_close (&eventMsg); will never be executed. Couldn't that create a memory leak?

Packaging -> Need a tagged version

As per discussion on #107, I would like to package cppzmq for conda, it would be very nice to have a tagged version on GitHub, to have a fixed version of the code to refer to.

One thing that would help is that the tag always follow the same pattern and can be completely deduced from the version number. (typically M.m.p).

cmake install TARGETS given no ARCHIVE DESTINATIOn for static library target "cppzmq"

From the master (0feae8c) , and using cmake v2.8.12.2 on CentOS 6.9, I clone and immediately did:

cmake .

and get the following error message:

--cppzmq v4.2.3
CMake Error at CMakeLists.txt:30 (install):
  install TARGETS given no ARCHIVE DESTINATION for static library target "cppzmq".


-- Configuring incomplete, errors occurred!

No idea how to fix that. Stackoverflow wasn't helpful there either.

using message_t

Hello, it is possible to "reuse" message_t into a recv loop? For instance, is the followed code correct?..or message_t varible has to create and destroy on each loop iteration? so I have to declare message_t msg inside while loop.

I'm wondering if reusing messate_t could be any internal memory leak?
...
void ReadThread(..)
{
message_t msg; //reused varible `` //... some code
while(true) `` {
`` poll(&items[0], items.size(), 1000);`` if (items [0].revents & ZMQ_POLLIN)`` { `` `` service->recv(&msg);`` `` // do something with msg..`` } `` }
}

Issue with no NULL-terminated strings.

Sender written in Python, receiver in C++.
recv() does not place an ending NULL after the received number of bytes but, as it does not return the number of bytes, it's not possible to do outside, either.
Result: Impossible to determine the end of the received string. It's just the example on strings on ZMQ tutorial for C.
The only solution seems to avoid the C++ port and use the underlying C functions, which return the length of the message. This method works perfectly with the Python sender.
Is this on purpose or a bug?
In this case, it's not possible to modify the Python sender to include the string length in the message itself.

The send and recv returns true even no connected.

Hi, when I use the cppzmq to connect a wrong IP(actually there no ZMQ server bind), the connect function does not trow exception. After then I try to send and received the data, but the functions always returns true! How could I detect the data is sent out and is recv ?

// connect 
try
{
    int linger = 0;
    mZmqSocket->setsockopt(ZMQ_LINGER, &linger, sizeof(linger));
    stringstream ss;
    ss << "tcp://" << mRemoteIP << ":" << mRemotePort;

    mZmqSocket->connect(ss.str().c_str());
}
catch (const zmq::error_t& e)
{
    cout << "Unable to connect ZMQ socket: " << e.what() << endl;
    return rt;
}


try
{
    while (!mZmqSocket->send(req))
    {
        resip::sleepMs(100);
    }
}

catch (const zmq::error_t& e)
{
    cout << "Failed to send request.";
    return rt;
}



// recv response
zmq::message_t response;
try
{
    if (mZmqSocket->recv(&response, ZMQ_DONTWAIT))
    {
        cout << "Received data from server: " << (char *)response.data() << endl;
    }
}
catch (const zmq::error_t& e)
{
    cout << "Got error with recv: " << e.what();
    return rt;
}

The send and recv functions always return true even no a ZMQ server side running!

Error with zmq::message_t::gets

Getting the following error trying to use the zmq.hpp on a new install. Don't know what change caused the error, I have an older version of the file that works fine.

/usr/local/include/zmq.hpp: In member function `const char* zmq::message_t::gets (const char*) const':
/usr/local/include/zmq.hpp:377:53: error: 'property' was not declared in this scope
  const char* value = zmq_msg_gets (&msg, property);

Support libzmq's Autotools Install: pkg-config

Following #127 and zeromq/libzmq#2621 (comment), the libzmq install via autotools is still a thing and used in packaging systems, too.

Albeit the autotools install lacks the install of CMake config modules, it would be great if we could add support for libzmq autotools-installs anyway.

One way could be to support the always-installed pkg-config module named libzmq in cppzmq's CMakeLists.txt.

For autotools based installs we could as a fallback to the current logic piggyback on pkg-config. This could look like this:

find_package(PkgConfig)
pkg_check_modules(PC_LIBZMQ QUIET libzmq)

set(ZeroMQ_VERSION ${PC_LIBZMQ_VERSION})
find_library(ZeroMQ_LIBRARY NAMES libzmq.so
             PATHS ${PC_LIBZMQ_LIBDIR} ${PC_LIBZMQ_LIBRARY_DIRS})
find_library(ZeroMQ_STATIC_LIBRARY NAMES libzmq.a
             PATHS ${PC_LIBZMQ_LIBDIR} ${PC_LIBZMQ_LIBRARY_DIRS})

Poll monitoring sockets

I would like to be able to use zmq::poll() for normal ZMQ sockets and monitoring ZMQ sockets, to handle them all within a single thread. However this isn't currently possible with the zmq::monitor_t class due to the blocking nature of the zmq::monitor_t::monitor() method and the lack of an accessor for the socket that is monitoring socketPtr.

Could we augment the zmq::monitor_t class with the functionality to allow polling? Perhaps something like the following would work (apologies in advance for syntax)...

class monitor_t {
    // ...
    inline operator void* () ZMQ_NOTHROW
    {
        return monitorPtr;
    }

    inline operator void const* () const ZMQ_NOTHROW
    {
        return monitorPtr;
    }

    void monitor_start(socket_t &socket, const char *addr_, int events = ZMQ_EVENT_ALL)
    {
        int rc = zmq_socket_monitor(socket.ptr, addr_, events);
        if (rc != 0)
            throw error_t ();

        socketPtr = socket.ptr;
        monitorPtr = zmq_socket (socket.ctxptr, ZMQ_PAIR);
        assert (monitorPtr);

        rc = zmq_connect (monitorPtr, addr_);
        assert (rc == 0);

        on_monitor_started();
    }

    bool monitor_poll()
    {
        zmq_msg_t eventMsg;
        zmq_msg_init (&eventMsg);
        int rc = zmq_msg_recv (&eventMsg, s, 0);
        if (rc == -1 && zmq_errno() == ETERM)
            return false;
        assert (rc != -1);

        // ...
    }

    void monitor(socket_t &socket, const char *addr_, int events = ZMQ_EVENT_ALL)
    {
        monitor_start(socket, addr_, events);

        bool keep_looping = monitor_poll();
        while (keep_looping) {
            keep_looping = monitor_poll();
        }
    }
    // ...

private:
    void* socketPtr;
    void* monitorPtr;
};

This would allow a usage similar to the following...

void Worker(zmq::socket_t* raw_zmq_data_sock)
{
    std::unique_ptr<zmq::socket_t> zmq_data_sock(raw_zmq_data_sock);
    std::unique_ptr<zmq::monitor_t> zmq_monitor_sock(new zmq::monitor_t);

    zmq_monitor_sock->start_monitor(*zmq_data_sock, "inproc://abc");

    std::vector<zmq::pollitem_t> poll_items = {
        { (void*)(*zmq_data_sock), 0, ZMQ_POLLIN | ZMQ_POLLERR, 0, },
        { (void*)(*zmq_monitor_sock), 0, ZMQ_POLLIN | ZMQ_POLLERR, 0, },
    };

    while (true) {
        poll_items[0].revents = 0;
        poll_items[1].revents = 0;
        items = zmq::poll(poll_items);

        // ...
        if (poll_items[1].revents) {
            zmq_monitor_sock->monitor_poll();
        }
    }

    // ...
}

I can put a pull request together if it sounds like a reasonable idea.

Creating a zmq::pollitem_t requires casting to void *

Looks like zmq::pollitem_t is a just typedef for zmq_pollitem_t. Is there any plans to make zmq::pollitem_t a C++ class on its own? The main reason is that creating a zmq::pollitem_t requires casting a zmq::socket_t to void *, which attracts bugs like:

zmq::pollitem_t { &socket, 0, ZMQ_POLLIN, 0 }

Doing a Google search shows that this bug is quite common and causes a lot of confusion. It would be good if the interface to zmq::pollitem_t can just take a socket without casting.

Abort signal thrown from zmq_send

The following is the string I'm trying to send as a message using zmq_send:
" Node[0]TC[0]: Thread tid 16814, cpu 14 started"

Intermittently, my program crashes only while sending this message, not for other messages. This string is generated using snprintf, so it is definitely NULL terminated.

Following is the stack trace of the crash:

#0 0x00007fa29b56d187 in raise () from /lib64/libc.so.6
#1 0x00007fa29b56e538 in abort () from /lib64/libc.so.6
#2 0x00007fa29ca9ba3e in zmq::zmq_abort(char const*) ()
from libzmq.so.4.2.0
#3 0x00007fa29caa4389 in zmq::msg_t::size() ()
from libzmq.so.4.2.0
#4 0x00007fa29cad1032 in zmq::v2_encoder_t::message_ready() ()
fromlibzmq.so.4.2.0
#5 0x00007fa29cac4801 in zmq::stream_engine_t::out_event() ()
from libzmq.so.4.2.0
#6 0x00007fa29ca9c8a4 in zmq::io_thread_t::in_event() ()
from libzmq.so.4.2.0
#7 0x00007fa29ca9b71e in zmq::epoll_t::loop() ()
from libzmq.so.4.2.0
#8 0x00007fa29cace915 in thread_routine ()
from libzmq.so.4.2.0
#9 0x00007fa2a18ec0a4 in start_thread () from /lib64/libpthread.so.0
#10 0x00007fa29b61d04d in clone () from /lib64/libc.so.6

I have reproduced the same with two version of zmq - 4.2.0 and 4.1.6.

zmq::send always releases its message

As a messages_t is an object, it'll be release anyway. So unless the message content is being moved, I can't see the benefit of zmq_send releasing the message.

In the case of creating a device that repeats a message to more than one destination socket, zmq_send_const must be called directly to stop the message from being released.

Can anyone explain why zmq_send behaves this way and why zmq should have a send_const member?

zmq_ctx_shutdown() is never called

When using the straight C API, if one has a listening thread that is blocking on a recv() function and the application shuts down, they call zmq_ctx_shutdown(context) and it signals the recv() function to exit and shutdown proceeds normally.

However, in the C++ wrapper you have this for the context_t destructor:

inline ~context_t ()
{
    close();
}

inline void close()
{
    if (ptr == NULL)
       return;
    int rc = zmq_ctx_destroy (ptr);
    ZMQ_ASSERT (rc == 0);
    ptr = NULL;
}

Note that this does not include a call to zmq_ctx_shutdown().

Would it not be better to first call zmq_ctx_shutdown() before zmq_ctx_destroy()? Without that, the caller has to manually call zmq_ctx_shutdown() before the destructor gets called, which sort of detracts from the automatic cleanup that destructors are intended to offer.

Thoughts?

2 Router-Dealer proxies do not work

Simply put, whichever proxy is first then the related processes work fine. The second one is ignored. For instance:

zmq::proxy(m_frontEnd, m_backEnd, 0); zmq::proxy(m_frontEnd2, m_backEnd2, 0);

I have a server with multiple threads listening for different connection points. All services listening for messages on the proxy m_frontEnd and m_backEnd work fine. The one using m_frontEnd2, m_backEnd2 never receive messages.

If I swap the order:

zmq::proxy(m_frontEnd2, m_backEnd2, 0); zmq::proxy(m_frontEnd, m_backEnd, 0);

Now all services not recieving messages before are working fine and the services listening for messages on the proxy m_frontEnd and m_backEnd never receive messages.

The docs imply that we can have multiple proxies. This isn't the case or is a bug.

I'm unsure which cppzmq version I'm using and the headers show support for cmake zmq over 4.1.0 and I'm using czmq 4.0.2 if that helps

expression result unused from macro 'ZMQ_ASSERT'

We met this issue while building an application with cppzmq using clang 3.1:

./build_tools/third_party/include/zmq.hpp:144:28: error: expression result unused [-Werror,-Wunused-value]
ZMQ_ASSERT (rc == 0);
~~~~~~~~~~~~~~~^~~~~
./build_tools/third_party/include/zmq.hpp:55:36: note: expanded from macro 'ZMQ_ASSERT'

define ZMQ_ASSERT(expression) (expression)

                                                                 ^

Here is the version of the clang we are using:

...$ clang++ --version
clang version 3.1 (trunk 154757)
Target: x86_64-unknown-linux-gnu
Thread model: posix

Is there a workaround for this?

Thanks,
Gang

Please tag a release for the c++ bindings

Would it be possible to also add a version to the c++ bindings and cut a release of it?

Then one can better package it for a distribution and maybe find a matching version with the main zeromq library and it always stays in sync with the latest zeromq.

With just one header file, why was it split into a separate git repository without any version information at all? Having it along the zeromq library would simplify this also.

segfault when testing the cppzmq implementation of the zguide Majordomo Protocol example

When executing the zguide C++ implementation of the Majordomo example in verbose and debug mode, using the cppzmq header file zmq.hpp; a segfault occurs in process ./mdworker,
just after a client has requested a first service to the broker.

It's a bit hard to debug with breakpoints because the code excerpt pointed to by valgrind is frequently executed. So I thank you in advance for your help.

When tracing the memory usage with valgrind,
I get the following memory error message (extracted from stdout)
Uninitialised value was created by a heap allocation, as listed in more details here below:

[004] echo

15-03-22 11:03:12 I: sending HEARTBEAT to broker

[000]
[006] MDPW01
[001] 04
==4784== Conditional jump or move depends on uninitialised value(s)
==4784== at 0x804ABF1: std::basic_string<unsigned char, std::char_traits, std::allocator >::basic_string(unsigned char const_, std::allocator const&) (char_traits.h:161)
==4784== by 0x804FE1B: mdwrk::recv(zmsg_&) (zmsg.hpp:71)
==4784== by 0x8049E9F: main (mdworker.cpp:18)
==4784== Uninitialised value was created by a heap allocation
==4784== at 0x402A9AC: operator new(unsigned int, std::nothrow_t const&) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4784== by 0x40A766A: zmq::stream_engine_t::handshake() (stream_engine.cpp:600)
==4784== by 0x40A840F: zmq::stream_engine_t::in_event() (stream_engine.cpp:257)
==4784== by 0x40837A8: zmq::epoll_t::loop() (epoll.cpp:166)
==4784== by 0x40AF90F: thread_routine (thread.cpp:86)
==4784== by 0x4058F6F: start_thread (pthread_create.c:312)
==4784== by 0x42C350D: clone (clone.S:129)
==4784==
15-03-22 11:03:12 I: received message from broker:

lsb_release -a
: Distributor ID: Ubuntu
: Description: Ubuntu 14.04.1 LTS
: Release: 14.04
: Codename: trusty
cppzmq version: git commit 67b2166
zeromq version: zeromq-4.1.0-rc1
zguide version: git commit 67a79791ab082b942e1c8ccb2953b10b0727fa66
mdworker.cpp version: commit 0b5b12b9c7dc5c30853adf10e75c500c43258c6e

mdclient log trace: > ./mdclient -v
15-03-22 11:03:17 I: connecting to broker at tcp://localhost:5555...

15-03-22 11:03:17 I: send request to 'echo' service:

[006] MDPC01
[004] echo
[011] Hello world

mdworker log traces: > ./valgrind --track-origins=yes ./mdworker -v 2>&1 | tee debug.mdworker.log

==4784== Memcheck, a memory error detector
==4784== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4784== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==4784== Command: ./mdworker -v
==4784==
15-03-22 11:03:09 I: connecting to broker at tcp://localhost:5555...

15-03-22 11:03:09 I: sending READY to broker

[000]
[006] MDPW01
[001] 01
[004] echo

15-03-22 11:03:12 I: sending HEARTBEAT to broker

[000]
[006] MDPW01
[001] 04
==4784== Conditional jump or move depends on uninitialised value(s)
==4784== at 0x804ABF1: std::basic_string<unsigned char, std::char_traits, std::allocator >::basic_string(unsigned char const_, std::allocator const&) (char_traits.h:161)
==4784== by 0x804FE1B: mdwrk::recv(zmsg_&) (zmsg.hpp:71)
==4784== by 0x8049E9F: main (mdworker.cpp:18)
==4784== Uninitialised value was created by a heap allocation
==4784== at 0x402A9AC: operator new(unsigned int, std::nothrow_t const&) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4784== by 0x40A766A: zmq::stream_engine_t::handshake() (stream_engine.cpp:600)
==4784== by 0x40A840F: zmq::stream_engine_t::in_event() (stream_engine.cpp:257)
==4784== by 0x40837A8: zmq::epoll_t::loop() (epoll.cpp:166)
==4784== by 0x40AF90F: thread_routine (thread.cpp:86)
==4784== by 0x4058F6F: start_thread (pthread_create.c:312)
==4784== by 0x42C350D: clone (clone.S:129)
==4784==

15-03-22 11:03:12 I: received message from broker:

[000]
[006] MDPW01
[001] 04

15-03-22 11:03:14 I: received message from broker:

[000]
[006] MDPW01
[001] 04

15-03-22 11:03:14 I: sending HEARTBEAT to broker

[000]
[006] MDPW01
[001] 04

15-03-22 11:03:17 I: received message from broker:

[000]
[006] MDPW01
[001] 04

15-03-22 11:03:17 I: sending HEARTBEAT to broker

[000]
[006] MDPW01
[001] 04

15-03-22 11:03:17 I: received message from broker:

[000]
[006] MDPW01
[001] 02
[000]
[000]
[00b] Hello world
mdworker: mdwrkapi.hpp:124: zmsg* mdwrk::recv(zmsg*&): Assertion `m_reply_to.size()!=0' failed.
==4784==
==4784== HEAP SUMMARY:
==4784== in use at exit: 55,634 bytes in 61 blocks
==4784== total heap usage: 261 allocs, 200 frees, 71,059 bytes allocated
==4784==
==4784== LEAK SUMMARY:
==4784== definitely lost: 0 bytes in 0 blocks
==4784== indirectly lost: 0 bytes in 0 blocks
==4784== possibly lost: 590 bytes in 14 blocks
==4784== still reachable: 55,044 bytes in 47 blocks
==4784== suppressed: 0 bytes in 0 blocks
==4784== Rerun with --leak-check=full to see details of leaked memory
==4784==
==4784== For counts of detected and suppressed errors, rerun with: -v
==4784== ERROR SUMMARY: 15 errors from 1 contexts (suppressed: 0 from 0)

mdbroker log trace: > ./mdbroker -v
15-03-22 11:03:09 I: MDP broker/0.1.1 is active at tcp://*:5555

15-03-22 11:03:10 I: received message:

[009] 64F6-D716
[000]
[006] MDPW01
[001] 01
[004] echo
15-03-22 11:03:10 I: registering new worker: 64F6-D716
15-03-22 11:03:10 I: received message:

15-03-22 11:03:12 I: received message:

[009] 64F6-D716
[000]
[006] MDPW01
[001] 04

15-03-22 11:03:12 I: sending HEARTBEAT to worker

[009] 64F6-D716
[000]
[006] MDPW01
[001] 04

15-03-22 11:03:14 I: sending HEARTBEAT to worker

[009] 64F6-D716
[000]
[006] MDPW01
[001] 04

15-03-22 11:03:14 I: received message:

[009] 64F6-D716
[000]
[006] MDPW01
[001] 04

15-03-22 11:03:17 I: sending HEARTBEAT to worker

[009] 64F6-D716
[000]
[006] MDPW01
[001] 04

15-03-22 11:03:17 I: received message:

[009] 64F6-D716
[000]
[006] MDPW01
[001] 04

15-03-22 11:03:17 I: received message:

[000]
[000]
[006] MDPC01
[004] echo
[00b] Hello world

15-03-22 11:03:17 I: sending REQUEST to worker

[009] 64F6-D716
[000]
[006] MDPW01
[001] 02
[000]
[000]
[00b] Hello world

15-03-22 11:03:20 I: received message:

[000]
[000]
[006] MDPC01
[004] echo
[00b] Hello world

15-03-22 11:03:22 I: received message:

[000]
[000]
[006] MDPC01
[004] echo
[00b] Hello world

zmq_msg_gets undefined

When I try to built multivero I get an error that "zmq_msg_gets" identifier is not found

Visual studio 2013 building (another one)

Hello,
I get this error:
error C2664: 'int zmq_msg_recv(zmq_msg_t *,void *,int)' : cannot convert 'void *' in 'zmq_msg_t *' t:\zeromq\cppzmq\zmq.hpp 666 1 cpp.hwclient

thank you for any hint

proxy functions should take C++ classes

Currently, the implementations of the proxy() and proxy_steerable() functions take void * arguments just like the C ZMQ API instead of these cppzmq classes (like zmq::socket_t for sockets instead of void *).

cppzmq ought to do the appropriate accessing/casting work in the proxy functions instead of the caller.

non-portable std::exception

Hello, while compiling with mingw on Win10 and/or gcc on Xunbutun 16 the following error is thrown:
../include/zmq_addon.hpp:225:86: error: no matching function for call to ‘std::exception::exception(const char [51])’
throw std::exception("Invalid type, size does not match the message size");

I think that the std exception only takes a string constructor in the Windows lib, not in the standard c++.
I just change the std::exception by a std::runtime_error and everything is fine.
Tell me if you agree on the solution, and if you would accept a merge request.

is send() from the multipart_t intentionally broken?

Let's assume below fragment of code was taken from zmq_addon.hpp file:

    // Send multipart message to socket
    bool send(socket_t& socket, int flags = 0)
    {
        flags &= ~(ZMQ_SNDMORE);
        bool more = size() > 0;
        while (more)
        {
            message_t message = pop();
            more = size() > 0;
            if (!socket.send(message, (more ? ZMQ_SNDMORE : 0) | flags))
                return false;
        }
        clear();
        return true;
    }

First thing, this code works, when there are no errors on the transmission channel itself, and all sent messages/parts were received in proper manner and the other end. Let's also assume socket.send() returns true when everything went fine, and returning false means the message might have been sent, but surely not received at the other endpoint. Which in case of previously sent ZMQ_SNDMORE flag leaves the receiving endpoint in an ambiguous state for short, but undefined period of time, from the perspective of the sender (since it returns immediately after).

Did someone say undefined behavior on a higher layer of abstraction?

In case the socket.send() fails, we have one popped message on stack (destroyed after the next line return), and some leftover messages in the m_parts. It's totally possible to invoke multipart_t::send() again immediately after the return, on the leftover data, but absolutely no way to tell the C-API, that this is a "continuation" of previously interrupted transmission (if that's even possible, mainly at the receiving side).
It is simply because of the first line in the function body, which disallows that flag to propagate further.

The laziest, and also the worst (in my opinion), way to solve this situation, is to break out of the while loop, and actually use invoked clear() method. Since this would be the only case in which calling clear() here would change anything.

More elegant solution, would be to push the message from local scope back to the front of the m_parts, and then return false. Of course that's in case we want to keep any leftover message parts, as it may give some feedback to the sender (also because we don't lose the message from the while loop scope), about which data might've been actually sent already.

This may also be, of course, the canonical situation when the whole transmission has failed, and the receiving socket properly discarded all previously received message parts.
But, it may also be a situation when the communication channel was struck by an unknown space radiation waves, and while the message was send successfully, in vanished on the way and temporary quantum disturbance disallows any form of communication with the other endpoint, to ask it for e.g. an ACK?
It's still worth choosing some solution instead of choosing none and leaving it as it is probably.

Also, those are just some minor notes on the what-ifs of the networking depths with zeromq. I hope this post have jogged someone's memory in a why the heck it was implemented in this particular way manner.

Cheers,

-- Emil

PS. Feel free to correct/scold me, in case I was entirely wrong on this one.

assert error in the context_t

I think in the content_t class, we must check the ptr has been destroyed or not, otherwise if we called the close before destroy, then the ZMQ_ASSERT will be raise when the class destroying.

Below is the modified code:

inline ~context_t () ZMQ_NOTHROW
{
    if (!ptr)
    {
        return;
    }

    int rc = zmq_ctx_destroy (ptr);
    ptr = NULL;
    ZMQ_ASSERT (rc == 0);
}

inline void close() ZMQ_NOTHROW
{
    if (!ptr)
    {
        return;
    }

    int rc = zmq_ctx_destroy (ptr);
    ptr = NULL;
    ZMQ_ASSERT (rc == 0);
}

compile fails with github libzmg due to missing zmq_event_t

Trying to compile the first example in the zeromq guide gives the following error:

gcc -lzmq hwserver.cpp -o hwserver

In file included from hwserver.cpp:6:0:
/usr/local/include/zmq.hpp:574:47: error: ‘zmq_event_t’ does not name a type
/usr/local/include/zmq.hpp:575:53: error: ‘zmq_event_t’ does not name a type
/usr/local/include/zmq.hpp:576:53: error: ‘zmq_event_t’ does not name a type
/usr/local/include/zmq.hpp:577:47: error: ‘zmq_event_t’ does not name a type
/usr/local/include/zmq.hpp:578:49: error: ‘zmq_event_t’ does not name a type
/usr/local/include/zmq.hpp:579:46: error: ‘zmq_event_t’ does not name a type
/usr/local/include/zmq.hpp:580:51: error: ‘zmq_event_t’ does not name a type
/usr/local/include/zmq.hpp:581:44: error: ‘zmq_event_t’ does not name a type
/usr/local/include/zmq.hpp:582:50: error: ‘zmq_event_t’ does not name a type
/usr/local/include/zmq.hpp:583:50: error: ‘zmq_event_t’ does not name a type
/usr/local/include/zmq.hpp:584:45: error: ‘zmq_event_t’ does not name a type
In file included from hwserver.cpp:6:0:
/usr/local/include/zmq.hpp: In member function ‘void zmq::monitor_t::monitor(zmq::socket_t&, const char*, int)’:
/usr/local/include/zmq.hpp:497:17: error: ‘zmq_event_t’ was not declared in this scope
/usr/local/include/zmq.hpp:497:29: error: expected ‘;’ before ‘msgEvent’
/usr/local/include/zmq.hpp:498:17: error: ‘msgEvent’ was not declared in this scope
/usr/local/include/zmq.hpp:500:30: error: ‘event’ was not declared in this scope

As far as I can tell, this datatype has been removed from >4.0 versions of libzmq? I can't find zmq_event_t in the header files or anywhere in the current libzmq project.
Another user had a similar issue a while ago: pebbe/zmq3#4

The hwserver example above compiles without problems when using the czmq binding (although that's using slightly different C example code).

Build problem VS2013

Hey,
I have build ZeroMq_4.1.3 as static library. When I include the library and the cpp binding file into my project I got the following errors:

ZmqRSAggregationTripOutput.obj : error LNK2019: unresolved external symbol __imp_zmq_errno referenced in function "public: __cdecl zmq::context_t::context_t(int,int)" (??0context_t@zmq@@qeaa@HH@Z)
1>ZmqRSAggregationTripOutput.obj : error LNK2019: unresolved external symbol __imp_zmq_strerror referenced in function "public: virtual char const * __cdecl zmq::error_t::what(void)const " (?what@error_t@zmq@@UEBAPEBDXZ)
1>ZmqRSAggregationTripOutput.obj : error LNK2019: unresolved external symbol __imp_zmq_ctx_new referenced in function "public: __cdecl zmq::context_t::context_t(int,int)" (??0context_t@zmq@@qeaa@HH@Z)
1>ZmqRSAggregationTripOutput.obj : error LNK2019: unresolved external symbol __imp_zmq_ctx_set referenced in function "public: __cdecl zmq::context_t::context_t(int,int)" (??0context_t@zmq@@qeaa@HH@Z)
1>ZmqRSAggregationTripOutput.obj : error LNK2019: unresolved external symbol __imp_zmq_ctx_destroy referenced in function "public: void __cdecl zmq::context_t::close(void)" (?close@context_t@zmq@@QEAAXXZ)
1>ZmqRSAggregationTripOutput.obj : error LNK2019: unresolved external symbol __imp_zmq_msg_init_size referenced in function "public: __cdecl zmq::message_t::message_t(unsigned __int64)" (??0message_t@zmq@@qeaa@_K@Z)
1>ZmqRSAggregationTripOutput.obj : error LNK2019: unresolved external symbol __imp_zmq_msg_send referenced in function "public: bool __cdecl zmq::socket_t::send(class zmq::message_t &,int)" (?send@socket_t@zmq@@QEAA_NAEAVmessage_t@2@H@Z)
1>ZmqRSAggregationTripOutput.obj : error LNK2019: unresolved external symbol __imp_zmq_msg_close referenced in function "private: void __cdecl ZmqRSAggregationTripOutput::ProduceOutput(char *,unsigned __int64,unsigned __int64)" (?ProduceOutput@ZmqRSAggregationTripOutput@@AEAAXPEAD_K1@Z)
1>ZmqRSAggregationTripOutput.obj : error LNK2019: unresolved external symbol __imp_zmq_socket referenced in function "private: void __cdecl zmq::socket_t::init(class zmq::context_t &,int)" (?init@socket_t@zmq@@AEAAXAEAVcontext_t@2@H@Z)
1>ZmqRSAggregationTripOutput.obj : error LNK2019: unresolved external symbol __imp_zmq_close referenced in function "public: void __cdecl zmq::socket_t::close(void)" (?close@socket_t@zmq@@QEAAXXZ)
1>ZmqRSAggregationTripOutput.obj : error LNK2019: unresolved external symbol __imp_zmq_bind referenced in function "public: void __cdecl zmq::socket_t::bind(char const *)" (?bind@socket_t@zmq@@QEAAXPEBD@Z)

It seemed that it doesn't find the zmq functions in the library that I compiled
Unused libraries:
1> D:..\libs\libzmq.lib

How do I make it work?

Bert

Does zmq is thread safe ?

Hi, does the zmq is thread safe? Say I have two thread, one is called the zmq::poll in loop, another one will call zmq::send to send the data, shall I lock the poll and send ?

Thanks in advance.

How could I store the message_t into a map ?

Hello I'm new to ZMQ, I have a question, when I use dealer mode, how to store the id after I received then I can send back the response after a while ?

while (!isShutdown())
{
    try
    {
        zmq::message_t identity;
        zmq::message_t msg;

        // 10 milliseconds
        zmq::poll(items, 1, 10);
        if (items[0].revents & ZMQ_POLLIN)
        {
            mWorkerSocket.recv(&identity);
            mWorkerSocket.recv(&msg);
        // How to store the identity into a map or list then after a while I can send back a response ?
        }
    }
    catch (std::exception &e)
    {
        (void)e;
        break;
    }
}

VS2008 compiling error

When I compiling an example of ZeroMQ in VS2008, there is error with zmq.hpp, which I saw there is problem in zmq.hpp file. I saw the CPP11 check which does not include the last function, in which std::vector does not support .data operator in old C++ compiler version.

#ifdef ZMQ_CPP11
inline int poll(zmq_pollitem_t const* items, size_t nitems, std::chrono::milliseconds timeout)
{
    return poll(items, nitems, timeout.count() );
}

inline int poll(std::vector<zmq_pollitem_t> const& items, std::chrono::milliseconds timeout)
{
    return poll(items.data(), items.size(), timeout.count() );
}
#endif

inline int poll(std::vector<zmq_pollitem_t> const& items, long timeout_ = -1)
{
    return poll(items.data(), items.size(), timeout_);      
}

data() appeared in std::vector<T> in C++11

In code snippet below (https://github.com/zeromq/cppzmq/blob/master/zmq.hpp#L137-L152) you check whether is c++11 supported on system. If not, you use -1 as value of timeout. But items.data() won't compile on machine which not supports c++11, as data() appeared in c++11.

    #ifdef ZMQ_CPP11
    inline int poll(zmq_pollitem_t const* items, size_t nitems, std::chrono::milliseconds timeout)
    {
        return poll(items, nitems, timeout.count() );
    }

    inline int poll(std::vector<zmq_pollitem_t> const& items, std::chrono::milliseconds timeout)
    {
        return poll(items.data(), items.size(), timeout.count() );
    }
    #endif

    inline int poll(std::vector<zmq_pollitem_t> const& items, long timeout_ = -1)
    {
        return poll(items.data(), items.size(), timeout_);
    }

Clang warnings: warning when using names reserved by C++ standard

please remove from all names '__' (double underscore) or preceding underscore followed by a capital letter, e.g. '_Z'. These names are reserved for C++ standard library and C++ compiler intrinsics. Having such names in includes (especially guards) and using very restrictive compilation mode with clang results in a lot of compilation warnings.

in linux x86_64 the monitor_t has a bug in monitor function.

// in zmq.hpp monitor_t monitor()
zmq_msg_t eventMsg;¬  
                zmq_msg_init (&eventMsg);¬  
                rc = zmq_recvmsg (s, &eventMsg, 0);¬  
                if (rc == -1 && zmq_errno() == ETERM)¬  
                    break;¬  
                assert (rc != -1);¬  
                zmq_event_t* event = static_cast<zmq_event_t*>(zmq_msg_data (&eventMsg));¬
                zmq_event_t event2;¬  
                const char *data = (char *)zmq_msg_data(&eventMsg);¬  
                memcpy(&(event2.event), data, sizeof(event2.event));¬  
                memcpy(&(event2.value), data + sizeof(event2.event),¬  
                       sizeof(event2.value));¬  
                assert(event2.event == event->event);¬  
                assert(event2.value == event->value);¬  ///// it's fired!!!!!!!!!!!!!!!!!!!

I think the memcpy's version is right. because the event->value will always be 0 ! (memory layout bugs??)

zmq.hpp errors in gnuradio build

The following errors occur building gnuradio-3.7.4 with zeromq-4.0.4 and zmq.hpp in Mageia Linux (tested in Mga4 stable and Cauldron unstable). I have asked in zeromq and gnuradio irc channels with no solution forthcoming, so am now reporting it here.

In file included from /home/baz/rpmbuild/BUILD/gnuradio/gr-zeromq/lib/pub_sink_impl.h:27:0,
from /home/baz/rpmbuild/BUILD/gnuradio/gr-zeromq/lib/pub_sink_impl.cc:28:
/usr/include/zmq.hpp:550:47: error: 'zmq_event_t' does not name a type
virtual void on_event_connected(const zmq_event_t &event_, const char* addr_) {}
^
/usr/include/zmq.hpp:551:53: error: 'zmq_event_t' does not name a type
virtual void on_event_connect_delayed(const zmq_event_t &event_, const char* addr_) {}
^
/usr/include/zmq.hpp:552:53: error: 'zmq_event_t' does not name a type
virtual void on_event_connect_retried(const zmq_event_t &event_, const char* addr_) {}
^
/usr/include/zmq.hpp:553:47: error: 'zmq_event_t' does not name a type
virtual void on_event_listening(const zmq_event_t &event_, const char* addr_) {}
^
/usr/include/zmq.hpp:554:49: error: 'zmq_event_t' does not name a type
virtual void on_event_bind_failed(const zmq_event_t &event_, const char* addr_) {}
^
/usr/include/zmq.hpp:555:46: error: 'zmq_event_t' does not name a type
virtual void on_event_accepted(const zmq_event_t &event_, const char* addr_) {}
^
/usr/include/zmq.hpp:556:51: error: 'zmq_event_t' does not name a type
virtual void on_event_accept_failed(const zmq_event_t &event_, const char* addr_) {}
^
/usr/include/zmq.hpp:557:44: error: 'zmq_event_t' does not name a type
virtual void on_event_closed(const zmq_event_t &event_, const char* addr_) {}
^
/usr/include/zmq.hpp:558:50: error: 'zmq_event_t' does not name a type
virtual void on_event_close_failed(const zmq_event_t &event_, const char* addr_) {}
^
/usr/include/zmq.hpp:559:50: error: 'zmq_event_t' does not name a type
virtual void on_event_disconnected(const zmq_event_t &event_, const char* addr_) {}
^
/usr/include/zmq.hpp:560:45: error: 'zmq_event_t' does not name a type
virtual void on_event_unknown(const zmq_event_t &event_, const char* addr_) {}
^
In file included from /home/baz/rpmbuild/BUILD/gnuradio/gr-zeromq/lib/pub_sink_impl.h:27:0,
from /home/baz/rpmbuild/BUILD/gnuradio/gr-zeromq/lib/pub_sink_impl.cc:28:
/usr/include/zmq.hpp: In member function 'void zmq::monitor_t::monitor(zmq::socket_t&, const char_, int)':
/usr/include/zmq.hpp:479:17: error: 'zmq_event_t' was not declared in this scope
zmq_event_t_ event = static_cast<zmq_event_t*>(zmq_msg_data (&eventMsg));
^
/usr/include/zmq.hpp:479:30: error: 'event' was not declared in this scope
zmq_event_t* event = static_cast<zmq_event_t*>(zmq_msg_data (&eventMsg));
^
/usr/include/zmq.hpp:479:50: error: expected type-specifier before 'zmq_event_t'
zmq_event_t* event = static_cast<zmq_event_t*>(zmq_msg_data (&eventMsg));
^
/usr/include/zmq.hpp:479:50: error: expected '>' before 'zmq_event_t'
/usr/include/zmq.hpp:479:50: error: expected '(' before 'zmq_event_t'
/usr/include/zmq.hpp:479:62: error: expected primary-expression before '>' token
zmq_event_t* event = static_cast<zmq_event_t*>(zmq_msg_data (&eventMsg));
^
/usr/include/zmq.hpp:479:89: error: expected ')' before ';' token
zmq_event_t* event = static_cast<zmq_event_t*>(zmq_msg_data (&eventMsg));
^
make[2]: *** [gr-zeromq/lib/CMakeFiles/gnuradio-zeromq.dir/pub_sink_impl.cc.o] Error 1
CMakeFiles/Makefile2:13379: recipe for target 'gr-zeromq/lib/CMakeFiles/gnuradio-zeromq.dir/all' failed
make[1]: *** [gr-zeromq/lib/CMakeFiles/gnuradio-zeromq.dir/all] Error 2

no longer compatible with zeromq/zermq4-x

Not sure if this c++ bindings should be compatible with zeromq4-x legacy stable release, but I am using zeromq 4.0.8 and cppzmq will no longer compile because method zmq_msg_gets() does not exist for reference in zmq.hpp:

https://github.com/zeromq/cppzmq/blob/master/zmq.hpp#L376

This may be as simple as changing the VERSION that is referenced in preprocessor directive?

I plan on upgrading to the zeromq/libzmq core engine soon, but I see a use to keep this compatible with legacy stable releases.

Also, are there any plans to create tags for this repo that somehow denote the compatible zeromq library version? Maybe at least a couple that denote compatibility with the two legacy releases 4.0.x and 4.1.x?

send has ambiguous error/success return

        inline size_t send (const void *buf_, size_t len_, int flags_ = 0)
        {
            int nbytes = zmq_send (ptr, buf_, len_, flags_);
            if (nbytes >= 0)
                return (size_t) nbytes;
            if (zmq_errno () == EAGAIN)
                return 0;
            throw error_t ();
        }

For nbytes == 0 (e.g. for parts with size zero), the return is zero, but it's success. Nonetheless, a zero return is being used to mean EAGAIN.

Proxy Steerable does not termimate

The following snippet just hangs

// g++ -std=c++11 test.cc -lzmq
#include <iostream>
#include <thread>
#include <memory>
#include "./zmq.hpp"

int main() {

zmq::context_t context(1);

std::thread t( [&context]() {
  sleep(2);
  zmq::socket_t conttwo(context,zmq::socket_type::pub);
  conttwo.bind("inproc://control.default");
  conttwo.send("TERMINATE",9);
  std::cerr << "Terminate Fired" << std::endl;
});

try {
  zmq::socket_t frontend(context,zmq::socket_type::router);
  zmq::socket_t backend(context,zmq::socket_type::dealer);
  zmq::socket_t control(context,zmq::socket_type::sub);
  frontend.bind("inproc://frontend.default");
  backend.bind("inproc://backend.default");
  control.connect("inproc://control.default");
  std::cerr << "Proxy Starting" << std::endl;
  zmq::proxy_steerable(
    (void *)frontend,
    (void *)backend,
    nullptr,
    (void *)control
  );
  std::cerr << " Proxy Stopped" << std::endl;
} catch (std::exception& e) {
  std::cerr << " Threw " << e.what() << std::endl;
}
  t.join();
}

ZMQ_ASSERT execute code in release mode

#ifndef NDEBUG

define ZMQ_ASSERT(expression) assert(expression)

#else

define ZMQ_ASSERT(expression) (void)(expression)

#endif

ZMQ_ASSERT() execute code in release mode.
Should rename it to ZMQ_VERIFY() or change the behavior.

FindZeroMQ.cmake

Currently (in 4.2.1) cppzmq requires ZeroMQ module in CMake -- however, needed module is not bundled nor it can be found in libzmq distribution. Where should one take it from? Sorry if I have just overlooked something.

PROXY_STEERABLE not available with version 4.0.4

I think in the last commit there is an error:

at line 63:

if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 0, 4)

I think should be

if ZMQ_VERSION > ZMQ_MAKE_VERSION(4, 0, 4)

I've installed zmq 4.0.4 and I don't find proxy_steerable, so probably are included in 4.1 only.
At the moment a program including the zmq.hpp and zmq 4.0.4 does not compile

Is there a "shadow context"

I have a Java application using the JeroMQ project. At one point, it creates a sub-thread and initializes it with a "shadow context" for thread safety. Something like

ZContext shadowCtx = ZContext.shadow( mainCtx );

I am porting this application to a C++ version based on CPPZMQ classes, esp. zmq::context_t.

I am not finding the equivalent idea of a shadow context. Does that exist for C++ applications. Can anyone point me at an example?

EAGAIN should also be thrown

Hello,

perhaps I am missing the rationale behind the decision to return 0 (or false) inside recv and send when an EAGAIN is spotted, instead of throwing - and I apologize in advance if this is the case.

The problem I encountered with this approach is that, when returning 0 only (instead of explicitly throwing EAGAIN like the other errors), I cannot tell, specially in the context of recv, whether I am reading a valid message with an empty frame (with size 0), or if this is an actual case of EAGAIN.

Is there a way to tell apart a genuine EAGAIN error versus reading an empty frame of a multipart message? Or should EAGAIN really be thrown?

Thanks,
Rafael

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.