Message API Goals

Why sending and receiving functions use message objects (zmq_msg_t) instead of raw buffers (void*):

  • User should be able to send buffer — without copying it — that was allocated by application-specific allocation mechanism. Thus, the message contains pointer to deallocation function rather then relying on hard-wired allocation mechanism such as malloc/free.
  • When using inproc:// transport, message is never copied. Thus, the buffer sent in one thread, will be received in the other thread and should be deallocated there. Thus, when doing recv() we should get pointer to deallocation function alongside the buffer itself.
  • For very small messages (VSMs) it's cheaper to copy the message than keep it on heap. These messages thus have no associated buffer and the data are stored directly in the zmq_msg_t structure — presumably on the stack. This has huge impact on performance as it almost entirely avoids need to do allocations/deallocations.
  • zmq_msg_t supports reference counting. Thus, if a message is published to many different TCP connections, all the sending threads access the same buffer rather then copying the buffers. Same trick can be used by user using zmq_msg_copy function:
   zmq_msg_copy (copy_of_msg, msg);
   zmq_send (sock1, msg);
   zmq_send (sock2, copy_of_msg);