Hi Kent,

Nice catch. The API should get a string, for a few reasons. First,
symmetry with clone_set. Second, kvmsg is an internal detail, it
should not be visible to calling applications.

The code is therefore buggy... do you want to try to fix it and send a
pull request, or shall I do that?

-Pieter

On Tue, Jun 4, 2013 at 8:04 AM, Kent Headley <[email protected]> wrote:
> 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
> [email protected]
>
> ==================================
> 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
>
_______________________________________________
zeromq-dev mailing list
[email protected]
http://lists.zeromq.org/mailman/listinfo/zeromq-dev

Reply via email to