Author: mahadev Date: Wed Mar 17 04:14:52 2010 New Revision: 924147 URL: http://svn.apache.org/viewvc?rev=924147&view=rev Log: ZOOKEEPER-591. The C Client cannot exit properly in some situation (mahadev)
Modified: hadoop/zookeeper/trunk/CHANGES.txt hadoop/zookeeper/trunk/src/c/src/zookeeper.c hadoop/zookeeper/trunk/src/c/tests/TestClient.cc Modified: hadoop/zookeeper/trunk/CHANGES.txt URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/CHANGES.txt?rev=924147&r1=924146&r2=924147&view=diff ============================================================================== --- hadoop/zookeeper/trunk/CHANGES.txt (original) +++ hadoop/zookeeper/trunk/CHANGES.txt Wed Mar 17 04:14:52 2010 @@ -293,6 +293,8 @@ BUGFIXES: ZOOKEEPER-624. The C Client cause core dump when receive error data from Zookeeper Server (mahadev) + ZOOKEEPER-591. The C Client cannot exit properly in some situation (mahadev) + IMPROVEMENTS: ZOOKEEPER-473. cleanup junit tests to eliminate false positives due to "socket reuse" and failure to close client (phunt via mahadev) Modified: hadoop/zookeeper/trunk/src/c/src/zookeeper.c URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/c/src/zookeeper.c?rev=924147&r1=924146&r2=924147&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/c/src/zookeeper.c (original) +++ hadoop/zookeeper/trunk/src/c/src/zookeeper.c Wed Mar 17 04:14:52 2010 @@ -176,9 +176,10 @@ static int add_completion(zhandle_t *zh, static completion_list_t* create_completion_entry(int xid, int completion_type, const void *dc, const void *data,watcher_registration_t* wo); static void destroy_completion_entry(completion_list_t* c); +static void queue_completion_nolock(completion_head_t *list, completion_list_t *c, + int add_to_front); static void queue_completion(completion_head_t *list, completion_list_t *c, int add_to_front); - static int handle_socket_error_msg(zhandle_t *zh, int line, int rc, const char* format,...); static void cleanup_bufs(zhandle_t *zh,int callCompletion,int rc); @@ -2172,12 +2173,12 @@ static void destroy_completion_entry(com } } -static void queue_completion(completion_head_t *list, completion_list_t *c, - int add_to_front) +static void queue_completion_nolock(completion_head_t *list, + completion_list_t *c, + int add_to_front) { c->next = 0; /* appending a new entry to the back of the list */ - lock_completion_list(list); if (list->last) { assert(list->head); // List is not empty @@ -2194,6 +2195,14 @@ static void queue_completion(completion_ list->head = c; list->last = c; } +} + +static void queue_completion(completion_head_t *list, completion_list_t *c, + int add_to_front) +{ + + lock_completion_list(list); + queue_completion_nolock(list, c, add_to_front); unlock_completion_list(list); } @@ -2203,9 +2212,17 @@ static int add_completion(zhandle_t *zh, { completion_list_t *c =create_completion_entry(xid, completion_type, dc, data,wo); + int rc = 0; if (!c) return ZSYSTEMERROR; - queue_completion(&zh->sent_requests, c, add_to_front); + lock_completion_list(&zh->sent_requests); + if (zh->close_requested != 1) { + queue_completion_nolock(&zh->sent_requests, c, add_to_front); + rc = ZOK; + } else { + rc = ZINVALIDSTATE; + } + unlock_completion_list(&zh->sent_requests); if (dc == SYNCHRONOUS_MARKER) { zh->outstanding_sync++; } @@ -2262,6 +2279,7 @@ int zookeeper_close(zhandle_t *zh) zh->close_requested=1; if (inc_ref_counter(zh,0)!=0) { + cleanup_bufs(zh, 1, ZCLOSING); adaptor_finish(zh); return ZOK; } Modified: hadoop/zookeeper/trunk/src/c/tests/TestClient.cc URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/c/tests/TestClient.cc?rev=924147&r1=924146&r2=924147&view=diff ============================================================================== --- hadoop/zookeeper/trunk/src/c/tests/TestClient.cc (original) +++ hadoop/zookeeper/trunk/src/c/tests/TestClient.cc Wed Mar 17 04:14:52 2010 @@ -195,6 +195,7 @@ class Zookeeper_simpleSystem : public CP CPPUNIT_TEST(testAcl); CPPUNIT_TEST(testChroot); CPPUNIT_TEST(testAuth); + CPPUNIT_TEST(testHangingClient); CPPUNIT_TEST(testWatcherAutoResetWithGlobal); CPPUNIT_TEST(testWatcherAutoResetWithLocal); CPPUNIT_TEST(testGetChildren2); @@ -277,6 +278,31 @@ public: void tearDown() { } + + /** have a callback in the default watcher **/ + static void default_zoo_watcher(zhandle_t *zzh, int type, int state, const char *path, void *context){ + int zrc = 0; + struct String_vector str_vec = {0, NULL}; + zrc = zoo_wget_children(zzh, "/mytest", default_zoo_watcher, NULL, &str_vec); + } + + /** this checks for a deadlock in calling zookeeper_close and calls from a default watcher that might get triggered just when zookeeper_close() is in progress **/ + void testHangingClient() { + int zrc = 0; + char buff[10] = "testall"; + char path[512]; + watchctx_t *ctx; + struct String_vector str_vec = {0, NULL}; + zhandle_t *zh = zookeeper_init(hostPorts, NULL, 10000, 0, ctx, 0); + sleep(1); + zrc = zoo_create(zh, "/mytest", buff, 10, &ZOO_OPEN_ACL_UNSAFE, 0, path, 512); + zrc = zoo_wget_children(zh, "/mytest", default_zoo_watcher, NULL, &str_vec); + zrc = zoo_create(zh, "/mytest/test1", buff, 10, &ZOO_OPEN_ACL_UNSAFE, 0, path, 512); + zrc = zoo_wget_children(zh, "/mytest", default_zoo_watcher, NULL, &str_vec); + zrc = zoo_delete(zh, "/mytest/test1", -1); + zookeeper_close(zh); + } + void testPing() {