Hello,

I've been trying out some code based on the clone client/server example code in the 0MQ Guide (clone.c, clonecli6.c and clonesrv6.c, zmq v 3.2.2).
As with other ZMQ code I've tried so far, the example code builds and runs cleanly - ZMQ is very nice that way.

The clone client/server appear to do essentially what I need in an application.
As a starting point, I'm using clonecli6 as-is, and wrote a clone client  in C using the clone class; it is very similar to clonecli6.c, but another thread catches and handles signals.

There is one thing I am confused about, that I haven't seen posted on the archives: 
When  clone_get() is invoked, should the return value be treated as a kvmsg or as a string?

I ask because it looks like the clonesvr6/clonecli6  example works as follows:

The clonesvr6 stores a key:kvmsg pair in its hash map (stores entire kvmsg received from clone agent). 
The clonecli6 agent stores a key:string pair in its hash map when it receives a SET message from clone_set().
The clonecli6 agent stores a key:kvmsg pair in its hash map when it receives a a (kvmsg) update from clonesvr.

Does that mean that a client's zhash_lookup ( in clone_get() ) may return either a string or kvmsg, depending on whether the server is running and the state of the transaction between the clone agent and clonesvr?
So, I'm unclear about whether clone_get is intended to return a string value, or a kvmsg.

The clonecli6.c example only posts updates and never calls clone_get(), so the ambiguity isn't apparent until I try to write a client that subscribes to the (clonecli6) updates.

To illustrate, if I modify the clonecli6.c to update a single subtree ("/client/" instead of "/client/randof(10000)"), 
I expect the following client  to consume updates produced by clonecli6:

#include "clone.c"
#define SUBTREE "/client/"

int main (void)
{
    //  Create distributed hash instance
    clone_t *clone = clone_new ();

    //  Specify configuration
    clone_subtree (clone, SUBTREE);
    clone_connect (clone, "tcp://localhost", "5556");
    clone_connect (clone, "tcp://localhost", "5566");

    //  Set random tuples into the distributed hash
    while (!zctx_interrupted) {

        //  Set random value, check it was stored
        char key [255];
        sprintf (key, "%s", SUBTREE);
printf("clone requesting key %s\n",key);

// What does clone_get really return?
        char *sval=clone_get (clone, key);

if(sval!=NULL){
  int len=strlen(sval);
  printf("message value len %d:\n",len);
  printf("[%s]\n",sval);
  if(len>1){
            kvmsg_t *kval=(kvmsg_t *)sval;
    byte *mbody=kvmsg_body(kval);
    printf("kval: [%s]\n",(char *)mbody);
  }else
    printf("message len <= 1\n");

}else{
 printf("NULL message \n");
}
        sleep (1);
    }
    clone_destroy (&clone);
    return 0;
}

Maybe I'm doing something wrong, but in addition to my uncertainty about the return value of clone_get(), this client crashes:

*** glibc detected *** ../../git/zguide/examples/C/evilclone: double free or corruption (out): 0xb5a1ceb0 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0xb75c1ee2]
../../git/zguide/examples/C/evilclone[0x804964a]
/usr/local/lib/libczmq.so.1(zhash_update+0x5b)[0xb76fe36b]
../../git/zguide/examples/C/evilclone[0x804a6e1]
../../git/zguide/examples/C/evilclone[0x804b9ab]
/usr/local/lib/libczmq.so.1(s_thread_shim+0x3a)[0xb770701a]
/lib/i386-linux-gnu/libpthread.so.0(+0x6d4c)[0xb752ed4c]
/lib/i386-linux-gnu/libc.so.6(clone+0x5e)[0xb763ad3e]

I believe this is caused by the clone agent_control_message GET handler (clone.c:284) calling free(value), which releases the memory reference returned by clone_get.
Even if I change comment out that free(value) the example still does not return valid strings (or a kvmsg).

In my own application, I modified the clone agent update handler so that it only ever stores string values (never kvmsg) in its hash map.
So, only string values are returned by clone_get(). 
I also eliminated the aforementioned free(value) in clone.c. 
Doing so seems to work, and valgrind indicates no memory leaks.

Have I stumbled upon an issue with this example, or do I misunderstand how the clone example should work?

Kent Headley

==================================
Monterey Bay Aquarium Research Institute
7700 Sandholdt Road
Moss Landing, CA 95039



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

Reply via email to