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
