On 27/11/2012 21:23, Kah-Chan Low wrote:
Earlier this year someone floated the idea of passing an object pointer between threads in the context of "inproc" protocol and there was broad agreement that it could be done with no problem:
http://comments.gmane.org/gmane.network.zeromq.devel/7300

Right now I am in similar situation: I don't want to sacrifice speed by needlessly serializing and de-serializing my objects. However, I am now very worried because Valgrind flags data race errors in my code due to my passing of pointers around.
I wrote the following simple program as an illustration:

#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <algorithm>
#include <zmq.hpp>
#include <zmq_utils.h>
#include <iostream>

using namespace std;

void dealer2router(zmq::context_t& context, size_t limit)
{
  zmq::socket_t skDealer(context, ZMQ_DEALER);
  int hwm=0;
  skDealer.setsockopt(ZMQ_SNDHWM, &hwm, sizeof(hwm));
  skDealer.connect("inproc://i_love_zmq");
  for (size_t i=0; i<limit; i++) {
    int32_t *n = new int32_t; // this line is pass_pointer:19
    *n = 4;
    *n += 2;   // assign value of *n to 6, then
    skDealer.send(&n, sizeof(int32_t*)); // send the pointer
  }
}

void router_do_smth(zmq::context_t& context, size_t limit)
{

  zmq::socket_t skRouter(context, ZMQ_ROUTER);
  int hwm=0;
  skRouter.setsockopt(ZMQ_RCVHWM, &hwm, sizeof(hwm));
  skRouter.bind("inproc://i_love_zmq");
  for (size_t i=0; i<limit; i++) {
    int32_t *n;
    zmq::message_t msg;
    skRouter.recv(&msg);
    skRouter.recv(&n, sizeof(n));
    cout << "I got " << *n << '\n';  // this line is pass_pointer:38
    delete n;
  }
}

int main (int argc, char *argv[])
{
  zmq::context_t context(1);
  boost::thread_group threads;

  const size_t iter=100;
threads.create_thread(boost::bind(router_do_smth, boost::ref(context), iter));
  zmq_sleep(5);
threads.create_thread(boost::bind(dealer2router, boost::ref(context), iter));
  threads.join_all();
}

.......


This error can not be suppressed by using CPPFLAGS=-DZMQ_MAKE_VALGRIND_HAPPY to build zmq.
I am usingv3.2.2 stable release.

I have two questions:
1. I don't understand the error message above: how does accessing the value of variable n have anything to do with the internals of ZMQ? 2. Is it possible for the compiler to rearrange the machine instructions such that the assignment of value of n (i.e. *n=4; *n += 2;) occurs after the message has been sent and received on the other thread? In this case, is it possible for the program to output any value other than '6' for 'n'?

A complete guess, probably wrong. Is it possible that valgrind is complaining that before the new allocation replaces it ,n in dealer2router() still has the same value as the previous iteration around the loop (and the same as the other thread is dereferencing). Try setting n=null after the send to see if that gets rid of the warning.

John

_______________________________________________
zeromq-dev mailing list
[email protected]
http://lists.zeromq.org/mailman/listinfo/zeromq-dev

Reply via email to