[zeromq-dev] [zmqpp] receiving can only be done to empty messages?

Lindley French lindleyf at gmail.com
Thu Jan 9 15:36:32 CET 2014


I imagine you've figured it out by now, but just in case----

When a vector method needs to reallocate the underlying array, existing
elements are move-constructed onto the new memory. If no move constructor
is defined or if you are not using C++11 mode, they will be
copy-constructed instead. (Placement new is used.) Then the objects in the
original memory will be destructed. This usually provides the "expected"
behavior for both C and C++ types.

My one concern is that the vector class does contain some optimizations to
allow it to use memcpy() if the contained type is plain-old-data. This is
usually detected correctly, but since zmq.h does some trickery to make the
zmq_msg_t type opaque, I can't be certain the right thing will happen
without more study.

Your solution in the above thread of defining a frame move constructor that
calls zmq_msg_move() should be safe enough.

> This branch also has been switched to using a deque over a vector to
support push and pop front, however this appears > to result in a much less
performant binding and so I need to take another look at it.

Strange. A deque will be slower than a vector in some cases, but it should
be a small constant multiplier. If you figure out what's going on I'd be
curious to know what it is.

Pragmatically speaking, a vector should usually be fine even if you want to
support a push/pop_front capability----zmq messages will rarely have *that*
many parts, and your current master branch shows that zmq_msg_move()ing all
of them when a part is added isn't unacceptably slow anyway.

Another way of looking at the situation is that it's pretty rare for people
to access message parts in other than linear order, so something like a
std::list could be made to work relatively well. The worst-case promises
would be a little odd though.


On Thu, Jan 9, 2014 at 4:22 AM, Ben Gray <ben at benjamg.com> wrote:

> The main reason for not just using push_back was that I was unsure how
> shifting the message when vectors went over capacity would effect the
> zmq_msg_t structures. I've since wrapped the whole lot in a frame object
> that handles it and now does just use push_back. (see
> https://github.com/benjamg/zmqpp/tree/feature/prepend_pop_message_frames)
>
> This branch also has been switched to using a deque over a vector to
> support push and pop front, however this appears to result in a much less
> performant binding and so I need to take another look at it.
>
> I may branch out the previous commit and issue a pull request for that
> though as it would solve your need for a new_raw_msg with a size as well.
>
>
> On 8 January 2014 20:42, Lindley French <lindleyf at gmail.com> wrote:
>
>> A question about the implementation.
>>
>> I notice that the zmqpp::message_t class jumps through some hoops
>> whenever the add() or raw_new_msg() method is called. It appears to be
>> creating a new array of parts, moving all existing parts there, and then
>> swapping them.
>>
>> What's the rationale for this design? It seems like it would require a
>> lot more allocations and copies (thankfully only of pointers, not entire
>> buffers) than simply doing a push_back on the vector.
>>
>>
>> On Wed, Jan 8, 2014 at 2:01 PM, Lindley French <lindleyf at gmail.com>wrote:
>>
>>> One additional minor suggestion: In the poller class, the add() and
>>> remove() overloads that take simple ints should probably accept them by
>>> value rather than const reference. There's no performance penalty, and it
>>> would make the type system play a bit nicer in some cases.
>>>
>>> For instance, I just tried to add a Boost.Asio UDP socket's
>>> native_handle() to a zmqpp poller (as a standin until UDP is working in
>>> 0MQ), and found that I couldn't do it if I was calling native_handle() from
>>> a const reference, but it worked fine with a non-const reference.
>>>
>>>
>>> On Wed, Jan 8, 2014 at 5:59 AM, Ben Gray <ben at benjamg.com> wrote:
>>>
>>>> Pull request https://github.com/zeromq/zmqpp/pull/29 raised for this
>>>> part of the issue (and the assert).
>>>>
>>>>
>>>> On 7 January 2014 16:24, Lindley French <lindleyf at gmail.com> wrote:
>>>>
>>>>>  In zmqpp, the socket_t::receive() method throws an exception if you
>>>>> pass it a non-empty message_t. This seems to be contradictory to the
>>>>> philosophy of zmq_recv(), which states that the message passed to it will
>>>>> be deallocated cleanly if necessary.
>>>>>
>>>>> Now, I know zmqpp defines a "message" as all parts of a multipart
>>>>> message, while libzmq defines it as just one part. So this isn't a direct
>>>>> contradiction of the API semantics. But it seems like this could be fixed
>>>>> without much effort.
>>>>>
>>>>> _______________________________________________
>>>>> zeromq-dev mailing list
>>>>> zeromq-dev at lists.zeromq.org
>>>>> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
>>>>>
>>>>>
>>>>
>>>> _______________________________________________
>>>> zeromq-dev mailing list
>>>> zeromq-dev at lists.zeromq.org
>>>> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
>>>>
>>>>
>>>
>>
>> _______________________________________________
>> zeromq-dev mailing list
>> zeromq-dev at lists.zeromq.org
>> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
>>
>>
>
> _______________________________________________
> zeromq-dev mailing list
> zeromq-dev at lists.zeromq.org
> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20140109/cc854e6b/attachment.htm>


More information about the zeromq-dev mailing list