You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by an...@apache.org on 2018/08/23 14:11:53 UTC

[01/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Repository: zookeeper
Updated Branches:
  refs/heads/branch-3.4 f90e4a4de -> 5694559d7


http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/TestZookeeperInit.cc
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/TestZookeeperInit.cc b/zookeeper-client/zookeeper-client-c/tests/TestZookeeperInit.cc
new file mode 100644
index 0000000..eadf41d
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/TestZookeeperInit.cc
@@ -0,0 +1,301 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <errno.h>
+
+#include "Util.h"
+#include "LibCMocks.h"
+#include "ZKMocks.h"
+
+#ifdef THREADED
+#include "PthreadMocks.h"
+#else
+class MockPthreadsNull;
+#endif
+
+using namespace std;
+
+class Zookeeper_init : public CPPUNIT_NS::TestFixture
+{
+    CPPUNIT_TEST_SUITE(Zookeeper_init);
+    CPPUNIT_TEST(testBasic);
+    CPPUNIT_TEST(testAddressResolution);
+    CPPUNIT_TEST(testMultipleAddressResolution);
+    CPPUNIT_TEST(testNullAddressString);
+    CPPUNIT_TEST(testEmptyAddressString);
+    CPPUNIT_TEST(testOneSpaceAddressString);
+    CPPUNIT_TEST(testTwoSpacesAddressString);
+    CPPUNIT_TEST(testInvalidAddressString1);
+    CPPUNIT_TEST(testInvalidAddressString2);
+    CPPUNIT_TEST(testNonexistentHost);
+    CPPUNIT_TEST(testOutOfMemory_init);
+    CPPUNIT_TEST(testOutOfMemory_getaddrs1);
+#if !defined(__CYGWIN__) // not valid for cygwin
+    CPPUNIT_TEST(testOutOfMemory_getaddrs2);
+#endif
+    CPPUNIT_TEST(testPermuteAddrsList);
+    CPPUNIT_TEST_SUITE_END();
+    zhandle_t *zh;
+    MockPthreadsNull* pthreadMock;
+    static void watcher(zhandle_t *, int , int , const char *,void*){}
+    FILE *logfile;
+public:
+    Zookeeper_init():zh(0),pthreadMock(0){
+      logfile = openlogfile("Zookeeper_init");
+    }
+
+    ~Zookeeper_init() {
+      if (logfile) {
+        fflush(logfile);
+        fclose(logfile);
+        logfile = 0;
+      }
+    }
+
+    void setUp()
+    {
+        zoo_set_log_stream(logfile);
+
+        zoo_deterministic_conn_order(0);
+#ifdef THREADED
+        // disable threading
+        pthreadMock=new MockPthreadZKNull;
+#endif
+        zh=0;
+    }
+
+    void tearDown()
+    {
+        zookeeper_close(zh);
+#ifdef THREADED
+        delete pthreadMock;
+#endif
+    }
+
+    void testBasic()
+    {
+        const string EXPECTED_HOST("127.0.0.1:2121");
+        const int EXPECTED_ADDRS_COUNT =1;
+        const int EXPECTED_RECV_TIMEOUT=10000;
+        clientid_t cid;
+        memset(&cid,0xFE,sizeof(cid));
+
+        zh=zookeeper_init(EXPECTED_HOST.c_str(),watcher,EXPECTED_RECV_TIMEOUT,
+                &cid,(void*)1,0);
+
+        CPPUNIT_ASSERT(zh!=0);
+        CPPUNIT_ASSERT(zh->fd == -1);
+        CPPUNIT_ASSERT(zh->hostname!=0);
+        CPPUNIT_ASSERT_EQUAL(EXPECTED_ADDRS_COUNT,zh->addrs_count);
+        CPPUNIT_ASSERT_EQUAL(EXPECTED_HOST,string(zh->hostname));
+        CPPUNIT_ASSERT(zh->state == NOTCONNECTED_STATE_DEF);
+        CPPUNIT_ASSERT(zh->context == (void*)1);
+        CPPUNIT_ASSERT_EQUAL(EXPECTED_RECV_TIMEOUT,zh->recv_timeout);
+        CPPUNIT_ASSERT(zh->watcher == watcher);
+        CPPUNIT_ASSERT(zh->connect_index==0);
+        CPPUNIT_ASSERT(zh->primer_buffer.buffer==zh->primer_storage_buffer);
+        CPPUNIT_ASSERT(zh->primer_buffer.curr_offset ==0);
+        CPPUNIT_ASSERT(zh->primer_buffer.len == sizeof(zh->primer_storage_buffer));
+        CPPUNIT_ASSERT(zh->primer_buffer.next == 0);
+        CPPUNIT_ASSERT(zh->last_zxid ==0);
+        CPPUNIT_ASSERT(memcmp(&zh->client_id,&cid,sizeof(cid))==0);
+
+#ifdef THREADED
+        // thread specific checks
+        adaptor_threads* adaptor=(adaptor_threads*)zh->adaptor_priv;
+        CPPUNIT_ASSERT(adaptor!=0);
+        CPPUNIT_ASSERT(pthreadMock->pthread_createCounter==2);
+        CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(adaptor->io));
+        CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(adaptor->completion));
+        CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->to_process.lock));
+        CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->to_send.lock));
+        CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->sent_requests.lock));
+        CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->completions_to_process.lock));
+        CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->sent_requests.cond));
+        CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->completions_to_process.cond));
+#endif
+    }
+    void testAddressResolution()
+    {
+        const char EXPECTED_IPS[][4]={{127,0,0,1}};
+        const int EXPECTED_ADDRS_COUNT =COUNTOF(EXPECTED_IPS);
+
+        zoo_deterministic_conn_order(1);
+        zh=zookeeper_init("127.0.0.1:2121",0,10000,0,0,0);
+
+        CPPUNIT_ASSERT(zh!=0);
+        CPPUNIT_ASSERT_EQUAL(EXPECTED_ADDRS_COUNT,zh->addrs_count);
+        for(int i=0;i<zh->addrs_count;i++){
+            sockaddr_in* addr=(struct sockaddr_in*)&zh->addrs[i];
+            CPPUNIT_ASSERT(memcmp(EXPECTED_IPS[i],&addr->sin_addr,sizeof(addr->sin_addr))==0);
+            CPPUNIT_ASSERT_EQUAL(2121,(int)ntohs(addr->sin_port));
+        }
+    }
+    void testMultipleAddressResolution()
+    {
+        const string EXPECTED_HOST("127.0.0.1:2121,127.0.0.2:3434");
+        const char EXPECTED_IPS[][4]={{127,0,0,1},{127,0,0,2}};
+        const int EXPECTED_ADDRS_COUNT =COUNTOF(EXPECTED_IPS);
+
+        zoo_deterministic_conn_order(1);
+        zh=zookeeper_init(EXPECTED_HOST.c_str(),0,1000,0,0,0);
+
+        CPPUNIT_ASSERT(zh!=0);
+        CPPUNIT_ASSERT_EQUAL(EXPECTED_ADDRS_COUNT,zh->addrs_count);
+
+        for(int i=0;i<zh->addrs_count;i++){
+            sockaddr_in* addr=(struct sockaddr_in*)&zh->addrs[i];
+            CPPUNIT_ASSERT(memcmp(EXPECTED_IPS[i],&addr->sin_addr,sizeof(addr->sin_addr))==0);
+            if(i<1)
+                CPPUNIT_ASSERT_EQUAL(2121,(int)ntohs(addr->sin_port));
+            else
+                CPPUNIT_ASSERT_EQUAL(3434,(int)ntohs(addr->sin_port));
+        }
+    }
+    void testMultipleAddressWithSpace()
+    { 
+        const string EXPECTED_HOST("127.0.0.1:2121,  127.0.0.2:3434");
+        const char EXPECTED_IPS[][4]={{127,0,0,1},{127,0,0,2}};
+        const int EXPECTED_ADDRS_COUNT =COUNTOF(EXPECTED_IPS);
+
+        zoo_deterministic_conn_order(1);
+        zh=zookeeper_init(EXPECTED_HOST.c_str(),0,1000,0,0,0);
+
+        CPPUNIT_ASSERT(zh!=0);
+        CPPUNIT_ASSERT_EQUAL(EXPECTED_ADDRS_COUNT,zh->addrs_count);
+
+        for(int i=0;i<zh->addrs_count;i++){
+            sockaddr_in* addr=(struct sockaddr_in*)&zh->addrs[i];
+            CPPUNIT_ASSERT(memcmp(EXPECTED_IPS[i],&addr->sin_addr,sizeof(addr->sin_addr))==0);
+            if(i<1)
+                CPPUNIT_ASSERT_EQUAL(2121,(int)ntohs(addr->sin_port));
+            else
+                CPPUNIT_ASSERT_EQUAL(3434,(int)ntohs(addr->sin_port));
+        }
+    }
+    void testNullAddressString()
+    {
+        zh=zookeeper_init(NULL,0,0,0,0,0);
+        CPPUNIT_ASSERT(zh==0);
+        CPPUNIT_ASSERT_EQUAL(EINVAL,errno);
+    }
+    void testEmptyAddressString()
+    {
+        const string INVALID_HOST("");
+        zh=zookeeper_init(INVALID_HOST.c_str(),0,0,0,0,0);
+        CPPUNIT_ASSERT(zh==0);
+        CPPUNIT_ASSERT_EQUAL(EINVAL,errno);
+    }
+    void testOneSpaceAddressString()
+    {
+        const string INVALID_HOST(" ");
+        zh=zookeeper_init(INVALID_HOST.c_str(),0,0,0,0,0);
+        CPPUNIT_ASSERT(zh==0);
+        CPPUNIT_ASSERT_EQUAL(EINVAL,errno);
+    }
+    void testTwoSpacesAddressString()
+    {
+        const string INVALID_HOST("  ");
+        zh=zookeeper_init(INVALID_HOST.c_str(),0,0,0,0,0);
+        CPPUNIT_ASSERT(zh==0);
+        CPPUNIT_ASSERT_EQUAL(EINVAL,errno);
+    }
+    void testInvalidAddressString1()
+    {
+        const string INVALID_HOST("host1");
+        zh=zookeeper_init(INVALID_HOST.c_str(),0,0,0,0,0);
+        CPPUNIT_ASSERT(zh==0);
+        CPPUNIT_ASSERT_EQUAL(EINVAL,errno);
+    }
+    void testInvalidAddressString2()
+    {
+        const string INVALID_HOST("host1:1111+host:123");
+        zh=zookeeper_init(INVALID_HOST.c_str(),0,0,0,0,0);
+        CPPUNIT_ASSERT(zh==0);
+        CPPUNIT_ASSERT((ENOENT|EINVAL) & errno);
+    }
+    void testNonexistentHost()
+    {
+        const string EXPECTED_HOST("host1.blabadibla.bla.:1111");
+
+        zh=zookeeper_init(EXPECTED_HOST.c_str(),0,0,0,0,0);
+
+        CPPUNIT_ASSERT(zh==0);
+        //With the switch to thread safe getaddrinfo, we don't get
+        //these global variables
+        //CPPUNIT_ASSERT_EQUAL(EINVAL,errno);
+        //CPPUNIT_ASSERT_EQUAL(HOST_NOT_FOUND,h_errno);
+    }
+    void testOutOfMemory_init()
+    {
+        Mock_calloc mock;
+        mock.callsBeforeFailure=0; // fail first calloc in init()
+
+        zh=zookeeper_init("ahost:123",watcher,10000,0,0,0);
+
+        CPPUNIT_ASSERT(zh==0);
+        CPPUNIT_ASSERT_EQUAL(ENOMEM,errno);
+    }
+    void testOutOfMemory_getaddrs1()
+    {
+        Mock_realloc reallocMock;
+        reallocMock.callsBeforeFailure=0; // fail on first call to realloc
+
+        zh=zookeeper_init("127.0.0.1:123",0,0,0,0,0);
+
+        CPPUNIT_ASSERT(zh==0);
+        CPPUNIT_ASSERT_EQUAL(ENOMEM,errno);
+    }
+    void testOutOfMemory_getaddrs2()
+    {
+        Mock_realloc reallocMock;
+        reallocMock.callsBeforeFailure=1; // fail on the second call to realloc
+
+        zh=zookeeper_init("127.0.0.1:123,127.0.0.2:123,127.0.0.3:123,127.0.0.4:123,127.0.0.5:123,127.0.0.6:123,127.0.0.7:123,127.0.0.8:123,127.0.0.9:123,127.0.0.10:123,127.0.0.11:123,127.0.0.12:123,127.0.0.13:123,127.0.0.14:123,127.0.0.15:123,127.0.0.16:123,127.0.0.17:123",0,0,0,0,0);
+
+        CPPUNIT_ASSERT(zh==0);
+        CPPUNIT_ASSERT_EQUAL(ENOMEM,errno);
+    }
+    void testPermuteAddrsList()
+    {
+        const char EXPECTED[][5]={"\0\0\0\0","\1\1\1\1","\2\2\2\2","\3\3\3\3"};
+        const int EXPECTED_ADDR_COUNT=COUNTOF(EXPECTED);
+
+        const int RAND_SEQ[]={0,1,1,-1};
+        const int RAND_SIZE=COUNTOF(RAND_SEQ);
+        Mock_random randomMock;
+        randomMock.randomReturns.assign(RAND_SEQ,RAND_SEQ+RAND_SIZE-1);
+        zh=zookeeper_init("0.0.0.0:123,1.1.1.1:123,2.2.2.2:123,3.3.3.3:123",0,1000,0,0,0);
+
+        CPPUNIT_ASSERT(zh!=0);
+        CPPUNIT_ASSERT_EQUAL(EXPECTED_ADDR_COUNT,zh->addrs_count);
+        const string EXPECTED_SEQ("3210");
+        char ACTUAL_SEQ[EXPECTED_ADDR_COUNT+1]; ACTUAL_SEQ[EXPECTED_ADDR_COUNT]=0;
+        for(int i=0;i<zh->addrs_count;i++){
+            sockaddr_in* addr=(struct sockaddr_in*)&zh->addrs[i];
+            // match the first byte of the EXPECTED and of the actual address
+            ACTUAL_SEQ[i]=((char*)&addr->sin_addr)[0]+'0';
+        }
+        CPPUNIT_ASSERT_EQUAL(EXPECTED_SEQ,string(ACTUAL_SEQ));
+    }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_init);

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/ThreadingUtil.cc
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/ThreadingUtil.cc b/zookeeper-client/zookeeper-client-c/tests/ThreadingUtil.cc
new file mode 100644
index 0000000..3b5170a
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/ThreadingUtil.cc
@@ -0,0 +1,87 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/types.h>
+#include "ThreadingUtil.h"
+#include "LibCSymTable.h"
+
+#ifdef THREADED
+
+// ****************************************************************************
+// Mutex wrapper
+struct Mutex::Impl{
+    Impl(){
+        LIBC_SYMBOLS.pthread_mutex_init(&mut_, 0);        
+    }
+    ~Impl(){
+        LIBC_SYMBOLS.pthread_mutex_destroy(&mut_);        
+    }
+    pthread_mutex_t mut_;
+};
+
+Mutex::Mutex():impl_(new Impl) {}
+Mutex::~Mutex() { delete impl_;}
+void Mutex::acquire() {
+    LIBC_SYMBOLS.pthread_mutex_lock(&impl_->mut_);
+}
+void Mutex::release() {
+    LIBC_SYMBOLS.pthread_mutex_unlock(&impl_->mut_);
+}
+
+// ****************************************************************************
+// Atomics
+int32_t atomic_post_incr(volatile int32_t* operand, int32_t incr)
+{
+#if defined(__GNUC__)
+    return __sync_fetch_and_add(operand,incr);
+#else
+    int32_t result;
+    __asm__ __volatile__(
+         "lock xaddl %0,%1\n"
+         : "=r"(result), "=m"(*operand)
+         : "0"(incr)
+         : "memory");
+   return result;
+#endif
+}
+int32_t atomic_fetch_store(volatile int32_t *ptr, int32_t value)
+{
+#if defined(__GNUC__)
+    return __sync_lock_test_and_set(ptr,value);
+#else
+    int32_t result;
+    __asm__ __volatile__("lock xchgl %0,%1\n"
+                          : "=r"(result), "=m"(*ptr)
+                          : "0"(value)
+                          : "memory");
+   return result; 
+#endif
+}
+#else
+int32_t atomic_post_incr(volatile int32_t* operand, int32_t incr){
+    int32_t v=*operand;
+    *operand+=incr;
+    return v;
+}
+int32_t atomic_fetch_store(volatile int32_t *ptr, int32_t value)
+{
+    int32_t result=*ptr;
+    *ptr=value;
+    return result;
+}
+#endif // THREADED

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/ThreadingUtil.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/ThreadingUtil.h b/zookeeper-client/zookeeper-client-c/tests/ThreadingUtil.h
new file mode 100644
index 0000000..9165412
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/ThreadingUtil.h
@@ -0,0 +1,261 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef THREADINGUTIL_H_
+#define THREADINGUTIL_H_
+
+#include <vector>
+
+#ifdef THREADED
+#include "pthread.h"
+#endif
+
+// *****************************************************************************
+// Threading primitives
+
+// atomic post-increment; returns the previous value of the operand
+int32_t atomic_post_incr(volatile int32_t* operand, int32_t incr);
+// atomic fetch&store; returns the previous value of the operand
+int32_t atomic_fetch_store(volatile int32_t *operand, int32_t value);
+
+// a partial implementation of an atomic integer type
+class AtomicInt{
+public:
+    explicit AtomicInt(int32_t init=0):v_(init){}
+    AtomicInt(const AtomicInt& other):v_(other){}
+    // assigment
+    AtomicInt& operator=(const AtomicInt& lhs){
+        atomic_fetch_store(&v_,lhs);
+        return *this;
+    }
+    AtomicInt& operator=(int32_t i){
+        atomic_fetch_store(&v_,i);
+        return *this;
+    }
+    // pre-increment
+    AtomicInt& operator++() {
+        atomic_post_incr(&v_,1);
+        return *this;
+    }
+    // pre-decrement
+    AtomicInt& operator--() {
+        atomic_post_incr(&v_,-1);
+        return *this;
+    }
+    // post-increment
+    AtomicInt operator++(int){
+        return AtomicInt(atomic_post_incr(&v_,1));
+    }
+    // post-decrement
+    AtomicInt operator--(int){
+        return AtomicInt(atomic_post_incr(&v_,-1));
+    }
+    
+    operator int() const{
+        return atomic_post_incr(&v_,0);
+    }
+    int get() const{
+        return atomic_post_incr(&v_,0);
+    }
+private:
+    mutable int32_t v_;
+};
+
+#ifdef THREADED
+// ****************************************************************************
+#define VALIDATE_JOBS(jm) jm.validateJobs(__FILE__,__LINE__)
+#define VALIDATE_JOB(j) j.validate(__FILE__,__LINE__)
+
+class Mutex{
+public:
+    Mutex();
+    ~Mutex();
+    void acquire();
+    void release();
+private:
+    Mutex(const Mutex&);
+    Mutex& operator=(const Mutex&);
+    struct Impl;
+    Impl* impl_;
+};
+
+class MTLock{
+public:
+    MTLock(Mutex& m):m_(m){m.acquire();}
+    ~MTLock(){m_.release();}
+    Mutex& m_;
+};
+
+#define synchronized(m) MTLock __lock(m)
+
+// ****************************************************************************
+class Latch {
+public:
+    virtual ~Latch() {}
+    virtual void await() const =0;
+    virtual void signalAndWait() =0;
+    virtual void signal() =0;
+};
+
+class CountDownLatch: public Latch {
+public:
+    CountDownLatch(int count):count_(count) {
+        pthread_cond_init(&cond_,0);
+        pthread_mutex_init(&mut_,0);
+    }
+    virtual ~CountDownLatch() {
+        pthread_mutex_lock(&mut_);
+        if(count_!=0) {
+            count_=0;
+            pthread_cond_broadcast(&cond_);
+        }
+        pthread_mutex_unlock(&mut_);
+
+        pthread_cond_destroy(&cond_);
+        pthread_mutex_destroy(&mut_);
+    }
+
+    virtual void await() const {
+        pthread_mutex_lock(&mut_);
+        awaitImpl();
+        pthread_mutex_unlock(&mut_);
+    }
+    virtual void signalAndWait() {
+        pthread_mutex_lock(&mut_);
+        signalImpl();
+        awaitImpl();
+        pthread_mutex_unlock(&mut_);
+    }
+    virtual void signal() {
+        pthread_mutex_lock(&mut_);
+        signalImpl();
+        pthread_mutex_unlock(&mut_);
+    }
+private:
+    void awaitImpl() const{
+        while(count_!=0)
+        pthread_cond_wait(&cond_,&mut_);
+    }
+    void signalImpl() {
+        if(count_>0) {
+            count_--;
+            pthread_cond_broadcast(&cond_);
+        }
+    }
+    int count_;
+    mutable pthread_mutex_t mut_;
+    mutable pthread_cond_t cond_;
+};
+
+class TestJob {
+public:
+    typedef long JobId;
+    TestJob():hasRun_(false),startLatch_(0),endLatch_(0) {}
+    virtual ~TestJob() {
+        join();
+    }
+    virtual TestJob* clone() const =0;
+
+    virtual void run() =0;
+    virtual void validate(const char* file, int line) const =0;
+
+    virtual void start(Latch* startLatch=0,Latch* endLatch=0) {
+        startLatch_=startLatch;endLatch_=endLatch;
+        hasRun_=true;
+        pthread_create(&thread_, 0, thread, this);
+    }
+    virtual JobId getJobId() const {
+        return (JobId)thread_;
+    }
+    virtual void join() {
+        if(!hasRun_)
+        return;
+        if(!pthread_equal(thread_,pthread_self()))
+        pthread_join(thread_,0);
+        else
+        pthread_detach(thread_);
+    }
+private:
+    void awaitStart() {
+        if(startLatch_==0) return;
+        startLatch_->signalAndWait();
+    }
+    void signalFinished() {
+        if(endLatch_==0) return;
+        endLatch_->signal();
+    }
+    static void* thread(void* p) {
+        TestJob* j=(TestJob*)p;
+        j->awaitStart(); // wait for the start command
+        j->run();
+        j->signalFinished();
+        return 0;
+    }
+    bool hasRun_;
+    Latch* startLatch_;
+    Latch* endLatch_;
+    pthread_t thread_;
+};
+
+class TestJobManager {
+    typedef std::vector<TestJob*> JobList;
+public:
+    TestJobManager(const TestJob& tj,int threadCount=1):
+        startLatch_(threadCount),endLatch_(threadCount)
+    {
+        for(int i=0;i<threadCount;++i)
+            jobs_.push_back(tj.clone());
+    }
+    virtual ~TestJobManager(){
+        for(unsigned  i=0;i<jobs_.size();++i)
+            delete jobs_[i];
+    }
+    
+    virtual void startAllJobs() {
+        for(unsigned i=0;i<jobs_.size();++i)
+            jobs_[i]->start(&startLatch_,&endLatch_);
+    }
+    virtual void startJobsImmediately() {
+        for(unsigned i=0;i<jobs_.size();++i)
+            jobs_[i]->start(0,&endLatch_);
+    }
+    virtual void wait() const {
+        endLatch_.await();
+    }
+    virtual void validateJobs(const char* file, int line) const{
+        for(unsigned i=0;i<jobs_.size();++i)
+            jobs_[i]->validate(file,line);        
+    }
+private:
+    JobList jobs_;
+    CountDownLatch startLatch_;
+    CountDownLatch endLatch_;
+};
+
+#else // THREADED
+// single THREADED
+class Mutex{
+public:
+    void acquire(){}
+    void release(){}
+};
+#define synchronized(m)
+
+#endif // THREADED
+
+#endif /*THREADINGUTIL_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/Util.cc
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/Util.cc b/zookeeper-client/zookeeper-client-c/tests/Util.cc
new file mode 100644
index 0000000..2b9da84
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/Util.cc
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Util.h"
+#include "string.h"
+
+const std::string EMPTY_STRING;
+
+TestConfig globalTestConfig;
+
+void millisleep(int ms){
+    timespec ts;
+    ts.tv_sec=ms/1000;
+    ts.tv_nsec=(ms%1000)*1000000; // to nanoseconds
+    nanosleep(&ts,0);
+}
+
+FILE *openlogfile(const char* testname) {
+  char name[1024];
+  strcpy(name, "TEST-");
+  strncpy(name + 5, testname, sizeof(name) - 5);
+#ifdef THREADED
+  strcpy(name + strlen(name), "-mt.txt");
+#else
+  strcpy(name + strlen(name), "-st.txt");
+#endif
+
+  FILE *logfile = fopen(name, "a");
+
+  if (logfile == 0) {
+    fprintf(stderr, "Can't open log file %s!\n", name);
+    return 0;
+  }
+
+  return logfile;
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/Util.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/Util.h b/zookeeper-client/zookeeper-client-c/tests/Util.h
new file mode 100644
index 0000000..01e21ce
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/Util.h
@@ -0,0 +1,137 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef UTIL_H_
+#define UTIL_H_
+
+#include <map>
+#include <vector>
+#include <string>
+
+#include "zookeeper_log.h"
+
+// number of elements in array
+#define COUNTOF(array) sizeof(array)/sizeof(array[0])
+
+#define DECLARE_WRAPPER(ret,sym,sig) \
+    extern "C" ret __real_##sym sig; \
+    extern "C" ret __wrap_##sym sig
+
+#define CALL_REAL(sym,params) \
+    __real_##sym params
+
+// must include "src/zookeeper_log.h" to be able to use this macro
+#define TEST_TRACE(x) \
+    log_message(ZOO_LOG_LEVEL_DEBUG,__LINE__,__func__,format_log_message x)
+
+extern const std::string EMPTY_STRING;
+
+// *****************************************************************************
+// A bit of wizardry to get to the bare type from a reference or a pointer 
+// to the type
+template <class T>
+struct TypeOp {
+    typedef T BareT;
+    typedef T ArgT;
+};
+
+// partial specialization for reference types
+template <class T>
+struct TypeOp<T&>{
+    typedef T& ArgT;
+    typedef typename TypeOp<T>::BareT BareT;
+};
+
+// partial specialization for pointers
+template <class T>
+struct TypeOp<T*>{
+    typedef T* ArgT;
+    typedef typename TypeOp<T>::BareT BareT;
+};
+
+// *****************************************************************************
+// Container utilities
+
+template <class K, class V>
+void putValue(std::map<K,V>& map,const K& k, const V& v){
+    typedef std::map<K,V> Map;
+    typename Map::const_iterator it=map.find(k);
+    if(it==map.end())
+        map.insert(typename Map::value_type(k,v));
+    else
+        map[k]=v;
+}
+
+template <class K, class V>
+bool getValue(const std::map<K,V>& map,const K& k,V& v){
+    typedef std::map<K,V> Map;
+    typename Map::const_iterator it=map.find(k);
+    if(it==map.end())
+        return false;
+    v=it->second;
+    return true;
+}
+
+// *****************************************************************************
+// misc utils
+
+// millisecond sleep
+void millisleep(int ms);
+FILE *openlogfile(const char* name);
+// evaluate given predicate until it returns true or the timeout 
+// (in millis) has expired
+template<class Predicate>
+int ensureCondition(const Predicate& p,int timeout){
+    int elapsed=0;
+    while(!p() && elapsed<timeout){
+        millisleep(2);
+        elapsed+=2;
+    }
+    return elapsed;
+};
+
+// *****************************************************************************
+// test global configuration data 
+class TestConfig{
+    typedef std::vector<std::string> CmdLineOptList;
+public:
+    typedef CmdLineOptList::const_iterator const_iterator;
+    TestConfig(){}
+    ~TestConfig(){}
+    void addConfigFromCmdLine(int argc, char* argv[]){
+        if(argc>=2)
+            testName_=argv[1];
+        for(int i=2; i<argc;++i)
+            cmdOpts_.push_back(argv[i]);
+    }
+    const_iterator getExtraOptBegin() const {return cmdOpts_.begin();}
+    const_iterator getExtraOptEnd() const {return cmdOpts_.end();}
+    size_t getExtraOptCount() const {
+        return cmdOpts_.size();
+    }
+    const std::string& getTestName() const {
+        return testName_=="all"?EMPTY_STRING:testName_;
+    }
+private:
+    CmdLineOptList cmdOpts_;
+    std::string testName_;
+};
+
+extern TestConfig globalTestConfig;
+
+#endif /*UTIL_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/Vector.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/Vector.h b/zookeeper-client/zookeeper-client-c/tests/Vector.h
new file mode 100644
index 0000000..d75fe07
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/Vector.h
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _VECTOR_UTIL_H
+#define _VECTOR_UTIL_H
+
+#include <vector>
+
+// function to conveniently stream vectors
+template <class U>
+std::ostream& operator<<(std::ostream& os,const std::vector<U>& c){
+  typedef std::vector<U> V;
+  os<<"[";
+  if(c.size()>0){
+      for(typename V::const_iterator it=c.begin();it!=c.end();++it)
+          os<<*it<<",";
+      os.seekp(-1,std::ios::cur);
+  }
+  os<<"]";
+  return os;
+}
+
+#endif // _VECTOR_UTIL_H

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/ZKMocks.cc
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/ZKMocks.cc b/zookeeper-client/zookeeper-client-c/tests/ZKMocks.cc
new file mode 100644
index 0000000..69bea16
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/ZKMocks.cc
@@ -0,0 +1,519 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <arpa/inet.h>  // for htonl
+#include <memory>
+
+#include <zookeeper.h>
+#include <proto.h>
+
+#ifdef THREADED
+#include "PthreadMocks.h"
+#endif
+#include "ZKMocks.h"
+
+using namespace std;
+
+TestClientId testClientId;
+const char* TestClientId::PASSWD="1234567890123456";
+
+HandshakeRequest* HandshakeRequest::parse(const std::string& buf){
+    auto_ptr<HandshakeRequest> req(new HandshakeRequest);
+
+    memcpy(&req->protocolVersion,buf.data(), sizeof(req->protocolVersion));
+    req->protocolVersion = htonl(req->protocolVersion);
+    
+    int offset=sizeof(req->protocolVersion);
+    
+    memcpy(&req->lastZxidSeen,buf.data()+offset,sizeof(req->lastZxidSeen));
+    req->lastZxidSeen = zoo_htonll(req->lastZxidSeen);
+    offset+=sizeof(req->lastZxidSeen);
+    
+    memcpy(&req->timeOut,buf.data()+offset,sizeof(req->timeOut));
+    req->timeOut = htonl(req->timeOut);
+    offset+=sizeof(req->timeOut);
+    
+    memcpy(&req->sessionId,buf.data()+offset,sizeof(req->sessionId));
+    req->sessionId = zoo_htonll(req->sessionId);
+    offset+=sizeof(req->sessionId);
+    
+    memcpy(&req->passwd_len,buf.data()+offset,sizeof(req->passwd_len));
+    req->passwd_len = htonl(req->passwd_len);
+    offset+=sizeof(req->passwd_len);
+    
+    memcpy(req->passwd,buf.data()+offset,sizeof(req->passwd));
+    if(testClientId.client_id==req->sessionId &&
+            !memcmp(testClientId.passwd,req->passwd,sizeof(req->passwd)))
+        return req.release();
+    // the request didn't match -- may not be a handshake request after all
+    return 0;
+}
+
+// *****************************************************************************
+// watcher action implementation
+void activeWatcher(zhandle_t *zh, int type, int state, const char *path,void* ctx){
+    if(zh==0 || ctx==0) return;
+    WatcherAction* action=(WatcherAction*)ctx;
+    
+    if(type==ZOO_SESSION_EVENT){
+        if(state==ZOO_EXPIRED_SESSION_STATE)
+            action->onSessionExpired(zh);
+        else if(state==ZOO_CONNECTING_STATE)
+            action->onConnectionLost(zh);
+        else if(state==ZOO_CONNECTED_STATE)
+            action->onConnectionEstablished(zh);
+    }else if(type==ZOO_CHANGED_EVENT)
+        action->onNodeValueChanged(zh,path);
+    else if(type==ZOO_DELETED_EVENT)
+        action->onNodeDeleted(zh,path);
+    else if(type==ZOO_CHILD_EVENT)
+        action->onChildChanged(zh,path);
+    // TODO: implement for the rest of the event types
+    // ...
+    action->setWatcherTriggered();    
+}
+SyncedBoolCondition WatcherAction::isWatcherTriggered() const{
+    return SyncedBoolCondition(triggered_,mx_);
+}
+
+// *****************************************************************************
+// a set of async completion signatures
+void asyncCompletion(int rc, ACL_vector *acl,Stat *stat, const void *data){
+    assert("Completion data is NULL"&&data);
+    static_cast<AsyncCompletion*>((void*)data)->aclCompl(rc,acl,stat);
+}
+void asyncCompletion(int rc, const char *value, int len, const Stat *stat, 
+        const void *data){    
+    assert("Completion data is NULL"&&data);
+    static_cast<AsyncCompletion*>((void*)data)->dataCompl(rc,value,len,stat);    
+}
+void asyncCompletion(int rc, const Stat *stat, const void *data){    
+    assert("Completion data is NULL"&&data);
+    static_cast<AsyncCompletion*>((void*)data)->statCompl(rc,stat);
+}
+void asyncCompletion(int rc, const char *value, const void *data){
+    assert("Completion data is NULL"&&data);
+    static_cast<AsyncCompletion*>((void*)data)->stringCompl(rc,value);
+}
+void asyncCompletion(int rc,const String_vector *strings, const void *data){    
+    assert("Completion data is NULL"&&data);
+    static_cast<AsyncCompletion*>((void*)data)->stringsCompl(rc,strings);
+}
+void asyncCompletion(int rc, const void *data){    
+    assert("Completion data is NULL"&&data);
+    static_cast<AsyncCompletion*>((void*)data)->voidCompl(rc);
+}
+
+// *****************************************************************************
+// a predicate implementation
+bool IOThreadStopped::operator()() const{
+#ifdef THREADED
+    adaptor_threads* adaptor=(adaptor_threads*)zh_->adaptor_priv;
+    return CheckedPthread::isTerminated(adaptor->io);
+#else
+    assert("IOThreadStopped predicate is only for use with THREADED client"&& false);
+    return false;
+#endif
+}
+
+//******************************************************************************
+//
+DECLARE_WRAPPER(int,flush_send_queue,(zhandle_t*zh, int timeout))
+{
+    if(!Mock_flush_send_queue::mock_)
+        return CALL_REAL(flush_send_queue,(zh,timeout));
+    return Mock_flush_send_queue::mock_->call(zh,timeout);
+}
+
+Mock_flush_send_queue* Mock_flush_send_queue::mock_=0;
+
+//******************************************************************************
+//
+DECLARE_WRAPPER(int32_t,get_xid,())
+{
+    if(!Mock_get_xid::mock_)
+        return CALL_REAL(get_xid,());
+    return Mock_get_xid::mock_->call();
+}
+
+Mock_get_xid* Mock_get_xid::mock_=0;
+
+//******************************************************************************
+// activateWatcher mock
+
+DECLARE_WRAPPER(void,activateWatcher,(zhandle_t *zh, watcher_registration_t* reg, int rc))
+{
+    if(!Mock_activateWatcher::mock_){
+        CALL_REAL(activateWatcher,(zh, reg,rc));
+    }else{
+        Mock_activateWatcher::mock_->call(zh, reg,rc);
+    }
+}
+Mock_activateWatcher* Mock_activateWatcher::mock_=0;
+
+class ActivateWatcherWrapper: public Mock_activateWatcher{
+public:
+    ActivateWatcherWrapper():ctx_(0),activated_(false){}
+    
+    virtual void call(zhandle_t *zh, watcher_registration_t* reg, int rc){
+        CALL_REAL(activateWatcher,(zh, reg,rc));
+        synchronized(mx_);
+        if(reg->context==ctx_){
+            activated_=true;
+            ctx_=0;
+        }
+    }
+    
+    void setContext(void* ctx){
+        synchronized(mx_);
+        ctx_=ctx;
+        activated_=false;
+    }
+    
+    SyncedBoolCondition isActivated() const{
+        return SyncedBoolCondition(activated_,mx_);
+    }
+    mutable Mutex mx_;
+    void* ctx_;
+    bool activated_;
+};
+
+WatcherActivationTracker::WatcherActivationTracker():
+    wrapper_(new ActivateWatcherWrapper)
+{    
+}
+
+WatcherActivationTracker::~WatcherActivationTracker(){
+    delete wrapper_;
+}
+
+void WatcherActivationTracker::track(void* ctx){
+    wrapper_->setContext(ctx);
+}
+
+SyncedBoolCondition WatcherActivationTracker::isWatcherActivated() const{
+    return wrapper_->isActivated();
+}
+
+//******************************************************************************
+//
+DECLARE_WRAPPER(void,deliverWatchers,(zhandle_t* zh,int type,int state, const char* path, watcher_object_list_t **list))
+{
+    if(!Mock_deliverWatchers::mock_){
+        CALL_REAL(deliverWatchers,(zh,type,state,path, list));
+    }else{
+        Mock_deliverWatchers::mock_->call(zh,type,state,path, list);
+    }
+}
+
+Mock_deliverWatchers* Mock_deliverWatchers::mock_=0;
+
+struct RefCounterValue{
+    RefCounterValue(zhandle_t* const& zh,int32_t expectedCounter,Mutex& mx):
+        zh_(zh),expectedCounter_(expectedCounter),mx_(mx){}
+    bool operator()() const{
+        {
+            synchronized(mx_);
+            if(zh_==0)
+                return false;
+        }
+        return inc_ref_counter(zh_,0)==expectedCounter_;
+    }
+    zhandle_t* const& zh_;
+    int32_t expectedCounter_;
+    Mutex& mx_;
+};
+
+
+class DeliverWatchersWrapper: public Mock_deliverWatchers{
+public:
+    DeliverWatchersWrapper(int type,int state,bool terminate):
+        type_(type),state_(state),
+        allDelivered_(false),terminate_(terminate),zh_(0),deliveryCounter_(0){}
+    virtual void call(zhandle_t* zh,int type,int state, const char* path, watcher_object_list **list){
+        {
+            synchronized(mx_);
+            zh_=zh;
+            allDelivered_=false;
+        }
+        CALL_REAL(deliverWatchers,(zh,type,state,path, list));
+        if(type_==type && state_==state){
+            if(terminate_){
+                // prevent zhandle_t from being prematurely distroyed;
+                // this will also ensure that zookeeper_close() cleanups the thread
+                // resources by calling finish_adaptor()
+                inc_ref_counter(zh,1);
+                terminateZookeeperThreads(zh);
+            }
+            synchronized(mx_);
+            allDelivered_=true;
+            deliveryCounter_++;
+        }
+    }
+    SyncedBoolCondition isDelivered() const{
+        if(terminate_){
+            int i=ensureCondition(RefCounterValue(zh_,1,mx_),1000);
+            assert(i<1000);
+        }
+        return SyncedBoolCondition(allDelivered_,mx_);
+    }
+    void resetDeliveryCounter(){
+        synchronized(mx_);
+        deliveryCounter_=0;
+    }
+    SyncedIntegerEqual deliveryCounterEquals(int expected) const{
+        if(terminate_){
+            int i=ensureCondition(RefCounterValue(zh_,1,mx_),1000);
+            assert(i<1000);
+        }
+        return SyncedIntegerEqual(deliveryCounter_,expected,mx_);
+    }
+    int type_;
+    int state_;
+    mutable Mutex mx_;
+    bool allDelivered_;
+    bool terminate_;
+    zhandle_t* zh_;
+    int deliveryCounter_;
+};
+
+WatcherDeliveryTracker::WatcherDeliveryTracker(
+        int type,int state,bool terminateCompletionThread):
+    deliveryWrapper_(new DeliverWatchersWrapper(
+            type,state,terminateCompletionThread)){
+}
+
+WatcherDeliveryTracker::~WatcherDeliveryTracker(){
+    delete deliveryWrapper_;
+}
+
+SyncedBoolCondition WatcherDeliveryTracker::isWatcherProcessingCompleted() const{
+    return deliveryWrapper_->isDelivered();
+}
+
+void WatcherDeliveryTracker::resetDeliveryCounter(){
+    deliveryWrapper_->resetDeliveryCounter();
+}
+
+SyncedIntegerEqual WatcherDeliveryTracker::deliveryCounterEquals(int expected) const{
+    return deliveryWrapper_->deliveryCounterEquals(expected);
+}
+
+//******************************************************************************
+//
+string HandshakeResponse::toString() const {
+    string buf;
+    int32_t tmp=htonl(protocolVersion);
+    buf.append((char*)&tmp,sizeof(tmp));
+    tmp=htonl(timeOut);
+    buf.append((char*)&tmp,sizeof(tmp));
+    int64_t tmp64=zoo_htonll(sessionId);
+    buf.append((char*)&tmp64,sizeof(sessionId));
+    tmp=htonl(passwd_len);
+    buf.append((char*)&tmp,sizeof(tmp));
+    buf.append(passwd,sizeof(passwd));
+    // finally set the buffer length
+    tmp=htonl(buf.size()+sizeof(tmp));
+    buf.insert(0,(char*)&tmp, sizeof(tmp));
+    return buf;
+}
+
+string ZooGetResponse::toString() const{
+    oarchive* oa=create_buffer_oarchive();
+    
+    ReplyHeader h = {xid_,1,ZOK};
+    serialize_ReplyHeader(oa, "hdr", &h);
+    
+    GetDataResponse resp;
+	char buf[1024];
+    assert("GetDataResponse is too long"&&data_.size()<=sizeof(buf));
+    resp.data.len=data_.size();
+    resp.data.buff=buf;
+    data_.copy(resp.data.buff, data_.size());
+    resp.stat=stat_;
+    serialize_GetDataResponse(oa, "reply", &resp);
+    int32_t len=htonl(get_buffer_len(oa));
+    string res((char*)&len,sizeof(len));
+    res.append(get_buffer(oa),get_buffer_len(oa));
+    
+    close_buffer_oarchive(&oa,1);
+    return res;
+}
+
+string ZooStatResponse::toString() const{
+    oarchive* oa=create_buffer_oarchive();
+    
+    ReplyHeader h = {xid_,1,rc_};
+    serialize_ReplyHeader(oa, "hdr", &h);
+    
+    SetDataResponse resp;
+    resp.stat=stat_;
+    serialize_SetDataResponse(oa, "reply", &resp);
+    int32_t len=htonl(get_buffer_len(oa));
+    string res((char*)&len,sizeof(len));
+    res.append(get_buffer(oa),get_buffer_len(oa));
+    
+    close_buffer_oarchive(&oa,1);
+    return res;
+}
+
+string ZooGetChildrenResponse::toString() const{
+    oarchive* oa=create_buffer_oarchive();
+    
+    ReplyHeader h = {xid_,1,rc_};
+    serialize_ReplyHeader(oa, "hdr", &h);
+ 
+    GetChildrenResponse resp;
+    // populate the string vector
+    allocate_String_vector(&resp.children,strings_.size());
+    for(int i=0;i<(int)strings_.size();++i)
+        resp.children.data[i]=strdup(strings_[i].c_str());
+    serialize_GetChildrenResponse(oa, "reply", &resp);
+    deallocate_GetChildrenResponse(&resp);
+    
+    int32_t len=htonl(get_buffer_len(oa));
+    string res((char*)&len,sizeof(len));
+    res.append(get_buffer(oa),get_buffer_len(oa));
+    
+    close_buffer_oarchive(&oa,1);
+    return res;
+}
+
+string ZNodeEvent::toString() const{
+    oarchive* oa=create_buffer_oarchive();
+    struct WatcherEvent evt = {type_,0,(char*)path_.c_str()};
+    struct ReplyHeader h = {WATCHER_EVENT_XID,0,ZOK };
+    
+    serialize_ReplyHeader(oa, "hdr", &h);
+    serialize_WatcherEvent(oa, "event", &evt);
+    
+    int32_t len=htonl(get_buffer_len(oa));
+    string res((char*)&len,sizeof(len));
+    res.append(get_buffer(oa),get_buffer_len(oa));
+    
+    close_buffer_oarchive(&oa,1);
+    return res;
+}
+
+string PingResponse::toString() const{
+    oarchive* oa=create_buffer_oarchive();
+    
+    ReplyHeader h = {PING_XID,1,ZOK};
+    serialize_ReplyHeader(oa, "hdr", &h);
+    
+    int32_t len=htonl(get_buffer_len(oa));
+    string res((char*)&len,sizeof(len));
+    res.append(get_buffer(oa),get_buffer_len(oa));
+    
+    close_buffer_oarchive(&oa,1);
+    return res;
+}
+
+//******************************************************************************
+// Zookeeper server simulator
+// 
+bool ZookeeperServer::hasMoreRecv() const{
+  return recvHasMore.get()!=0  || connectionLost;
+}
+
+ssize_t ZookeeperServer::callRecv(int s,void *buf,size_t len,int flags){
+    if(connectionLost){
+        recvReturnBuffer.erase();
+        return 0;
+    }
+    // done transmitting the current buffer?
+    if(recvReturnBuffer.size()==0){
+        synchronized(recvQMx);
+        if(recvQueue.empty()){
+            recvErrno=EAGAIN;
+            return Mock_socket::callRecv(s,buf,len,flags);
+        }
+        --recvHasMore;
+        Element& el=recvQueue.front();
+        if(el.first!=0){
+            recvReturnBuffer=el.first->toString();
+            delete el.first;
+        }
+        recvErrno=el.second;
+        recvQueue.pop_front();
+    }
+    return Mock_socket::callRecv(s,buf,len,flags);
+}
+
+void ZookeeperServer::onMessageReceived(const RequestHeader& rh, iarchive* ia){
+    // no-op by default
+}
+
+void ZookeeperServer::notifyBufferSent(const std::string& buffer){
+    if(HandshakeRequest::isValid(buffer)){
+        // could be a connect request
+        auto_ptr<HandshakeRequest> req(HandshakeRequest::parse(buffer));
+        if(req.get()!=0){
+            // handle the handshake
+            int64_t sessId=sessionExpired?req->sessionId+1:req->sessionId;
+            sessionExpired=false;
+            addRecvResponse(new HandshakeResponse(sessId));            
+            return;
+        }
+        // not a connect request -- fall thru
+    }
+    // parse the buffer to extract the request type and its xid
+    iarchive *ia=create_buffer_iarchive((char*)buffer.data(), buffer.size());
+    RequestHeader rh;
+    deserialize_RequestHeader(ia,"hdr",&rh);
+    // notify the "server" a client request has arrived
+    if (rh.xid == -8) {
+        Element e = Element(new ZooStatResponse,0);
+        e.first->setXID(-8);
+        addRecvResponse(e);
+        close_buffer_iarchive(&ia);
+        return;
+    } else {
+        onMessageReceived(rh,ia);
+    }
+    close_buffer_iarchive(&ia);
+    if(rh.type==ZOO_CLOSE_OP){
+        ++closeSent;
+        return; // no reply for close requests
+    }
+    // get the next response from the response queue and append it to the receive list
+    Element e;
+    {
+        synchronized(respQMx);
+        if(respQueue.empty())
+            return;
+        e=respQueue.front();
+        respQueue.pop_front();
+    }
+    e.first->setXID(rh.xid);
+    addRecvResponse(e);
+}
+
+void forceConnected(zhandle_t* zh){
+    // simulate connected state
+    zh->state=ZOO_CONNECTED_STATE;
+    zh->fd=ZookeeperServer::FD;
+    zh->input_buffer=0;
+    gettimeofday(&zh->last_recv,0);    
+    gettimeofday(&zh->last_send,0);    
+}
+
+void terminateZookeeperThreads(zhandle_t* zh){
+    // this will cause the zookeeper threads to terminate
+    zh->close_requested=1;
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/ZKMocks.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/ZKMocks.h b/zookeeper-client/zookeeper-client-c/tests/ZKMocks.h
new file mode 100644
index 0000000..fbcfc4f
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/ZKMocks.h
@@ -0,0 +1,509 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ZKMOCKS_H_
+#define ZKMOCKS_H_
+
+#include <zookeeper.h>
+#include "src/zk_adaptor.h"
+
+#include "Util.h"
+#include "LibCMocks.h"
+#include "MocksBase.h"
+
+// *****************************************************************************
+// sets internal zhandle_t members to certain values to simulate the client 
+// connected state. This function should only be used with the single-threaded
+// Async API tests!
+void forceConnected(zhandle_t* zh); 
+
+/**
+ * Gracefully terminates zookeeper I/O and completion threads. 
+ */
+void terminateZookeeperThreads(zhandle_t* zh);
+
+// *****************************************************************************
+// Abstract watcher action
+struct SyncedBoolCondition;
+
+class WatcherAction{
+public:
+    WatcherAction():triggered_(false){}
+    virtual ~WatcherAction(){}
+    
+    virtual void onSessionExpired(zhandle_t*){}
+    virtual void onConnectionEstablished(zhandle_t*){}
+    virtual void onConnectionLost(zhandle_t*){}
+    virtual void onNodeValueChanged(zhandle_t*,const char* path){}
+    virtual void onNodeDeleted(zhandle_t*,const char* path){}
+    virtual void onChildChanged(zhandle_t*,const char* path){}
+    
+    SyncedBoolCondition isWatcherTriggered() const;
+    void setWatcherTriggered(){
+        synchronized(mx_);
+        triggered_=true;
+    }
+
+protected:
+    mutable Mutex mx_;
+    bool triggered_;
+};
+// zh->context is a pointer to a WatcherAction instance
+// based on the event type and state, the watcher calls a specific watcher 
+// action method
+void activeWatcher(zhandle_t *zh, int type, int state, const char *path,void* ctx);
+
+// *****************************************************************************
+// a set of async completion signatures
+class AsyncCompletion{
+public:
+    virtual ~AsyncCompletion(){}
+    virtual void aclCompl(int rc, ACL_vector *acl,Stat *stat){}
+    virtual void dataCompl(int rc, const char *value, int len, const Stat *stat){}
+    virtual void statCompl(int rc, const Stat *stat){}
+    virtual void stringCompl(int rc, const char *value){}
+    virtual void stringsCompl(int rc,const String_vector *strings){}
+    virtual void voidCompl(int rc){}
+};
+void asyncCompletion(int rc, ACL_vector *acl,Stat *stat, const void *data);
+void asyncCompletion(int rc, const char *value, int len, const Stat *stat, 
+        const void *data);
+void asyncCompletion(int rc, const Stat *stat, const void *data);
+void asyncCompletion(int rc, const char *value, const void *data);
+void asyncCompletion(int rc,const String_vector *strings, const void *data);
+void asyncCompletion(int rc, const void *data);
+
+// *****************************************************************************
+// some common predicates to use with ensureCondition():
+// checks if the connection is established
+struct ClientConnected{
+    ClientConnected(zhandle_t* zh):zh_(zh){}
+    bool operator()() const{
+        return zoo_state(zh_)==ZOO_CONNECTED_STATE;
+    }
+    zhandle_t* zh_;
+};
+// check in the session expired
+struct SessionExpired{
+    SessionExpired(zhandle_t* zh):zh_(zh){}
+    bool operator()() const{
+        return zoo_state(zh_)==ZOO_EXPIRED_SESSION_STATE;
+    }
+    zhandle_t* zh_;
+};
+// checks if the IO thread has stopped; CheckedPthread must be active
+struct IOThreadStopped{
+    IOThreadStopped(zhandle_t* zh):zh_(zh){}
+    bool operator()() const;
+    zhandle_t* zh_;
+};
+
+// a synchronized boolean condition
+struct SyncedBoolCondition{
+    SyncedBoolCondition(const bool& cond,Mutex& mx):cond_(cond),mx_(mx){}
+    bool operator()() const{
+        synchronized(mx_);
+        return cond_;
+    }
+    const bool& cond_;
+    Mutex& mx_;
+};
+
+// a synchronized integer comparison
+struct SyncedIntegerEqual{
+    SyncedIntegerEqual(const int& cond,int expected,Mutex& mx):
+        cond_(cond),expected_(expected),mx_(mx){}
+    bool operator()() const{
+        synchronized(mx_);
+        return cond_==expected_;
+    }
+    const int& cond_;
+    const int expected_;
+    Mutex& mx_;
+};
+
+// *****************************************************************************
+// make sure to call zookeeper_close() even in presence of exceptions 
+struct CloseFinally{
+    CloseFinally(zhandle_t** zh):zh_(zh){}
+    ~CloseFinally(){
+        execute();
+    }
+    int execute(){
+        if(zh_==0)return ZOK;
+        zhandle_t* lzh=*zh_;
+        *zh_=0;
+        disarm();
+        return zookeeper_close(lzh);
+    }
+    void disarm(){zh_=0;}
+    zhandle_t ** zh_;
+};
+
+struct TestClientId: clientid_t{
+    static const int SESSION_ID=123456789;
+    static const char* PASSWD;
+    TestClientId(){
+        client_id=SESSION_ID;
+        memcpy(passwd,PASSWD,sizeof(passwd));
+    }
+};
+
+// *****************************************************************************
+// special client id recongnized by the ZK server simulator 
+extern TestClientId testClientId;
+#define TEST_CLIENT_ID &testClientId
+
+// *****************************************************************************
+//
+struct HandshakeRequest: public connect_req
+{
+    static HandshakeRequest* parse(const std::string& buf);
+    static bool isValid(const std::string& buf){
+        // this is just quick and dirty check before we go and parse the request
+        return buf.size()==HANDSHAKE_REQ_SIZE;
+    }
+};
+
+// *****************************************************************************
+// flush_send_queue
+class Mock_flush_send_queue: public Mock
+{
+public:
+    Mock_flush_send_queue():counter(0),callReturns(ZOK){mock_=this;}
+    ~Mock_flush_send_queue(){mock_=0;}
+    
+    int counter;
+    int callReturns;
+    virtual int call(zhandle_t* zh, int timeout){
+        counter++;
+        return callReturns;
+    }
+
+    static Mock_flush_send_queue* mock_;
+};
+
+// *****************************************************************************
+// get_xid
+class Mock_get_xid: public Mock
+{
+public:
+    static const int32_t XID=123456;
+    Mock_get_xid(int retValue=XID):callReturns(retValue){mock_=this;}
+    ~Mock_get_xid(){mock_=0;}
+    
+    int callReturns;
+    virtual int call(){
+        return callReturns;
+    }
+
+    static Mock_get_xid* mock_;
+};
+
+// *****************************************************************************
+// activateWatcher
+class Mock_activateWatcher: public Mock{
+public:
+    Mock_activateWatcher(){mock_=this;}
+    virtual ~Mock_activateWatcher(){mock_=0;}
+    
+    virtual void call(zhandle_t *zh, watcher_registration_t* reg, int rc){}
+    static Mock_activateWatcher* mock_;
+};
+
+class ActivateWatcherWrapper;
+class WatcherActivationTracker{
+public:
+    WatcherActivationTracker();
+    ~WatcherActivationTracker();
+    
+    void track(void* ctx);
+    SyncedBoolCondition isWatcherActivated() const;
+private:
+    ActivateWatcherWrapper* wrapper_;
+};
+
+// *****************************************************************************
+// deliverWatchers
+class Mock_deliverWatchers: public Mock{
+public:
+    Mock_deliverWatchers(){mock_=this;}
+    virtual ~Mock_deliverWatchers(){mock_=0;}
+    
+    virtual void call(zhandle_t* zh,int type,int state, const char* path, watcher_object_list **){}
+    static Mock_deliverWatchers* mock_;
+};
+
+class DeliverWatchersWrapper;
+class WatcherDeliveryTracker{
+public:
+    // filters deliveries by state and type
+    WatcherDeliveryTracker(int type,int state,bool terminateCompletionThread=true);
+    ~WatcherDeliveryTracker();
+    
+    // if the thread termination requested (see the ctor params)
+    // this function will wait for the I/O and completion threads to 
+    // terminate before returning a SyncBoolCondition instance
+    SyncedBoolCondition isWatcherProcessingCompleted() const;
+    void resetDeliveryCounter();
+    SyncedIntegerEqual deliveryCounterEquals(int expected) const;
+private:
+    DeliverWatchersWrapper* deliveryWrapper_;
+};
+
+// *****************************************************************************
+// a zookeeper Stat wrapper
+struct NodeStat: public Stat
+{
+    NodeStat(){
+        czxid=0;
+        mzxid=0;
+        ctime=0;
+        mtime=0;
+        version=1;
+        cversion=0;
+        aversion=0;
+        ephemeralOwner=0;
+    }
+    NodeStat(const Stat& other){
+        memcpy(this,&other,sizeof(*this));
+    }
+};
+
+// *****************************************************************************
+// Abstract server Response
+class Response
+{
+public:
+    virtual ~Response(){}
+    
+    virtual void setXID(int32_t xid){}
+    // this method is used by the ZookeeperServer class to serialize 
+    // the instance of Response
+    virtual std::string toString() const =0;
+};
+
+// *****************************************************************************
+// Handshake response
+class HandshakeResponse: public Response
+{
+public:
+    HandshakeResponse(int64_t sessId=1)
+        :protocolVersion(1),timeOut(10000),sessionId(sessId),passwd_len(sizeof(passwd))
+    {
+        memcpy(passwd,"1234567890123456",sizeof(passwd));
+    }
+    int32_t protocolVersion;
+    int32_t timeOut;
+    int64_t sessionId;
+    int32_t passwd_len;
+    char passwd[16];
+    virtual std::string toString() const ;
+};
+
+// zoo_get() response
+class ZooGetResponse: public Response
+{
+public:
+    ZooGetResponse(const char* data, int len,int32_t xid=0,int rc=ZOK,const Stat& stat=NodeStat())
+        :xid_(xid),data_(data,len),rc_(rc),stat_(stat)
+    {
+    }
+    virtual std::string toString() const;
+    virtual void setXID(int32_t xid) {xid_=xid;}
+    
+private:
+    int32_t xid_;
+    std::string data_;
+    int rc_;
+    Stat stat_;
+};
+
+// zoo_exists(), zoo_set() response
+class ZooStatResponse: public Response
+{
+public:
+    ZooStatResponse(int32_t xid=0,int rc=ZOK,const Stat& stat=NodeStat())
+        :xid_(xid),rc_(rc),stat_(stat)
+    {
+    }
+    virtual std::string toString() const;
+    virtual void setXID(int32_t xid) {xid_=xid;}
+    
+private:
+    int32_t xid_;
+    int rc_;
+    Stat stat_;
+};
+
+// zoo_get_children()
+class ZooGetChildrenResponse: public Response
+{
+public:
+    typedef std::vector<std::string> StringVector;
+    ZooGetChildrenResponse(const StringVector& v,int rc=ZOK):
+        xid_(0),strings_(v),rc_(rc)
+    {
+    }
+    
+    virtual std::string toString() const;
+    virtual void setXID(int32_t xid) {xid_=xid;}
+
+    int32_t xid_;
+    StringVector strings_;
+    int rc_;
+};
+
+// PING response
+class PingResponse: public Response
+{
+public:
+    virtual std::string toString() const;    
+};
+
+// watcher znode event
+class ZNodeEvent: public Response
+{
+public:
+    ZNodeEvent(int type,const char* path):type_(type),path_(path){}
+    
+    virtual std::string toString() const;
+    
+private:
+    int type_;
+    std::string path_;
+};
+
+// ****************************************************************************
+// Zookeeper server simulator
+
+class ZookeeperServer: public Mock_socket
+{
+public:
+    ZookeeperServer():
+        serverDownSkipCount_(-1),sessionExpired(false),connectionLost(false)
+    {
+        connectReturns=-1;
+        connectErrno=EWOULDBLOCK;        
+    }
+    virtual ~ZookeeperServer(){
+        clearRecvQueue();
+        clearRespQueue();
+    }
+    virtual int callClose(int fd){
+        if(fd!=FD)
+            return LIBC_SYMBOLS.close(fd);
+        clearRecvQueue();
+        clearRespQueue();
+        return Mock_socket::callClose(fd);
+    }
+    // connection handling
+    // what to do when the handshake request comes in?
+    int serverDownSkipCount_;
+    // this will cause getsockopt(zh->fd,SOL_SOCKET,SO_ERROR,&error,&len) return 
+    // a failure after skipCount dropped to zero, thus simulating a server down 
+    // condition
+    // passing skipCount==-1 will make every connect attempt succeed
+    void setServerDown(int skipCount=0){ 
+        serverDownSkipCount_=skipCount;
+        optvalSO_ERROR=0;            
+    }
+    virtual void setSO_ERROR(void *optval,socklen_t len){
+        if(serverDownSkipCount_!=-1){
+            if(serverDownSkipCount_==0)
+                optvalSO_ERROR=ECONNREFUSED;
+            else
+                serverDownSkipCount_--;
+        }
+        Mock_socket::setSO_ERROR(optval,len);
+    }
+
+    // this is a trigger that gets reset back to false
+    // a connect request will return a non-matching session id thus causing 
+    // the client throw SESSION_EXPIRED
+    volatile bool sessionExpired;
+    void returnSessionExpired(){ sessionExpired=true; }
+    
+    // this is a one shot trigger that gets reset back to false
+    // next recv call will return 0 length, thus simulating a connecton loss
+    volatile bool connectionLost;
+    void setConnectionLost() {connectionLost=true;}
+    
+    // recv
+    // this queue is used for server responses: client's recv() system call 
+    // returns next available message from this queue
+    typedef std::pair<Response*,int> Element;
+    typedef std::deque<Element> ResponseList;
+    ResponseList recvQueue;
+    mutable Mutex recvQMx;
+    AtomicInt recvHasMore;
+    ZookeeperServer& addRecvResponse(Response* resp, int errnum=0){
+        synchronized(recvQMx);
+        recvQueue.push_back(Element(resp,errnum));
+        ++recvHasMore;
+        return *this;
+    }
+    ZookeeperServer& addRecvResponse(int errnum){
+        synchronized(recvQMx);
+        recvQueue.push_back(Element(0,errnum));
+        ++recvHasMore;
+        return *this;
+    }
+    ZookeeperServer& addRecvResponse(const Element& e){
+        synchronized(recvQMx);
+        recvQueue.push_back(e);
+        ++recvHasMore;
+        return *this;
+    }
+    void clearRecvQueue(){
+        synchronized(recvQMx);
+        recvHasMore=0;
+        for(unsigned i=0; i<recvQueue.size();i++)
+            delete recvQueue[i].first;
+        recvQueue.clear();
+    }
+
+    virtual ssize_t callRecv(int s,void *buf,size_t len,int flags);
+    virtual bool hasMoreRecv() const;
+    
+    // the operation response queue holds zookeeper operation responses till the
+    // operation request has been sent to the server. After that, the operation
+    // response gets moved on to the recv queue (see above) ready to be read by 
+    // the next recv() system call
+    // send operation doesn't try to match request to the response
+    ResponseList respQueue;
+    mutable Mutex respQMx;
+    ZookeeperServer& addOperationResponse(Response* resp, int errnum=0){
+        synchronized(respQMx);
+        respQueue.push_back(Element(resp,errnum));
+        return *this;
+    }
+    void clearRespQueue(){
+        synchronized(respQMx);
+        for(unsigned i=0; i<respQueue.size();i++)
+            delete respQueue[i].first;
+        respQueue.clear();
+    }
+    AtomicInt closeSent;
+    virtual void notifyBufferSent(const std::string& buffer);
+    // simulates an arrival of a client request
+    // a callback to be implemented by subclasses (no-op by default)
+    virtual void onMessageReceived(const RequestHeader& rh, iarchive* ia);
+};
+
+#endif /*ZKMOCKS_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/wrappers-mt.opt
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/wrappers-mt.opt b/zookeeper-client/zookeeper-client-c/tests/wrappers-mt.opt
new file mode 100644
index 0000000..01046fb
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/wrappers-mt.opt
@@ -0,0 +1,3 @@
+-Wl,--wrap -Wl,pthread_mutex_lock
+-Wl,--wrap -Wl,pthread_mutex_trylock
+-Wl,--wrap -Wl,pthread_mutex_unlock

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/wrappers.opt
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/wrappers.opt b/zookeeper-client/zookeeper-client-c/tests/wrappers.opt
new file mode 100644
index 0000000..bce192f
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/wrappers.opt
@@ -0,0 +1,7 @@
+-Wl,--wrap -Wl,calloc
+-Wl,--wrap -Wl,free
+-Wl,--wrap -Wl,flush_send_queue
+-Wl,--wrap -Wl,get_xid
+-Wl,--wrap -Wl,deliverWatchers
+-Wl,--wrap -Wl,activateWatcher
+-Wl,--wrap -Wl,realloc

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/zkServer.sh
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/zkServer.sh b/zookeeper-client/zookeeper-client-c/tests/zkServer.sh
new file mode 100755
index 0000000..4872fba
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/zkServer.sh
@@ -0,0 +1,161 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is the port where zookeeper server runs on.
+ZOOPORT=22181
+
+if [ "x$1" == "x" ]
+then
+    echo "USAGE: $0 startClean|start|stop hostPorts"
+    exit 2
+fi
+
+case "`uname`" in
+    CYGWIN*) cygwin=true ;;
+    *) cygwin=false ;;
+esac
+
+if [ "x$1" == "xstartClean" ]
+then
+    if [ "x${base_dir}" == "x" ]
+    then
+    rm -rf /tmp/zkdata
+    else
+    rm -rf "${base_dir}/build/tmp"
+    fi
+fi
+
+if $cygwin
+then
+    # cygwin has a "kill" in the shell itself, gets confused
+    KILL=/bin/kill
+else
+    KILL=kill
+fi
+
+# Make sure nothing is left over from before
+if [ -r "/tmp/zk.pid" ]
+then
+pid=`cat /tmp/zk.pid`
+$KILL -9 $pid
+rm -f /tmp/zk.pid
+fi
+
+if [ -r "${base_dir}/build/tmp/zk.pid" ]
+then
+pid=`cat "${base_dir}/build/tmp/zk.pid"`
+$KILL -9 $pid
+rm -f "${base_dir}/build/tmp/zk.pid"
+fi
+
+# [ZOOKEEPER-820] If lsof command is present, look for a process listening
+# on ZOOPORT and kill it. 
+which lsof &> /dev/null
+if [ $? -eq 0  ]
+then
+    pid=`lsof -i :$ZOOPORT | grep LISTEN | awk '{print $2}'`
+    if [ -n "$pid" ]
+    then
+        $KILL -9 $pid
+    fi
+fi
+
+if [ "x${base_dir}" == "x" ]
+then
+zk_base="../../"
+else
+zk_base="${base_dir}"
+fi
+
+CLASSPATH="$CLASSPATH:${zk_base}/build/classes"
+CLASSPATH="$CLASSPATH:${zk_base}/conf"
+
+for i in "${zk_base}"/build/lib/*.jar
+do
+    CLASSPATH="$CLASSPATH:$i"
+done
+
+for i in "${zk_base}"/src/java/lib/*.jar
+do
+    CLASSPATH="$CLASSPATH:$i"
+done
+
+CLASSPATH="$CLASSPATH:${CLOVER_HOME}/lib/clover.jar"
+
+if $cygwin
+then
+    CLASSPATH=`cygpath -wp "$CLASSPATH"`
+fi
+
+case $1 in
+start|startClean)
+    if [ "x${base_dir}" == "x" ]
+    then
+        mkdir -p /tmp/zkdata
+        java -cp "$CLASSPATH" org.apache.zookeeper.server.ZooKeeperServerMain $ZOOPORT /tmp/zkdata 3000 $ZKMAXCNXNS &> /tmp/zk.log &
+        pid=$!
+        echo -n $! > /tmp/zk.pid
+    else
+        mkdir -p "${base_dir}/build/tmp/zkdata"
+        java -cp "$CLASSPATH" org.apache.zookeeper.server.ZooKeeperServerMain $ZOOPORT "${base_dir}/build/tmp/zkdata" 3000 $ZKMAXCNXNS &> "${base_dir}/build/tmp/zk.log" &
+        pid=$!
+        echo -n $pid > "${base_dir}/build/tmp/zk.pid"
+    fi
+
+    # wait max 120 seconds for server to be ready to server clients
+    # this handles testing on slow hosts
+    success=false
+    for i in {1..120}
+    do
+        if ps -p $pid > /dev/null
+        then
+            java -cp "$CLASSPATH" org.apache.zookeeper.ZooKeeperMain -server localhost:$ZOOPORT ls / > /dev/null 2>&1
+            if [ $? -ne 0  ]
+            then
+                # server not up yet - wait
+                sleep 1
+            else
+                # server is up and serving client connections
+                success=true
+                break
+            fi
+        else
+            # server died - exit now
+            echo -n " ZooKeeper server process failed"
+            break
+        fi
+    done
+
+    if $success
+    then
+        ## in case for debug, but generally don't use as it messes up the
+        ## console test output
+        echo -n " ZooKeeper server started"
+    else
+        echo -n " ZooKeeper server NOT started"
+    fi
+
+    ;;
+stop)
+    # Already killed above
+    ;;
+*)
+    echo "Unknown command " + $1
+    exit 2
+esac
+

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-contrib/zookeeper-contrib-zkpython/src/python/setup.py
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zkpython/src/python/setup.py b/zookeeper-contrib/zookeeper-contrib-zkpython/src/python/setup.py
index c6a1cee..d9fa36b 100755
--- a/zookeeper-contrib/zookeeper-contrib-zkpython/src/python/setup.py
+++ b/zookeeper-contrib/zookeeper-contrib-zkpython/src/python/setup.py
@@ -19,12 +19,12 @@ from distutils.core import setup, Extension
 zookeeper_basedir = "../../../"
 
 zookeepermodule = Extension("zookeeper",
-                            sources=["src/c/zookeeper.c"],
-                            include_dirs=[zookeeper_basedir + "/src/c/include",
+                            sources=["zookeeper-client/zookeeper-client-c/zookeeper.c"],
+                            include_dirs=[zookeeper_basedir + "/zookeeper-client/zookeeper-client-c/include",
                                           zookeeper_basedir + "/build/c",
-                                          zookeeper_basedir + "/src/c/generated"],
+                                          zookeeper_basedir + "/zookeeper-client/zookeeper-client-c/generated"],
                             libraries=["zookeeper_mt"],
-                            library_dirs=[zookeeper_basedir + "/src/c/.libs/",
+                            library_dirs=[zookeeper_basedir + "/zookeeper-client/zookeeper-client-c/.libs/",
                                           zookeeper_basedir + "/build/c/.libs/",
                                           zookeeper_basedir + "/build/test/test-cppunit/.libs",
                                           "/usr/local/lib"

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-docs/src/documentation/content/xdocs/zookeeperProgrammers.xml
----------------------------------------------------------------------
diff --git a/zookeeper-docs/src/documentation/content/xdocs/zookeeperProgrammers.xml b/zookeeper-docs/src/documentation/content/xdocs/zookeeperProgrammers.xml
index 8fbd679..aaf21c4 100644
--- a/zookeeper-docs/src/documentation/content/xdocs/zookeeperProgrammers.xml
+++ b/zookeeper-docs/src/documentation/content/xdocs/zookeeperProgrammers.xml
@@ -941,7 +941,7 @@
 
       <note><para>This is a very simple example which is intended to show
         how to interact with ZooKeeper ACLs
-        specifically. See <filename>.../trunk/src/c/src/cli.c</filename>
+        specifically. See <filename>.../trunk/zookeeper-client/zookeeper-client-c/src/cli.c</filename>
         for an example of a C client implementation</para>
       </note>
 
@@ -1329,11 +1329,11 @@ authProvider.2=com.f.MyAuth2
             <para>Run <command>ant compile_jute</command> from the ZooKeeper
             top level directory (<filename>.../trunk</filename>).
             This will create a directory named "generated" under
-            <filename>.../trunk/src/c</filename>.</para>
+            <filename>.../trunk/zookeeper-client/zookeeper-client-c</filename>.</para>
           </listitem>
 
           <listitem>
-            <para>Change directory to the<filename>.../trunk/src/c</filename>
+            <para>Change directory to the<filename>.../trunk/zookeeper-client/zookeeper-client-c</filename>
             and run <command>autoreconf -if</command> to bootstrap <emphasis
             role="bold">autoconf</emphasis>, <emphasis
             role="bold">automake</emphasis> and <emphasis
@@ -1345,7 +1345,7 @@ authProvider.2=com.f.MyAuth2
           <listitem>
             <para>If you are building from a project source package,
             unzip/untar the source tarball and cd to the<filename>
-            zookeeper-x.x.x/src/c</filename> directory.</para>
+            zookeeper-x.x.x/zookeeper-client/zookeeper-client-c</filename> directory.</para>
           </listitem>
 
           <listitem>
@@ -1429,7 +1429,7 @@ authProvider.2=com.f.MyAuth2
         </orderedlist>
 
         <note><para>
-          See <filename>.../trunk/src/c/src/cli.c</filename>
+          See <filename>.../trunk/zookeeper-client/zookeeper-client-c/src/cli.c</filename>
             for an example of a C client implementation</para>
         </note>
       </section>

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-recipes/zookeeper-recipes-lock/src/main/c/configure.ac
----------------------------------------------------------------------
diff --git a/zookeeper-recipes/zookeeper-recipes-lock/src/main/c/configure.ac b/zookeeper-recipes/zookeeper-recipes-lock/src/main/c/configure.ac
index 3954123..31c5406 100644
--- a/zookeeper-recipes/zookeeper-recipes-lock/src/main/c/configure.ac
+++ b/zookeeper-recipes/zookeeper-recipes-lock/src/main/c/configure.ac
@@ -48,8 +48,8 @@ DX_PS_FEATURE(OFF)
 DX_INIT_DOXYGEN([zookeeper-locks],[c-doc.Doxyfile],[docs])
 
   
-ZOOKEEPER_PATH=${BUILD_PATH}/../../../../../src/c
-ZOOKEEPER_LD=-L${BUILD_PATH}/../../../../../src/c\ -lzookeeper_mt
+ZOOKEEPER_PATH=${BUILD_PATH}/../../../../zookeeper-client/zookeeper-client-c
+ZOOKEEPER_LD=-L${BUILD_PATH}/../../../../zookeeper-client/zookeeper-client-c\ -lzookeeper_mt
 
 AC_SUBST(ZOOKEEPER_PATH)
 AC_SUBST(ZOOKEEPER_LD)

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-recipes/zookeeper-recipes-queue/src/main/c/configure.ac
----------------------------------------------------------------------
diff --git a/zookeeper-recipes/zookeeper-recipes-queue/src/main/c/configure.ac b/zookeeper-recipes/zookeeper-recipes-queue/src/main/c/configure.ac
index a9fb7b1..23fa8c9 100644
--- a/zookeeper-recipes/zookeeper-recipes-queue/src/main/c/configure.ac
+++ b/zookeeper-recipes/zookeeper-recipes-queue/src/main/c/configure.ac
@@ -48,8 +48,8 @@ DX_PS_FEATURE(OFF)
 DX_INIT_DOXYGEN([zookeeper-queues],[c-doc.Doxyfile],[docs])
 
   
-ZOOKEEPER_PATH=${BUILD_PATH}/../../../../../src/c
-ZOOKEEPER_LD=-L${BUILD_PATH}/../../../../../src/c\ -lzookeeper_mt
+ZOOKEEPER_PATH=${BUILD_PATH}/../../../../zookeeper-client/zookeeper-client-c
+ZOOKEEPER_LD=-L${BUILD_PATH}/../../../../zookeeper-client/zookeeper-client-c\ -lzookeeper_mt
 
 AC_SUBST(ZOOKEEPER_PATH)
 AC_SUBST(ZOOKEEPER_LD)


[18/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/include/zookeeper.h
----------------------------------------------------------------------
diff --git a/src/c/include/zookeeper.h b/src/c/include/zookeeper.h
deleted file mode 100644
index aee865b..0000000
--- a/src/c/include/zookeeper.h
+++ /dev/null
@@ -1,1589 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ZOOKEEPER_H_
-#define ZOOKEEPER_H_
-
-#include <stdlib.h>
-
-/* we must not include config.h as a public header */
-#ifndef WIN32
-#include <sys/socket.h>
-#include <sys/time.h>
-#endif
-
-#ifdef WIN32
-#include <winsock2.h> /* must always be included before ws2tcpip.h */
-#include <ws2tcpip.h> /* for struct sock_addr and socklen_t */
-#endif
-
-#include <stdio.h>
-#include <ctype.h>
-
-#include "proto.h"
-#include "zookeeper_version.h"
-#include "recordio.h"
-#include "zookeeper.jute.h"
-
-/**
- * \file zookeeper.h 
- * \brief ZooKeeper functions and definitions.
- * 
- * ZooKeeper is a network service that may be backed by a cluster of
- * synchronized servers. The data in the service is represented as a tree
- * of data nodes. Each node has data, children, an ACL, and status information.
- * The data for a node is read and write in its entirety.
- * 
- * ZooKeeper clients can leave watches when they queries the data or children
- * of a node. If a watch is left, that client will be notified of the change.
- * The notification is a one time trigger. Subsequent chances to the node will
- * not trigger a notification unless the client issues a query with the watch
- * flag set. If the client is ever disconnected from the service, the watches do 
- * not need to be reset. The client automatically resets the watches.
- * 
- * When a node is created, it may be flagged as an ephemeral node. Ephemeral
- * nodes are automatically removed when a client session is closed or when
- * a session times out due to inactivity (the ZooKeeper runtime fills in
- * periods of inactivity with pings). Ephemeral nodes cannot have children.
- * 
- * ZooKeeper clients are identified by a server assigned session id. For
- * security reasons The server
- * also generates a corresponding password for a session. A client may save its
- * id and corresponding password to persistent storage in order to use the
- * session across program invocation boundaries.
- */
-
-/* Support for building on various platforms */
-
-// on cygwin we should take care of exporting/importing symbols properly 
-#ifdef DLL_EXPORT
-#    define ZOOAPI __declspec(dllexport)
-#else
-#  if (defined(__CYGWIN__) || defined(WIN32)) && !defined(USE_STATIC_LIB)
-#    define ZOOAPI __declspec(dllimport)
-#  else
-#    define ZOOAPI
-#  endif
-#endif
-
-/** zookeeper return constants **/
-
-enum ZOO_ERRORS {
-  ZOK = 0, /*!< Everything is OK */
-
-  /** System and server-side errors.
-   * This is never thrown by the server, it shouldn't be used other than
-   * to indicate a range. Specifically error codes greater than this
-   * value, but lesser than {@link #ZAPIERROR}, are system errors. */
-  ZSYSTEMERROR = -1,
-  ZRUNTIMEINCONSISTENCY = -2, /*!< A runtime inconsistency was found */
-  ZDATAINCONSISTENCY = -3, /*!< A data inconsistency was found */
-  ZCONNECTIONLOSS = -4, /*!< Connection to the server has been lost */
-  ZMARSHALLINGERROR = -5, /*!< Error while marshalling or unmarshalling data */
-  ZUNIMPLEMENTED = -6, /*!< Operation is unimplemented */
-  ZOPERATIONTIMEOUT = -7, /*!< Operation timeout */
-  ZBADARGUMENTS = -8, /*!< Invalid arguments */
-  ZINVALIDSTATE = -9, /*!< Invliad zhandle state */
-
-  /** API errors.
-   * This is never thrown by the server, it shouldn't be used other than
-   * to indicate a range. Specifically error codes greater than this
-   * value are API errors (while values less than this indicate a 
-   * {@link #ZSYSTEMERROR}).
-   */
-  ZAPIERROR = -100,
-  ZNONODE = -101, /*!< Node does not exist */
-  ZNOAUTH = -102, /*!< Not authenticated */
-  ZBADVERSION = -103, /*!< Version conflict */
-  ZNOCHILDRENFOREPHEMERALS = -108, /*!< Ephemeral nodes may not have children */
-  ZNODEEXISTS = -110, /*!< The node already exists */
-  ZNOTEMPTY = -111, /*!< The node has children */
-  ZSESSIONEXPIRED = -112, /*!< The session has been expired by the server */
-  ZINVALIDCALLBACK = -113, /*!< Invalid callback specified */
-  ZINVALIDACL = -114, /*!< Invalid ACL specified */
-  ZAUTHFAILED = -115, /*!< Client authentication failed */
-  ZCLOSING = -116, /*!< ZooKeeper is closing */
-  ZNOTHING = -117, /*!< (not error) no server responses to process */
-  ZSESSIONMOVED = -118 /*!<session moved to another server, so operation is ignored */ 
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
-*  @name Debug levels
-*/
-typedef enum {ZOO_LOG_LEVEL_ERROR=1,ZOO_LOG_LEVEL_WARN=2,ZOO_LOG_LEVEL_INFO=3,ZOO_LOG_LEVEL_DEBUG=4} ZooLogLevel;
-
-/**
- * @name ACL Consts
- */
-extern ZOOAPI const int ZOO_PERM_READ;
-extern ZOOAPI const int ZOO_PERM_WRITE;
-extern ZOOAPI const int ZOO_PERM_CREATE;
-extern ZOOAPI const int ZOO_PERM_DELETE;
-extern ZOOAPI const int ZOO_PERM_ADMIN;
-extern ZOOAPI const int ZOO_PERM_ALL;
-
-/** This Id represents anyone. */
-extern ZOOAPI struct Id ZOO_ANYONE_ID_UNSAFE;
-/** This Id is only usable to set ACLs. It will get substituted with the
- * Id's the client authenticated with.
- */
-extern ZOOAPI struct Id ZOO_AUTH_IDS;
-
-/** This is a completely open ACL*/
-extern ZOOAPI struct ACL_vector ZOO_OPEN_ACL_UNSAFE;
-/** This ACL gives the world the ability to read. */
-extern ZOOAPI struct ACL_vector ZOO_READ_ACL_UNSAFE;
-/** This ACL gives the creators authentication id's all permissions. */
-extern ZOOAPI struct ACL_vector ZOO_CREATOR_ALL_ACL;
-
-/**
- * @name Interest Consts
- * These constants are used to express interest in an event and to
- * indicate to zookeeper which events have occurred. They can
- * be ORed together to express multiple interests. These flags are
- * used in the interest and event parameters of 
- * \ref zookeeper_interest and \ref zookeeper_process.
- */
-// @{
-extern ZOOAPI const int ZOOKEEPER_WRITE;
-extern ZOOAPI const int ZOOKEEPER_READ;
-// @}
-
-/**
- * @name Create Flags
- * 
- * These flags are used by zoo_create to affect node create. They may
- * be ORed together to combine effects.
- */
-// @{
-extern ZOOAPI const int ZOO_EPHEMERAL;
-extern ZOOAPI const int ZOO_SEQUENCE;
-// @}
-
-/**
- * @name State Consts
- * These constants represent the states of a zookeeper connection. They are
- * possible parameters of the watcher callback.
- */
-// @{
-extern ZOOAPI const int ZOO_EXPIRED_SESSION_STATE;
-extern ZOOAPI const int ZOO_AUTH_FAILED_STATE;
-extern ZOOAPI const int ZOO_CONNECTING_STATE;
-extern ZOOAPI const int ZOO_ASSOCIATING_STATE;
-extern ZOOAPI const int ZOO_CONNECTED_STATE;
-// @}
-
-/**
- * @name Watch Types
- * These constants indicate the event that caused the watch event. They are
- * possible values of the first parameter of the watcher callback.
- */
-// @{
-/**
- * \brief a node has been created.
- * 
- * This is only generated by watches on non-existent nodes. These watches
- * are set using \ref zoo_exists.
- */
-extern ZOOAPI const int ZOO_CREATED_EVENT;
-/**
- * \brief a node has been deleted.
- * 
- * This is only generated by watches on nodes. These watches
- * are set using \ref zoo_exists and \ref zoo_get.
- */
-extern ZOOAPI const int ZOO_DELETED_EVENT;
-/**
- * \brief a node has changed.
- * 
- * This is only generated by watches on nodes. These watches
- * are set using \ref zoo_exists and \ref zoo_get.
- */
-extern ZOOAPI const int ZOO_CHANGED_EVENT;
-/**
- * \brief a change as occurred in the list of children.
- * 
- * This is only generated by watches on the child list of a node. These watches
- * are set using \ref zoo_get_children or \ref zoo_get_children2.
- */
-extern ZOOAPI const int ZOO_CHILD_EVENT;
-/**
- * \brief a session has been lost.
- * 
- * This is generated when a client loses contact or reconnects with a server.
- */
-extern ZOOAPI const int ZOO_SESSION_EVENT;
-
-/**
- * \brief a watch has been removed.
- * 
- * This is generated when the server for some reason, probably a resource
- * constraint, will no longer watch a node for a client.
- */
-extern ZOOAPI const int ZOO_NOTWATCHING_EVENT;
-// @}
-
-/**
- * \brief ZooKeeper handle.
- * 
- * This is the handle that represents a connection to the ZooKeeper service.
- * It is needed to invoke any ZooKeeper function. A handle is obtained using
- * \ref zookeeper_init.
- */
-typedef struct _zhandle zhandle_t;
-
-/**
- * \brief client id structure.
- * 
- * This structure holds the id and password for the session. This structure
- * should be treated as opaque. It is received from the server when a session
- * is established and needs to be sent back as-is when reconnecting a session.
- */
-typedef struct {
-    int64_t client_id;
-    char passwd[16];
-} clientid_t;
-
-/**
- * \brief zoo_op structure.
- *
- * This structure holds all the arguments necessary for one op as part
- * of a containing multi_op via \ref zoo_multi or \ref zoo_amulti.
- * This structure should be treated as opaque and initialized via 
- * \ref zoo_create_op_init, \ref zoo_delete_op_init, \ref zoo_set_op_init
- * and \ref zoo_check_op_init.
- */
-typedef struct zoo_op {
-    int type;
-    union {
-        // CREATE
-        struct {
-            const char *path;
-            const char *data;
-            int datalen;
-	        char *buf;
-            int buflen;
-            const struct ACL_vector *acl;
-            int flags;
-        } create_op;
-
-        // DELETE 
-        struct {
-            const char *path;
-            int version;
-        } delete_op;
-        
-        // SET
-        struct {
-            const char *path;
-            const char *data;
-            int datalen;
-            int version;
-            struct Stat *stat;
-        } set_op;
-        
-        // CHECK
-        struct {
-            const char *path;
-            int version;
-        } check_op;
-    };
-} zoo_op_t;
-
-/**
- * \brief zoo_create_op_init.
- *
- * This function initializes a zoo_op_t with the arguments for a ZOO_CREATE_OP.
- *
- * \param op A pointer to the zoo_op_t to be initialized.
- * \param path The name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param value The data to be stored in the node.
- * \param valuelen The number of bytes in data. To set the data to be NULL use
- * value as NULL and valuelen as -1.
- * \param acl The initial ACL of the node. The ACL must not be null or empty.
- * \param flags this parameter can be set to 0 for normal create or an OR
- *    of the Create Flags
- * \param path_buffer Buffer which will be filled with the path of the
- *    new node (this might be different than the supplied path
- *    because of the ZOO_SEQUENCE flag).  The path string will always be
- *    null-terminated. This parameter may be NULL if path_buffer_len = 0.
- * \param path_buffer_len Size of path buffer; if the path of the new
- *    node (including space for the null terminator) exceeds the buffer size,
- *    the path string will be truncated to fit.  The actual path of the
- *    new node in the server will not be affected by the truncation.
- *    The path string will always be null-terminated.
- */
-void zoo_create_op_init(zoo_op_t *op, const char *path, const char *value,
-        int valuelen,  const struct ACL_vector *acl, int flags, 
-        char *path_buffer, int path_buffer_len);
-
-/**
- * \brief zoo_delete_op_init.
- *
- * This function initializes a zoo_op_t with the arguments for a ZOO_DELETE_OP.
- *
- * \param op A pointer to the zoo_op_t to be initialized.
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param version the expected version of the node. The function will fail if the
- *    actual version of the node does not match the expected version.
- *  If -1 is used the version check will not take place. 
- */
-void zoo_delete_op_init(zoo_op_t *op, const char *path, int version);
-
-/**
- * \brief zoo_set_op_init.
- *
- * This function initializes an zoo_op_t with the arguments for a ZOO_SETDATA_OP.
- *
- * \param op A pointer to the zoo_op_t to be initialized.
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param buffer the buffer holding data to be written to the node.
- * \param buflen the number of bytes from buffer to write. To set NULL as data 
- * use buffer as NULL and buflen as -1.
- * \param version the expected version of the node. The function will fail if 
- * the actual version of the node does not match the expected version. If -1 is 
- * used the version check will not take place. 
- */
-void zoo_set_op_init(zoo_op_t *op, const char *path, const char *buffer, 
-        int buflen, int version, struct Stat *stat);
-
-/**
- * \brief zoo_check_op_init.
- *
- * This function initializes an zoo_op_t with the arguments for a ZOO_CHECK_OP.
- *
- * \param op A pointer to the zoo_op_t to be initialized.
- * \param path The name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param version the expected version of the node. The function will fail if the
- *    actual version of the node does not match the expected version.
- */
-void zoo_check_op_init(zoo_op_t *op, const char *path, int version);
-
-/**
- * \brief zoo_op_result structure.
- *
- * This structure holds the result for an op submitted as part of a multi_op
- * via \ref zoo_multi or \ref zoo_amulti.
- */
-typedef struct zoo_op_result {
-    int err;
-    char *value;
-	int valuelen;
-    struct Stat *stat;
-} zoo_op_result_t; 
-
-/**
- * \brief signature of a watch function.
- * 
- * There are two ways to receive watch notifications: legacy and watcher object.
- * <p>
- * The legacy style, an application wishing to receive events from ZooKeeper must 
- * first implement a function with this signature and pass a pointer to the function 
- * to \ref zookeeper_init. Next, the application sets a watch by calling one of 
- * the getter API that accept the watch integer flag (for example, \ref zoo_aexists, 
- * \ref zoo_get, etc).
- * <p>
- * The watcher object style uses an instance of a "watcher object" which in 
- * the C world is represented by a pair: a pointer to a function implementing this
- * signature and a pointer to watcher context -- handback user-specific data. 
- * When a watch is triggered this function will be called along with 
- * the watcher context. An application wishing to use this style must use
- * the getter API functions with the "w" prefix in their names (for example, \ref
- * zoo_awexists, \ref zoo_wget, etc).
- * 
- * \param zh zookeeper handle
- * \param type event type. This is one of the *_EVENT constants. 
- * \param state connection state. The state value will be one of the *_STATE constants.
- * \param path znode path for which the watcher is triggered. NULL if the event 
- * type is ZOO_SESSION_EVENT
- * \param watcherCtx watcher context.
- */
-typedef void (*watcher_fn)(zhandle_t *zh, int type, 
-        int state, const char *path,void *watcherCtx);
-
-/**
- * \brief create a handle to used communicate with zookeeper.
- * 
- * This method creates a new handle and a zookeeper session that corresponds
- * to that handle. Session establishment is asynchronous, meaning that the
- * session should not be considered established until (and unless) an
- * event of state ZOO_CONNECTED_STATE is received.
- * \param host comma separated host:port pairs, each corresponding to a zk
- *   server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"
- * \param fn the global watcher callback function. When notifications are
- *   triggered this function will be invoked.
- * \param clientid the id of a previously established session that this
- *   client will be reconnecting to. Pass 0 if not reconnecting to a previous
- *   session. Clients can access the session id of an established, valid,
- *   connection by calling \ref zoo_client_id. If the session corresponding to
- *   the specified clientid has expired, or if the clientid is invalid for 
- *   any reason, the returned zhandle_t will be invalid -- the zhandle_t 
- *   state will indicate the reason for failure (typically
- *   ZOO_EXPIRED_SESSION_STATE).
- * \param context the handback object that will be associated with this instance 
- *   of zhandle_t. Application can access it (for example, in the watcher 
- *   callback) using \ref zoo_get_context. The object is not used by zookeeper 
- *   internally and can be null.
- * \param flags reserved for future use. Should be set to zero.
- * \return a pointer to the opaque zhandle structure. If it fails to create 
- * a new zhandle the function returns NULL and the errno variable 
- * indicates the reason.
- */
-ZOOAPI zhandle_t *zookeeper_init(const char *host, watcher_fn fn,
-  int recv_timeout, const clientid_t *clientid, void *context, int flags);
-
-/**
- * \brief close the zookeeper handle and free up any resources.
- * 
- * After this call, the client session will no longer be valid. The function
- * will flush any outstanding send requests before return. As a result it may 
- * block.
- *
- * This method should only be called only once on a zookeeper handle. Calling
- * twice will cause undefined (and probably undesirable behavior). Calling any other
- * zookeeper method after calling close is undefined behaviour and should be avoided.
- *
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \return a result code. Regardless of the error code returned, the zhandle 
- * will be destroyed and all resources freed. 
- *
- * ZOK - success
- * ZBADARGUMENTS - invalid input parameters
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- * ZOPERATIONTIMEOUT - failed to flush the buffers within the specified timeout.
- * ZCONNECTIONLOSS - a network error occurred while attempting to send request to server
- * ZSYSTEMERROR -- a system (OS) error occurred; it's worth checking errno to get details
- */
-ZOOAPI int zookeeper_close(zhandle_t *zh);
-
-/**
- * \brief return the client session id, only valid if the connections
- * is currently connected (ie. last watcher state is ZOO_CONNECTED_STATE)
- */
-ZOOAPI const clientid_t *zoo_client_id(zhandle_t *zh);
-
-/**
- * \brief return the timeout for this session, only valid if the connections
- * is currently connected (ie. last watcher state is ZOO_CONNECTED_STATE). This
- * value may change after a server re-connect.
- */
-ZOOAPI int zoo_recv_timeout(zhandle_t *zh);
-
-/**
- * \brief return the context for this handle.
- */
-ZOOAPI const void *zoo_get_context(zhandle_t *zh);
-
-/**
- * \brief set the context for this handle.
- */
-ZOOAPI void zoo_set_context(zhandle_t *zh, void *context);
-
-/**
- * \brief set a watcher function
- * \return previous watcher function
- */
-ZOOAPI watcher_fn zoo_set_watcher(zhandle_t *zh,watcher_fn newFn);
-
-/**
- * \brief returns the socket address for the current connection
- * \return socket address of the connected host or NULL on failure, only valid if the
- * connection is current connected
- */
-ZOOAPI struct sockaddr* zookeeper_get_connected_host(zhandle_t *zh,
-        struct sockaddr *addr, socklen_t *addr_len);
-
-#ifndef THREADED
-/**
- * \brief Returns the events that zookeeper is interested in.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param fd is the file descriptor of interest
- * \param interest is an or of the ZOOKEEPER_WRITE and ZOOKEEPER_READ flags to
- *    indicate the I/O of interest on fd.
- * \param tv a timeout value to be used with select/poll system call
- * \return a result code.
- * ZOK - success
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZCONNECTIONLOSS - a network error occurred while attempting to establish 
- * a connection to the server
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- * ZOPERATIONTIMEOUT - hasn't received anything from the server for 2/3 of the
- * timeout value specified in zookeeper_init()
- * ZSYSTEMERROR -- a system (OS) error occurred; it's worth checking errno to get details
- */
-#ifdef WIN32
-ZOOAPI int zookeeper_interest(zhandle_t *zh, SOCKET *fd, int *interest, 
-	struct timeval *tv);
-#else
-ZOOAPI int zookeeper_interest(zhandle_t *zh, int *fd, int *interest, 
-	struct timeval *tv);
-#endif
-
-/**
- * \brief Notifies zookeeper that an event of interest has happened.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param events will be an OR of the ZOOKEEPER_WRITE and ZOOKEEPER_READ flags.
- * \return a result code. 
- * ZOK - success
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZCONNECTIONLOSS - a network error occurred while attempting to send request to server
- * ZSESSIONEXPIRED - connection attempt failed -- the session's expired
- * ZAUTHFAILED - authentication request failed, e.i. invalid credentials
- * ZRUNTIMEINCONSISTENCY - a server response came out of order
- * ZSYSTEMERROR -- a system (OS) error occurred; it's worth checking errno to get details
- * ZNOTHING -- not an error; simply indicates that there no more data from the server 
- *              to be processed (when called with ZOOKEEPER_READ flag).
- */
-ZOOAPI int zookeeper_process(zhandle_t *zh, int events);
-#endif
-
-/**
- * \brief signature of a completion function for a call that returns void.
- * 
- * This method will be invoked at the end of a asynchronous call and also as 
- * a result of connection loss or timeout.
- * \param rc the error code of the call. Connection loss/timeout triggers 
- * the completion with one of the following error codes:
- * ZCONNECTIONLOSS -- lost connection to the server
- * ZOPERATIONTIMEOUT -- connection timed out
- * Data related events trigger the completion with error codes listed the 
- * Exceptions section of the documentation of the function that initiated the
- * call. (Zero indicates call was successful.)
- * \param data the pointer that was passed by the caller when the function
- *   that this completion corresponds to was invoked. The programmer
- *   is responsible for any memory freeing associated with the data
- *   pointer.
- */
-typedef void (*void_completion_t)(int rc, const void *data);
-
-/**
- * \brief signature of a completion function that returns a Stat structure.
- * 
- * This method will be invoked at the end of a asynchronous call and also as 
- * a result of connection loss or timeout.
- * \param rc the error code of the call. Connection loss/timeout triggers 
- * the completion with one of the following error codes:
- * ZCONNECTIONLOSS -- lost connection to the server
- * ZOPERATIONTIMEOUT -- connection timed out
- * Data related events trigger the completion with error codes listed the 
- * Exceptions section of the documentation of the function that initiated the
- * call. (Zero indicates call was successful.)
- * \param stat a pointer to the stat information for the node involved in
- *   this function. If a non zero error code is returned, the content of
- *   stat is undefined. The programmer is NOT responsible for freeing stat.
- * \param data the pointer that was passed by the caller when the function
- *   that this completion corresponds to was invoked. The programmer
- *   is responsible for any memory freeing associated with the data
- *   pointer.
- */
-typedef void (*stat_completion_t)(int rc, const struct Stat *stat,
-        const void *data);
-
-/**
- * \brief signature of a completion function that returns data.
- * 
- * This method will be invoked at the end of a asynchronous call and also as 
- * a result of connection loss or timeout.
- * \param rc the error code of the call. Connection loss/timeout triggers 
- * the completion with one of the following error codes:
- * ZCONNECTIONLOSS -- lost connection to the server
- * ZOPERATIONTIMEOUT -- connection timed out
- * Data related events trigger the completion with error codes listed the 
- * Exceptions section of the documentation of the function that initiated the
- * call. (Zero indicates call was successful.)
- * \param value the value of the information returned by the asynchronous call.
- *   If a non zero error code is returned, the content of value is undefined.
- *   The programmer is NOT responsible for freeing value.
- * \param value_len the number of bytes in value.
- * \param stat a pointer to the stat information for the node involved in
- *   this function. If a non zero error code is returned, the content of
- *   stat is undefined. The programmer is NOT responsible for freeing stat.
- * \param data the pointer that was passed by the caller when the function
- *   that this completion corresponds to was invoked. The programmer
- *   is responsible for any memory freeing associated with the data
- *   pointer.
- */
-typedef void (*data_completion_t)(int rc, const char *value, int value_len,
-        const struct Stat *stat, const void *data);
-
-/**
- * \brief signature of a completion function that returns a list of strings.
- * 
- * This method will be invoked at the end of a asynchronous call and also as 
- * a result of connection loss or timeout.
- * \param rc the error code of the call. Connection loss/timeout triggers 
- * the completion with one of the following error codes:
- * ZCONNECTIONLOSS -- lost connection to the server
- * ZOPERATIONTIMEOUT -- connection timed out
- * Data related events trigger the completion with error codes listed the 
- * Exceptions section of the documentation of the function that initiated the
- * call. (Zero indicates call was successful.)
- * \param strings a pointer to the structure containng the list of strings of the
- *   names of the children of a node. If a non zero error code is returned,
- *   the content of strings is undefined. The programmer is NOT responsible
- *   for freeing strings.
- * \param data the pointer that was passed by the caller when the function
- *   that this completion corresponds to was invoked. The programmer
- *   is responsible for any memory freeing associated with the data
- *   pointer.
- */
-typedef void (*strings_completion_t)(int rc,
-        const struct String_vector *strings, const void *data);
-
-/**
- * \brief signature of a completion function that returns a list of strings and stat.
- * .
- * 
- * This method will be invoked at the end of a asynchronous call and also as 
- * a result of connection loss or timeout.
- * \param rc the error code of the call. Connection loss/timeout triggers 
- * the completion with one of the following error codes:
- * ZCONNECTIONLOSS -- lost connection to the server
- * ZOPERATIONTIMEOUT -- connection timed out
- * Data related events trigger the completion with error codes listed the 
- * Exceptions section of the documentation of the function that initiated the
- * call. (Zero indicates call was successful.)
- * \param strings a pointer to the structure containng the list of strings of the
- *   names of the children of a node. If a non zero error code is returned,
- *   the content of strings is undefined. The programmer is NOT responsible
- *   for freeing strings.
- * \param stat a pointer to the stat information for the node involved in
- *   this function. If a non zero error code is returned, the content of
- *   stat is undefined. The programmer is NOT responsible for freeing stat.
- * \param data the pointer that was passed by the caller when the function
- *   that this completion corresponds to was invoked. The programmer
- *   is responsible for any memory freeing associated with the data
- *   pointer.
- */
-typedef void (*strings_stat_completion_t)(int rc,
-        const struct String_vector *strings, const struct Stat *stat,
-        const void *data);
-
-/**
- * \brief signature of a completion function that returns a list of strings.
- * 
- * This method will be invoked at the end of a asynchronous call and also as 
- * a result of connection loss or timeout.
- * \param rc the error code of the call. Connection loss/timeout triggers 
- * the completion with one of the following error codes:
- * ZCONNECTIONLOSS -- lost connection to the server
- * ZOPERATIONTIMEOUT -- connection timed out
- * Data related events trigger the completion with error codes listed the 
- * Exceptions section of the documentation of the function that initiated the
- * call. (Zero indicates call was successful.)
- * \param value the value of the string returned.
- * \param data the pointer that was passed by the caller when the function
- *   that this completion corresponds to was invoked. The programmer
- *   is responsible for any memory freeing associated with the data
- *   pointer.
- */
-typedef void
-        (*string_completion_t)(int rc, const char *value, const void *data);
-
-/**
- * \brief signature of a completion function that returns an ACL.
- * 
- * This method will be invoked at the end of a asynchronous call and also as 
- * a result of connection loss or timeout.
- * \param rc the error code of the call. Connection loss/timeout triggers 
- * the completion with one of the following error codes:
- * ZCONNECTIONLOSS -- lost connection to the server
- * ZOPERATIONTIMEOUT -- connection timed out
- * Data related events trigger the completion with error codes listed the 
- * Exceptions section of the documentation of the function that initiated the
- * call. (Zero indicates call was successful.)
- * \param acl a pointer to the structure containng the ACL of a node. If a non 
- *   zero error code is returned, the content of strings is undefined. The
- *   programmer is NOT responsible for freeing acl.
- * \param stat a pointer to the stat information for the node involved in
- *   this function. If a non zero error code is returned, the content of
- *   stat is undefined. The programmer is NOT responsible for freeing stat.
- * \param data the pointer that was passed by the caller when the function
- *   that this completion corresponds to was invoked. The programmer
- *   is responsible for any memory freeing associated with the data
- *   pointer.
- */
-typedef void (*acl_completion_t)(int rc, struct ACL_vector *acl,
-        struct Stat *stat, const void *data);
-
-/**
- * \brief get the state of the zookeeper connection.
- * 
- * The return value will be one of the \ref State Consts.
- */
-ZOOAPI int zoo_state(zhandle_t *zh);
-
-/**
- * \brief create a node.
- * 
- * This method will create a node in ZooKeeper. A node can only be created if
- * it does not already exists. The Create Flags affect the creation of nodes.
- * If ZOO_EPHEMERAL flag is set, the node will automatically get removed if the
- * client session goes away. If the ZOO_SEQUENCE flag is set, a unique
- * monotonically increasing sequence number is appended to the path name. The
- * sequence number is always fixed length of 10 digits, 0 padded.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path The name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param value The data to be stored in the node.
- * \param valuelen The number of bytes in data.
- * \param acl The initial ACL of the node. The ACL must not be null or empty.
- * \param flags this parameter can be set to 0 for normal create or an OR
- *    of the Create Flags
- * \param completion the routine to invoke when the request completes. The completion
- * will be triggered with one of the following codes passed in as the rc argument:
- * ZOK operation completed successfully
- * ZNONODE the parent node does not exist.
- * ZNODEEXISTS the node already exists
- * ZNOAUTH the client does not have permission.
- * ZNOCHILDRENFOREPHEMERALS cannot create children of ephemeral nodes.
- * \param data The data that will be passed to the completion routine when the 
- * function completes.
- * \return ZOK on success or one of the following errcodes on failure:
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_acreate(zhandle_t *zh, const char *path, const char *value, 
-        int valuelen, const struct ACL_vector *acl, int flags,
-        string_completion_t completion, const void *data);
-
-/**
- * \brief delete a node in zookeeper.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param version the expected version of the node. The function will fail if the
- *    actual version of the node does not match the expected version.
- *  If -1 is used the version check will not take place. 
- * \param completion the routine to invoke when the request completes. The completion
- * will be triggered with one of the following codes passed in as the rc argument:
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * ZBADVERSION expected version does not match actual version.
- * ZNOTEMPTY children are present; node cannot be deleted.
- * \param data the data that will be passed to the completion routine when 
- * the function completes.
- * \return ZOK on success or one of the following errcodes on failure:
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_adelete(zhandle_t *zh, const char *path, int version, 
-        void_completion_t completion, const void *data);
-
-/**
- * \brief checks the existence of a node in zookeeper.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param watch if nonzero, a watch will be set at the server to notify the 
- * client if the node changes. The watch will be set even if the node does not 
- * exist. This allows clients to watch for nodes to appear.
- * \param completion the routine to invoke when the request completes. The completion
- * will be triggered with one of the following codes passed in as the rc argument:
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when the 
- * function completes.
- * \return ZOK on success or one of the following errcodes on failure:
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_aexists(zhandle_t *zh, const char *path, int watch, 
-        stat_completion_t completion, const void *data);
-
-/**
- * \brief checks the existence of a node in zookeeper.
- * 
- * This function is similar to \ref zoo_axists except it allows one specify 
- * a watcher object - a function pointer and associated context. The function
- * will be called once the watch has fired. The associated context data will be 
- * passed to the function as the watcher context parameter. 
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param watcher if non-null a watch will set on the specified znode on the server.
- * The watch will be set even if the node does not exist. This allows clients 
- * to watch for nodes to appear.
- * \param watcherCtx user specific data, will be passed to the watcher callback.
- * Unlike the global context set by \ref zookeeper_init, this watcher context
- * is associated with the given instance of the watcher only.
- * \param completion the routine to invoke when the request completes. The completion
- * will be triggered with one of the following codes passed in as the rc argument:
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when the 
- * function completes.
- * \return ZOK on success or one of the following errcodes on failure:
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_awexists(zhandle_t *zh, const char *path, 
-        watcher_fn watcher, void* watcherCtx, 
-        stat_completion_t completion, const void *data);
-
-/**
- * \brief gets the data associated with a node.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param watch if nonzero, a watch will be set at the server to notify 
- * the client if the node changes.
- * \param completion the routine to invoke when the request completes. The completion
- * will be triggered with one of the following codes passed in as the rc argument:
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when 
- * the function completes.
- * \return ZOK on success or one of the following errcodes on failure:
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_aget(zhandle_t *zh, const char *path, int watch, 
-        data_completion_t completion, const void *data);
-
-/**
- * \brief gets the data associated with a node.
- * 
- * This function is similar to \ref zoo_aget except it allows one specify 
- * a watcher object rather than a boolean watch flag. 
- *
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param watcher if non-null, a watch will be set at the server to notify 
- * the client if the node changes.
- * \param watcherCtx user specific data, will be passed to the watcher callback.
- * Unlike the global context set by \ref zookeeper_init, this watcher context
- * is associated with the given instance of the watcher only.
- * \param completion the routine to invoke when the request completes. The completion
- * will be triggered with one of the following codes passed in as the rc argument:
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when 
- * the function completes.
- * \return ZOK on success or one of the following errcodes on failure:
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_awget(zhandle_t *zh, const char *path, 
-        watcher_fn watcher, void* watcherCtx, 
-        data_completion_t completion, const void *data);
-
-/**
- * \brief sets the data associated with a node.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param buffer the buffer holding data to be written to the node.
- * \param buflen the number of bytes from buffer to write.
- * \param version the expected version of the node. The function will fail if 
- * the actual version of the node does not match the expected version. If -1 is 
- * used the version check will not take place. * completion: If null, 
- * the function will execute synchronously. Otherwise, the function will return 
- * immediately and invoke the completion routine when the request completes.
- * \param completion the routine to invoke when the request completes. The completion
- * will be triggered with one of the following codes passed in as the rc argument:
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * ZBADVERSION expected version does not match actual version.
- * \param data the data that will be passed to the completion routine when 
- * the function completes.
- * \return ZOK on success or one of the following errcodes on failure:
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_aset(zhandle_t *zh, const char *path, const char *buffer, int buflen, 
-        int version, stat_completion_t completion, const void *data);
-
-/**
- * \brief lists the children of a node.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param watch if nonzero, a watch will be set at the server to notify 
- * the client if the node changes.
- * \param completion the routine to invoke when the request completes. The completion
- * will be triggered with one of the following codes passed in as the rc argument:
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when 
- * the function completes.
- * \return ZOK on success or one of the following errcodes on failure:
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_aget_children(zhandle_t *zh, const char *path, int watch, 
-        strings_completion_t completion, const void *data);
-
-/**
- * \brief lists the children of a node.
- * 
- * This function is similar to \ref zoo_aget_children except it allows one specify 
- * a watcher object rather than a boolean watch flag.
- *  
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param watcher if non-null, a watch will be set at the server to notify 
- * the client if the node changes.
- * \param watcherCtx user specific data, will be passed to the watcher callback.
- * Unlike the global context set by \ref zookeeper_init, this watcher context
- * is associated with the given instance of the watcher only.
- * \param completion the routine to invoke when the request completes. The completion
- * will be triggered with one of the following codes passed in as the rc argument:
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when 
- * the function completes.
- * \return ZOK on success or one of the following errcodes on failure:
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_awget_children(zhandle_t *zh, const char *path,
-        watcher_fn watcher, void* watcherCtx, 
-        strings_completion_t completion, const void *data);
-
-/**
- * \brief lists the children of a node, and get the parent stat.
- * 
- * This function is new in version 3.3.0
- *
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param watch if nonzero, a watch will be set at the server to notify 
- * the client if the node changes.
- * \param completion the routine to invoke when the request completes. The completion
- * will be triggered with one of the following codes passed in as the rc argument:
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when 
- * the function completes.
- * \return ZOK on success or one of the following errcodes on failure:
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_aget_children2(zhandle_t *zh, const char *path, int watch, 
-        strings_stat_completion_t completion, const void *data);
-
-/**
- * \brief lists the children of a node, and get the parent stat.
- * 
- * This function is similar to \ref zoo_aget_children2 except it allows one specify 
- * a watcher object rather than a boolean watch flag.
- *  
- * This function is new in version 3.3.0
- *
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param watcher if non-null, a watch will be set at the server to notify 
- * the client if the node changes.
- * \param watcherCtx user specific data, will be passed to the watcher callback.
- * Unlike the global context set by \ref zookeeper_init, this watcher context
- * is associated with the given instance of the watcher only.
- * \param completion the routine to invoke when the request completes. The completion
- * will be triggered with one of the following codes passed in as the rc argument:
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when 
- * the function completes.
- * \return ZOK on success or one of the following errcodes on failure:
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_awget_children2(zhandle_t *zh, const char *path,
-        watcher_fn watcher, void* watcherCtx, 
-        strings_stat_completion_t completion, const void *data);
-
-/**
- * \brief Flush leader channel.
- *
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes
- * separating ancestors of the node.
- * \param completion the routine to invoke when the request completes. The completion
- * will be triggered with one of the following codes passed in as the rc argument:
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when
- * the function completes.
- * \return ZOK on success or one of the following errcodes on failure:
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-
-ZOOAPI int zoo_async(zhandle_t *zh, const char *path, 
-        string_completion_t completion, const void *data);
-
-
-/**
- * \brief gets the acl associated with a node.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param completion the routine to invoke when the request completes. The completion
- * will be triggered with one of the following codes passed in as the rc argument:
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * \param data the data that will be passed to the completion routine when 
- * the function completes.
- * \return ZOK on success or one of the following errcodes on failure:
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_aget_acl(zhandle_t *zh, const char *path, acl_completion_t completion, 
-        const void *data);
-
-/**
- * \brief sets the acl associated with a node.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param buffer the buffer holding the acls to be written to the node.
- * \param buflen the number of bytes from buffer to write.
- * \param completion the routine to invoke when the request completes. The completion
- * will be triggered with one of the following codes passed in as the rc argument:
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * ZINVALIDACL invalid ACL specified
- * ZBADVERSION expected version does not match actual version.
- * \param data the data that will be passed to the completion routine when 
- * the function completes.
- * \return ZOK on success or one of the following errcodes on failure:
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_aset_acl(zhandle_t *zh, const char *path, int version, 
-        struct ACL_vector *acl, void_completion_t, const void *data);
-
-/**
- * \brief atomically commits multiple zookeeper operations.
- *
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param count the number of operations
- * \param ops an array of operations to commit
- * \param results an array to hold the results of the operations
- * \param completion the routine to invoke when the request completes. The completion
- * will be triggered with any of the error codes that can that can be returned by the 
- * ops supported by a multi op (see \ref zoo_acreate, \ref zoo_adelete, \ref zoo_aset).
- * \param data the data that will be passed to the completion routine when
- * the function completes.
- * \return the return code for the function call. This can be any of the
- * values that can be returned by the ops supported by a multi op (see
- * \ref zoo_acreate, \ref zoo_adelete, \ref zoo_aset).
- */
-ZOOAPI int zoo_amulti(zhandle_t *zh, int count, const zoo_op_t *ops, 
-        zoo_op_result_t *results, void_completion_t, const void *data);
-
-/**
- * \brief return an error string.
- * 
- * \param return code
- * \return string corresponding to the return code
- */
-ZOOAPI const char* zerror(int c);
-
-/**
- * \brief specify application credentials.
- * 
- * The application calls this function to specify its credentials for purposes
- * of authentication. The server will use the security provider specified by 
- * the scheme parameter to authenticate the client connection. If the 
- * authentication request has failed:
- * - the server connection is dropped
- * - the watcher is called with the ZOO_AUTH_FAILED_STATE value as the state 
- * parameter.
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param scheme the id of authentication scheme. Natively supported:
- * "digest" password-based authentication
- * \param cert application credentials. The actual value depends on the scheme.
- * \param certLen the length of the data parameter
- * \param completion the routine to invoke when the request completes. One of 
- * the following result codes may be passed into the completion callback:
- * ZOK operation completed successfully
- * ZAUTHFAILED authentication failed 
- * \param data the data that will be passed to the completion routine when the 
- * function completes.
- * \return ZOK on success or one of the following errcodes on failure:
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- * ZSYSTEMERROR - a system error occurred
- */
-ZOOAPI int zoo_add_auth(zhandle_t *zh,const char* scheme,const char* cert, 
-	int certLen, void_completion_t completion, const void *data);
-
-/**
- * \brief checks if the current zookeeper connection state can't be recovered.
- * 
- *  The application must close the zhandle and try to reconnect.
- * 
- * \param zh the zookeeper handle (see \ref zookeeper_init)
- * \return ZINVALIDSTATE if connection is unrecoverable
- */
-ZOOAPI int is_unrecoverable(zhandle_t *zh);
-
-/**
- * \brief sets the debugging level for the library 
- */
-ZOOAPI void zoo_set_debug_level(ZooLogLevel logLevel);
-
-/**
- * \brief sets the stream to be used by the library for logging 
- * 
- * The zookeeper library uses stderr as its default log stream. Application
- * must make sure the stream is writable. Passing in NULL resets the stream 
- * to its default value (stderr).
- */
-ZOOAPI void zoo_set_log_stream(FILE* logStream);
-
-/**
- * \brief enable/disable quorum endpoint order randomization
- * 
- * Note: typically this method should NOT be used outside of testing.
- *
- * If passed a non-zero value, will make the client connect to quorum peers
- * in the order as specified in the zookeeper_init() call.
- * A zero value causes zookeeper_init() to permute the peer endpoints
- * which is good for more even client connection distribution among the 
- * quorum peers.
- */
-ZOOAPI void zoo_deterministic_conn_order(int yesOrNo);
-
-/**
- * \brief create a node synchronously.
- * 
- * This method will create a node in ZooKeeper. A node can only be created if
- * it does not already exists. The Create Flags affect the creation of nodes.
- * If ZOO_EPHEMERAL flag is set, the node will automatically get removed if the
- * client session goes away. If the ZOO_SEQUENCE flag is set, a unique
- * monotonically increasing sequence number is appended to the path name.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path The name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param value The data to be stored in the node.
- * \param valuelen The number of bytes in data. To set the data to be NULL use
- * value as NULL and valuelen as -1.
- * \param acl The initial ACL of the node. The ACL must not be null or empty.
- * \param flags this parameter can be set to 0 for normal create or an OR
- *    of the Create Flags
- * \param path_buffer Buffer which will be filled with the path of the
- *    new node (this might be different than the supplied path
- *    because of the ZOO_SEQUENCE flag).  The path string will always be
- *    null-terminated. This parameter may be NULL if path_buffer_len = 0.
- * \param path_buffer_len Size of path buffer; if the path of the new
- *    node (including space for the null terminator) exceeds the buffer size,
- *    the path string will be truncated to fit.  The actual path of the
- *    new node in the server will not be affected by the truncation.
- *    The path string will always be null-terminated.
- * \return  one of the following codes are returned:
- * ZOK operation completed successfully
- * ZNONODE the parent node does not exist.
- * ZNODEEXISTS the node already exists
- * ZNOAUTH the client does not have permission.
- * ZNOCHILDRENFOREPHEMERALS cannot create children of ephemeral nodes.
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_create(zhandle_t *zh, const char *path, const char *value,
-        int valuelen, const struct ACL_vector *acl, int flags,
-        char *path_buffer, int path_buffer_len);
-
-/**
- * \brief delete a node in zookeeper synchronously.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param version the expected version of the node. The function will fail if the
- *    actual version of the node does not match the expected version.
- *  If -1 is used the version check will not take place. 
- * \return one of the following values is returned.
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * ZBADVERSION expected version does not match actual version.
- * ZNOTEMPTY children are present; node cannot be deleted.
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_delete(zhandle_t *zh, const char *path, int version);
-
-
-/**
- * \brief checks the existence of a node in zookeeper synchronously.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param watch if nonzero, a watch will be set at the server to notify the 
- * client if the node changes. The watch will be set even if the node does not 
- * exist. This allows clients to watch for nodes to appear.
- * \param the return stat value of the node.
- * \return  return code of the function call.
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_exists(zhandle_t *zh, const char *path, int watch, struct Stat *stat);
-
-/**
- * \brief checks the existence of a node in zookeeper synchronously.
- * 
- * This function is similar to \ref zoo_exists except it allows one specify 
- * a watcher object rather than a boolean watch flag.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param watcher if non-null a watch will set on the specified znode on the server.
- * The watch will be set even if the node does not exist. This allows clients 
- * to watch for nodes to appear.
- * \param watcherCtx user specific data, will be passed to the watcher callback.
- * Unlike the global context set by \ref zookeeper_init, this watcher context
- * is associated with the given instance of the watcher only.
- * \param the return stat value of the node.
- * \return  return code of the function call.
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_wexists(zhandle_t *zh, const char *path,
-        watcher_fn watcher, void* watcherCtx, struct Stat *stat);
-
-/**
- * \brief gets the data associated with a node synchronously.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param watch if nonzero, a watch will be set at the server to notify 
- * the client if the node changes.
- * \param buffer the buffer holding the node data returned by the server
- * \param buffer_len is the size of the buffer pointed to by the buffer parameter.
- * It'll be set to the actual data length upon return. If the data is NULL, length is -1.
- * \param stat if not NULL, will hold the value of stat for the path on return.
- * \return return value of the function call.
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_get(zhandle_t *zh, const char *path, int watch, char *buffer,   
-                   int* buffer_len, struct Stat *stat);
-
-/**
- * \brief gets the data associated with a node synchronously.
- * 
- * This function is similar to \ref zoo_get except it allows one specify 
- * a watcher object rather than a boolean watch flag.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param watcher if non-null, a watch will be set at the server to notify 
- * the client if the node changes.
- * \param watcherCtx user specific data, will be passed to the watcher callback.
- * Unlike the global context set by \ref zookeeper_init, this watcher context
- * is associated with the given instance of the watcher only.
- * \param buffer the buffer holding the node data returned by the server
- * \param buffer_len is the size of the buffer pointed to by the buffer parameter.
- * It'll be set to the actual data length upon return. If the data is NULL, length is -1.
- * \param stat if not NULL, will hold the value of stat for the path on return.
- * \return return value of the function call.
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_wget(zhandle_t *zh, const char *path, 
-        watcher_fn watcher, void* watcherCtx, 
-        char *buffer, int* buffer_len, struct Stat *stat);
-
-/**
- * \brief sets the data associated with a node. See zoo_set2 function if
- * you require access to the stat information associated with the znode.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param buffer the buffer holding data to be written to the node.
- * \param buflen the number of bytes from buffer to write. To set NULL as data 
- * use buffer as NULL and buflen as -1.
- * \param version the expected version of the node. The function will fail if 
- * the actual version of the node does not match the expected version. If -1 is 
- * used the version check will not take place. 
- * \return the return code for the function call.
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * ZBADVERSION expected version does not match actual version.
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_set(zhandle_t *zh, const char *path, const char *buffer,
-                   int buflen, int version);
-
-/**
- * \brief sets the data associated with a node. This function is the same
- * as zoo_set except that it also provides access to stat information
- * associated with the znode.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param buffer the buffer holding data to be written to the node.
- * \param buflen the number of bytes from buffer to write. To set NULL as data
- * use buffer as NULL and buflen as -1.
- * \param version the expected version of the node. The function will fail if 
- * the actual version of the node does not match the expected version. If -1 is 
- * used the version check will not take place. 
- * \param stat if not NULL, will hold the value of stat for the path on return.
- * \return the return code for the function call.
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * ZBADVERSION expected version does not match actual version.
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_set2(zhandle_t *zh, const char *path, const char *buffer,
-                   int buflen, int version, struct Stat *stat);
-
-/**
- * \brief lists the children of a node synchronously.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param watch if nonzero, a watch will be set at the server to notify 
- * the client if the node changes.
- * \param strings return value of children paths.
- * \return the return code of the function.
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_get_children(zhandle_t *zh, const char *path, int watch,
-                            struct String_vector *strings);
-
-/**
- * \brief lists the children of a node synchronously.
- * 
- * This function is similar to \ref zoo_get_children except it allows one specify 
- * a watcher object rather than a boolean watch flag.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param watcher if non-null, a watch will be set at the server to notify 
- * the client if the node changes.
- * \param watcherCtx user specific data, will be passed to the watcher callback.
- * Unlike the global context set by \ref zookeeper_init, this watcher context
- * is associated with the given instance of the watcher only.
- * \param strings return value of children paths.
- * \return the return code of the function.
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_wget_children(zhandle_t *zh, const char *path, 
-        watcher_fn watcher, void* watcherCtx,
-        struct String_vector *strings);
-
-/**
- * \brief lists the children of a node and get its stat synchronously.
- * 
- * This function is new in version 3.3.0
- *
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param watch if nonzero, a watch will be set at the server to notify 
- * the client if the node changes.
- * \param strings return value of children paths.
- * \param stat return value of node stat.
- * \return the return code of the function.
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_get_children2(zhandle_t *zh, const char *path, int watch,
-                            struct String_vector *strings, struct Stat *stat);
-
-/**
- * \brief lists the children of a node and get its stat synchronously.
- * 
- * This function is similar to \ref zoo_get_children except it allows one specify 
- * a watcher object rather than a boolean watch flag.
- * 
- * This function is new in version 3.3.0
- *
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param watcher if non-null, a watch will be set at the server to notify 
- * the client if the node changes.
- * \param watcherCtx user specific data, will be passed to the watcher callback.
- * Unlike the global context set by \ref zookeeper_init, this watcher context
- * is associated with the given instance of the watcher only.
- * \param strings return value of children paths.
- * \param stat return value of node stat.
- * \return the return code of the function.
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_wget_children2(zhandle_t *zh, const char *path, 
-        watcher_fn watcher, void* watcherCtx,
-        struct String_vector *strings, struct Stat *stat);
-
-/**
- * \brief gets the acl associated with a node synchronously.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param acl the return value of acls on the path.
- * \param stat returns the stat of the path specified.
- * \return the return code for the function call.
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_get_acl(zhandle_t *zh, const char *path, struct ACL_vector *acl,
-                       struct Stat *stat);
-
-/**
- * \brief sets the acl associated with a node synchronously.
- * 
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param path the name of the node. Expressed as a file name with slashes 
- * separating ancestors of the node.
- * \param version the expected version of the path.
- * \param acl the acl to be set on the path. 
- * \return the return code for the function call.
- * ZOK operation completed successfully
- * ZNONODE the node does not exist.
- * ZNOAUTH the client does not have permission.
- * ZINVALIDACL invalid ACL specified
- * ZBADVERSION expected version does not match actual version.
- * ZBADARGUMENTS - invalid input parameters
- * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
- * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
- */
-ZOOAPI int zoo_set_acl(zhandle_t *zh, const char *path, int version,
-                           const struct ACL_vector *acl);
-
-/**
- * \brief atomically commits multiple zookeeper operations synchronously.
- *
- * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
- * \param count the number of operations
- * \param ops an array of operations to commit
- * \param results an array to hold the results of the operations
- * \return the return code for the function call. This can be any of the
- * values that can be returned by the ops supported by a multi op (see
- * \ref zoo_acreate, \ref zoo_adelete, \ref zoo_aset).
- */ 
-ZOOAPI int zoo_multi(zhandle_t *zh, int count, const zoo_op_t *ops, zoo_op_result_t *results);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*ZOOKEEPER_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/include/zookeeper_log.h
----------------------------------------------------------------------
diff --git a/src/c/include/zookeeper_log.h b/src/c/include/zookeeper_log.h
deleted file mode 100644
index e5917cb..0000000
--- a/src/c/include/zookeeper_log.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ZK_LOG_H_
-#define ZK_LOG_H_
-
-#include <zookeeper.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern ZOOAPI ZooLogLevel logLevel;
-#define LOGSTREAM getLogStream()
-
-#define LOG_ERROR(x) if(logLevel>=ZOO_LOG_LEVEL_ERROR) \
-    log_message(ZOO_LOG_LEVEL_ERROR,__LINE__,__func__,format_log_message x)
-#define LOG_WARN(x) if(logLevel>=ZOO_LOG_LEVEL_WARN) \
-    log_message(ZOO_LOG_LEVEL_WARN,__LINE__,__func__,format_log_message x)
-#define LOG_INFO(x) if(logLevel>=ZOO_LOG_LEVEL_INFO) \
-    log_message(ZOO_LOG_LEVEL_INFO,__LINE__,__func__,format_log_message x)
-#define LOG_DEBUG(x) if(logLevel==ZOO_LOG_LEVEL_DEBUG) \
-    log_message(ZOO_LOG_LEVEL_DEBUG,__LINE__,__func__,format_log_message x)
-
-ZOOAPI void log_message(ZooLogLevel curLevel, int line,const char* funcName,
-    const char* message);
-
-ZOOAPI const char* format_log_message(const char* format,...);
-
-FILE* getLogStream();
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*ZK_LOG_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/include/zookeeper_version.h
----------------------------------------------------------------------
diff --git a/src/c/include/zookeeper_version.h b/src/c/include/zookeeper_version.h
deleted file mode 100644
index 518f7e6..0000000
--- a/src/c/include/zookeeper_version.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef ZOOKEEPER_VERSION_H_
-#define ZOOKEEPER_VERSION_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ZOO_MAJOR_VERSION 3
-#define ZOO_MINOR_VERSION 4
-#define ZOO_PATCH_VERSION 12
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ZOOKEEPER_VERSION_H_ */


[14/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/CollectionUtil.h
----------------------------------------------------------------------
diff --git a/src/c/tests/CollectionUtil.h b/src/c/tests/CollectionUtil.h
deleted file mode 100644
index dd34811..0000000
--- a/src/c/tests/CollectionUtil.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef _COLLECTION_UTIL_H_
-#define _COLLECTION_UTIL_H_
-
-/**
- * \file
- * CollectionBuilder and DictionaryBuilder classes and collection utility functions
- */
-
-namespace Util 
-{
-
-// *********************************************************
-/** A shortcut to use for building collections.
- * This class is a wrapper around standard STL collection containers such as vector.
- * It allows one to conveniently build collections at the variable initialization time:
- * \code
- * #include "CollectionUtil.h"
- * #include "Vector.h"  // for ostream << operator overload for STL vector
- * using Util;
- * 
- * int main()
- * {
- *   typedef vector<string> MyVector;
- *   MyVector myVector=CollectionBuilder<MyVector>()("str1")("str2")("str3");
- *   cout<<myVector;
- *   // the following output will be produced:
- *   // [str1,str2,str3]
- * }
- * \endcode
- */
-template <class CONT>
-class CollectionBuilder
-{
-public:
-  /// Type of the collection container. 
-  typedef CONT CollectionType;
-  /// Container's value type.
-  typedef typename CollectionType::value_type value_type;
-  /// Container's constant iterator type.
-  typedef typename CollectionType::const_iterator const_iterator;
-  /// Container's size type.
-  typedef typename CollectionType::size_type size_type;
-
-  /** Operator function call overload to allow call chaining.
-   * \param value the value to be inserted into the container
-   */
-  CollectionBuilder<CONT>& operator()(const value_type& value){
-    return push_back(value);
-  }
-  /** Same as regular STL push_back() but allows call chaining.
-   * \param value the value to be inserted into the container
-   */
-  CollectionBuilder<CONT>& push_back(const value_type& value){
-    collection_.push_back(value);
-    return *this;
-  }
-  /// \name Standard STL container interface
-  /// @{
-  const_iterator begin() const{return collection_.begin();}
-  const_iterator end() const{return collection_.end();}
-  size_type size() const{return collection_.size();}
-  void clear() {collection_.clear();}
-  ///@}
-  /// Explicit typecast operator.
-  operator const CollectionType&() const {return collection_;}
-private:
-  /// \cond PRIVATE
-  CollectionType collection_;
-  /// \endcond
-};
-
-
-// *********************************************************
-/** A shortcut to use for building dictionaries.
- * This class is a wrapper around standard STL associative containers such as map.
- * It allows one to conveniently build dictionaries at the variable initialization time:
- * \code
- * #include "CollectionUtil.h"
- * #include "Map.h"  // for ostream << operator overload for STL map
- * using Util;
- * 
- * int main()
- * {
- *   typedef map<string,int> MyMap;
- *   MyMap myMap=DictionaryBuilder<MyMap>()("str1",1)("str2",2)("str3",3);
- *   cout<<myMap;
- *   // the following output will be produced:
- *   // [str1=1,str2=2,str3=3]
- * }
- * \endcode
- */
-template <class CONT>
-class DictionaryBuilder
-{
-public:
-  /// The type of the associative container
-  typedef CONT DictionaryType;
-  /// Container's element type (usually a pair<key_type,mapped_type>)
-  typedef typename DictionaryType::value_type value_type;
-  /// Container's key type
-  typedef typename DictionaryType::key_type key_type;
-  /// Container's value type 
-  typedef typename DictionaryType::mapped_type mapped_type;
-  /// Container's constant iterator type 
-  typedef typename DictionaryType::const_iterator const_iterator;
-  /// Container's writable iterator type   
-  typedef typename DictionaryType::iterator iterator;
-  /// Container's size type
-  typedef typename DictionaryType::size_type size_type;
- 
-  /** Operator function call overload to allow call chaining.
-   * \param key the value key to be inserted
-   * \param value the value to be inserted into the container
-   * \return a non-const reference to self
-   */
-  DictionaryBuilder<CONT>& operator()(const key_type& key,const mapped_type& value){
-    dict_.insert(value_type(key,value));
-    return *this;
-  }
-  /** Lookup value by key.
-   * \param key the key associated with the value.
-   * \return a non-const iterator pointing to the element whose key matched the \a key parameter
-   */
-  iterator find(const key_type& key){
-    return dict_.find(key);
-  }
-  /** Lookup value by key.
-   * \param key the key associated with the value.
-   * \return a const iterator pointing to the element whose key matched the \a key parameter
-   */
-  const_iterator find(const key_type& key) const{
-    return dict_.find(key);
-  }
-
-  /// \name Standard STL container interface
-  /// @{
-  const_iterator begin() const{return dict_.begin();}
-  const_iterator end() const{return dict_.end();}
-  size_type size() const{return dict_.size();}
-  void clear() {dict_.clear();}
-  ///@}
-  /// Explicit typecast operator.
-  operator const DictionaryType&() const {return dict_;}
-private:
-  DictionaryType dict_;
-};
-
-
-// ***********************************************************
-/** Deletes all dynamically allocated elements of a collection.
- * C::value_type is expected to be a pointer to a dynamically allocated object, or it won't compile.
- * The function will iterate over all container elements and call delete for each of them.
- * \param c a collection (vector,set) whose elements are being deleted.
- */
-template <class C>
-void clearCollection(C& c){
-  for(typename C::const_iterator it=c.begin();it!=c.end();++it)
-    delete *it;
-  c.clear();
-}
-
-/** Deletes all dynamically allocated values of the assotiative container.
- * The function expects the M::value_type to be a pair<..., ptr_to_type>, or it won't compile.
- * It first deletes the objects pointed to by ptr_to_type
- * and then clears (calls m.clear()) the container.
- * \param m an associative container (map,hash_map) whose elements are being deleted.
- */
-template <class M>
-void clearMap(M& m){
-  for(typename M::const_iterator it=m.begin();it!=m.end();++it)
-    delete it->second;
-  m.clear();
-}
-
-} // namespace Util
-
-
-#endif // _COLLECTION_UTIL_H_

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/CppAssertHelper.h
----------------------------------------------------------------------
diff --git a/src/c/tests/CppAssertHelper.h b/src/c/tests/CppAssertHelper.h
deleted file mode 100644
index 3926f51..0000000
--- a/src/c/tests/CppAssertHelper.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CPPASSERTHELPER_H_
-#define CPPASSERTHELPER_H_
-
-#include <cppunit/TestAssert.h>
-
-// make it possible to specify location of the ASSERT call
-#define CPPUNIT_ASSERT_EQUAL_LOC(expected,actual,file,line) \
-  ( CPPUNIT_NS::assertEquals( (expected),              \
-                              (actual),                \
-                              CPPUNIT_NS::SourceLine(file,line),    \
-                              "" ) )
-
-#define CPPUNIT_ASSERT_EQUAL_MESSAGE_LOC(message,expected,actual,file,line) \
-  ( CPPUNIT_NS::assertEquals( (expected),              \
-                              (actual),                \
-                              CPPUNIT_NS::SourceLine(file,line), \
-                              (message) ) )
-
-#endif /*CPPASSERTHELPER_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/LibCMocks.cc
----------------------------------------------------------------------
diff --git a/src/c/tests/LibCMocks.cc b/src/c/tests/LibCMocks.cc
deleted file mode 100644
index 5db4553..0000000
--- a/src/c/tests/LibCMocks.cc
+++ /dev/null
@@ -1,333 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <cstdlib>
-#include <cstdarg>
-#include <iostream>
-#include <stdarg.h>
-
-#include "Util.h"
-#include "LibCMocks.h"
-
-#undef USING_DUMA
-
-using namespace std;
-
-// *****************************************************************************
-// gethostbyname
-
-struct hostent* gethostbyname(const char *name) {
-    if(!Mock_gethostbyname::mock_)
-        return LIBC_SYMBOLS.gethostbyname(name);
-    return Mock_gethostbyname::mock_->call(name);
-}
-
-Mock_gethostbyname* Mock_gethostbyname::mock_=0;
-
-Mock_gethostbyname::~Mock_gethostbyname(){
-    mock_=0;
-    for(unsigned int i=0;i<gethostbynameReturns.size();i++)
-        delete gethostbynameReturns[i];
-}
-
-Mock_gethostbyname::HostEntry& Mock_gethostbyname::addHostEntry(
-        const char* hostName, short addrtype) {
-    gethostbynameReturns.push_back(new HostEntry(hostName, addrtype));
-    return *gethostbynameReturns.back();
-}
-
-hostent* Mock_gethostbyname::call(const char* name) {
-    assert("Must add one or more mock hostent entries first"&&
-            (gethostbynameReturns.size()!=0));
-    return gethostbynameReturns[current++ % gethostbynameReturns.size()];
-}
-
-static char** appendString(char **list,const char* str,int len=0){
-    const int SIZE_INCREMENT=16;
-    if(list==0)
-        list=(char**)LIBC_SYMBOLS.calloc(SIZE_INCREMENT,sizeof(char*));
-    // find the first available slot
-    int count=0;
-    for(char** ptr=list; *ptr!=0; ptr++,count++);
-    if(((count+1)%SIZE_INCREMENT)==0){
-        list=(char**)LIBC_SYMBOLS.realloc(list,(count+1+SIZE_INCREMENT)*sizeof(char*));
-        memset(list+count+1,0,SIZE_INCREMENT*sizeof(char*));
-    }
-    if(len==0){
-        len=strlen(str)+1;
-    }
-    char* ptr=(char*)malloc(len);
-    memcpy(ptr,str,len);
-    list[count]=ptr;
-    return list;
-}
-
-static void freeList(char **list){
-    if(list==0) return;
-    for(char** ptr=list; *ptr!=0; ptr++)
-        LIBC_SYMBOLS.free((void*)*ptr);
-    LIBC_SYMBOLS.free((void*)list);
-}
-
-Mock_gethostbyname::HostEntry::HostEntry(const char* hostName, short addrtype) {
-    h_name=strdup(hostName);
-    h_addrtype=addrtype;
-    if(addrtype==AF_INET)
-        h_length=4;
-    else{
-#ifdef AF_INET6
-        h_length=6; // TODO: not really sure, verify!
-#else
-        assert("AF_INET6 not supported yet"&&false);
-#endif
-    }
-    h_aliases=h_addr_list=0;
-}
-
-Mock_gethostbyname::HostEntry::~HostEntry(){
-    if(h_name) LIBC_SYMBOLS.free((void*)h_name);
-    freeList(h_aliases); h_aliases=0;
-    freeList(h_addr_list); h_addr_list=0;
-}
-
-Mock_gethostbyname::HostEntry& Mock_gethostbyname::HostEntry::addAlias(
-        const char* alias) {
-    h_aliases=appendString(h_aliases,alias);
-    return *this;
-}
-
-Mock_gethostbyname::HostEntry& Mock_gethostbyname::HostEntry::addAddress(
-        const char* addr4) {
-    h_addr_list=appendString(h_addr_list,addr4,4);
-    return *this;
-}
-
-
-// *****************************************************************************
-// calloc
-#ifndef USING_DUMA
-DECLARE_WRAPPER(void*,calloc,(size_t p1, size_t p2)){
-    if(!Mock_calloc::mock_)
-        return CALL_REAL(calloc,(p1,p2));
-    return Mock_calloc::mock_->call(p1,p2);
-}
-#endif
-
-void* Mock_calloc::call(size_t p1, size_t p2){
-#ifndef USING_DUMA
-    if(counter++ ==callsBeforeFailure){
-        counter=0;
-        errno=errnoOnFailure;
-        return 0;
-    }
-    return CALL_REAL(calloc,(p1,p2));
-#else
-    return 0;
-#endif
-}
-
-Mock_calloc* Mock_calloc::mock_=0;
-
-// *****************************************************************************
-// realloc
-
-#ifndef USING_DUMA
-DECLARE_WRAPPER(void*,realloc,(void* p, size_t s)){
-    if(!Mock_realloc::mock_)
-        return LIBC_SYMBOLS.realloc(p,s);
-    return Mock_realloc::mock_->call(p,s);
-}
-#endif
-
-Mock_realloc* Mock_realloc::mock_=0;
-
-void* Mock_realloc::call(void* p, size_t s){
-    if(counter++ ==callsBeforeFailure){
-        counter=0;
-        errno=errnoOnFailure;
-        return 0;
-    }
-    return LIBC_SYMBOLS.realloc(p,s);
-}
-
-// *****************************************************************************
-// random
-RANDOM_RET_TYPE random(){
-    if(!Mock_random::mock_)
-        return LIBC_SYMBOLS.random();
-    return Mock_random::mock_->call();    
-}
-
-void srandom(unsigned long seed){
-    if (!Mock_random::mock_)
-        LIBC_SYMBOLS.srandom(seed);
-    else
-        Mock_random::mock_->setSeed(seed);
-}
-
-Mock_random* Mock_random::mock_=0;
-
-int Mock_random::call(){
-    assert("Must specify one or more random integers"&&(randomReturns.size()!=0));
-    return randomReturns[currentIdx++ % randomReturns.size()];
-}
-
-// *****************************************************************************
-// free
-#ifndef USING_DUMA
-DECLARE_WRAPPER(void,free,(void* p)){
-    if(Mock_free_noop::mock_ && !Mock_free_noop::mock_->nested)
-        Mock_free_noop::mock_->call(p);
-    else
-        CALL_REAL(free,(p));
-}
-#endif
-
-void Mock_free_noop::call(void* p){
-    // on cygwin libc++ is linked statically
-    // push_back() may call free(), hence the nesting guards
-    synchronized(mx);
-    nested++;
-    callCounter++;
-    requested.push_back(p);
-    nested--;
-}
-void Mock_free_noop::freeRequested(){
-#ifndef USING_DUMA
-    synchronized(mx);
-    for(unsigned i=0; i<requested.size();i++)
-        CALL_REAL(free,(requested[i]));
-#endif
-}
-
-int Mock_free_noop::getFreeCount(void* p){
-    int cnt=0;
-    synchronized(mx);
-    for(unsigned i=0;i<requested.size();i++)
-        if(requested[i]==p)cnt++;
-    return cnt;
-}
-
-bool Mock_free_noop::isFreed(void* p){
-    synchronized(mx);
-    for(unsigned i=0;i<requested.size();i++)
-        if(requested[i]==p)return true;
-    return false;
-}
-
-Mock_free_noop* Mock_free_noop::mock_=0;
-
-// *****************************************************************************
-// socket
-int socket(int domain, int type, int protocol){
-    if (!Mock_socket::mock_)
-        return LIBC_SYMBOLS.socket(domain,type,protocol);
-    return Mock_socket::mock_->callSocket(domain,type,protocol);
-}
-
-int close(int fd){
-    if (!Mock_socket::mock_)
-        return LIBC_SYMBOLS.close(fd);
-    return Mock_socket::mock_->callClose(fd);
-}
-
-int getsockopt(int s,int level,int optname,void *optval,socklen_t *optlen){
-    if (!Mock_socket::mock_)
-        return LIBC_SYMBOLS.getsockopt(s,level,optname,optval,optlen);
-    return Mock_socket::mock_->callGet(s,level,optname,optval,optlen);    
-}
-
-int setsockopt(int s,int level,int optname,const void *optval,socklen_t optlen){
-    if (!Mock_socket::mock_)
-        return LIBC_SYMBOLS.setsockopt(s,level,optname,optval,optlen);
-    return Mock_socket::mock_->callSet(s,level,optname,optval,optlen);      
-}
-int connect(int s,const struct sockaddr *addr,socklen_t len){
-    if (!Mock_socket::mock_)
-        return LIBC_SYMBOLS.connect(s,addr,len);
-    return Mock_socket::mock_->callConnect(s,addr,len);
-}
-ssize_t send(int s,const void *buf,size_t len,int flags){
-    if (!Mock_socket::mock_)
-        return LIBC_SYMBOLS.send(s,buf,len,flags);
-    return Mock_socket::mock_->callSend(s,buf,len,flags);    
-}
-
-ssize_t recv(int s,void *buf,size_t len,int flags){
-    if (!Mock_socket::mock_)
-        return LIBC_SYMBOLS.recv(s,buf,len,flags);
-    return Mock_socket::mock_->callRecv(s,buf,len,flags);        
-}
-
-Mock_socket* Mock_socket::mock_=0;
-
-// *****************************************************************************
-// fcntl
-extern "C" int fcntl(int fd,int cmd,...){
-    va_list va;
-    va_start(va,cmd);
-    void* arg = va_arg(va, void *);
-    va_end (va);
-    if (!Mock_fcntl::mock_)
-        return LIBC_SYMBOLS.fcntl(fd,cmd,arg);
-    return Mock_fcntl::mock_->call(fd,cmd,arg);    
-}
-
-Mock_fcntl* Mock_fcntl::mock_=0;
-
-// *****************************************************************************
-// select
-int select(int nfds,fd_set *rfds,fd_set *wfds,fd_set *efds,struct timeval *timeout){
-    if (!Mock_select::mock_)
-        return LIBC_SYMBOLS.select(nfds,rfds,wfds,efds,timeout);
-    return Mock_select::mock_->call(nfds,rfds,wfds,efds,timeout);        
-}
-
-Mock_select* Mock_select::mock_=0;
-
-// *****************************************************************************
-// poll
-Mock_poll* Mock_poll::mock_=0;
-int poll(struct pollfd *fds, POLL_NFDS_TYPE nfds, int timeout){
-    if (!Mock_poll::mock_)
-        return LIBC_SYMBOLS.poll(fds,nfds,timeout);
-    return Mock_poll::mock_->call(fds,nfds,timeout);        
-    
-}
-
-/*
- * Recent gcc with -O2 and glibc FORTIFY feature may cause our poll
- * mock to be ignored.
- */
-#if __USE_FORTIFY_LEVEL > 0
-int __poll_chk (struct pollfd *__fds, nfds_t __nfds, int __timeout,
-                __SIZE_TYPE__ __fdslen) {
-    return poll(__fds, __nfds, __timeout);
-}
-#endif
-
-// *****************************************************************************
-// gettimeofday
-int gettimeofday(struct timeval *tp, GETTIMEOFDAY_ARG2_TYPE tzp){
-    if (!Mock_gettimeofday::mock_)
-        return LIBC_SYMBOLS.gettimeofday(tp,tzp);
-    return Mock_gettimeofday::mock_->call(tp,tzp);            
-}
-
-Mock_gettimeofday* Mock_gettimeofday::mock_=0;
-

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/LibCMocks.h
----------------------------------------------------------------------
diff --git a/src/c/tests/LibCMocks.h b/src/c/tests/LibCMocks.h
deleted file mode 100644
index 5b07cda..0000000
--- a/src/c/tests/LibCMocks.h
+++ /dev/null
@@ -1,408 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef LIBCMOCKS_H_
-#define LIBCMOCKS_H_
-
-#include <string>
-#include <vector>
-#include <deque>
-
-#include <errno.h>
-#include <string.h>
-
-#include "MocksBase.h"
-#include "LibCSymTable.h"
-#include "ThreadingUtil.h"
-
-// *****************************************************************************
-// gethostbyname
-
-class Mock_gethostbyname: public Mock
-{
-public:
-    struct HostEntry: public hostent {
-        HostEntry(const char* hostName,short addrtype);
-        ~HostEntry();
-        HostEntry& addAlias(const char* alias);
-        HostEntry& addAddress(const char* addr4);
-    };
-
-    Mock_gethostbyname():current(0){mock_=this;}
-    virtual ~Mock_gethostbyname();
-    HostEntry& addHostEntry(const char* hostName,short addrtype=AF_INET);
-    virtual hostent* call(const char* name);
-
-    typedef std::vector<HostEntry*> HostEntryCollection;
-    HostEntryCollection gethostbynameReturns;
-    int current;
-    static Mock_gethostbyname* mock_;
-};
-
-class MockFailed_gethostbyname: public Mock_gethostbyname
-{
-public:
-    MockFailed_gethostbyname():h_errnoReturn(HOST_NOT_FOUND) {}
-
-    int h_errnoReturn;
-    virtual hostent* call(const char* name) {
-        h_errno=h_errnoReturn;
-        return 0;
-    }
-};
-
-// *****************************************************************************
-// calloc
-
-class Mock_calloc: public Mock
-{
-public:
-    Mock_calloc():errnoOnFailure(ENOMEM),callsBeforeFailure(-1),counter(0) {
-        mock_=this;
-    }
-    virtual ~Mock_calloc() {mock_=0;}
-
-    int errnoOnFailure;
-    int callsBeforeFailure;
-    int counter;
-    virtual void* call(size_t p1, size_t p2);
-
-    static Mock_calloc* mock_;
-};
-
-// *****************************************************************************
-// realloc
-
-class Mock_realloc: public Mock
-{
-public:
-    Mock_realloc():errnoOnFailure(ENOMEM),callsBeforeFailure(-1),counter(0) {
-        mock_=this;
-    }
-    virtual ~Mock_realloc() {mock_=0;}
-
-    int errnoOnFailure;
-    int callsBeforeFailure;
-    int counter;
-    virtual void* call(void* p, size_t s);
-
-    static Mock_realloc* mock_;
-};
-
-// *****************************************************************************
-// random
-
-class Mock_random: public Mock
-{
-public:
-    Mock_random():currentIdx(0) {mock_=this;}
-    virtual ~Mock_random() {mock_=0;}
-
-    int currentIdx;
-    std::vector<int> randomReturns;
-    virtual int call();
-    void setSeed(unsigned long){currentIdx=0;}
-
-    static Mock_random* mock_;
-};
-
-// *****************************************************************************
-// no-op free; keeps track of all deallocation requests
-class Mock_free_noop: public Mock
-{
-    Mutex mx;
-    std::vector<void*> requested;
-public:
-    Mock_free_noop():nested(0),callCounter(0){mock_=this;}
-    virtual ~Mock_free_noop(){
-        mock_=0;
-        freeRequested();
-    }
-    
-    int nested;
-    int callCounter;
-    virtual void call(void* p);
-    void freeRequested();
-    void disable(){mock_=0;}
-    // returns number of times the pointer was freed
-    int getFreeCount(void*);
-    bool isFreed(void*);
-    
-    static Mock_free_noop* mock_;
-};
-
-// *****************************************************************************
-// socket and related system calls
-
-class Mock_socket: public Mock
-{
-public:
-    static const int FD=63;
-    Mock_socket():socketReturns(FD),closeReturns(0),getsocketoptReturns(0),
-        optvalSO_ERROR(0),
-        setsockoptReturns(0),connectReturns(0),connectErrno(0),
-        sendErrno(0),recvErrno(0)
-    {
-        mock_=this;
-    }
-    virtual ~Mock_socket(){mock_=0;}
-
-    int socketReturns;
-    virtual int callSocket(int domain, int type, int protocol){
-        return socketReturns;
-    }
-    int closeReturns;
-    virtual int callClose(int fd){
-        return closeReturns;
-    }
-    int getsocketoptReturns;
-    int optvalSO_ERROR;
-    virtual int callGet(int s,int level,int optname,void *optval,socklen_t *len){
-        if(level==SOL_SOCKET && optname==SO_ERROR){
-            setSO_ERROR(optval,*len);
-        }
-        return getsocketoptReturns;
-    }
-    virtual void setSO_ERROR(void *optval,socklen_t len){
-        memcpy(optval,&optvalSO_ERROR,len);
-    }
-    
-    int setsockoptReturns;
-    virtual int callSet(int s,int level,int optname,const void *optval,socklen_t len){
-        return setsockoptReturns;
-    }
-    int connectReturns;
-    int connectErrno;
-    virtual int callConnect(int s,const struct sockaddr *addr,socklen_t len){
-        errno=connectErrno;
-        return connectReturns;
-    }
-    
-    virtual void notifyBufferSent(const std::string& buffer){}
-    
-    int sendErrno;
-    std::string sendBuffer;
-    virtual ssize_t callSend(int s,const void *buf,size_t len,int flags){
-        if(sendErrno!=0){
-            errno=sendErrno;
-            return -1;
-        }
-        // first call to send() is always the length of the buffer to follow
-        bool sendingLength=sendBuffer.size()==0;
-        // overwrite the length bytes
-        sendBuffer.assign((const char*)buf,len);
-        if(!sendingLength){
-            notifyBufferSent(sendBuffer);
-            sendBuffer.erase();
-        }
-        return len;
-    }
-
-    int recvErrno;
-    std::string recvReturnBuffer;
-    virtual ssize_t callRecv(int s,void *buf,size_t len,int flags){
-        if(recvErrno!=0){
-            errno=recvErrno;
-            return -1;
-        }
-        int k=std::min(len,recvReturnBuffer.length());
-        if(k==0)
-            return 0;
-        memcpy(buf,recvReturnBuffer.data(),k);
-        recvReturnBuffer.erase(0,k);
-        return k;
-    }
-    virtual bool hasMoreRecv() const{
-        return recvReturnBuffer.size()!=0;
-    }
-    static Mock_socket* mock_;
-};
-
-// *****************************************************************************
-// fcntl
-class Mock_fcntl: public Mock
-{
-public:
-    Mock_fcntl():callReturns(0),trapFD(-1){mock_=this;}
-    ~Mock_fcntl(){mock_=0;}
-    
-    int callReturns;
-    int trapFD;
-    virtual int call(int fd, int cmd, void* arg){
-        if(trapFD==-1)
-            return LIBC_SYMBOLS.fcntl(fd,cmd,arg);
-        return callReturns;
-    }
-
-    static Mock_fcntl* mock_;
-};
-
-// *****************************************************************************
-// select
-class Mock_select: public Mock
-{
-public:
-    Mock_select(Mock_socket* s,int fd):sock(s),
-        callReturns(0),myFD(fd),timeout(50)
-    {
-        mock_=this;
-    }
-    ~Mock_select(){mock_=0;}
-    
-    Mock_socket* sock;
-    int callReturns;
-    int myFD;
-    int timeout; //in millis
-    virtual int call(int nfds,fd_set *rfds,fd_set *wfds,fd_set *efds,struct timeval *tv){
-        bool isWritableRequested=(wfds && FD_ISSET(myFD,wfds));
-        if(rfds) FD_CLR(myFD,rfds);
-        if(wfds) FD_CLR(myFD,wfds);
-        // this timeout is only to prevent a tight loop
-        timeval myTimeout={0,0};
-        if(!isWritableRequested && !isFDReadable()){
-            myTimeout.tv_sec=timeout/1000;
-            myTimeout.tv_usec=(timeout%1000)*1000;
-        }
-        LIBC_SYMBOLS.select(nfds,rfds,wfds,efds,&myTimeout);
-        // myFD is always writable
-        if(isWritableRequested) FD_SET(myFD,wfds);
-        // myFD is only readable if the socket has anything to read
-        if(isFDReadable() && rfds) FD_SET(myFD,rfds);
-        return callReturns;
-    }
-
-    virtual bool isFDReadable() const {
-        return sock->hasMoreRecv();
-    }
-    
-    static Mock_select* mock_;
-};
-
-// *****************************************************************************
-// poll
-// the last element of the pollfd array is expected to be test FD
-class Mock_poll: public Mock
-{
-public:
-    Mock_poll(Mock_socket* s,int fd):sock(s),
-        callReturns(1),myFD(fd),timeout(50)
-    {
-        mock_=this;
-    }
-    ~Mock_poll(){mock_=0;}
-    
-    Mock_socket* sock;
-    int callReturns;
-    int myFD;
-    int timeout; //in millis
-    virtual int call(struct pollfd *fds, POLL_NFDS_TYPE nfds, int to) {
-        pollfd* myPoll=0;
-        if(fds[nfds-1].fd==myFD)
-            myPoll=&fds[nfds-1];
-        bool isWritableRequested=false;
-        if(myPoll!=0){
-            isWritableRequested=myPoll->events&POLLOUT;
-            nfds--;
-        }
-        LIBC_SYMBOLS.poll(fds,nfds,(!isWritableRequested&&!isFDReadable())?timeout:0);
-        if(myPoll!=0){
-            // myFD is always writable if requested
-            myPoll->revents=isWritableRequested?POLLOUT:0;
-            // myFD is only readable if the socket has anything to read
-            myPoll->revents|=isFDReadable()?POLLIN:0;
-        }
-        return callReturns;
-    }
-
-    virtual bool isFDReadable() const {
-        return sock->hasMoreRecv();
-    }
-    
-    static Mock_poll* mock_;
-};
-
-// *****************************************************************************
-// gettimeofday
-class Mock_gettimeofday: public Mock
-{
-public:
-    Mock_gettimeofday(){
-        LIBC_SYMBOLS.gettimeofday(&tv,0);
-        mock_=this;
-    }
-    Mock_gettimeofday(const Mock_gettimeofday& other):tv(other.tv){}
-    Mock_gettimeofday(int32_t sec,int32_t usec){
-        tv.tv_sec=sec;
-        tv.tv_usec=usec;
-    }
-    ~Mock_gettimeofday(){mock_=0;}
-    
-    timeval tv;
-    virtual int call(struct timeval *tp, GETTIMEOFDAY_ARG2_TYPE tzp){
-        *tp=tv;
-        return 0;
-    }
-    operator timeval() const{
-        return tv;
-    }
-    // advance secs
-    virtual void tick(int howmuch=1){tv.tv_sec+=howmuch;}
-    // advance milliseconds
-    // can move the clock forward as well as backward by providing a negative
-    // number
-    virtual void millitick(int howmuch=1){
-        int ms=tv.tv_usec/1000+howmuch;
-        tv.tv_sec+=ms/1000;
-        // going backward?
-        if(ms<0){
-            ms=1000-(-ms%1000); //wrap millis around
-        }
-        tv.tv_usec=(ms%1000)*1000;
-    }
-    virtual void tick(const timeval& howmuch){
-        // add milliseconds (discarding microsecond portion)
-        long ms=tv.tv_usec/1000+howmuch.tv_usec/1000;
-        tv.tv_sec+=howmuch.tv_sec+ms/1000;
-        tv.tv_usec=(ms%1000)*1000;
-    }
-    static Mock_gettimeofday* mock_;
-};
-
-// discard microseconds!
-inline bool operator==(const timeval& lhs, const timeval& rhs){
-    return rhs.tv_sec==lhs.tv_sec && rhs.tv_usec/1000==lhs.tv_usec/1000;
-}
-
-// simplistic implementation: no normalization, assume lhs >= rhs,
-// discarding microseconds
-inline timeval operator-(const timeval& lhs, const timeval& rhs){
-    timeval res;
-    res.tv_sec=lhs.tv_sec-rhs.tv_sec;
-    res.tv_usec=(lhs.tv_usec/1000-rhs.tv_usec/1000)*1000;
-    if(res.tv_usec<0){
-        res.tv_sec--;
-        res.tv_usec=1000000+res.tv_usec%1000000; // wrap the millis around
-    }
-    return res;
-}
-
-inline int32_t toMilliseconds(const timeval& tv){
-    return tv.tv_sec*1000+tv.tv_usec/1000;    
-}
-
-#endif /*LIBCMOCKS_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/LibCSymTable.cc
----------------------------------------------------------------------
diff --git a/src/c/tests/LibCSymTable.cc b/src/c/tests/LibCSymTable.cc
deleted file mode 100644
index 5378579..0000000
--- a/src/c/tests/LibCSymTable.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "LibCSymTable.h" 
-
-#define LOAD_SYM(sym) \
-    sym=(sym##_sig)dlsym(handle,#sym); \
-    assert("Unable to load "#sym" from libc"&&sym)      
-    
-
-LibCSymTable& LibCSymTable::instance(){
-    static LibCSymTable tbl;
-    return tbl;
-}
-
-//******************************************************************************
-// preload original libc symbols
-LibCSymTable::LibCSymTable()
-{
-    void* handle=getHandle();
-    LOAD_SYM(gethostbyname);
-    LOAD_SYM(calloc);
-    LOAD_SYM(realloc);
-    LOAD_SYM(free);
-    LOAD_SYM(random);
-    LOAD_SYM(srandom);
-    LOAD_SYM(printf);
-    LOAD_SYM(socket);
-    LOAD_SYM(close);
-    LOAD_SYM(getsockopt);
-    LOAD_SYM(setsockopt);
-    LOAD_SYM(fcntl);
-    LOAD_SYM(connect);
-    LOAD_SYM(send);
-    LOAD_SYM(recv);
-    LOAD_SYM(select);
-    LOAD_SYM(poll);
-    LOAD_SYM(gettimeofday);
-#ifdef THREADED
-    LOAD_SYM(pthread_create);
-    LOAD_SYM(pthread_detach);
-    LOAD_SYM(pthread_cond_broadcast);
-    LOAD_SYM(pthread_cond_destroy);
-    LOAD_SYM(pthread_cond_init);
-    LOAD_SYM(pthread_cond_signal);
-    LOAD_SYM(pthread_cond_timedwait);
-    LOAD_SYM(pthread_cond_wait);
-    LOAD_SYM(pthread_join);
-    LOAD_SYM(pthread_mutex_destroy);
-    LOAD_SYM(pthread_mutex_init);
-    LOAD_SYM(pthread_mutex_lock);
-    LOAD_SYM(pthread_mutex_trylock);
-    LOAD_SYM(pthread_mutex_unlock);
-#endif
-}
-
-void* LibCSymTable::getHandle(){
-    static void* handle=0;
-    if(!handle){
-#ifdef __CYGWIN__
-        handle=dlopen("cygwin1.dll",RTLD_LAZY);
-        assert("Unable to dlopen global sym table"&&handle);
-#else
-        handle=RTLD_NEXT;
-#endif
-    }
-    return handle;
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/LibCSymTable.h
----------------------------------------------------------------------
diff --git a/src/c/tests/LibCSymTable.h b/src/c/tests/LibCSymTable.h
deleted file mode 100644
index 2f7e0c2..0000000
--- a/src/c/tests/LibCSymTable.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef LIBCSYMTABLE_H_
-#define LIBCSYMTABLE_H_
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <stddef.h>
-#include <dlfcn.h>
-#include <cassert>
-#include <poll.h>
-
-#ifdef THREADED
-#include <pthread.h>
-#endif
-
-#include "config.h"
-
-// TODO: move all these macros to config.h (generated by autoconf) 
-#ifdef __CYGWIN__
-#if (CYGWIN_VERSION_DLL_MAJOR < 1007)
-#define RANDOM_RET_TYPE int
-#else
-#define RANDOM_RET_TYPE long int
-#endif
-#define GETTIMEOFDAY_ARG2_TYPE void*
-#else
-#define RANDOM_RET_TYPE long int
-#define GETTIMEOFDAY_ARG2_TYPE struct timezone*
-#endif
-
-#define DECLARE_SYM(ret,sym,sig) \
-    typedef ret (*sym##_sig)sig; \
-    static sym##_sig preload_##sym () { \
-        static sym##_sig ptr=0;\
-        if(!ptr){ void* h=getHandle(); ptr=(sym##_sig)dlsym(h,#sym); } \
-        assert("Unable to load "#sym" from libc"&&ptr); \
-        return ptr; \
-    } \
-    sym##_sig sym
-
-#define LIBC_SYMBOLS LibCSymTable::instance()
-
-//******************************************************************************
-// preload original libc symbols
-struct LibCSymTable
-{
-    DECLARE_SYM(hostent*,gethostbyname,(const char*));
-    DECLARE_SYM(void*,calloc,(size_t, size_t));
-    DECLARE_SYM(void*,realloc,(void*, size_t));
-    DECLARE_SYM(void,free,(void*));
-    DECLARE_SYM(RANDOM_RET_TYPE,random,(void));
-    DECLARE_SYM(void,srandom,(unsigned long));
-    DECLARE_SYM(int,printf,(const char*, ...));
-    DECLARE_SYM(int,socket,(int,int,int));
-    DECLARE_SYM(int,close,(int));
-    DECLARE_SYM(int,getsockopt,(int,int,int,void*,socklen_t*));
-    DECLARE_SYM(int,setsockopt,(int,int,int,const void*,socklen_t));
-    DECLARE_SYM(int,fcntl,(int,int,...));
-    DECLARE_SYM(int,connect,(int,const struct sockaddr*,socklen_t));
-    DECLARE_SYM(ssize_t,send,(int,const void*,size_t,int));
-    DECLARE_SYM(ssize_t,recv,(int,const void*,size_t,int));
-    DECLARE_SYM(int,select,(int,fd_set*,fd_set*,fd_set*,struct timeval*));
-    DECLARE_SYM(int,poll,(struct pollfd*,POLL_NFDS_TYPE,int));
-    DECLARE_SYM(int,gettimeofday,(struct timeval*,GETTIMEOFDAY_ARG2_TYPE));
-#ifdef THREADED
-    DECLARE_SYM(int,pthread_create,(pthread_t *, const pthread_attr_t *,
-                void *(*)(void *), void *));
-    DECLARE_SYM(int,pthread_detach,(pthread_t));
-    DECLARE_SYM(int,pthread_cond_broadcast,(pthread_cond_t *));
-    DECLARE_SYM(int,pthread_cond_destroy,(pthread_cond_t *));
-    DECLARE_SYM(int,pthread_cond_init,(pthread_cond_t *, const pthread_condattr_t *));
-    DECLARE_SYM(int,pthread_cond_signal,(pthread_cond_t *));
-    DECLARE_SYM(int,pthread_cond_timedwait,(pthread_cond_t *,
-                    pthread_mutex_t *, const struct timespec *));
-    DECLARE_SYM(int,pthread_cond_wait,(pthread_cond_t *, pthread_mutex_t *));
-    DECLARE_SYM(int,pthread_join,(pthread_t, void **));
-    DECLARE_SYM(int,pthread_mutex_destroy,(pthread_mutex_t *));
-    DECLARE_SYM(int,pthread_mutex_init,(pthread_mutex_t *, const pthread_mutexattr_t *));
-    DECLARE_SYM(int,pthread_mutex_lock,(pthread_mutex_t *));
-    DECLARE_SYM(int,pthread_mutex_trylock,(pthread_mutex_t *));
-    DECLARE_SYM(int,pthread_mutex_unlock,(pthread_mutex_t *));
-#endif
-    LibCSymTable();
-    
-    static void* getHandle();
-    static LibCSymTable& instance();
-};
-
-#endif /*LIBCSYMTABLE_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/MocksBase.cc
----------------------------------------------------------------------
diff --git a/src/c/tests/MocksBase.cc b/src/c/tests/MocksBase.cc
deleted file mode 100644
index 60b2c75..0000000
--- a/src/c/tests/MocksBase.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <cstdlib>
-#include <new>
-
-#include "MocksBase.h"
-#include "LibCSymTable.h"
-
-// *****************************************************************************
-// Mock base
-void* Mock::operator new(std::size_t s){
-    void* p=malloc(s);
-    if(!p)
-        throw std::bad_alloc();
-    return p;
-}
-
-void Mock::operator delete(void* p){
-    LIBC_SYMBOLS.free(p);
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/MocksBase.h
----------------------------------------------------------------------
diff --git a/src/c/tests/MocksBase.h b/src/c/tests/MocksBase.h
deleted file mode 100644
index 5b54251..0000000
--- a/src/c/tests/MocksBase.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MOCKSBASE_H_
-#define MOCKSBASE_H_
-
-#include <cstddef>
-
-// *****************************************************************************
-// Mock base
-
-class Mock
-{
-public:
-    virtual ~Mock(){}
-
-    static void* operator new(std::size_t s);
-    static void operator delete(void* p);
-};
-
-#endif /*MOCKSBASE_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/PthreadMocks.cc
----------------------------------------------------------------------
diff --git a/src/c/tests/PthreadMocks.cc b/src/c/tests/PthreadMocks.cc
deleted file mode 100644
index 490cebf..0000000
--- a/src/c/tests/PthreadMocks.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "PthreadMocks.h"
-
-MockPthreadsBase* MockPthreadsBase::mock_=0;
-
-#undef USING_DUMA
-
-#ifndef USING_DUMA
-int pthread_cond_broadcast (pthread_cond_t *c){
-    if(!MockPthreadsBase::mock_)
-        return LIBC_SYMBOLS.pthread_cond_broadcast(c);
-    return MockPthreadsBase::mock_->pthread_cond_broadcast(c);
-}
-int pthread_cond_destroy (pthread_cond_t *c){
-    if(!MockPthreadsBase::mock_)
-        return LIBC_SYMBOLS.pthread_cond_destroy(c);
-    return MockPthreadsBase::mock_->pthread_cond_destroy(c);
-}
-int pthread_cond_init (pthread_cond_t *c, const pthread_condattr_t *a){
-    if(!MockPthreadsBase::mock_)
-        return LIBC_SYMBOLS.pthread_cond_init(c,a);
-    return MockPthreadsBase::mock_->pthread_cond_init(c,a);
-}
-int pthread_cond_signal (pthread_cond_t *c){
-    if(!MockPthreadsBase::mock_)
-        return LIBC_SYMBOLS.pthread_cond_signal(c);
-    return MockPthreadsBase::mock_->pthread_cond_signal(c);
-}
-int pthread_cond_timedwait (pthread_cond_t *c,
-                pthread_mutex_t *m, const struct timespec *t){
-    if(!MockPthreadsBase::mock_)
-        return LIBC_SYMBOLS.pthread_cond_timedwait(c,m,t);
-    return MockPthreadsBase::mock_->pthread_cond_timedwait(c,m,t);
-}
-int pthread_cond_wait (pthread_cond_t *c, pthread_mutex_t *m){
-    if(!MockPthreadsBase::mock_)
-        return LIBC_SYMBOLS.pthread_cond_wait(c,m);
-    return MockPthreadsBase::mock_->pthread_cond_wait(c,m);
-}
-int pthread_create (pthread_t *t, const pthread_attr_t *a,
-            void *(*f)(void *), void *d){
-    if(!MockPthreadsBase::mock_)
-        return LIBC_SYMBOLS.pthread_create(t,a,f,d);
-    return MockPthreadsBase::mock_->pthread_create(t,a,f,d);
-}
-int pthread_detach(pthread_t t){
-    if(!MockPthreadsBase::mock_)
-        return LIBC_SYMBOLS.pthread_detach(t);
-    return MockPthreadsBase::mock_->pthread_detach(t);    
-}
-int pthread_join (pthread_t t, void **r){
-    if(!MockPthreadsBase::mock_)
-        return LIBC_SYMBOLS.pthread_join(t,r);
-    return MockPthreadsBase::mock_->pthread_join(t,r);
-}
-int pthread_mutex_destroy (pthread_mutex_t *m){
-    if(!MockPthreadsBase::mock_)
-        return LIBC_SYMBOLS.pthread_mutex_destroy(m);
-    return MockPthreadsBase::mock_->pthread_mutex_destroy(m);
-}
-int pthread_mutex_init (pthread_mutex_t *m, const pthread_mutexattr_t *a){
-    if(!MockPthreadsBase::mock_)
-        return LIBC_SYMBOLS.pthread_mutex_init(m,a);
-    return MockPthreadsBase::mock_->pthread_mutex_init(m,a);
-}
-
-DECLARE_WRAPPER(int,pthread_mutex_lock,(pthread_mutex_t *m)){
-    if(!MockPthreadsBase::mock_)
-        return CALL_REAL(pthread_mutex_lock,(m));
-    return MockPthreadsBase::mock_->pthread_mutex_lock(m);
-}
-
-int pthread_mutex_trylock (pthread_mutex_t *m){
-    if(!MockPthreadsBase::mock_)
-        return LIBC_SYMBOLS.pthread_mutex_trylock(m);
-    return MockPthreadsBase::mock_->pthread_mutex_trylock(m);
-}
-
-DECLARE_WRAPPER(int,pthread_mutex_unlock,(pthread_mutex_t *m)){
-    if(!MockPthreadsBase::mock_)
-        return CALL_REAL(pthread_mutex_unlock,(m));
-    return MockPthreadsBase::mock_->pthread_mutex_unlock(m);
-}
-#endif
-
-CheckedPthread::ThreadMap CheckedPthread::tmap_;
-CheckedPthread::MutexMap CheckedPthread::mmap_;
-CheckedPthread::CVMap CheckedPthread::cvmap_;
-Mutex CheckedPthread::mx;

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/PthreadMocks.h
----------------------------------------------------------------------
diff --git a/src/c/tests/PthreadMocks.h b/src/c/tests/PthreadMocks.h
deleted file mode 100644
index 8db8815..0000000
--- a/src/c/tests/PthreadMocks.h
+++ /dev/null
@@ -1,449 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef PTHREADMOCKS_H_
-#define PTHREADMOCKS_H_
-
-#include <pthread.h>
-#include <string.h>
-#include <errno.h>
-
-#include "src/zk_adaptor.h"
-
-#include "Util.h"
-#include "MocksBase.h"
-#include "LibCSymTable.h"
-#include "ThreadingUtil.h"
-
-// an ABC for pthreads
-class MockPthreadsBase: public Mock
-{
-public:
-    MockPthreadsBase(){mock_=this;}
-    virtual ~MockPthreadsBase(){mock_=0;}
-    
-    virtual int pthread_create(pthread_t * t, const pthread_attr_t *a,
-            void *(*f)(void *), void *d) =0;
-    virtual int pthread_join(pthread_t t, void ** r) =0;
-    virtual int pthread_detach(pthread_t t) =0;
-    virtual int pthread_cond_broadcast(pthread_cond_t *c) =0;
-    virtual int pthread_cond_destroy(pthread_cond_t *c) =0;
-    virtual int pthread_cond_init(pthread_cond_t *c, const pthread_condattr_t *a) =0;
-    virtual int pthread_cond_signal(pthread_cond_t *c) =0;
-    virtual int pthread_cond_timedwait(pthread_cond_t *c,
-            pthread_mutex_t *m, const struct timespec *t) =0;
-    virtual int pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m) =0;
-    virtual int pthread_mutex_destroy(pthread_mutex_t *m) =0;
-    virtual int pthread_mutex_init(pthread_mutex_t *m, const pthread_mutexattr_t *a) =0;
-    virtual int pthread_mutex_lock(pthread_mutex_t *m) =0;
-    virtual int pthread_mutex_trylock(pthread_mutex_t *m) =0;
-    virtual int pthread_mutex_unlock(pthread_mutex_t *m) =0;
-    
-    static MockPthreadsBase* mock_;
-};
-
-// all pthread functions simply return an error code
-// and increment their invocation counter. No actual threads are spawned.
-class MockPthreadsNull: public MockPthreadsBase
-{
-public:
-    MockPthreadsNull():
-    pthread_createReturns(0),pthread_createCounter(0),
-    pthread_joinReturns(0),pthread_joinCounter(0),pthread_joinResultReturn(0),
-    pthread_detachReturns(0),pthread_detachCounter(0),
-    pthread_cond_broadcastReturns(0),pthread_cond_broadcastCounter(0),
-    pthread_cond_destroyReturns(0),pthread_cond_destroyCounter(0),
-    pthread_cond_initReturns(0),pthread_cond_initCounter(0),
-    pthread_cond_signalReturns(0),pthread_cond_signalCounter(0),
-    pthread_cond_timedwaitReturns(0),pthread_cond_timedwaitCounter(0),
-    pthread_cond_waitReturns(0),pthread_cond_waitCounter(0),
-    pthread_mutex_destroyReturns(0),pthread_mutex_destroyCounter(0),
-    pthread_mutex_initReturns(0),pthread_mutex_initCounter(0),
-    pthread_mutex_lockReturns(0),pthread_mutex_lockCounter(0),
-    pthread_mutex_trylockReturns(0),pthread_mutex_trylockCounter(0),
-    pthread_mutex_unlockReturns(0),pthread_mutex_unlockCounter(0)
-    {
-        memset(threads,0,sizeof(threads));
-    }
-    
-    short threads[512];
-    
-    int pthread_createReturns;
-    int pthread_createCounter;
-    virtual int pthread_create(pthread_t * t, const pthread_attr_t *a,
-            void *(*f)(void *), void *d){
-        char* p=(char*)&threads[pthread_createCounter++];
-        p[0]='i'; // mark as created
-        *t=(pthread_t)p;
-        return pthread_createReturns; 
-    }
-    int pthread_joinReturns;
-    int pthread_joinCounter;
-    void* pthread_joinResultReturn;
-    virtual int pthread_join(pthread_t t, void ** r){
-        pthread_joinCounter++;
-        if(r!=0)
-            *r=pthread_joinResultReturn;
-        char* p=(char*)t;
-        p[0]='x';p[1]+=1;
-        return pthread_joinReturns; 
-    }
-    int pthread_detachReturns;
-    int pthread_detachCounter;        
-    virtual int pthread_detach(pthread_t t){
-        pthread_detachCounter++;
-        char* p=(char*)t;
-        p[0]='x';p[1]+=1;        
-        return pthread_detachReturns;
-    }
-
-    template<class T>
-    static bool isInitialized(const T& t){
-        return ((char*)t)[0]=='i';
-    }
-    template<class T>
-    static bool isDestroyed(const T& t){
-        return ((char*)t)[0]=='x';
-    }
-    template<class T>
-    static int getDestroyCounter(const T& t){
-        return ((char*)t)[1];
-    }
-    template<class T>
-    static int getInvalidAccessCounter(const T& t){
-        return ((char*)t)[2];
-    }
-    int pthread_cond_broadcastReturns;
-    int pthread_cond_broadcastCounter;
-    virtual int pthread_cond_broadcast(pthread_cond_t *c){
-        pthread_cond_broadcastCounter++;
-        if(isDestroyed(c))((char*)c)[2]++;
-        return pthread_cond_broadcastReturns; 
-    }
-    int pthread_cond_destroyReturns;
-    int pthread_cond_destroyCounter;
-    virtual int pthread_cond_destroy(pthread_cond_t *c){
-        pthread_cond_destroyCounter++;
-        char* p=(char*)c;
-        p[0]='x';p[1]+=1;
-        return pthread_cond_destroyReturns; 
-    }
-    int pthread_cond_initReturns;
-    int pthread_cond_initCounter;
-    virtual int pthread_cond_init(pthread_cond_t *c, const pthread_condattr_t *a){
-        pthread_cond_initCounter++;
-        char* p=(char*)c;
-        p[0]='i'; // mark as created
-        p[1]=0;   // destruction counter
-        p[2]=0;   // access after destruction counter
-        return pthread_cond_initReturns; 
-    }
-    int pthread_cond_signalReturns;
-    int pthread_cond_signalCounter;
-    virtual int pthread_cond_signal(pthread_cond_t *c){
-        pthread_cond_signalCounter++;
-        if(isDestroyed(c))((char*)c)[2]++;
-        return pthread_cond_signalReturns; 
-    }
-    int pthread_cond_timedwaitReturns;
-    int pthread_cond_timedwaitCounter;
-    virtual int pthread_cond_timedwait(pthread_cond_t *c,
-            pthread_mutex_t *m, const struct timespec *t){
-        pthread_cond_timedwaitCounter++;
-        if(isDestroyed(c))((char*)c)[2]++;
-        return pthread_cond_timedwaitReturns; 
-    }
-    int pthread_cond_waitReturns;
-    int pthread_cond_waitCounter;
-    virtual int pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m){
-        pthread_cond_waitCounter++;
-        if(isDestroyed(c))((char*)c)[2]++;
-        return pthread_cond_waitReturns; 
-    }
-    int pthread_mutex_destroyReturns;
-    int pthread_mutex_destroyCounter;
-    virtual int pthread_mutex_destroy(pthread_mutex_t *m){
-        pthread_mutex_destroyCounter++;
-        char* p=(char*)m;
-        p[0]='x';p[1]+=1;
-        return pthread_mutex_destroyReturns; 
-    }
-    int pthread_mutex_initReturns;
-    int pthread_mutex_initCounter;
-    virtual int pthread_mutex_init(pthread_mutex_t *m, const pthread_mutexattr_t *a){
-        pthread_mutex_initCounter++;
-        char* p=(char*)m;
-        p[0]='i'; // mark as created
-        p[1]=0;   // destruction counter
-        p[2]=0;   // access after destruction counter
-        return pthread_mutex_initReturns; 
-    }
-    int pthread_mutex_lockReturns;
-    int pthread_mutex_lockCounter;
-    virtual int pthread_mutex_lock(pthread_mutex_t *m){
-        pthread_mutex_lockCounter++;
-        if(isDestroyed(m))((char*)m)[2]++;
-        return pthread_mutex_lockReturns; 
-    }
-    int pthread_mutex_trylockReturns;
-    int pthread_mutex_trylockCounter;
-    virtual int pthread_mutex_trylock(pthread_mutex_t *m){
-        pthread_mutex_trylockCounter++;
-        if(isDestroyed(m))((char*)m)[2]++;
-        return pthread_mutex_trylockReturns; 
-    }
-    int pthread_mutex_unlockReturns;
-    int pthread_mutex_unlockCounter;
-    virtual int pthread_mutex_unlock(pthread_mutex_t *m){
-        pthread_mutex_unlockCounter++;
-        if(isDestroyed(m))((char*)m)[2]++;
-        return pthread_mutex_unlockReturns; 
-    }
-};
-
-// simulates the way zookeeper threads make use of api_prolog/epilog and
-// 
-class MockPthreadZKNull: public MockPthreadsNull
-{
-    typedef std::map<pthread_t,zhandle_t*> Map;
-    Map map_;
-public:
-    virtual int pthread_create(pthread_t * t, const pthread_attr_t *a,
-            void *(*f)(void *), void *d){
-        int ret=MockPthreadsNull::pthread_create(t,a,f,d);
-        zhandle_t* zh=(zhandle_t*)d;
-        adaptor_threads* ad=(adaptor_threads*)zh->adaptor_priv;
-        api_prolog(zh);
-        ad->threadsToWait--;
-        putValue(map_,*t,zh);
-        return ret;
-    }
-    virtual int pthread_join(pthread_t t, void ** r){
-        zhandle_t* zh=0;
-        if(getValue(map_,t,zh))
-            api_epilog(zh,0);
-        return MockPthreadsNull::pthread_join(t,r);
-    }
-};
-
-struct ThreadInfo{
-    typedef enum {RUNNING,TERMINATED} ThreadState;
-    
-    ThreadInfo():
-        destructionCounter_(0),invalidAccessCounter_(0),state_(RUNNING)
-    {
-    }
-    
-    ThreadInfo& incDestroyed() {
-        destructionCounter_++;
-        return *this;
-    }
-    ThreadInfo& incInvalidAccess(){
-        invalidAccessCounter_++;
-        return *this;
-    }
-    ThreadInfo& setTerminated(){
-        state_=TERMINATED;
-        return *this;
-    }
-    int destructionCounter_;
-    int invalidAccessCounter_;
-    ThreadState state_;
-};
-
-class CheckedPthread: public MockPthreadsBase
-{
-    // first => destruction counter
-    // second => invalid access counter
-    //typedef std::pair<int,int> Entry;
-    typedef ThreadInfo Entry;
-    typedef std::map<pthread_t,Entry> ThreadMap;
-    static ThreadMap tmap_;
-    static ThreadMap& getMap(const TypeOp<pthread_t>::BareT&){return tmap_;}
-    typedef std::map<pthread_mutex_t*,Entry> MutexMap;
-    static MutexMap mmap_;
-    static MutexMap& getMap(const TypeOp<pthread_mutex_t>::BareT&){return mmap_;}
-    typedef std::map<pthread_cond_t*,Entry> CVMap;
-    static CVMap cvmap_;
-    static CVMap& getMap(const TypeOp<pthread_cond_t>::BareT&){return cvmap_;}
-    
-    static Mutex mx;
-    
-    template<class T>
-    static void markDestroyed(T& t){
-        typedef typename TypeOp<T>::BareT Type;
-        Entry e;
-        synchronized(mx);
-        if(getValue(getMap(Type()),t,e)){
-            putValue(getMap(Type()),t,Entry(e).incDestroyed());
-        }else{
-            putValue(getMap(Type()),t,Entry().incDestroyed());
-        }
-    }
-    template<class T>
-    static void markCreated(T& t){
-        typedef typename TypeOp<T>::BareT Type;
-        Entry e;
-        synchronized(mx);
-        if(!getValue(getMap(Type()),t,e))
-            putValue(getMap(Type()),t,Entry());
-    }
-    template<class T>
-    static void checkAccessed(T& t){
-        typedef typename TypeOp<T>::BareT Type;
-        Entry e;
-        synchronized(mx);
-        if(getValue(getMap(Type()),t,e) && e.destructionCounter_>0)
-            putValue(getMap(Type()),t,Entry(e).incInvalidAccess());
-    }
-    static void setTerminated(pthread_t t){
-        Entry e;
-        synchronized(mx);
-        if(getValue(tmap_,t,e))
-            putValue(tmap_,t,Entry(e).setTerminated());
-    }
-public:
-    bool verbose;
-    CheckedPthread():verbose(false){
-        tmap_.clear();
-        mmap_.clear();
-        cvmap_.clear();
-        mx.release();
-    }
-    template <class T>
-    static bool isInitialized(const T& t){
-        typedef typename TypeOp<T>::BareT Type;
-        Entry e;
-        synchronized(mx);
-        return getValue(getMap(Type()),t,e) && e.destructionCounter_==0;
-    }
-    template <class T>
-    static bool isDestroyed(const T& t){
-        typedef typename TypeOp<T>::BareT Type;
-        Entry e;
-        synchronized(mx);
-        return getValue(getMap(Type()),t,e) && e.destructionCounter_>0;
-    }
-    static bool isTerminated(pthread_t t){
-        Entry e;
-        synchronized(mx);
-        return getValue(tmap_,t,e) && e.state_==ThreadInfo::TERMINATED;        
-    }
-    template <class T>
-    static int getDestroyCounter(const T& t){
-        typedef typename TypeOp<T>::BareT Type;
-        Entry e;
-        synchronized(mx);
-        return getValue(getMap(Type()),t,e)?e.destructionCounter_:-1;
-    }
-    template<class T>
-    static int getInvalidAccessCounter(const T& t){
-        typedef typename TypeOp<T>::BareT Type;
-        Entry e;
-        synchronized(mx);
-        return getValue(getMap(Type()),t,e)?e.invalidAccessCounter_:-1;
-    }
-
-    struct ThreadContext{
-        typedef void *(*ThreadFunc)(void *);
-        
-        ThreadContext(ThreadFunc func,void* param):func_(func),param_(param){}
-        ThreadFunc func_;
-        void* param_;        
-    };
-    static void* threadFuncWrapper(void* v){
-        ThreadContext* ctx=(ThreadContext*)v;
-        pthread_t t=pthread_self();
-        markCreated(t);
-        void* res=ctx->func_(ctx->param_);
-        setTerminated(pthread_self());
-        delete ctx;
-        return res;
-    }
-    virtual int pthread_create(pthread_t * t, const pthread_attr_t *a,
-            void *(*f)(void *), void *d)
-    {
-        int ret=LIBC_SYMBOLS.pthread_create(t,a,threadFuncWrapper,
-                new ThreadContext(f,d));
-        if(verbose)
-            TEST_TRACE(("thread created %p",*t));
-        return ret;
-    }
-    virtual int pthread_join(pthread_t t, void ** r){
-        if(verbose) TEST_TRACE(("thread joined %p",t));
-        int ret=LIBC_SYMBOLS.pthread_join(t,r);
-        if(ret==0)
-            markDestroyed(t);
-        return ret;
-    }
-    virtual int pthread_detach(pthread_t t){
-        if(verbose) TEST_TRACE(("thread detached %p",t));
-        int ret=LIBC_SYMBOLS.pthread_detach(t);
-        if(ret==0)
-            markDestroyed(t);
-        return ret;
-    }
-    virtual int pthread_cond_broadcast(pthread_cond_t *c){
-        checkAccessed(c);
-        return LIBC_SYMBOLS.pthread_cond_broadcast(c);
-    }
-    virtual int pthread_cond_destroy(pthread_cond_t *c){
-        markDestroyed(c);
-        return LIBC_SYMBOLS.pthread_cond_destroy(c);
-    }
-    virtual int pthread_cond_init(pthread_cond_t *c, const pthread_condattr_t *a){
-        markCreated(c);
-        return LIBC_SYMBOLS.pthread_cond_init(c,a);
-    }
-    virtual int pthread_cond_signal(pthread_cond_t *c){
-        checkAccessed(c);
-        return LIBC_SYMBOLS.pthread_cond_signal(c);
-    }
-    virtual int pthread_cond_timedwait(pthread_cond_t *c,
-            pthread_mutex_t *m, const struct timespec *t){
-        checkAccessed(c);
-        return LIBC_SYMBOLS.pthread_cond_timedwait(c,m,t);
-    }
-    virtual int pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m){
-        checkAccessed(c);
-        return LIBC_SYMBOLS.pthread_cond_wait(c,m);
-    }
-    virtual int pthread_mutex_destroy(pthread_mutex_t *m){
-        markDestroyed(m);
-        return LIBC_SYMBOLS.pthread_mutex_destroy(m);
-    }
-    virtual int pthread_mutex_init(pthread_mutex_t *m, const pthread_mutexattr_t *a){
-        markCreated(m);
-        return LIBC_SYMBOLS.pthread_mutex_init(m,a);
-    }
-    virtual int pthread_mutex_lock(pthread_mutex_t *m){
-        checkAccessed(m);
-        return LIBC_SYMBOLS.pthread_mutex_lock(m);
-    }
-    virtual int pthread_mutex_trylock(pthread_mutex_t *m){
-        checkAccessed(m);
-        return LIBC_SYMBOLS.pthread_mutex_trylock(m);
-    }
-    virtual int pthread_mutex_unlock(pthread_mutex_t *m){
-        checkAccessed(m);
-        return LIBC_SYMBOLS.pthread_mutex_unlock(m);
-    }    
-};
-
-#endif /*PTHREADMOCKS_H_*/
-


[09/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/c-doc.Doxyfile
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/c-doc.Doxyfile b/zookeeper-client/zookeeper-client-c/c-doc.Doxyfile
new file mode 100644
index 0000000..e9029cb
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/c-doc.Doxyfile
@@ -0,0 +1,1252 @@
+# Doxyfile 1.4.7
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME = $(PROJECT)-$(VERSION)
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = $(DOCDIR)
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, 
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, 
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, 
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# This tag can be used to specify the encoding used in the generated output. 
+# The encoding is not always determined by the language that is chosen, 
+# but also whether or not the output is meant for Windows or non-Windows users. 
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
+# forces the Windows encoding (this is the default for the Windows binary), 
+# whereas setting the tag to NO uses a Unix-style encoding (the default for 
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to 
+# include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST = YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT = include/zookeeper.h
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
+
+FILE_PATTERNS = 
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.  Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML = $(GENERATE_HTML)
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = $(GENERATE_HTMLHELP)
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE = ../$(PROJECT).chm
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION = $(HHC_PATH)
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = $(GENERATE_CHI)
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX = $(GENERATE_LATEX)
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = $(PAPER_SIZE)
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX = $(GENERATE_PDF)
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF = $(GENERATE_RTF)
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN = $(GENERATE_MAN)
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML = $(GENERATE_XML)
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE = $(DOCDIR)/$(PROJECT).tag
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = $(HAVE_DOT)
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a caller dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable caller graphs for selected 
+# functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH = $(DOT_PATH)
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that a graph may be further truncated if the graph's 
+# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH 
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), 
+# the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/cmake_config.h.in
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/cmake_config.h.in b/zookeeper-client/zookeeper-client-c/cmake_config.h.in
new file mode 100644
index 0000000..55efd8a
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/cmake_config.h.in
@@ -0,0 +1,154 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CONFIG_H_
+#define CONFIG_H_
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#cmakedefine HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#cmakedefine HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#cmakedefine HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the file `generated/zookeeper.jute.c'. */
+#cmakedefine HAVE_GENERATED_ZOOKEEPER_JUTE_C 1
+
+/* Define to 1 if you have the file `generated/zookeeper.jute.h'. */
+#cmakedefine HAVE_GENERATED_ZOOKEEPER_JUTE_H 1
+
+/* Define to 1 if you have the `getcwd' function. */
+#cmakedefine HAVE_GETCWD 1
+
+/* Define to 1 if you have the `gethostbyname' function. */
+#cmakedefine HAVE_GETHOSTBYNAME 1
+
+/* Define to 1 if you have the `gethostname' function. */
+#cmakedefine HAVE_GETHOSTNAME 1
+
+/* Define to 1 if you have the `getlogin' function. */
+#cmakedefine HAVE_GETLOGIN 1
+
+/* Define to 1 if you have the `getpwuid_r' function. */
+#cmakedefine HAVE_GETPWUID_R 1
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#cmakedefine HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have the `getuid' function. */
+#cmakedefine HAVE_GETUID 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#cmakedefine HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `rt' library (-lrt). */
+#cmakedefine HAVE_LIBRT 1
+
+/* Define to 1 if you have the `memmove' function. */
+#cmakedefine HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#cmakedefine HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `memset' function. */
+#cmakedefine HAVE_MEMSET 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#cmakedefine HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#cmakedefine HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the `poll' function. */
+#cmakedefine HAVE_POLL 1
+
+/* Define to 1 if you have the `socket' function. */
+#cmakedefine HAVE_SOCKET 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#cmakedefine HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#cmakedefine HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strchr' function. */
+#cmakedefine HAVE_STRCHR 1
+
+/* Define to 1 if you have the `strdup' function. */
+#cmakedefine HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#cmakedefine HAVE_STRERROR 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#cmakedefine HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#cmakedefine HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strtol' function. */
+#cmakedefine HAVE_STRTOL 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#cmakedefine HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#cmakedefine HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#cmakedefine HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#cmakedefine HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+#cmakedefine HAVE_SYS_UTSNAME_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#cmakedefine HAVE_UNISTD_H 1
+
+/* Define to 1 if IPv6 support is available. */
+#cmakedefine ZOO_IPV6_ENABLED 1
+
+/* poll() second argument type */
+#define POLL_NFDS_TYPE nfds_t
+
+/* Name of package */
+#define PACKAGE "${PROJECT_NAME}"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "${email}"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "${description}"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "${description} ${PROJECT_VERSION}"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "${PROJECT_NAME}"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "${PROJECT_VERSION}"
+
+/* Version number of package */
+#define VERSION "${PROJECT_VERSION}"
+
+#endif

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/configure.ac
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/configure.ac b/zookeeper-client/zookeeper-client-c/configure.ac
new file mode 100644
index 0000000..51dcfcd
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/configure.ac
@@ -0,0 +1,165 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.59)
+
+AC_INIT([zookeeper C client],3.4.13,[user@zookeeper.apache.org],[zookeeper])
+AC_CONFIG_SRCDIR([src/zookeeper.c])
+
+# Save initial CFLAGS and CXXFLAGS values before AC_PROG_CC and AC_PROG_CXX
+init_cflags="$CFLAGS"
+init_cxxflags="$CXXFLAGS"
+
+# initialize Doxygen support
+DX_HTML_FEATURE(ON)
+DX_CHM_FEATURE(OFF)
+DX_CHI_FEATURE(OFF)
+DX_MAN_FEATURE(OFF)
+DX_RTF_FEATURE(OFF)
+DX_XML_FEATURE(OFF)
+DX_PDF_FEATURE(OFF)
+DX_PS_FEATURE(OFF)
+DX_INIT_DOXYGEN([zookeeper],[c-doc.Doxyfile],[docs])
+
+# initialize automake
+AM_INIT_AUTOMAKE([-Wall foreign])
+AC_CONFIG_HEADER([config.h])
+
+# Checks for programs.
+AC_ARG_WITH(cppunit,
+        [  --without-cppunit       do not use CPPUNIT])
+
+if test "$with_cppunit" = "no" ; then
+   CPPUNIT_PATH="No_CPPUNIT"
+   CPPUNIT_INCLUDE=
+   CPPUNIT_LIBS=
+else
+   AM_PATH_CPPUNIT(1.10.2)
+fi
+
+if test "$CALLER" = "ANT" ; then
+CPPUNIT_CFLAGS="$CPPUNIT_CFLAGS -DZKSERVER_CMD=\"\\\"${base_dir}/zookeeper-client/zookeeper-client-c/tests/zkServer.sh\\\"\""
+else
+CPPUNIT_CFLAGS="$CPPUNIT_CFLAGS -DZKSERVER_CMD=\"\\\"./tests/zkServer.sh\\\"\""
+AC_CHECK_FILES([$srcdir/generated/zookeeper.jute.c $srcdir/generated/zookeeper.jute.h],[],
+    [AC_MSG_ERROR([jute files are missing! Please run "ant compile_jute" while in the zookeeper top level directory.])
+])
+fi
+AC_SUBST(CPPUNIT_CFLAGS)
+
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_CXX
+AC_PROG_INSTALL
+AC_PROG_LN_S
+
+# AC_DISABLE_SHARED
+AC_PROG_LIBTOOL
+
+#enable -D_GNU_SOURCE since the return code value of getaddrinfo
+#ifdefed with __USE_GNU
+#features.h header undef's __USE_GNU and defines it only if _GNU_SOURCE is defined
+#hence this define for gcc
+AC_ARG_ENABLE([debug],
+ [AS_HELP_STRING([--enable-debug],[enable debug build [default=no]])],
+ [],[enable_debug=no])
+
+if test "x$enable_debug" = xyes; then
+    if test "x$init_cflags" = x; then
+        CFLAGS=""
+    fi
+    CFLAGS="$CFLAGS -g -O0 -D_GNU_SOURCE"
+else
+    if test "x$init_cflags" = x; then
+        CFLAGS="-g -O2 -D_GNU_SOURCE"
+    fi
+fi
+
+if test "x$enable_debug" = xyes; then
+    if test "x$init_cxxflags" = x; then
+        CXXFLAGS=""
+    fi
+    CXXFLAGS="$CXXFLAGS -g -O0"
+else
+    if test "x$init_cxxflags" = x; then
+        CXXFLAGS="-g -O2"
+    fi
+fi
+
+# Check whether to enable gcov (coverage test)
+AC_ARG_ENABLE(gcov, [AS_HELP_STRING([--enable-gcov],[enable coverage test])])
+AC_MSG_CHECKING([whether to enable gcov])
+AS_IF([test "x${enable_gcov}" = "xyes"],AC_MSG_RESULT([yes]),AC_MSG_RESULT([no]))
+AM_CONDITIONAL([ENABLEGCOV],[test "x${enable_gcov}" = "xyes"])
+
+AC_ARG_WITH([syncapi],
+ [AS_HELP_STRING([--with-syncapi],[build with support for SyncAPI [default=yes]])],
+ [],[with_syncapi=yes])
+
+# Checks for libraries.
+AC_CHECK_LIB([pthread], [pthread_mutex_lock],[have_pthread=yes],[have_pthread=no])
+
+if test "x$with_syncapi" != xno && test "x$have_pthread" = xno; then
+    AC_MSG_WARN([cannot build SyncAPI -- pthread not found])
+    with_syncapi=no
+fi
+if test "x$with_syncapi" != xno; then
+    AC_MSG_NOTICE([building with SyncAPI support])
+else
+    AC_MSG_NOTICE([building without SyncAPI support])
+fi
+
+AM_CONDITIONAL([WANT_SYNCAPI],[test "x$with_syncapi" != xno])
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h sys/time.h unistd.h sys/utsname.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+AC_HEADER_TIME
+AC_CHECK_TYPE([nfds_t],
+    [AC_DEFINE([POLL_NFDS_TYPE],[nfds_t],[poll() second argument type])],
+    [AC_DEFINE([POLL_NFDS_TYPE],[unsigned int],[poll() second argument type])],
+    [#include <poll.h>])
+
+AC_MSG_CHECKING([whether to enable ipv6])
+
+AC_TRY_RUN([ /* is AF_INET6 available? */
+#include <sys/types.h>
+#include <sys/socket.h>
+main()
+{
+ if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
+   exit(1);
+ else
+   exit(0);
+}
+], AC_MSG_RESULT(yes) 
+   ipv6=yes, 
+   AC_MSG_RESULT(no) 
+   ipv6=no, 
+   AC_MSG_RESULT(no) 
+   ipv6=no)
+
+if test x"$ipv6" = xyes; then
+  USEIPV6="-DZOO_IPV6_ENABLED"
+  AC_SUBST(USEIPV6)
+fi
+
+# Checks for library functions.
+AC_CHECK_FUNCS([getcwd gethostbyname gethostname getlogin getpwuid_r gettimeofday getuid memmove memset poll socket strchr strdup strerror strtol])
+
+AC_CONFIG_FILES([Makefile])
+AC_CANONICAL_HOST
+AM_CONDITIONAL([SOLARIS],[
+  case "$host_os" in
+  *solaris*)
+    true
+    ;;
+  *)
+    false
+    ;;
+  esac ])
+AC_OUTPUT

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/include/proto.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/include/proto.h b/zookeeper-client/zookeeper-client-c/include/proto.h
new file mode 100644
index 0000000..bce408e
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/include/proto.h
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef PROTO_H_
+#define PROTO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZOO_NOTIFY_OP 0
+#define ZOO_CREATE_OP 1
+#define ZOO_DELETE_OP 2
+#define ZOO_EXISTS_OP 3
+#define ZOO_GETDATA_OP 4
+#define ZOO_SETDATA_OP 5
+#define ZOO_GETACL_OP 6
+#define ZOO_SETACL_OP 7
+#define ZOO_GETCHILDREN_OP 8
+#define ZOO_SYNC_OP 9
+#define ZOO_PING_OP 11
+#define ZOO_GETCHILDREN2_OP 12
+#define ZOO_CHECK_OP 13
+#define ZOO_MULTI_OP 14
+#define ZOO_CLOSE_OP -11
+#define ZOO_SETAUTH_OP 100
+#define ZOO_SETWATCHES_OP 101
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*PROTO_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/include/recordio.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/include/recordio.h b/zookeeper-client/zookeeper-client-c/include/recordio.h
new file mode 100644
index 0000000..eed5f99
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/include/recordio.h
@@ -0,0 +1,83 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __RECORDIO_H__
+#define __RECORDIO_H__
+
+#include <sys/types.h>
+#include <stdint.h> /* for int64_t */
+#ifdef WIN32
+#include "winconfig.h"
+#define STRUCT_INITIALIZER(l,r)  r
+#else
+#define STRUCT_INITIALIZER(l,r) .l = r
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct buffer {
+    int32_t len;
+    char *buff;
+};
+
+void deallocate_String(char **s);
+void deallocate_Buffer(struct buffer *b);
+void deallocate_vector(void *d);
+struct iarchive {
+    int (*start_record)(struct iarchive *ia, const char *tag);
+    int (*end_record)(struct iarchive *ia, const char *tag);
+    int (*start_vector)(struct iarchive *ia, const char *tag, int32_t *count);
+    int (*end_vector)(struct iarchive *ia, const char *tag);
+    int (*deserialize_Bool)(struct iarchive *ia, const char *name, int32_t *);
+    int (*deserialize_Int)(struct iarchive *ia, const char *name, int32_t *);
+    int (*deserialize_Long)(struct iarchive *ia, const char *name, int64_t *);
+    int (*deserialize_Buffer)(struct iarchive *ia, const char *name,
+            struct buffer *);
+    int (*deserialize_String)(struct iarchive *ia, const char *name, char **);
+    void *priv;
+};
+struct oarchive {
+    int (*start_record)(struct oarchive *oa, const char *tag);
+    int (*end_record)(struct oarchive *oa, const char *tag);
+    int (*start_vector)(struct oarchive *oa, const char *tag, const int32_t *count);
+    int (*end_vector)(struct oarchive *oa, const char *tag);
+    int (*serialize_Bool)(struct oarchive *oa, const char *name, const int32_t *);
+    int (*serialize_Int)(struct oarchive *oa, const char *name, const int32_t *);
+    int (*serialize_Long)(struct oarchive *oa, const char *name,
+            const int64_t *);
+    int (*serialize_Buffer)(struct oarchive *oa, const char *name,
+            const struct buffer *);
+    int (*serialize_String)(struct oarchive *oa, const char *name, char **);
+    void *priv;
+};
+
+struct oarchive *create_buffer_oarchive(void);
+void close_buffer_oarchive(struct oarchive **oa, int free_buffer);
+struct iarchive *create_buffer_iarchive(char *buffer, int len);
+void close_buffer_iarchive(struct iarchive **ia);
+char *get_buffer(struct oarchive *);
+int get_buffer_len(struct oarchive *);
+
+int64_t zoo_htonll(int64_t v);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/include/winconfig.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/include/winconfig.h b/zookeeper-client/zookeeper-client-c/include/winconfig.h
new file mode 100644
index 0000000..c273a93
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/include/winconfig.h
@@ -0,0 +1,15 @@
+#ifndef WINCONFIG_H_
+#define WINCONFIG_H_
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+#define inline __inline
+#endif
+
+#define __attribute__(x)
+#define __func__ __FUNCTION__
+
+#define ACL ZKACL /* Conflict with windows API */
+
+#endif


[16/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/recordio.c
----------------------------------------------------------------------
diff --git a/src/c/src/recordio.c b/src/c/src/recordio.c
deleted file mode 100644
index 0fcf48e..0000000
--- a/src/c/src/recordio.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <recordio.h>
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#ifndef WIN32
-#include <netinet/in.h>
-#else
-#include <winsock2.h> /* for _htonl and _ntohl */
-#endif
-
-void deallocate_String(char **s)
-{
-    if (*s)
-        free(*s);
-    *s = 0;
-}
-
-void deallocate_Buffer(struct buffer *b)
-{
-    if (b->buff)
-        free(b->buff);
-    b->buff = 0;
-}
-
-struct buff_struct {
-    int32_t len;
-    int32_t off;
-    char *buffer;
-};
-
-static int resize_buffer(struct buff_struct *s, int newlen)
-{
-    char *buffer= NULL;
-    while (s->len < newlen) {
-        s->len *= 2;
-    }
-    buffer = (char*)realloc(s->buffer, s->len);
-    if (!buffer) {
-        s->buffer = 0;
-        return -ENOMEM;
-    }
-    s->buffer = buffer;
-    return 0;
-}
-
-int oa_start_record(struct oarchive *oa, const char *tag)
-{
-    return 0;
-}
-int oa_end_record(struct oarchive *oa, const char *tag)
-{
-    return 0;
-}
-int oa_serialize_int(struct oarchive *oa, const char *tag, const int32_t *d)
-{
-    struct buff_struct *priv = oa->priv;
-    int32_t i = htonl(*d);
-    if ((priv->len - priv->off) < sizeof(i)) {
-        int rc = resize_buffer(priv, priv->len + sizeof(i));
-        if (rc < 0) return rc;
-    }
-    memcpy(priv->buffer+priv->off, &i, sizeof(i));
-    priv->off+=sizeof(i);
-    return 0;
-}
-int64_t zoo_htonll(int64_t v)
-{
-    int i = 0;
-    char *s = (char *)&v;
-    if (htonl(1) == 1) {
-        return v;
-    }
-    for (i = 0; i < 4; i++) {
-        int tmp = s[i];
-        s[i] = s[8-i-1];
-        s[8-i-1] = tmp;
-    }
-
-    return v;
-}
-
-int oa_serialize_long(struct oarchive *oa, const char *tag, const int64_t *d)
-{
-    const int64_t i = zoo_htonll(*d);
-    struct buff_struct *priv = oa->priv;
-    if ((priv->len - priv->off) < sizeof(i)) {
-        int rc = resize_buffer(priv, priv->len + sizeof(i));
-        if (rc < 0) return rc;
-    }
-    memcpy(priv->buffer+priv->off, &i, sizeof(i));
-    priv->off+=sizeof(i);
-    return 0;
-}
-int oa_start_vector(struct oarchive *oa, const char *tag, const int32_t *count)
-{
-    return oa_serialize_int(oa, tag, count);
-}
-int oa_end_vector(struct oarchive *oa, const char *tag)
-{
-    return 0;
-}
-int oa_serialize_bool(struct oarchive *oa, const char *name, const int32_t *i)
-{
-    //return oa_serialize_int(oa, name, i);
-    struct buff_struct *priv = oa->priv;
-    if ((priv->len - priv->off) < 1) {
-        int rc = resize_buffer(priv, priv->len + 1);
-        if (rc < 0)
-            return rc;
-    }
-    priv->buffer[priv->off] = (*i == 0 ? '\0' : '\1');
-    priv->off++;
-    return 0;
-}
-static const int32_t negone = -1;
-int oa_serialize_buffer(struct oarchive *oa, const char *name,
-        const struct buffer *b)
-{
-    struct buff_struct *priv = oa->priv;
-    int rc;
-    if (!b) {
-        return oa_serialize_int(oa, "len", &negone);
-    }
-    rc = oa_serialize_int(oa, "len", &b->len);
-    if (rc < 0)
-        return rc;
-    // this means a buffer of NUll 
-    // with size of -1. This is 
-    // waht we use in java serialization for NULL
-    if (b->len == -1) {
-      return rc;
-    }
-    if ((priv->len - priv->off) < b->len) {
-        rc = resize_buffer(priv, priv->len + b->len);
-        if (rc < 0)
-            return rc;
-    }
-    memcpy(priv->buffer+priv->off, b->buff, b->len);
-    priv->off += b->len;
-    return 0;
-}
-int oa_serialize_string(struct oarchive *oa, const char *name, char **s)
-{
-    struct buff_struct *priv = oa->priv;
-    int32_t len;
-    int rc;
-    if (!*s) {
-        oa_serialize_int(oa, "len", &negone);
-        return 0;
-    }
-    len = strlen(*s);
-    rc = oa_serialize_int(oa, "len", &len);
-    if (rc < 0)
-        return rc;
-    if ((priv->len - priv->off) < len) {
-        rc = resize_buffer(priv, priv->len + len);
-        if (rc < 0)
-            return rc;
-    }
-    memcpy(priv->buffer+priv->off, *s, len);
-    priv->off += len;
-    return 0;
-}
-int ia_start_record(struct iarchive *ia, const char *tag)
-{
-    return 0;
-}
-int ia_end_record(struct iarchive *ia, const char *tag)
-{
-    return 0;
-}
-int ia_deserialize_int(struct iarchive *ia, const char *tag, int32_t *count)
-{
-    struct buff_struct *priv = ia->priv;
-    if ((priv->len - priv->off) < sizeof(*count)) {
-        return -E2BIG;
-    }
-    memcpy(count, priv->buffer+priv->off, sizeof(*count));
-    priv->off+=sizeof(*count);
-    *count = ntohl(*count);
-    return 0;
-}
-
-int ia_deserialize_long(struct iarchive *ia, const char *tag, int64_t *count)
-{
-    struct buff_struct *priv = ia->priv;
-    int64_t v = 0;
-    if ((priv->len - priv->off) < sizeof(*count)) {
-        return -E2BIG;
-    }
-    memcpy(count, priv->buffer+priv->off, sizeof(*count));
-    priv->off+=sizeof(*count);
-    v = zoo_htonll(*count); // htonll and  ntohll do the same
-    *count = v;
-    return 0;
-}
-int ia_start_vector(struct iarchive *ia, const char *tag, int32_t *count)
-{
-    return ia_deserialize_int(ia, tag, count);
-}
-int ia_end_vector(struct iarchive *ia, const char *tag)
-{
-    return 0;
-}
-int ia_deserialize_bool(struct iarchive *ia, const char *name, int32_t *v)
-{
-    struct buff_struct *priv = ia->priv;
-    //fprintf(stderr, "Deserializing bool %d\n", priv->off);
-    //return ia_deserialize_int(ia, name, v);
-    if ((priv->len - priv->off) < 1) {
-        return -E2BIG;
-    }
-    *v = priv->buffer[priv->off];
-    priv->off+=1;
-    //fprintf(stderr, "Deserializing bool end %d\n", priv->off);
-    return 0;
-}
-int ia_deserialize_buffer(struct iarchive *ia, const char *name,
-        struct buffer *b)
-{
-    struct buff_struct *priv = ia->priv;
-    int rc = ia_deserialize_int(ia, "len", &b->len);
-    if (rc < 0)
-        return rc;
-    if ((priv->len - priv->off) < b->len) {
-        return -E2BIG;
-    }
-    // set the buffer to null
-    if (b->len == -1) {
-       b->buff = NULL;
-       return rc;
-    }
-    b->buff = malloc(b->len);
-    if (!b->buff) {
-        return -ENOMEM;
-    }
-    memcpy(b->buff, priv->buffer+priv->off, b->len);
-    priv->off += b->len;
-    return 0;
-}
-int ia_deserialize_string(struct iarchive *ia, const char *name, char **s)
-{
-    struct buff_struct *priv = ia->priv;
-    int32_t len;
-    int rc = ia_deserialize_int(ia, "len", &len);
-    if (rc < 0)
-        return rc;
-    if ((priv->len - priv->off) < len) {
-        return -E2BIG;
-    }
-    if (len < 0) {
-        return -EINVAL;
-    }
-    *s = malloc(len+1);
-    if (!*s) {
-        return -ENOMEM;
-    }
-    memcpy(*s, priv->buffer+priv->off, len);
-    (*s)[len] = '\0';
-    priv->off += len;
-    return 0;
-}
-
-static struct iarchive ia_default = { STRUCT_INITIALIZER (start_record ,ia_start_record),
-        STRUCT_INITIALIZER (end_record ,ia_end_record), STRUCT_INITIALIZER (start_vector , ia_start_vector),
-        STRUCT_INITIALIZER (end_vector ,ia_end_vector), STRUCT_INITIALIZER (deserialize_Bool , ia_deserialize_bool),
-        STRUCT_INITIALIZER (deserialize_Int ,ia_deserialize_int),
-        STRUCT_INITIALIZER (deserialize_Long , ia_deserialize_long) ,
-        STRUCT_INITIALIZER (deserialize_Buffer, ia_deserialize_buffer),
-        STRUCT_INITIALIZER (deserialize_String, ia_deserialize_string)   };
-
-static struct oarchive oa_default = { STRUCT_INITIALIZER (start_record , oa_start_record),
-        STRUCT_INITIALIZER (end_record , oa_end_record), STRUCT_INITIALIZER (start_vector , oa_start_vector),
-        STRUCT_INITIALIZER (end_vector , oa_end_vector), STRUCT_INITIALIZER (serialize_Bool , oa_serialize_bool),
-        STRUCT_INITIALIZER (serialize_Int , oa_serialize_int),
-        STRUCT_INITIALIZER (serialize_Long , oa_serialize_long) ,
-        STRUCT_INITIALIZER (serialize_Buffer , oa_serialize_buffer),
-        STRUCT_INITIALIZER (serialize_String , oa_serialize_string) };
-
-struct iarchive *create_buffer_iarchive(char *buffer, int len)
-{
-    struct iarchive *ia;
-    struct buff_struct *buff;
-    ia = malloc(sizeof(*ia));
-    if (!ia) return 0;
-    buff = malloc(sizeof(struct buff_struct));
-    if (!buff) {
-        free(ia);
-        return 0;
-    }
-    *ia = ia_default;
-    buff->off = 0;
-    buff->buffer = buffer;
-    buff->len = len;
-    ia->priv = buff;
-    return ia;
-}
-
-struct oarchive *create_buffer_oarchive()
-{
-    struct oarchive *oa;
-    struct buff_struct *buff;
-    oa = malloc(sizeof(*oa));
-    if (!oa) return 0;
-    buff = malloc(sizeof(struct buff_struct));
-    if (!buff) {
-        free(oa);
-        return 0;
-    }
-    *oa = oa_default;
-    buff->off = 0;
-    buff->buffer = malloc(128);
-    buff->len = 128;
-    oa->priv = buff;
-    return oa;
-}
-
-void close_buffer_iarchive(struct iarchive **ia)
-{
-    free((*ia)->priv);
-    free(*ia);
-    *ia = 0;
-}
-
-void close_buffer_oarchive(struct oarchive **oa, int free_buffer)
-{
-    if (free_buffer) {
-        struct buff_struct *buff = (struct buff_struct *)(*oa)->priv;
-        if (buff->buffer) {
-            free(buff->buffer);
-        }
-    }
-    free((*oa)->priv);
-    free(*oa);
-    *oa = 0;
-}
-
-char *get_buffer(struct oarchive *oa)
-{
-    struct buff_struct *buff = oa->priv;
-    return buff->buffer;
-}
-int get_buffer_len(struct oarchive *oa)
-{
-    struct buff_struct *buff = oa->priv;
-    return buff->off;
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/st_adaptor.c
----------------------------------------------------------------------
diff --git a/src/c/src/st_adaptor.c b/src/c/src/st_adaptor.c
deleted file mode 100644
index 23573b3..0000000
--- a/src/c/src/st_adaptor.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef DLL_EXPORT
-#  define USE_STATIC_LIB
-#endif
-
-#include "zk_adaptor.h"
-#include <stdlib.h>
-#include <time.h>
-
-int zoo_lock_auth(zhandle_t *zh)
-{
-	return 0;
-}
-int zoo_unlock_auth(zhandle_t *zh)
-{
-	return 0;
-}
-int lock_buffer_list(buffer_head_t *l)
-{
-	return 0;
-}
-int unlock_buffer_list(buffer_head_t *l)
-{
-	return 0;
-}
-int lock_completion_list(completion_head_t *l)
-{
-	return 0;
-}
-int unlock_completion_list(completion_head_t *l)
-{
-	return 0;
-}
-struct sync_completion *alloc_sync_completion(void)
-{
-    return (struct sync_completion*)calloc(1, sizeof(struct sync_completion));
-}
-int wait_sync_completion(struct sync_completion *sc)
-{
-    return 0;
-}
-
-void free_sync_completion(struct sync_completion *sc)
-{
-    free(sc);
-}
-
-void notify_sync_completion(struct sync_completion *sc)
-{
-}
-
-int process_async(int outstanding_sync)
-{
-    return outstanding_sync == 0;
-}
-
-int adaptor_init(zhandle_t *zh)
-{
-    return 0;
-}
-
-void adaptor_finish(zhandle_t *zh){}
-
-void adaptor_destroy(zhandle_t *zh){}
-
-int flush_send_queue(zhandle_t *, int);
-
-int adaptor_send_queue(zhandle_t *zh, int timeout)
-{
-    return flush_send_queue(zh, timeout);
-}
-
-int32_t inc_ref_counter(zhandle_t* zh,int i)
-{
-    zh->ref_counter+=(i<0?-1:(i>0?1:0));
-    return zh->ref_counter;
-}
-
-int32_t get_xid()
-{
-    static int32_t xid = -1;
-    if (xid == -1) {
-        xid = time(0);
-    }
-    return xid++;
-}
-
-int enter_critical(zhandle_t* zh)
-{
-	return 0;
-}
-
-int leave_critical(zhandle_t* zh)
-{
-	return 0;
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/winport.c
----------------------------------------------------------------------
diff --git a/src/c/src/winport.c b/src/c/src/winport.c
deleted file mode 100644
index 3592ea1..0000000
--- a/src/c/src/winport.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifdef WIN32
-#include "winport.h"
-#include <stdlib.h>
-#include <stdint.h> /* for int64_t */
-#include <winsock2.h> /* must always be included before ws2tcpip.h */
-#include <ws2tcpip.h> /* for SOCKET */
-
-int pthread_mutex_lock(pthread_mutex_t* _mutex ){      
-       int rc = WaitForSingleObject( *_mutex,    // handle to mutex
-            INFINITE);  // no time-out interval
-       return ((rc == WAIT_OBJECT_0) ? 0: rc); 
-}
-
-int pthread_mutex_unlock( pthread_mutex_t* _mutex ){   
-       int rc = ReleaseMutex(*_mutex);
-       return ((rc != 0)? 0: GetLastError());  
-}
-
-int pthread_mutex_init(pthread_mutex_t* _mutex, void* ignoredAttr){
-       //use CreateMutex as we are using the HANDLES in pthread_cond
-       *_mutex = CreateMutex( 
-        NULL,              // default security attributes
-        FALSE,             // initially not owned
-        NULL);             // unnamed mutex    
-       return ((*_mutex == NULL) ? GetLastError() : 0);
-}
-
-int pthread_mutex_destroy(pthread_mutex_t* _mutex)
-{
-       int rc = CloseHandle(*_mutex);
-       return ((rc != 0)? 0: GetLastError());  
-}
-
-int pthread_create(pthread_t *thread, const pthread_attr_t *attr, unsigned  (__stdcall* start_routine)(void* a), void *arg)
-{
-   int _intThreadId; 
-   (*thread).thread_handle = (HANDLE)_beginthreadex( NULL, 0, start_routine , arg, 0, (unsigned int*)&_intThreadId );
-   (*thread).thread_id = _intThreadId;
-   return (((*thread).thread_handle == 0 ) ? errno : 0 );         
-}
-
-
-int pthread_equal(pthread_t t1, pthread_t t2){
-//Is there a better way to do this? GetThreadId(handle) is only supported Windows 2003 n above.
-       return ((t1.thread_id == t2.thread_id) ? 1:0);              
-}
-
-pthread_t pthread_self(){
-    pthread_t thread_self;
-    thread_self.thread_handle = GetCurrentThread();
-    thread_self.thread_id     = GetCurrentThreadId();
-    return thread_self;
-}
-
-int pthread_join(pthread_t _thread, void** ignore)
-{
-       int rc = WaitForSingleObject( _thread.thread_handle, INFINITE );
-       return ((rc == WAIT_OBJECT_0) ? 0: rc); 
-}
-
-int pthread_detach(pthread_t _thread)
-{
-       int rc = CloseHandle(_thread.thread_handle) ;
-       return  (rc != 0) ? 0: GetLastError();
-}
-
-void pthread_mutexattr_init(pthread_mutexattr_t* ignore){}
-void pthread_mutexattr_settype(pthread_mutexattr_t* ingore_attr, int ignore){}
-void pthread_mutexattr_destroy(pthread_mutexattr_t* ignore_attr){}
-       
-int 
-pthread_cond_init (pthread_cond_t *cv,
-                   const pthread_condattr_t * ignore)
-{
-  cv->waiters_count_ = 0;
-  cv->was_broadcast_ = 0;
-  cv->sema_ = CreateSemaphore (NULL,       // no security
-                                0,          // initially 0
-                                0x7fffffff, // max count
-                                NULL);      // unnamed 
-  if (cv->sema_ == NULL ) 
-               return GetLastError();
-  InitializeCriticalSection (&cv->waiters_count_lock_);
-  cv->waiters_done_ = CreateEvent (NULL,  // no security
-                                   FALSE, // auto-reset
-                                   FALSE, // non-signaled initially
-                                   NULL); // unnamed
-  return (cv->waiters_done_ == NULL) ? GetLastError() : 0;
-       
-}
-
-
-int pthread_cond_destroy(pthread_cond_t *cond)
-{
-       CloseHandle( cond->sema_);
-       DeleteCriticalSection(&cond->waiters_count_lock_);
-       return (CloseHandle( cond->waiters_done_ ) == 0)? GetLastError(): 0 ;
-}
-
-
-int
-pthread_cond_signal (pthread_cond_t *cv)
-{
-  int have_waiters;
-  EnterCriticalSection (& (cv->waiters_count_lock_));
-  have_waiters = cv->waiters_count_ > 0;
-  LeaveCriticalSection (&cv->waiters_count_lock_);
-
-  // If there aren't any waiters, then this is a no-op.  
-  if (have_waiters){
-         return (ReleaseSemaphore (cv->sema_, 1, 0) == 0 )  ? GetLastError() : 0 ;
-  }else
-         return 0;
-}
-
-
-int
-pthread_cond_broadcast (pthread_cond_t *cv)
-{
-  // This is needed to ensure that <waiters_count_> and <was_broadcast_> are
-  // consistent relative to each other.
-  int have_waiters = 0;
-  EnterCriticalSection (&cv->waiters_count_lock_);
-  
-  if (cv->waiters_count_ > 0) {
-    // We are broadcasting, even if there is just one waiter...
-    // Record that we are broadcasting, which helps optimize
-    // <pthread_cond_wait> for the non-broadcast case.
-    cv->was_broadcast_ = 1;
-    have_waiters = 1;
-  }
-
-  if (have_waiters) {
-    // Wake up all the waiters atomically.
-    ReleaseSemaphore (cv->sema_, cv->waiters_count_, 0);
-
-    LeaveCriticalSection (&cv->waiters_count_lock_);
-
-    // Wait for all the awakened threads to acquire the counting
-    // semaphore. 
-    WaitForSingleObject (cv->waiters_done_, INFINITE);
-    // This assignment is okay, even without the <waiters_count_lock_> held 
-    // because no other waiter threads can wake up to access it.
-    cv->was_broadcast_ = 0;
-  }
-  else
-    LeaveCriticalSection (&cv->waiters_count_lock_);
-}
-
-
-int
-pthread_cond_wait (pthread_cond_t *cv, 
-                   pthread_mutex_t *external_mutex)
-{
-  int last_waiter;
-  // Avoid race conditions.
-  EnterCriticalSection (&cv->waiters_count_lock_);
-  cv->waiters_count_++;
-  LeaveCriticalSection (&cv->waiters_count_lock_);
-
-  // This call atomically releases the mutex and waits on the
-  // semaphore until <pthread_cond_signal> or <pthread_cond_broadcast>
-  // are called by another thread.
-  SignalObjectAndWait (*external_mutex, cv->sema_, INFINITE, FALSE);
-
-  // Reacquire lock to avoid race conditions.
-  EnterCriticalSection (&cv->waiters_count_lock_);
-
-  // We're no longer waiting...
-  cv->waiters_count_--;
-
-  // Check to see if we're the last waiter after <pthread_cond_broadcast>.
-  last_waiter = cv->was_broadcast_ && cv->waiters_count_ == 0;
-
-  LeaveCriticalSection (&cv->waiters_count_lock_);
-
-  // If we're the last waiter thread during this particular broadcast
-  // then let all the other threads proceed.
-  if (last_waiter)
-    // This call atomically signals the <waiters_done_> event and waits until
-    // it can acquire the <external_mutex>.  This is required to ensure fairness. 
-    SignalObjectAndWait (cv->waiters_done_, *external_mutex, INFINITE, FALSE);
-  else
-    // Always regain the external mutex since that's the guarantee we
-    // give to our callers. 
-    WaitForSingleObject (*external_mutex, INFINITE);
-}
-
-int pthread_key_create(pthread_key_t *key, void (*destructor)(void *) )
-{
-  int result = 0;
-  pthread_key_t* newkey;
-
-  if ((newkey = (pthread_key_t*) calloc (1, sizeof (pthread_key_t))) == NULL)
-    {
-      result = ENOMEM;
-    }
-  else if ((newkey->key = TlsAlloc ()) == TLS_OUT_OF_INDEXES)
-    {
-      result = EAGAIN;
-      free (newkey);
-      newkey = NULL;
-    }
-  else if (destructor != NULL)
-    {
-      //--we have to store the function pointer for destructor, so that we can call it 
-         //--to free up the user allocated storage--       
-      newkey->destructor = destructor;
-    }
-  key = newkey;  
-  return (result);     
-}
-
-int pthread_key_delete(pthread_key_t key)
-{
-  int rc = 0;
-  LPVOID lpvData =  TlsGetValue(key.key);
-  rc = TlsFree (key.key);
-  rc = (rc != 0 ) ? 0 : GetLastError();
-  if (key.destructor != NULL && lpvData != 0){
-       key.destructor(lpvData);         //we take control of calling destructor, instead of calling it on thread exit.
-  }
-  free (&key);
-  return (rc);
-}
-
-void *pthread_getspecific(pthread_key_t key)
-{
-       LPVOID lpvData =  TlsGetValue(key.key);
-       if ((lpvData == 0) && (GetLastError() != ERROR_SUCCESS)) 
-               return NULL;
-       else 
-               return lpvData;
-}
-
-int pthread_setspecific(pthread_key_t key, const void *value)
-{
-       int rc = TlsSetValue (key.key, value);
-       return ((rc != 0 ) ? 0 : GetLastError());
-}
-
-int gettimeofday(struct timeval *tp, void *tzp) {
-        int64_t now = 0;
-        if (tzp != 0) { errno = EINVAL; return -1; }
-        GetSystemTimeAsFileTime( (LPFILETIME)&now );
-        tp->tv_sec = (long)(now / 10000000 - 11644473600LL);
-        tp->tv_usec = (now / 10) % 1000000;
-        return 0;
-}
-
-int close(SOCKET fd) {
-        return closesocket(fd);
-}
-
-int Win32WSAStartup()
-{
-       WORD    wVersionRq;
-       WSADATA wsaData;
-       int             err;
-
-       wVersionRq = MAKEWORD(2,0);
-       err = WSAStartup(wVersionRq, &wsaData);
-       if (err != 0)
-               return 1;
-       
-       // confirm the version information
-       if ((LOBYTE(wsaData.wVersion) != 2) ||
-           (HIBYTE(wsaData.wVersion) != 0))
-       {
-               Win32WSACleanup();              
-               return 1;
-       }
-       return 0;
-}
-
-void Win32WSACleanup()
-{
-       WSACleanup();
-}
-
-#endif //WIN32
-
-
-

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/winport.h
----------------------------------------------------------------------
diff --git a/src/c/src/winport.h b/src/c/src/winport.h
deleted file mode 100644
index da6028c..0000000
--- a/src/c/src/winport.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * This header file is to port pthread lib , sockets and other utility methods on windows.
- * Specifically the threads function, mutexes, keys, and socket initialization.
- */
-
-#ifndef WINPORT_H_
-#define WINPORT_H_
-
-#ifdef WIN32
-#include "winconfig.h"
-
-#define _WINSOCK_DEPRECATED_NO_WARNINGS
-#include <winsock2.h> /* must always be included before ws2tcpip.h */
-#include <ws2tcpip.h> /* for struct sock_addr used in zookeeper.h */
-
-/* POSIX names are deprecated, use ISO conformant names instead. */
-#define strdup _strdup
-#define getcwd _getcwd
-#define getpid _getpid
-
-/* Windows "secure" versions of POSIX reentrant functions */
-#define strtok_r strtok_s
-#define localtime_r(a,b) localtime_s(b,a)
-
-/* After this version of MSVC, snprintf became a defined function,
-   and so cannot be redefined, nor can #ifndef be used to guard it. */
-#if ((defined(_MSC_VER) && _MSC_VER < 1900) || !defined(_MSC_VER))
-#define snprintf _snprintf
-#endif
-
-
-#include <errno.h>
-#include <process.h>
-#include <stdint.h> /* for int64_t */
-#include <stdlib.h>
-#include <malloc.h>
-
-
-typedef int ssize_t;
-typedef HANDLE pthread_mutex_t;
-
-struct pthread_t_
-{
-  HANDLE thread_handle;
-  DWORD  thread_id;
-};
-
-typedef struct pthread_t_ pthread_t;
-typedef int pthread_mutexattr_t;       
-typedef int pthread_condattr_t;        
-typedef int pthread_attr_t; 
-#define PTHREAD_MUTEX_RECURSIVE 0
-
-int pthread_mutex_lock(pthread_mutex_t* _mutex );
-int pthread_mutex_unlock( pthread_mutex_t* _mutex );
-int pthread_mutex_init(pthread_mutex_t* _mutex, void* ignoredAttr);
-int pthread_mutex_destroy(pthread_mutex_t* _mutex);
-int pthread_create(pthread_t *thread, const pthread_attr_t *attr, unsigned  (__stdcall* start_routine)(void* a), void *arg);
-int pthread_equal(pthread_t t1, pthread_t t2);
-pthread_t pthread_self();
-int pthread_join(pthread_t _thread, void** ignore);
-int pthread_detach(pthread_t _thread);
-
-void pthread_mutexattr_init(pthread_mutexattr_t* ignore);
-void pthread_mutexattr_settype(pthread_mutexattr_t* ingore_attr, int ignore);
-void pthread_mutexattr_destroy(pthread_mutexattr_t* ignore_attr);
-
-
-// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
- 
-typedef struct 
-{
-       int waiters_count_;
-    // Number of waiting threads.
-
-    CRITICAL_SECTION waiters_count_lock_;
-    // Serialize access to <waiters_count_>.
-
-    HANDLE sema_;
-       // Semaphore used to queue up threads waiting for the condition to
-    // become signaled. 
-
-    HANDLE waiters_done_;
-    // An auto-reset event used by the broadcast/signal thread to wait
-    // for all the waiting thread(s) to wake up and be released from the
-    // semaphore. 
-
-    size_t was_broadcast_;
-    // Keeps track of whether we were broadcasting or signaling.  This
-    // allows us to optimize the code if we're just signaling.
-}pthread_cond_t;
-       
-int pthread_cond_init (pthread_cond_t *cv,const pthread_condattr_t * ignore);
-int pthread_cond_destroy(pthread_cond_t *cond);
-int pthread_cond_signal (pthread_cond_t *cv);
-int pthread_cond_broadcast (pthread_cond_t *cv);
-int pthread_cond_wait (pthread_cond_t *cv, pthread_mutex_t *external_mutex);
-
-
-struct pthread_key_t_
-{
-  DWORD key;
-  void (*destructor) (void *);  
-};
-
-typedef struct pthread_key_t_ pthread_key_t;
-int pthread_key_create(pthread_key_t *key, void (*destructor)(void *) );
-int pthread_key_delete(pthread_key_t key);
-void *pthread_getspecific(pthread_key_t key);
-int pthread_setspecific(pthread_key_t key, const void *value);
-
-int gettimeofday(struct timeval *tp, void *tzp);
-int close(SOCKET fd);
-int Win32WSAStartup();
-void Win32WSACleanup();
-#endif //WIN32
-
-
-
-#endif //WINPORT_H_

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/zk_adaptor.h
----------------------------------------------------------------------
diff --git a/src/c/src/zk_adaptor.h b/src/c/src/zk_adaptor.h
deleted file mode 100644
index b990779..0000000
--- a/src/c/src/zk_adaptor.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ZK_ADAPTOR_H_
-#define ZK_ADAPTOR_H_
-#include <zookeeper.jute.h>
-#ifdef THREADED
-#ifndef WIN32
-#include <pthread.h>
-#else
-#include "winport.h"
-#endif
-#endif
-#include "zookeeper.h"
-#include "zk_hashtable.h"
-
-/* predefined xid's values recognized as special by the server */
-#define WATCHER_EVENT_XID -1 
-#define PING_XID -2
-#define AUTH_XID -4
-#define SET_WATCHES_XID -8
-
-/* zookeeper state constants */
-#define EXPIRED_SESSION_STATE_DEF -112
-#define AUTH_FAILED_STATE_DEF -113
-#define CONNECTING_STATE_DEF 1
-#define ASSOCIATING_STATE_DEF 2
-#define CONNECTED_STATE_DEF 3
-#define NOTCONNECTED_STATE_DEF 999
-
-/* zookeeper event type constants */
-#define CREATED_EVENT_DEF 1
-#define DELETED_EVENT_DEF 2
-#define CHANGED_EVENT_DEF 3
-#define CHILD_EVENT_DEF 4
-#define SESSION_EVENT_DEF -1
-#define NOTWATCHING_EVENT_DEF -2
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct _buffer_list;
-struct _completion_list;
-
-typedef struct _buffer_head {
-    struct _buffer_list *volatile head;
-    struct _buffer_list *last;
-#ifdef THREADED
-    pthread_mutex_t lock;
-#endif
-} buffer_head_t;
-
-typedef struct _completion_head {
-    struct _completion_list *volatile head;
-    struct _completion_list *last;
-#ifdef THREADED
-    pthread_cond_t cond;
-    pthread_mutex_t lock;
-#endif
-} completion_head_t;
-
-int lock_buffer_list(buffer_head_t *l);
-int unlock_buffer_list(buffer_head_t *l);
-int lock_completion_list(completion_head_t *l);
-int unlock_completion_list(completion_head_t *l);
-
-struct sync_completion {
-    int rc;
-    union {
-        struct {
-            char *str;
-            int str_len;
-        } str;
-        struct Stat stat;
-        struct {
-            char *buffer;
-            int buff_len;
-            struct Stat stat;
-        } data;
-        struct {
-            struct ACL_vector acl;
-            struct Stat stat;
-        } acl;
-        struct String_vector strs2;
-        struct {
-            struct String_vector strs2;
-            struct Stat stat2;
-        } strs_stat;
-    } u;
-    int complete;
-#ifdef THREADED
-    pthread_cond_t cond;
-    pthread_mutex_t lock;
-#endif
-};
-
-typedef struct _auth_info {
-    int state; /* 0=>inactive, >0 => active */
-    char* scheme;
-    struct buffer auth;
-    void_completion_t completion;
-    const char* data;
-    struct _auth_info *next;
-} auth_info;
-
-/**
- * This structure represents a packet being read or written.
- */
-typedef struct _buffer_list {
-    char *buffer;
-    int len; /* This represents the length of sizeof(header) + length of buffer */
-    int curr_offset; /* This is the offset into the header followed by offset into the buffer */
-    struct _buffer_list *next;
-} buffer_list_t;
-
-/* the size of connect request */
-#define HANDSHAKE_REQ_SIZE 44
-/* connect request */
-struct connect_req {
-    int32_t protocolVersion;
-    int64_t lastZxidSeen;
-    int32_t timeOut;
-    int64_t sessionId;
-    int32_t passwd_len;
-    char passwd[16];
-};
-
-/* the connect response */
-struct prime_struct {
-    int32_t len;
-    int32_t protocolVersion;
-    int32_t timeOut;
-    int64_t sessionId;
-    int32_t passwd_len;
-    char passwd[16];
-}; 
-
-#ifdef THREADED
-/* this is used by mt_adaptor internally for thread management */
-struct adaptor_threads {
-     pthread_t io;
-     pthread_t completion;
-     int threadsToWait;         // barrier
-     pthread_cond_t cond;       // barrier's conditional
-     pthread_mutex_t lock;      // ... and a lock
-     pthread_mutex_t zh_lock;   // critical section lock
-#ifdef WIN32
-     SOCKET self_pipe[2];
-#else
-     int self_pipe[2];
-#endif
-};
-#endif
-
-/** the auth list for adding auth */
-typedef struct _auth_list_head {
-     auth_info *auth;
-#ifdef THREADED
-     pthread_mutex_t lock;
-#endif
-} auth_list_head_t;
-
-/**
- * This structure represents the connection to zookeeper.
- */
-
-struct _zhandle {
-#ifdef WIN32
-    SOCKET fd; /* the descriptor used to talk to zookeeper */
-#else
-    int fd; /* the descriptor used to talk to zookeeper */
-#endif
-    char *hostname; /* the hostname of zookeeper */
-    struct sockaddr_storage *addrs; /* the addresses that correspond to the hostname */
-    int addrs_count; /* The number of addresses in the addrs array */
-    watcher_fn watcher; /* the registered watcher */
-    struct timeval last_recv; /* The time that the last message was received */
-    struct timeval last_send; /* The time that the last message was sent */
-    struct timeval last_ping; /* The time that the last PING was sent */
-    struct timeval next_deadline; /* The time of the next deadline */
-    int recv_timeout; /* The maximum amount of time that can go by without 
-     receiving anything from the zookeeper server */
-    buffer_list_t *input_buffer; /* the current buffer being read in */
-    buffer_head_t to_process; /* The buffers that have been read and are ready to be processed. */
-    buffer_head_t to_send; /* The packets queued to send */
-    completion_head_t sent_requests; /* The outstanding requests */
-    completion_head_t completions_to_process; /* completions that are ready to run */
-    int connect_index; /* The index of the address to connect to */
-    clientid_t client_id;
-    long long last_zxid;
-    int outstanding_sync; /* Number of outstanding synchronous requests */
-    struct _buffer_list primer_buffer; /* The buffer used for the handshake at the start of a connection */
-    struct prime_struct primer_storage; /* the connect response */
-    char primer_storage_buffer[40]; /* the true size of primer_storage */
-    volatile int state;
-    void *context;
-    auth_list_head_t auth_h; /* authentication data list */
-    /* zookeeper_close is not reentrant because it de-allocates the zhandler. 
-     * This guard variable is used to defer the destruction of zhandle till 
-     * right before top-level API call returns to the caller */
-    int32_t ref_counter;
-    volatile int close_requested;
-    void *adaptor_priv;
-    /* Used for debugging only: non-zero value indicates the time when the zookeeper_process
-     * call returned while there was at least one unprocessed server response 
-     * available in the socket recv buffer */
-    struct timeval socket_readable;
-    
-    zk_hashtable* active_node_watchers;   
-    zk_hashtable* active_exist_watchers;
-    zk_hashtable* active_child_watchers;
-    /** used for chroot path at the client side **/
-    char *chroot;
-};
-
-
-int adaptor_init(zhandle_t *zh);
-void adaptor_finish(zhandle_t *zh);
-void adaptor_destroy(zhandle_t *zh);
-struct sync_completion *alloc_sync_completion(void);
-int wait_sync_completion(struct sync_completion *sc);
-void free_sync_completion(struct sync_completion *sc);
-void notify_sync_completion(struct sync_completion *sc);
-int adaptor_send_queue(zhandle_t *zh, int timeout);
-int process_async(int outstanding_sync);
-void process_completions(zhandle_t *zh);
-int flush_send_queue(zhandle_t*zh, int timeout);
-char* sub_string(zhandle_t *zh, const char* server_path);
-void free_duplicate_path(const char* free_path, const char* path);
-int zoo_lock_auth(zhandle_t *zh);
-int zoo_unlock_auth(zhandle_t *zh);
-
-// critical section guards
-int enter_critical(zhandle_t* zh);
-int leave_critical(zhandle_t* zh);
-// zhandle object reference counting
-void api_prolog(zhandle_t* zh);
-int api_epilog(zhandle_t *zh, int rc);
-int32_t get_xid();
-// returns the new value of the ref counter
-int32_t inc_ref_counter(zhandle_t* zh,int i);
-
-#ifdef THREADED
-// atomic post-increment
-int32_t fetch_and_add(volatile int32_t* operand, int incr);
-// in mt mode process session event asynchronously by the completion thread
-#define PROCESS_SESSION_EVENT(zh,newstate) queue_session_event(zh,newstate)
-#else
-// in single-threaded mode process session event immediately
-//#define PROCESS_SESSION_EVENT(zh,newstate) deliverWatchers(zh,ZOO_SESSION_EVENT,newstate,0)
-#define PROCESS_SESSION_EVENT(zh,newstate) queue_session_event(zh,newstate)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*ZK_ADAPTOR_H_*/
-
-

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/zk_hashtable.c
----------------------------------------------------------------------
diff --git a/src/c/src/zk_hashtable.c b/src/c/src/zk_hashtable.c
deleted file mode 100644
index 0efc5aa..0000000
--- a/src/c/src/zk_hashtable.c
+++ /dev/null
@@ -1,337 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "zk_hashtable.h"
-#include "zk_adaptor.h"
-#include "hashtable/hashtable.h"
-#include "hashtable/hashtable_itr.h"
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-
-typedef struct _watcher_object {
-    watcher_fn watcher;
-    void* context;
-    struct _watcher_object* next;
-} watcher_object_t;
-
-
-struct _zk_hashtable {
-    struct hashtable* ht;
-};
-
-struct watcher_object_list {
-    watcher_object_t* head;
-};
-
-/* the following functions are for testing only */
-typedef struct hashtable hashtable_impl;
-
-hashtable_impl* getImpl(zk_hashtable* ht){
-    return ht->ht;
-}
-
-watcher_object_t* getFirstWatcher(zk_hashtable* ht,const char* path)
-{
-    watcher_object_list_t* wl=hashtable_search(ht->ht,(void*)path);
-    if(wl!=0)
-        return wl->head;
-    return 0;
-}
-/* end of testing functions */
-
-watcher_object_t* clone_watcher_object(watcher_object_t* wo)
-{
-    watcher_object_t* res=calloc(1,sizeof(watcher_object_t));
-    assert(res);
-    res->watcher=wo->watcher;
-    res->context=wo->context;
-    return res;
-}
-
-static unsigned int string_hash_djb2(void *str) 
-{
-    unsigned int hash = 5381;
-    int c;
-    const char* cstr = (const char*)str;
-    while ((c = *cstr++))
-        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
-
-    return hash;
-}
-
-static int string_equal(void *key1,void *key2)
-{
-    return strcmp((const char*)key1,(const char*)key2)==0;
-}
-
-static watcher_object_t* create_watcher_object(watcher_fn watcher,void* ctx)
-{
-    watcher_object_t* wo=calloc(1,sizeof(watcher_object_t));
-    assert(wo);
-    wo->watcher=watcher;
-    wo->context=ctx;
-    return wo;
-}
-
-static watcher_object_list_t* create_watcher_object_list(watcher_object_t* head) 
-{
-    watcher_object_list_t* wl=calloc(1,sizeof(watcher_object_list_t));
-    assert(wl);
-    wl->head=head;
-    return wl;
-}
-
-static void destroy_watcher_object_list(watcher_object_list_t* list)
-{
-    watcher_object_t* e = NULL;
-
-    if(list==0)
-        return;
-    e=list->head;
-    while(e!=0){
-        watcher_object_t* this=e;
-        e=e->next;
-        free(this);
-    }
-    free(list);
-}
-
-zk_hashtable* create_zk_hashtable()
-{
-    struct _zk_hashtable *ht=calloc(1,sizeof(struct _zk_hashtable));
-    assert(ht);
-    ht->ht=create_hashtable(32,string_hash_djb2,string_equal);
-    return ht;
-}
-
-static void do_clean_hashtable(zk_hashtable* ht)
-{
-    struct hashtable_itr *it;
-    int hasMore;
-    if(hashtable_count(ht->ht)==0)
-        return;
-    it=hashtable_iterator(ht->ht);
-    do {
-        watcher_object_list_t* w=hashtable_iterator_value(it);
-        destroy_watcher_object_list(w);
-        hasMore=hashtable_iterator_remove(it);
-    } while(hasMore);
-    free(it);
-}
-
-void destroy_zk_hashtable(zk_hashtable* ht)
-{
-    if(ht!=0){
-        do_clean_hashtable(ht);
-        hashtable_destroy(ht->ht,0);
-        free(ht);
-    }
-}
-
-// searches for a watcher object instance in a watcher object list;
-// two watcher objects are equal if their watcher function and context pointers
-// are equal
-static watcher_object_t* search_watcher(watcher_object_list_t** wl,watcher_object_t* wo)
-{
-    watcher_object_t* wobj=(*wl)->head;
-    while(wobj!=0){
-        if(wobj->watcher==wo->watcher && wobj->context==wo->context)
-            return wobj;
-        wobj=wobj->next;
-    }
-    return 0;
-}
-
-static int add_to_list(watcher_object_list_t **wl, watcher_object_t *wo,
-                       int clone)
-{
-    if (search_watcher(wl, wo)==0) {
-        watcher_object_t* cloned=wo;
-        if (clone) {
-            cloned = clone_watcher_object(wo);
-            assert(cloned);
-        }
-        cloned->next = (*wl)->head;
-        (*wl)->head = cloned;
-        return 1;
-    } else if (!clone) {
-        // If it's here and we aren't supposed to clone, we must destroy
-        free(wo);
-    }
-    return 0;
-}
-
-static int do_insert_watcher_object(zk_hashtable *ht, const char *path, watcher_object_t* wo)
-{
-    int res=1;
-    watcher_object_list_t* wl;
-
-    wl=hashtable_search(ht->ht,(void*)path);
-    if(wl==0){
-        int res;
-        /* inserting a new path element */
-        res=hashtable_insert(ht->ht,strdup(path),create_watcher_object_list(wo));
-        assert(res);
-    }else{
-        /*
-         * Path already exists; check if the watcher already exists.
-         * Don't clone the watcher since it's allocated on the heap --- avoids
-         * a memory leak and saves a clone operation (calloc + copy).
-         */
-        res = add_to_list(&wl, wo, 0);
-    }
-    return res;    
-}
-
-
-char **collect_keys(zk_hashtable *ht, int *count)
-{
-    char **list;
-    struct hashtable_itr *it;
-    int i;
-
-    *count = hashtable_count(ht->ht);
-    list = calloc(*count, sizeof(char*));
-    it=hashtable_iterator(ht->ht);
-    for(i = 0; i < *count; i++) {
-        list[i] = strdup(hashtable_iterator_key(it));
-        hashtable_iterator_advance(it);
-    }
-    free(it);
-    return list;
-}
-
-static int insert_watcher_object(zk_hashtable *ht, const char *path,
-                                 watcher_object_t* wo)
-{
-    int res;
-    res=do_insert_watcher_object(ht,path,wo);
-    return res;
-}
-
-static void copy_watchers(watcher_object_list_t *from, watcher_object_list_t *to, int clone)
-{
-    watcher_object_t* wo=from->head;
-    while(wo){
-        watcher_object_t *next = wo->next;
-        add_to_list(&to, wo, clone);
-        wo=next;
-    }
-}
-
-static void copy_table(zk_hashtable *from, watcher_object_list_t *to) {
-    struct hashtable_itr *it;
-    int hasMore;
-    if(hashtable_count(from->ht)==0)
-        return;
-    it=hashtable_iterator(from->ht);
-    do {
-        watcher_object_list_t *w = hashtable_iterator_value(it);
-        copy_watchers(w, to, 1);
-        hasMore=hashtable_iterator_advance(it);
-    } while(hasMore);
-    free(it);
-}
-
-static void collect_session_watchers(zhandle_t *zh,
-                                     watcher_object_list_t **list)
-{
-    copy_table(zh->active_node_watchers, *list);
-    copy_table(zh->active_exist_watchers, *list);
-    copy_table(zh->active_child_watchers, *list);
-}
-
-static void add_for_event(zk_hashtable *ht, char *path, watcher_object_list_t **list)
-{
-    watcher_object_list_t* wl;
-    wl = (watcher_object_list_t*)hashtable_remove(ht->ht, path);
-    if (wl) {
-        copy_watchers(wl, *list, 0);
-        // Since we move, not clone the watch_objects, we just need to free the
-        // head pointer
-        free(wl);
-    }
-}
-
-static void do_foreach_watcher(watcher_object_t* wo,zhandle_t* zh,
-        const char* path,int type,int state)
-{
-    // session event's don't have paths
-    const char *client_path =
-        (type != ZOO_SESSION_EVENT ? sub_string(zh, path) : path);
-    while(wo!=0){
-        wo->watcher(zh,type,state,client_path,wo->context);
-        wo=wo->next;
-    }    
-    free_duplicate_path(client_path, path);
-}
-
-watcher_object_list_t *collectWatchers(zhandle_t *zh,int type, char *path)
-{
-    struct watcher_object_list *list = create_watcher_object_list(0); 
-
-    if(type==ZOO_SESSION_EVENT){
-        watcher_object_t defWatcher;
-        defWatcher.watcher=zh->watcher;
-        defWatcher.context=zh->context;
-        add_to_list(&list, &defWatcher, 1);
-        collect_session_watchers(zh, &list);
-        return list;
-    }
-    switch(type){
-    case CREATED_EVENT_DEF:
-    case CHANGED_EVENT_DEF:
-        // look up the watchers for the path and move them to a delivery list
-        add_for_event(zh->active_node_watchers,path,&list);
-        add_for_event(zh->active_exist_watchers,path,&list);
-        break;
-    case CHILD_EVENT_DEF:
-        // look up the watchers for the path and move them to a delivery list
-        add_for_event(zh->active_child_watchers,path,&list);
-        break;
-    case DELETED_EVENT_DEF:
-        // look up the watchers for the path and move them to a delivery list
-        add_for_event(zh->active_node_watchers,path,&list);
-        add_for_event(zh->active_exist_watchers,path,&list);
-        add_for_event(zh->active_child_watchers,path,&list);
-        break;
-    }
-    return list;
-}
-
-void deliverWatchers(zhandle_t *zh, int type,int state, char *path, watcher_object_list_t **list)
-{
-    if (!list || !(*list)) return;
-    do_foreach_watcher((*list)->head, zh, path, type, state);
-    destroy_watcher_object_list(*list);
-    *list = 0;
-}
-
-void activateWatcher(zhandle_t *zh, watcher_registration_t* reg, int rc)
-{
-    if(reg){
-        /* in multithreaded lib, this code is executed 
-         * by the IO thread */
-        zk_hashtable *ht = reg->checker(zh, rc);
-        if(ht){
-            insert_watcher_object(ht,reg->path,
-                    create_watcher_object(reg->watcher, reg->context));
-        }
-    }    
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/zk_hashtable.h
----------------------------------------------------------------------
diff --git a/src/c/src/zk_hashtable.h b/src/c/src/zk_hashtable.h
deleted file mode 100644
index 31109c1..0000000
--- a/src/c/src/zk_hashtable.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ZK_HASHTABLE_H_
-#define ZK_HASHTABLE_H_
-
-#include <zookeeper.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-    typedef struct watcher_object_list watcher_object_list_t;
-typedef struct _zk_hashtable zk_hashtable;
-
-/**
- * The function must return a non-zero value if the watcher object can be activated
- * as a result of the server response. Normally, a watch can only be activated
- * if the server returns a success code (ZOK). However in the case when zoo_exists() 
- * returns a ZNONODE code the watcher should be activated nevertheless.
- */
-typedef zk_hashtable *(*result_checker_fn)(zhandle_t *, int rc);
-
-/**
- * A watcher object gets temporarily stored with the completion entry until 
- * the server response comes back at which moment the watcher object is moved
- * to the active watchers map.
- */
-typedef struct _watcher_registration {
-    watcher_fn watcher;
-    void* context;
-    result_checker_fn checker;
-    const char* path;
-} watcher_registration_t;
-
-zk_hashtable* create_zk_hashtable();
-void destroy_zk_hashtable(zk_hashtable* ht);
-
-char **collect_keys(zk_hashtable *ht, int *count);
-
-/**
- * check if the completion has a watcher object associated
- * with it. If it does, move the watcher object to the map of
- * active watchers (only if the checker allows to do so)
- */
-    void activateWatcher(zhandle_t *zh, watcher_registration_t* reg, int rc);
-    watcher_object_list_t *collectWatchers(zhandle_t *zh,int type, char *path);
-    void deliverWatchers(zhandle_t *zh, int type, int state, char *path, struct watcher_object_list **list);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*ZK_HASHTABLE_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/zk_log.c
----------------------------------------------------------------------
diff --git a/src/c/src/zk_log.c b/src/c/src/zk_log.c
deleted file mode 100644
index 6b4fdfa..0000000
--- a/src/c/src/zk_log.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#if !defined(DLL_EXPORT) && !defined(USE_STATIC_LIB)
-#  define USE_STATIC_LIB
-#endif
-
-#include "zookeeper_log.h"
-#ifndef WIN32
-#include <unistd.h>
-#else
-typedef DWORD pid_t;
-#include <process.h> /* for getpid */
-#endif
-
-#include <stdarg.h>
-#include <time.h>
-
-#define TIME_NOW_BUF_SIZE 1024
-#define FORMAT_LOG_BUF_SIZE 4096
-
-#ifdef THREADED
-#ifndef WIN32
-#include <pthread.h>
-#else 
-#include "winport.h"
-#endif
-
-static pthread_key_t time_now_buffer;
-static pthread_key_t format_log_msg_buffer;
-
-void freeBuffer(void* p){
-    if(p) free(p);
-}
-
-__attribute__((constructor)) void prepareTSDKeys() {
-    pthread_key_create (&time_now_buffer, freeBuffer);
-    pthread_key_create (&format_log_msg_buffer, freeBuffer);
-}
-
-char* getTSData(pthread_key_t key,int size){
-    char* p=pthread_getspecific(key);
-    if(p==0){
-        int res;
-        p=calloc(1,size);
-        res=pthread_setspecific(key,p);
-        if(res!=0){
-            fprintf(stderr,"Failed to set TSD key: %d",res);
-        }
-    }
-    return p;
-}
-
-char* get_time_buffer(){
-    return getTSData(time_now_buffer,TIME_NOW_BUF_SIZE);
-}
-
-char* get_format_log_buffer(){  
-    return getTSData(format_log_msg_buffer,FORMAT_LOG_BUF_SIZE);
-}
-#else
-char* get_time_buffer(){
-    static char buf[TIME_NOW_BUF_SIZE];
-    return buf;    
-}
-
-char* get_format_log_buffer(){
-    static char buf[FORMAT_LOG_BUF_SIZE];
-    return buf;
-}
-
-#endif
-
-ZooLogLevel logLevel=ZOO_LOG_LEVEL_INFO;
-
-static FILE* logStream=0;
-FILE* getLogStream(){
-    if(logStream==0)
-        logStream=stderr;
-    return logStream;
-}
-
-void zoo_set_log_stream(FILE* stream){
-    logStream=stream;
-}
-
-static const char* time_now(char* now_str){
-    struct timeval tv;
-    struct tm lt;
-    time_t now = 0;
-    size_t len = 0;
-    
-    gettimeofday(&tv,0);
-
-    now = tv.tv_sec;
-    localtime_r(&now, &lt);
-
-    // clone the format used by log4j ISO8601DateFormat
-    // specifically: "yyyy-MM-dd HH:mm:ss,SSS"
-
-    len = strftime(now_str, TIME_NOW_BUF_SIZE,
-                          "%Y-%m-%d %H:%M:%S",
-                          &lt);
-
-    len += snprintf(now_str + len,
-                    TIME_NOW_BUF_SIZE - len,
-                    ",%03d",
-                    (int)(tv.tv_usec/1000));
-
-    return now_str;
-}
-
-void log_message(ZooLogLevel curLevel,int line,const char* funcName,
-    const char* message)
-{
-    static const char* dbgLevelStr[]={"ZOO_INVALID","ZOO_ERROR","ZOO_WARN",
-            "ZOO_INFO","ZOO_DEBUG"};
-    static pid_t pid=0;
-#ifdef WIN32
-    char timebuf [TIME_NOW_BUF_SIZE];
-#endif
-    if(pid==0)pid=getpid();
-#ifndef THREADED
-    // pid_t is long on Solaris
-    fprintf(LOGSTREAM, "%s:%ld:%s@%s@%d: %s\n", time_now(get_time_buffer()),(long)pid,
-            dbgLevelStr[curLevel],funcName,line,message);
-#else
-#ifdef WIN32
-    fprintf(LOGSTREAM, "%s:%d(0x%lx):%s@%s@%d: %s\n", time_now(timebuf),pid,
-            (unsigned long int)(pthread_self().thread_id),
-            dbgLevelStr[curLevel],funcName,line,message);      
-#else
-    fprintf(LOGSTREAM, "%s:%ld(0x%lx):%s@%s@%d: %s\n", time_now(get_time_buffer()),(long)pid,
-            (unsigned long int)pthread_self(),
-            dbgLevelStr[curLevel],funcName,line,message);      
-#endif
-#endif
-    fflush(LOGSTREAM);
-}
-
-const char* format_log_message(const char* format,...)
-{
-    va_list va;
-    char* buf=get_format_log_buffer();
-    if(!buf)
-        return "format_log_message: Unable to allocate memory buffer";
-    
-    va_start(va,format);
-    vsnprintf(buf, FORMAT_LOG_BUF_SIZE-1,format,va);
-    va_end(va); 
-    return buf;
-}
-
-void zoo_set_debug_level(ZooLogLevel level)
-{
-    if(level==0){
-        // disable logging (unit tests do this)
-        logLevel=(ZooLogLevel)0;
-        return;
-    }
-    if(level<ZOO_LOG_LEVEL_ERROR)level=ZOO_LOG_LEVEL_ERROR;
-    if(level>ZOO_LOG_LEVEL_DEBUG)level=ZOO_LOG_LEVEL_DEBUG;
-    logLevel=level;
-}
-


[08/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/include/zookeeper.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/include/zookeeper.h b/zookeeper-client/zookeeper-client-c/include/zookeeper.h
new file mode 100644
index 0000000..aee865b
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/include/zookeeper.h
@@ -0,0 +1,1589 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ZOOKEEPER_H_
+#define ZOOKEEPER_H_
+
+#include <stdlib.h>
+
+/* we must not include config.h as a public header */
+#ifndef WIN32
+#include <sys/socket.h>
+#include <sys/time.h>
+#endif
+
+#ifdef WIN32
+#include <winsock2.h> /* must always be included before ws2tcpip.h */
+#include <ws2tcpip.h> /* for struct sock_addr and socklen_t */
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include "proto.h"
+#include "zookeeper_version.h"
+#include "recordio.h"
+#include "zookeeper.jute.h"
+
+/**
+ * \file zookeeper.h 
+ * \brief ZooKeeper functions and definitions.
+ * 
+ * ZooKeeper is a network service that may be backed by a cluster of
+ * synchronized servers. The data in the service is represented as a tree
+ * of data nodes. Each node has data, children, an ACL, and status information.
+ * The data for a node is read and write in its entirety.
+ * 
+ * ZooKeeper clients can leave watches when they queries the data or children
+ * of a node. If a watch is left, that client will be notified of the change.
+ * The notification is a one time trigger. Subsequent chances to the node will
+ * not trigger a notification unless the client issues a query with the watch
+ * flag set. If the client is ever disconnected from the service, the watches do 
+ * not need to be reset. The client automatically resets the watches.
+ * 
+ * When a node is created, it may be flagged as an ephemeral node. Ephemeral
+ * nodes are automatically removed when a client session is closed or when
+ * a session times out due to inactivity (the ZooKeeper runtime fills in
+ * periods of inactivity with pings). Ephemeral nodes cannot have children.
+ * 
+ * ZooKeeper clients are identified by a server assigned session id. For
+ * security reasons The server
+ * also generates a corresponding password for a session. A client may save its
+ * id and corresponding password to persistent storage in order to use the
+ * session across program invocation boundaries.
+ */
+
+/* Support for building on various platforms */
+
+// on cygwin we should take care of exporting/importing symbols properly 
+#ifdef DLL_EXPORT
+#    define ZOOAPI __declspec(dllexport)
+#else
+#  if (defined(__CYGWIN__) || defined(WIN32)) && !defined(USE_STATIC_LIB)
+#    define ZOOAPI __declspec(dllimport)
+#  else
+#    define ZOOAPI
+#  endif
+#endif
+
+/** zookeeper return constants **/
+
+enum ZOO_ERRORS {
+  ZOK = 0, /*!< Everything is OK */
+
+  /** System and server-side errors.
+   * This is never thrown by the server, it shouldn't be used other than
+   * to indicate a range. Specifically error codes greater than this
+   * value, but lesser than {@link #ZAPIERROR}, are system errors. */
+  ZSYSTEMERROR = -1,
+  ZRUNTIMEINCONSISTENCY = -2, /*!< A runtime inconsistency was found */
+  ZDATAINCONSISTENCY = -3, /*!< A data inconsistency was found */
+  ZCONNECTIONLOSS = -4, /*!< Connection to the server has been lost */
+  ZMARSHALLINGERROR = -5, /*!< Error while marshalling or unmarshalling data */
+  ZUNIMPLEMENTED = -6, /*!< Operation is unimplemented */
+  ZOPERATIONTIMEOUT = -7, /*!< Operation timeout */
+  ZBADARGUMENTS = -8, /*!< Invalid arguments */
+  ZINVALIDSTATE = -9, /*!< Invliad zhandle state */
+
+  /** API errors.
+   * This is never thrown by the server, it shouldn't be used other than
+   * to indicate a range. Specifically error codes greater than this
+   * value are API errors (while values less than this indicate a 
+   * {@link #ZSYSTEMERROR}).
+   */
+  ZAPIERROR = -100,
+  ZNONODE = -101, /*!< Node does not exist */
+  ZNOAUTH = -102, /*!< Not authenticated */
+  ZBADVERSION = -103, /*!< Version conflict */
+  ZNOCHILDRENFOREPHEMERALS = -108, /*!< Ephemeral nodes may not have children */
+  ZNODEEXISTS = -110, /*!< The node already exists */
+  ZNOTEMPTY = -111, /*!< The node has children */
+  ZSESSIONEXPIRED = -112, /*!< The session has been expired by the server */
+  ZINVALIDCALLBACK = -113, /*!< Invalid callback specified */
+  ZINVALIDACL = -114, /*!< Invalid ACL specified */
+  ZAUTHFAILED = -115, /*!< Client authentication failed */
+  ZCLOSING = -116, /*!< ZooKeeper is closing */
+  ZNOTHING = -117, /*!< (not error) no server responses to process */
+  ZSESSIONMOVED = -118 /*!<session moved to another server, so operation is ignored */ 
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+*  @name Debug levels
+*/
+typedef enum {ZOO_LOG_LEVEL_ERROR=1,ZOO_LOG_LEVEL_WARN=2,ZOO_LOG_LEVEL_INFO=3,ZOO_LOG_LEVEL_DEBUG=4} ZooLogLevel;
+
+/**
+ * @name ACL Consts
+ */
+extern ZOOAPI const int ZOO_PERM_READ;
+extern ZOOAPI const int ZOO_PERM_WRITE;
+extern ZOOAPI const int ZOO_PERM_CREATE;
+extern ZOOAPI const int ZOO_PERM_DELETE;
+extern ZOOAPI const int ZOO_PERM_ADMIN;
+extern ZOOAPI const int ZOO_PERM_ALL;
+
+/** This Id represents anyone. */
+extern ZOOAPI struct Id ZOO_ANYONE_ID_UNSAFE;
+/** This Id is only usable to set ACLs. It will get substituted with the
+ * Id's the client authenticated with.
+ */
+extern ZOOAPI struct Id ZOO_AUTH_IDS;
+
+/** This is a completely open ACL*/
+extern ZOOAPI struct ACL_vector ZOO_OPEN_ACL_UNSAFE;
+/** This ACL gives the world the ability to read. */
+extern ZOOAPI struct ACL_vector ZOO_READ_ACL_UNSAFE;
+/** This ACL gives the creators authentication id's all permissions. */
+extern ZOOAPI struct ACL_vector ZOO_CREATOR_ALL_ACL;
+
+/**
+ * @name Interest Consts
+ * These constants are used to express interest in an event and to
+ * indicate to zookeeper which events have occurred. They can
+ * be ORed together to express multiple interests. These flags are
+ * used in the interest and event parameters of 
+ * \ref zookeeper_interest and \ref zookeeper_process.
+ */
+// @{
+extern ZOOAPI const int ZOOKEEPER_WRITE;
+extern ZOOAPI const int ZOOKEEPER_READ;
+// @}
+
+/**
+ * @name Create Flags
+ * 
+ * These flags are used by zoo_create to affect node create. They may
+ * be ORed together to combine effects.
+ */
+// @{
+extern ZOOAPI const int ZOO_EPHEMERAL;
+extern ZOOAPI const int ZOO_SEQUENCE;
+// @}
+
+/**
+ * @name State Consts
+ * These constants represent the states of a zookeeper connection. They are
+ * possible parameters of the watcher callback.
+ */
+// @{
+extern ZOOAPI const int ZOO_EXPIRED_SESSION_STATE;
+extern ZOOAPI const int ZOO_AUTH_FAILED_STATE;
+extern ZOOAPI const int ZOO_CONNECTING_STATE;
+extern ZOOAPI const int ZOO_ASSOCIATING_STATE;
+extern ZOOAPI const int ZOO_CONNECTED_STATE;
+// @}
+
+/**
+ * @name Watch Types
+ * These constants indicate the event that caused the watch event. They are
+ * possible values of the first parameter of the watcher callback.
+ */
+// @{
+/**
+ * \brief a node has been created.
+ * 
+ * This is only generated by watches on non-existent nodes. These watches
+ * are set using \ref zoo_exists.
+ */
+extern ZOOAPI const int ZOO_CREATED_EVENT;
+/**
+ * \brief a node has been deleted.
+ * 
+ * This is only generated by watches on nodes. These watches
+ * are set using \ref zoo_exists and \ref zoo_get.
+ */
+extern ZOOAPI const int ZOO_DELETED_EVENT;
+/**
+ * \brief a node has changed.
+ * 
+ * This is only generated by watches on nodes. These watches
+ * are set using \ref zoo_exists and \ref zoo_get.
+ */
+extern ZOOAPI const int ZOO_CHANGED_EVENT;
+/**
+ * \brief a change as occurred in the list of children.
+ * 
+ * This is only generated by watches on the child list of a node. These watches
+ * are set using \ref zoo_get_children or \ref zoo_get_children2.
+ */
+extern ZOOAPI const int ZOO_CHILD_EVENT;
+/**
+ * \brief a session has been lost.
+ * 
+ * This is generated when a client loses contact or reconnects with a server.
+ */
+extern ZOOAPI const int ZOO_SESSION_EVENT;
+
+/**
+ * \brief a watch has been removed.
+ * 
+ * This is generated when the server for some reason, probably a resource
+ * constraint, will no longer watch a node for a client.
+ */
+extern ZOOAPI const int ZOO_NOTWATCHING_EVENT;
+// @}
+
+/**
+ * \brief ZooKeeper handle.
+ * 
+ * This is the handle that represents a connection to the ZooKeeper service.
+ * It is needed to invoke any ZooKeeper function. A handle is obtained using
+ * \ref zookeeper_init.
+ */
+typedef struct _zhandle zhandle_t;
+
+/**
+ * \brief client id structure.
+ * 
+ * This structure holds the id and password for the session. This structure
+ * should be treated as opaque. It is received from the server when a session
+ * is established and needs to be sent back as-is when reconnecting a session.
+ */
+typedef struct {
+    int64_t client_id;
+    char passwd[16];
+} clientid_t;
+
+/**
+ * \brief zoo_op structure.
+ *
+ * This structure holds all the arguments necessary for one op as part
+ * of a containing multi_op via \ref zoo_multi or \ref zoo_amulti.
+ * This structure should be treated as opaque and initialized via 
+ * \ref zoo_create_op_init, \ref zoo_delete_op_init, \ref zoo_set_op_init
+ * and \ref zoo_check_op_init.
+ */
+typedef struct zoo_op {
+    int type;
+    union {
+        // CREATE
+        struct {
+            const char *path;
+            const char *data;
+            int datalen;
+	        char *buf;
+            int buflen;
+            const struct ACL_vector *acl;
+            int flags;
+        } create_op;
+
+        // DELETE 
+        struct {
+            const char *path;
+            int version;
+        } delete_op;
+        
+        // SET
+        struct {
+            const char *path;
+            const char *data;
+            int datalen;
+            int version;
+            struct Stat *stat;
+        } set_op;
+        
+        // CHECK
+        struct {
+            const char *path;
+            int version;
+        } check_op;
+    };
+} zoo_op_t;
+
+/**
+ * \brief zoo_create_op_init.
+ *
+ * This function initializes a zoo_op_t with the arguments for a ZOO_CREATE_OP.
+ *
+ * \param op A pointer to the zoo_op_t to be initialized.
+ * \param path The name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param value The data to be stored in the node.
+ * \param valuelen The number of bytes in data. To set the data to be NULL use
+ * value as NULL and valuelen as -1.
+ * \param acl The initial ACL of the node. The ACL must not be null or empty.
+ * \param flags this parameter can be set to 0 for normal create or an OR
+ *    of the Create Flags
+ * \param path_buffer Buffer which will be filled with the path of the
+ *    new node (this might be different than the supplied path
+ *    because of the ZOO_SEQUENCE flag).  The path string will always be
+ *    null-terminated. This parameter may be NULL if path_buffer_len = 0.
+ * \param path_buffer_len Size of path buffer; if the path of the new
+ *    node (including space for the null terminator) exceeds the buffer size,
+ *    the path string will be truncated to fit.  The actual path of the
+ *    new node in the server will not be affected by the truncation.
+ *    The path string will always be null-terminated.
+ */
+void zoo_create_op_init(zoo_op_t *op, const char *path, const char *value,
+        int valuelen,  const struct ACL_vector *acl, int flags, 
+        char *path_buffer, int path_buffer_len);
+
+/**
+ * \brief zoo_delete_op_init.
+ *
+ * This function initializes a zoo_op_t with the arguments for a ZOO_DELETE_OP.
+ *
+ * \param op A pointer to the zoo_op_t to be initialized.
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param version the expected version of the node. The function will fail if the
+ *    actual version of the node does not match the expected version.
+ *  If -1 is used the version check will not take place. 
+ */
+void zoo_delete_op_init(zoo_op_t *op, const char *path, int version);
+
+/**
+ * \brief zoo_set_op_init.
+ *
+ * This function initializes an zoo_op_t with the arguments for a ZOO_SETDATA_OP.
+ *
+ * \param op A pointer to the zoo_op_t to be initialized.
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param buffer the buffer holding data to be written to the node.
+ * \param buflen the number of bytes from buffer to write. To set NULL as data 
+ * use buffer as NULL and buflen as -1.
+ * \param version the expected version of the node. The function will fail if 
+ * the actual version of the node does not match the expected version. If -1 is 
+ * used the version check will not take place. 
+ */
+void zoo_set_op_init(zoo_op_t *op, const char *path, const char *buffer, 
+        int buflen, int version, struct Stat *stat);
+
+/**
+ * \brief zoo_check_op_init.
+ *
+ * This function initializes an zoo_op_t with the arguments for a ZOO_CHECK_OP.
+ *
+ * \param op A pointer to the zoo_op_t to be initialized.
+ * \param path The name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param version the expected version of the node. The function will fail if the
+ *    actual version of the node does not match the expected version.
+ */
+void zoo_check_op_init(zoo_op_t *op, const char *path, int version);
+
+/**
+ * \brief zoo_op_result structure.
+ *
+ * This structure holds the result for an op submitted as part of a multi_op
+ * via \ref zoo_multi or \ref zoo_amulti.
+ */
+typedef struct zoo_op_result {
+    int err;
+    char *value;
+	int valuelen;
+    struct Stat *stat;
+} zoo_op_result_t; 
+
+/**
+ * \brief signature of a watch function.
+ * 
+ * There are two ways to receive watch notifications: legacy and watcher object.
+ * <p>
+ * The legacy style, an application wishing to receive events from ZooKeeper must 
+ * first implement a function with this signature and pass a pointer to the function 
+ * to \ref zookeeper_init. Next, the application sets a watch by calling one of 
+ * the getter API that accept the watch integer flag (for example, \ref zoo_aexists, 
+ * \ref zoo_get, etc).
+ * <p>
+ * The watcher object style uses an instance of a "watcher object" which in 
+ * the C world is represented by a pair: a pointer to a function implementing this
+ * signature and a pointer to watcher context -- handback user-specific data. 
+ * When a watch is triggered this function will be called along with 
+ * the watcher context. An application wishing to use this style must use
+ * the getter API functions with the "w" prefix in their names (for example, \ref
+ * zoo_awexists, \ref zoo_wget, etc).
+ * 
+ * \param zh zookeeper handle
+ * \param type event type. This is one of the *_EVENT constants. 
+ * \param state connection state. The state value will be one of the *_STATE constants.
+ * \param path znode path for which the watcher is triggered. NULL if the event 
+ * type is ZOO_SESSION_EVENT
+ * \param watcherCtx watcher context.
+ */
+typedef void (*watcher_fn)(zhandle_t *zh, int type, 
+        int state, const char *path,void *watcherCtx);
+
+/**
+ * \brief create a handle to used communicate with zookeeper.
+ * 
+ * This method creates a new handle and a zookeeper session that corresponds
+ * to that handle. Session establishment is asynchronous, meaning that the
+ * session should not be considered established until (and unless) an
+ * event of state ZOO_CONNECTED_STATE is received.
+ * \param host comma separated host:port pairs, each corresponding to a zk
+ *   server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002"
+ * \param fn the global watcher callback function. When notifications are
+ *   triggered this function will be invoked.
+ * \param clientid the id of a previously established session that this
+ *   client will be reconnecting to. Pass 0 if not reconnecting to a previous
+ *   session. Clients can access the session id of an established, valid,
+ *   connection by calling \ref zoo_client_id. If the session corresponding to
+ *   the specified clientid has expired, or if the clientid is invalid for 
+ *   any reason, the returned zhandle_t will be invalid -- the zhandle_t 
+ *   state will indicate the reason for failure (typically
+ *   ZOO_EXPIRED_SESSION_STATE).
+ * \param context the handback object that will be associated with this instance 
+ *   of zhandle_t. Application can access it (for example, in the watcher 
+ *   callback) using \ref zoo_get_context. The object is not used by zookeeper 
+ *   internally and can be null.
+ * \param flags reserved for future use. Should be set to zero.
+ * \return a pointer to the opaque zhandle structure. If it fails to create 
+ * a new zhandle the function returns NULL and the errno variable 
+ * indicates the reason.
+ */
+ZOOAPI zhandle_t *zookeeper_init(const char *host, watcher_fn fn,
+  int recv_timeout, const clientid_t *clientid, void *context, int flags);
+
+/**
+ * \brief close the zookeeper handle and free up any resources.
+ * 
+ * After this call, the client session will no longer be valid. The function
+ * will flush any outstanding send requests before return. As a result it may 
+ * block.
+ *
+ * This method should only be called only once on a zookeeper handle. Calling
+ * twice will cause undefined (and probably undesirable behavior). Calling any other
+ * zookeeper method after calling close is undefined behaviour and should be avoided.
+ *
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \return a result code. Regardless of the error code returned, the zhandle 
+ * will be destroyed and all resources freed. 
+ *
+ * ZOK - success
+ * ZBADARGUMENTS - invalid input parameters
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ * ZOPERATIONTIMEOUT - failed to flush the buffers within the specified timeout.
+ * ZCONNECTIONLOSS - a network error occurred while attempting to send request to server
+ * ZSYSTEMERROR -- a system (OS) error occurred; it's worth checking errno to get details
+ */
+ZOOAPI int zookeeper_close(zhandle_t *zh);
+
+/**
+ * \brief return the client session id, only valid if the connections
+ * is currently connected (ie. last watcher state is ZOO_CONNECTED_STATE)
+ */
+ZOOAPI const clientid_t *zoo_client_id(zhandle_t *zh);
+
+/**
+ * \brief return the timeout for this session, only valid if the connections
+ * is currently connected (ie. last watcher state is ZOO_CONNECTED_STATE). This
+ * value may change after a server re-connect.
+ */
+ZOOAPI int zoo_recv_timeout(zhandle_t *zh);
+
+/**
+ * \brief return the context for this handle.
+ */
+ZOOAPI const void *zoo_get_context(zhandle_t *zh);
+
+/**
+ * \brief set the context for this handle.
+ */
+ZOOAPI void zoo_set_context(zhandle_t *zh, void *context);
+
+/**
+ * \brief set a watcher function
+ * \return previous watcher function
+ */
+ZOOAPI watcher_fn zoo_set_watcher(zhandle_t *zh,watcher_fn newFn);
+
+/**
+ * \brief returns the socket address for the current connection
+ * \return socket address of the connected host or NULL on failure, only valid if the
+ * connection is current connected
+ */
+ZOOAPI struct sockaddr* zookeeper_get_connected_host(zhandle_t *zh,
+        struct sockaddr *addr, socklen_t *addr_len);
+
+#ifndef THREADED
+/**
+ * \brief Returns the events that zookeeper is interested in.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param fd is the file descriptor of interest
+ * \param interest is an or of the ZOOKEEPER_WRITE and ZOOKEEPER_READ flags to
+ *    indicate the I/O of interest on fd.
+ * \param tv a timeout value to be used with select/poll system call
+ * \return a result code.
+ * ZOK - success
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZCONNECTIONLOSS - a network error occurred while attempting to establish 
+ * a connection to the server
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ * ZOPERATIONTIMEOUT - hasn't received anything from the server for 2/3 of the
+ * timeout value specified in zookeeper_init()
+ * ZSYSTEMERROR -- a system (OS) error occurred; it's worth checking errno to get details
+ */
+#ifdef WIN32
+ZOOAPI int zookeeper_interest(zhandle_t *zh, SOCKET *fd, int *interest, 
+	struct timeval *tv);
+#else
+ZOOAPI int zookeeper_interest(zhandle_t *zh, int *fd, int *interest, 
+	struct timeval *tv);
+#endif
+
+/**
+ * \brief Notifies zookeeper that an event of interest has happened.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param events will be an OR of the ZOOKEEPER_WRITE and ZOOKEEPER_READ flags.
+ * \return a result code. 
+ * ZOK - success
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZCONNECTIONLOSS - a network error occurred while attempting to send request to server
+ * ZSESSIONEXPIRED - connection attempt failed -- the session's expired
+ * ZAUTHFAILED - authentication request failed, e.i. invalid credentials
+ * ZRUNTIMEINCONSISTENCY - a server response came out of order
+ * ZSYSTEMERROR -- a system (OS) error occurred; it's worth checking errno to get details
+ * ZNOTHING -- not an error; simply indicates that there no more data from the server 
+ *              to be processed (when called with ZOOKEEPER_READ flag).
+ */
+ZOOAPI int zookeeper_process(zhandle_t *zh, int events);
+#endif
+
+/**
+ * \brief signature of a completion function for a call that returns void.
+ * 
+ * This method will be invoked at the end of a asynchronous call and also as 
+ * a result of connection loss or timeout.
+ * \param rc the error code of the call. Connection loss/timeout triggers 
+ * the completion with one of the following error codes:
+ * ZCONNECTIONLOSS -- lost connection to the server
+ * ZOPERATIONTIMEOUT -- connection timed out
+ * Data related events trigger the completion with error codes listed the 
+ * Exceptions section of the documentation of the function that initiated the
+ * call. (Zero indicates call was successful.)
+ * \param data the pointer that was passed by the caller when the function
+ *   that this completion corresponds to was invoked. The programmer
+ *   is responsible for any memory freeing associated with the data
+ *   pointer.
+ */
+typedef void (*void_completion_t)(int rc, const void *data);
+
+/**
+ * \brief signature of a completion function that returns a Stat structure.
+ * 
+ * This method will be invoked at the end of a asynchronous call and also as 
+ * a result of connection loss or timeout.
+ * \param rc the error code of the call. Connection loss/timeout triggers 
+ * the completion with one of the following error codes:
+ * ZCONNECTIONLOSS -- lost connection to the server
+ * ZOPERATIONTIMEOUT -- connection timed out
+ * Data related events trigger the completion with error codes listed the 
+ * Exceptions section of the documentation of the function that initiated the
+ * call. (Zero indicates call was successful.)
+ * \param stat a pointer to the stat information for the node involved in
+ *   this function. If a non zero error code is returned, the content of
+ *   stat is undefined. The programmer is NOT responsible for freeing stat.
+ * \param data the pointer that was passed by the caller when the function
+ *   that this completion corresponds to was invoked. The programmer
+ *   is responsible for any memory freeing associated with the data
+ *   pointer.
+ */
+typedef void (*stat_completion_t)(int rc, const struct Stat *stat,
+        const void *data);
+
+/**
+ * \brief signature of a completion function that returns data.
+ * 
+ * This method will be invoked at the end of a asynchronous call and also as 
+ * a result of connection loss or timeout.
+ * \param rc the error code of the call. Connection loss/timeout triggers 
+ * the completion with one of the following error codes:
+ * ZCONNECTIONLOSS -- lost connection to the server
+ * ZOPERATIONTIMEOUT -- connection timed out
+ * Data related events trigger the completion with error codes listed the 
+ * Exceptions section of the documentation of the function that initiated the
+ * call. (Zero indicates call was successful.)
+ * \param value the value of the information returned by the asynchronous call.
+ *   If a non zero error code is returned, the content of value is undefined.
+ *   The programmer is NOT responsible for freeing value.
+ * \param value_len the number of bytes in value.
+ * \param stat a pointer to the stat information for the node involved in
+ *   this function. If a non zero error code is returned, the content of
+ *   stat is undefined. The programmer is NOT responsible for freeing stat.
+ * \param data the pointer that was passed by the caller when the function
+ *   that this completion corresponds to was invoked. The programmer
+ *   is responsible for any memory freeing associated with the data
+ *   pointer.
+ */
+typedef void (*data_completion_t)(int rc, const char *value, int value_len,
+        const struct Stat *stat, const void *data);
+
+/**
+ * \brief signature of a completion function that returns a list of strings.
+ * 
+ * This method will be invoked at the end of a asynchronous call and also as 
+ * a result of connection loss or timeout.
+ * \param rc the error code of the call. Connection loss/timeout triggers 
+ * the completion with one of the following error codes:
+ * ZCONNECTIONLOSS -- lost connection to the server
+ * ZOPERATIONTIMEOUT -- connection timed out
+ * Data related events trigger the completion with error codes listed the 
+ * Exceptions section of the documentation of the function that initiated the
+ * call. (Zero indicates call was successful.)
+ * \param strings a pointer to the structure containng the list of strings of the
+ *   names of the children of a node. If a non zero error code is returned,
+ *   the content of strings is undefined. The programmer is NOT responsible
+ *   for freeing strings.
+ * \param data the pointer that was passed by the caller when the function
+ *   that this completion corresponds to was invoked. The programmer
+ *   is responsible for any memory freeing associated with the data
+ *   pointer.
+ */
+typedef void (*strings_completion_t)(int rc,
+        const struct String_vector *strings, const void *data);
+
+/**
+ * \brief signature of a completion function that returns a list of strings and stat.
+ * .
+ * 
+ * This method will be invoked at the end of a asynchronous call and also as 
+ * a result of connection loss or timeout.
+ * \param rc the error code of the call. Connection loss/timeout triggers 
+ * the completion with one of the following error codes:
+ * ZCONNECTIONLOSS -- lost connection to the server
+ * ZOPERATIONTIMEOUT -- connection timed out
+ * Data related events trigger the completion with error codes listed the 
+ * Exceptions section of the documentation of the function that initiated the
+ * call. (Zero indicates call was successful.)
+ * \param strings a pointer to the structure containng the list of strings of the
+ *   names of the children of a node. If a non zero error code is returned,
+ *   the content of strings is undefined. The programmer is NOT responsible
+ *   for freeing strings.
+ * \param stat a pointer to the stat information for the node involved in
+ *   this function. If a non zero error code is returned, the content of
+ *   stat is undefined. The programmer is NOT responsible for freeing stat.
+ * \param data the pointer that was passed by the caller when the function
+ *   that this completion corresponds to was invoked. The programmer
+ *   is responsible for any memory freeing associated with the data
+ *   pointer.
+ */
+typedef void (*strings_stat_completion_t)(int rc,
+        const struct String_vector *strings, const struct Stat *stat,
+        const void *data);
+
+/**
+ * \brief signature of a completion function that returns a list of strings.
+ * 
+ * This method will be invoked at the end of a asynchronous call and also as 
+ * a result of connection loss or timeout.
+ * \param rc the error code of the call. Connection loss/timeout triggers 
+ * the completion with one of the following error codes:
+ * ZCONNECTIONLOSS -- lost connection to the server
+ * ZOPERATIONTIMEOUT -- connection timed out
+ * Data related events trigger the completion with error codes listed the 
+ * Exceptions section of the documentation of the function that initiated the
+ * call. (Zero indicates call was successful.)
+ * \param value the value of the string returned.
+ * \param data the pointer that was passed by the caller when the function
+ *   that this completion corresponds to was invoked. The programmer
+ *   is responsible for any memory freeing associated with the data
+ *   pointer.
+ */
+typedef void
+        (*string_completion_t)(int rc, const char *value, const void *data);
+
+/**
+ * \brief signature of a completion function that returns an ACL.
+ * 
+ * This method will be invoked at the end of a asynchronous call and also as 
+ * a result of connection loss or timeout.
+ * \param rc the error code of the call. Connection loss/timeout triggers 
+ * the completion with one of the following error codes:
+ * ZCONNECTIONLOSS -- lost connection to the server
+ * ZOPERATIONTIMEOUT -- connection timed out
+ * Data related events trigger the completion with error codes listed the 
+ * Exceptions section of the documentation of the function that initiated the
+ * call. (Zero indicates call was successful.)
+ * \param acl a pointer to the structure containng the ACL of a node. If a non 
+ *   zero error code is returned, the content of strings is undefined. The
+ *   programmer is NOT responsible for freeing acl.
+ * \param stat a pointer to the stat information for the node involved in
+ *   this function. If a non zero error code is returned, the content of
+ *   stat is undefined. The programmer is NOT responsible for freeing stat.
+ * \param data the pointer that was passed by the caller when the function
+ *   that this completion corresponds to was invoked. The programmer
+ *   is responsible for any memory freeing associated with the data
+ *   pointer.
+ */
+typedef void (*acl_completion_t)(int rc, struct ACL_vector *acl,
+        struct Stat *stat, const void *data);
+
+/**
+ * \brief get the state of the zookeeper connection.
+ * 
+ * The return value will be one of the \ref State Consts.
+ */
+ZOOAPI int zoo_state(zhandle_t *zh);
+
+/**
+ * \brief create a node.
+ * 
+ * This method will create a node in ZooKeeper. A node can only be created if
+ * it does not already exists. The Create Flags affect the creation of nodes.
+ * If ZOO_EPHEMERAL flag is set, the node will automatically get removed if the
+ * client session goes away. If the ZOO_SEQUENCE flag is set, a unique
+ * monotonically increasing sequence number is appended to the path name. The
+ * sequence number is always fixed length of 10 digits, 0 padded.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path The name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param value The data to be stored in the node.
+ * \param valuelen The number of bytes in data.
+ * \param acl The initial ACL of the node. The ACL must not be null or empty.
+ * \param flags this parameter can be set to 0 for normal create or an OR
+ *    of the Create Flags
+ * \param completion the routine to invoke when the request completes. The completion
+ * will be triggered with one of the following codes passed in as the rc argument:
+ * ZOK operation completed successfully
+ * ZNONODE the parent node does not exist.
+ * ZNODEEXISTS the node already exists
+ * ZNOAUTH the client does not have permission.
+ * ZNOCHILDRENFOREPHEMERALS cannot create children of ephemeral nodes.
+ * \param data The data that will be passed to the completion routine when the 
+ * function completes.
+ * \return ZOK on success or one of the following errcodes on failure:
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_acreate(zhandle_t *zh, const char *path, const char *value, 
+        int valuelen, const struct ACL_vector *acl, int flags,
+        string_completion_t completion, const void *data);
+
+/**
+ * \brief delete a node in zookeeper.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param version the expected version of the node. The function will fail if the
+ *    actual version of the node does not match the expected version.
+ *  If -1 is used the version check will not take place. 
+ * \param completion the routine to invoke when the request completes. The completion
+ * will be triggered with one of the following codes passed in as the rc argument:
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * ZBADVERSION expected version does not match actual version.
+ * ZNOTEMPTY children are present; node cannot be deleted.
+ * \param data the data that will be passed to the completion routine when 
+ * the function completes.
+ * \return ZOK on success or one of the following errcodes on failure:
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_adelete(zhandle_t *zh, const char *path, int version, 
+        void_completion_t completion, const void *data);
+
+/**
+ * \brief checks the existence of a node in zookeeper.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param watch if nonzero, a watch will be set at the server to notify the 
+ * client if the node changes. The watch will be set even if the node does not 
+ * exist. This allows clients to watch for nodes to appear.
+ * \param completion the routine to invoke when the request completes. The completion
+ * will be triggered with one of the following codes passed in as the rc argument:
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * \param data the data that will be passed to the completion routine when the 
+ * function completes.
+ * \return ZOK on success or one of the following errcodes on failure:
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_aexists(zhandle_t *zh, const char *path, int watch, 
+        stat_completion_t completion, const void *data);
+
+/**
+ * \brief checks the existence of a node in zookeeper.
+ * 
+ * This function is similar to \ref zoo_axists except it allows one specify 
+ * a watcher object - a function pointer and associated context. The function
+ * will be called once the watch has fired. The associated context data will be 
+ * passed to the function as the watcher context parameter. 
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param watcher if non-null a watch will set on the specified znode on the server.
+ * The watch will be set even if the node does not exist. This allows clients 
+ * to watch for nodes to appear.
+ * \param watcherCtx user specific data, will be passed to the watcher callback.
+ * Unlike the global context set by \ref zookeeper_init, this watcher context
+ * is associated with the given instance of the watcher only.
+ * \param completion the routine to invoke when the request completes. The completion
+ * will be triggered with one of the following codes passed in as the rc argument:
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * \param data the data that will be passed to the completion routine when the 
+ * function completes.
+ * \return ZOK on success or one of the following errcodes on failure:
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_awexists(zhandle_t *zh, const char *path, 
+        watcher_fn watcher, void* watcherCtx, 
+        stat_completion_t completion, const void *data);
+
+/**
+ * \brief gets the data associated with a node.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param watch if nonzero, a watch will be set at the server to notify 
+ * the client if the node changes.
+ * \param completion the routine to invoke when the request completes. The completion
+ * will be triggered with one of the following codes passed in as the rc argument:
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * \param data the data that will be passed to the completion routine when 
+ * the function completes.
+ * \return ZOK on success or one of the following errcodes on failure:
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_aget(zhandle_t *zh, const char *path, int watch, 
+        data_completion_t completion, const void *data);
+
+/**
+ * \brief gets the data associated with a node.
+ * 
+ * This function is similar to \ref zoo_aget except it allows one specify 
+ * a watcher object rather than a boolean watch flag. 
+ *
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param watcher if non-null, a watch will be set at the server to notify 
+ * the client if the node changes.
+ * \param watcherCtx user specific data, will be passed to the watcher callback.
+ * Unlike the global context set by \ref zookeeper_init, this watcher context
+ * is associated with the given instance of the watcher only.
+ * \param completion the routine to invoke when the request completes. The completion
+ * will be triggered with one of the following codes passed in as the rc argument:
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * \param data the data that will be passed to the completion routine when 
+ * the function completes.
+ * \return ZOK on success or one of the following errcodes on failure:
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_awget(zhandle_t *zh, const char *path, 
+        watcher_fn watcher, void* watcherCtx, 
+        data_completion_t completion, const void *data);
+
+/**
+ * \brief sets the data associated with a node.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param buffer the buffer holding data to be written to the node.
+ * \param buflen the number of bytes from buffer to write.
+ * \param version the expected version of the node. The function will fail if 
+ * the actual version of the node does not match the expected version. If -1 is 
+ * used the version check will not take place. * completion: If null, 
+ * the function will execute synchronously. Otherwise, the function will return 
+ * immediately and invoke the completion routine when the request completes.
+ * \param completion the routine to invoke when the request completes. The completion
+ * will be triggered with one of the following codes passed in as the rc argument:
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * ZBADVERSION expected version does not match actual version.
+ * \param data the data that will be passed to the completion routine when 
+ * the function completes.
+ * \return ZOK on success or one of the following errcodes on failure:
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_aset(zhandle_t *zh, const char *path, const char *buffer, int buflen, 
+        int version, stat_completion_t completion, const void *data);
+
+/**
+ * \brief lists the children of a node.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param watch if nonzero, a watch will be set at the server to notify 
+ * the client if the node changes.
+ * \param completion the routine to invoke when the request completes. The completion
+ * will be triggered with one of the following codes passed in as the rc argument:
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * \param data the data that will be passed to the completion routine when 
+ * the function completes.
+ * \return ZOK on success or one of the following errcodes on failure:
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_aget_children(zhandle_t *zh, const char *path, int watch, 
+        strings_completion_t completion, const void *data);
+
+/**
+ * \brief lists the children of a node.
+ * 
+ * This function is similar to \ref zoo_aget_children except it allows one specify 
+ * a watcher object rather than a boolean watch flag.
+ *  
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param watcher if non-null, a watch will be set at the server to notify 
+ * the client if the node changes.
+ * \param watcherCtx user specific data, will be passed to the watcher callback.
+ * Unlike the global context set by \ref zookeeper_init, this watcher context
+ * is associated with the given instance of the watcher only.
+ * \param completion the routine to invoke when the request completes. The completion
+ * will be triggered with one of the following codes passed in as the rc argument:
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * \param data the data that will be passed to the completion routine when 
+ * the function completes.
+ * \return ZOK on success or one of the following errcodes on failure:
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_awget_children(zhandle_t *zh, const char *path,
+        watcher_fn watcher, void* watcherCtx, 
+        strings_completion_t completion, const void *data);
+
+/**
+ * \brief lists the children of a node, and get the parent stat.
+ * 
+ * This function is new in version 3.3.0
+ *
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param watch if nonzero, a watch will be set at the server to notify 
+ * the client if the node changes.
+ * \param completion the routine to invoke when the request completes. The completion
+ * will be triggered with one of the following codes passed in as the rc argument:
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * \param data the data that will be passed to the completion routine when 
+ * the function completes.
+ * \return ZOK on success or one of the following errcodes on failure:
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_aget_children2(zhandle_t *zh, const char *path, int watch, 
+        strings_stat_completion_t completion, const void *data);
+
+/**
+ * \brief lists the children of a node, and get the parent stat.
+ * 
+ * This function is similar to \ref zoo_aget_children2 except it allows one specify 
+ * a watcher object rather than a boolean watch flag.
+ *  
+ * This function is new in version 3.3.0
+ *
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param watcher if non-null, a watch will be set at the server to notify 
+ * the client if the node changes.
+ * \param watcherCtx user specific data, will be passed to the watcher callback.
+ * Unlike the global context set by \ref zookeeper_init, this watcher context
+ * is associated with the given instance of the watcher only.
+ * \param completion the routine to invoke when the request completes. The completion
+ * will be triggered with one of the following codes passed in as the rc argument:
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * \param data the data that will be passed to the completion routine when 
+ * the function completes.
+ * \return ZOK on success or one of the following errcodes on failure:
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_awget_children2(zhandle_t *zh, const char *path,
+        watcher_fn watcher, void* watcherCtx, 
+        strings_stat_completion_t completion, const void *data);
+
+/**
+ * \brief Flush leader channel.
+ *
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes
+ * separating ancestors of the node.
+ * \param completion the routine to invoke when the request completes. The completion
+ * will be triggered with one of the following codes passed in as the rc argument:
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * \param data the data that will be passed to the completion routine when
+ * the function completes.
+ * \return ZOK on success or one of the following errcodes on failure:
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+
+ZOOAPI int zoo_async(zhandle_t *zh, const char *path, 
+        string_completion_t completion, const void *data);
+
+
+/**
+ * \brief gets the acl associated with a node.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param completion the routine to invoke when the request completes. The completion
+ * will be triggered with one of the following codes passed in as the rc argument:
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * \param data the data that will be passed to the completion routine when 
+ * the function completes.
+ * \return ZOK on success or one of the following errcodes on failure:
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_aget_acl(zhandle_t *zh, const char *path, acl_completion_t completion, 
+        const void *data);
+
+/**
+ * \brief sets the acl associated with a node.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param buffer the buffer holding the acls to be written to the node.
+ * \param buflen the number of bytes from buffer to write.
+ * \param completion the routine to invoke when the request completes. The completion
+ * will be triggered with one of the following codes passed in as the rc argument:
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * ZINVALIDACL invalid ACL specified
+ * ZBADVERSION expected version does not match actual version.
+ * \param data the data that will be passed to the completion routine when 
+ * the function completes.
+ * \return ZOK on success or one of the following errcodes on failure:
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_aset_acl(zhandle_t *zh, const char *path, int version, 
+        struct ACL_vector *acl, void_completion_t, const void *data);
+
+/**
+ * \brief atomically commits multiple zookeeper operations.
+ *
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param count the number of operations
+ * \param ops an array of operations to commit
+ * \param results an array to hold the results of the operations
+ * \param completion the routine to invoke when the request completes. The completion
+ * will be triggered with any of the error codes that can that can be returned by the 
+ * ops supported by a multi op (see \ref zoo_acreate, \ref zoo_adelete, \ref zoo_aset).
+ * \param data the data that will be passed to the completion routine when
+ * the function completes.
+ * \return the return code for the function call. This can be any of the
+ * values that can be returned by the ops supported by a multi op (see
+ * \ref zoo_acreate, \ref zoo_adelete, \ref zoo_aset).
+ */
+ZOOAPI int zoo_amulti(zhandle_t *zh, int count, const zoo_op_t *ops, 
+        zoo_op_result_t *results, void_completion_t, const void *data);
+
+/**
+ * \brief return an error string.
+ * 
+ * \param return code
+ * \return string corresponding to the return code
+ */
+ZOOAPI const char* zerror(int c);
+
+/**
+ * \brief specify application credentials.
+ * 
+ * The application calls this function to specify its credentials for purposes
+ * of authentication. The server will use the security provider specified by 
+ * the scheme parameter to authenticate the client connection. If the 
+ * authentication request has failed:
+ * - the server connection is dropped
+ * - the watcher is called with the ZOO_AUTH_FAILED_STATE value as the state 
+ * parameter.
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param scheme the id of authentication scheme. Natively supported:
+ * "digest" password-based authentication
+ * \param cert application credentials. The actual value depends on the scheme.
+ * \param certLen the length of the data parameter
+ * \param completion the routine to invoke when the request completes. One of 
+ * the following result codes may be passed into the completion callback:
+ * ZOK operation completed successfully
+ * ZAUTHFAILED authentication failed 
+ * \param data the data that will be passed to the completion routine when the 
+ * function completes.
+ * \return ZOK on success or one of the following errcodes on failure:
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ * ZSYSTEMERROR - a system error occurred
+ */
+ZOOAPI int zoo_add_auth(zhandle_t *zh,const char* scheme,const char* cert, 
+	int certLen, void_completion_t completion, const void *data);
+
+/**
+ * \brief checks if the current zookeeper connection state can't be recovered.
+ * 
+ *  The application must close the zhandle and try to reconnect.
+ * 
+ * \param zh the zookeeper handle (see \ref zookeeper_init)
+ * \return ZINVALIDSTATE if connection is unrecoverable
+ */
+ZOOAPI int is_unrecoverable(zhandle_t *zh);
+
+/**
+ * \brief sets the debugging level for the library 
+ */
+ZOOAPI void zoo_set_debug_level(ZooLogLevel logLevel);
+
+/**
+ * \brief sets the stream to be used by the library for logging 
+ * 
+ * The zookeeper library uses stderr as its default log stream. Application
+ * must make sure the stream is writable. Passing in NULL resets the stream 
+ * to its default value (stderr).
+ */
+ZOOAPI void zoo_set_log_stream(FILE* logStream);
+
+/**
+ * \brief enable/disable quorum endpoint order randomization
+ * 
+ * Note: typically this method should NOT be used outside of testing.
+ *
+ * If passed a non-zero value, will make the client connect to quorum peers
+ * in the order as specified in the zookeeper_init() call.
+ * A zero value causes zookeeper_init() to permute the peer endpoints
+ * which is good for more even client connection distribution among the 
+ * quorum peers.
+ */
+ZOOAPI void zoo_deterministic_conn_order(int yesOrNo);
+
+/**
+ * \brief create a node synchronously.
+ * 
+ * This method will create a node in ZooKeeper. A node can only be created if
+ * it does not already exists. The Create Flags affect the creation of nodes.
+ * If ZOO_EPHEMERAL flag is set, the node will automatically get removed if the
+ * client session goes away. If the ZOO_SEQUENCE flag is set, a unique
+ * monotonically increasing sequence number is appended to the path name.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path The name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param value The data to be stored in the node.
+ * \param valuelen The number of bytes in data. To set the data to be NULL use
+ * value as NULL and valuelen as -1.
+ * \param acl The initial ACL of the node. The ACL must not be null or empty.
+ * \param flags this parameter can be set to 0 for normal create or an OR
+ *    of the Create Flags
+ * \param path_buffer Buffer which will be filled with the path of the
+ *    new node (this might be different than the supplied path
+ *    because of the ZOO_SEQUENCE flag).  The path string will always be
+ *    null-terminated. This parameter may be NULL if path_buffer_len = 0.
+ * \param path_buffer_len Size of path buffer; if the path of the new
+ *    node (including space for the null terminator) exceeds the buffer size,
+ *    the path string will be truncated to fit.  The actual path of the
+ *    new node in the server will not be affected by the truncation.
+ *    The path string will always be null-terminated.
+ * \return  one of the following codes are returned:
+ * ZOK operation completed successfully
+ * ZNONODE the parent node does not exist.
+ * ZNODEEXISTS the node already exists
+ * ZNOAUTH the client does not have permission.
+ * ZNOCHILDRENFOREPHEMERALS cannot create children of ephemeral nodes.
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_create(zhandle_t *zh, const char *path, const char *value,
+        int valuelen, const struct ACL_vector *acl, int flags,
+        char *path_buffer, int path_buffer_len);
+
+/**
+ * \brief delete a node in zookeeper synchronously.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param version the expected version of the node. The function will fail if the
+ *    actual version of the node does not match the expected version.
+ *  If -1 is used the version check will not take place. 
+ * \return one of the following values is returned.
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * ZBADVERSION expected version does not match actual version.
+ * ZNOTEMPTY children are present; node cannot be deleted.
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_delete(zhandle_t *zh, const char *path, int version);
+
+
+/**
+ * \brief checks the existence of a node in zookeeper synchronously.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param watch if nonzero, a watch will be set at the server to notify the 
+ * client if the node changes. The watch will be set even if the node does not 
+ * exist. This allows clients to watch for nodes to appear.
+ * \param the return stat value of the node.
+ * \return  return code of the function call.
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_exists(zhandle_t *zh, const char *path, int watch, struct Stat *stat);
+
+/**
+ * \brief checks the existence of a node in zookeeper synchronously.
+ * 
+ * This function is similar to \ref zoo_exists except it allows one specify 
+ * a watcher object rather than a boolean watch flag.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param watcher if non-null a watch will set on the specified znode on the server.
+ * The watch will be set even if the node does not exist. This allows clients 
+ * to watch for nodes to appear.
+ * \param watcherCtx user specific data, will be passed to the watcher callback.
+ * Unlike the global context set by \ref zookeeper_init, this watcher context
+ * is associated with the given instance of the watcher only.
+ * \param the return stat value of the node.
+ * \return  return code of the function call.
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_wexists(zhandle_t *zh, const char *path,
+        watcher_fn watcher, void* watcherCtx, struct Stat *stat);
+
+/**
+ * \brief gets the data associated with a node synchronously.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param watch if nonzero, a watch will be set at the server to notify 
+ * the client if the node changes.
+ * \param buffer the buffer holding the node data returned by the server
+ * \param buffer_len is the size of the buffer pointed to by the buffer parameter.
+ * It'll be set to the actual data length upon return. If the data is NULL, length is -1.
+ * \param stat if not NULL, will hold the value of stat for the path on return.
+ * \return return value of the function call.
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_get(zhandle_t *zh, const char *path, int watch, char *buffer,   
+                   int* buffer_len, struct Stat *stat);
+
+/**
+ * \brief gets the data associated with a node synchronously.
+ * 
+ * This function is similar to \ref zoo_get except it allows one specify 
+ * a watcher object rather than a boolean watch flag.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param watcher if non-null, a watch will be set at the server to notify 
+ * the client if the node changes.
+ * \param watcherCtx user specific data, will be passed to the watcher callback.
+ * Unlike the global context set by \ref zookeeper_init, this watcher context
+ * is associated with the given instance of the watcher only.
+ * \param buffer the buffer holding the node data returned by the server
+ * \param buffer_len is the size of the buffer pointed to by the buffer parameter.
+ * It'll be set to the actual data length upon return. If the data is NULL, length is -1.
+ * \param stat if not NULL, will hold the value of stat for the path on return.
+ * \return return value of the function call.
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either in ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_wget(zhandle_t *zh, const char *path, 
+        watcher_fn watcher, void* watcherCtx, 
+        char *buffer, int* buffer_len, struct Stat *stat);
+
+/**
+ * \brief sets the data associated with a node. See zoo_set2 function if
+ * you require access to the stat information associated with the znode.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param buffer the buffer holding data to be written to the node.
+ * \param buflen the number of bytes from buffer to write. To set NULL as data 
+ * use buffer as NULL and buflen as -1.
+ * \param version the expected version of the node. The function will fail if 
+ * the actual version of the node does not match the expected version. If -1 is 
+ * used the version check will not take place. 
+ * \return the return code for the function call.
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * ZBADVERSION expected version does not match actual version.
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_set(zhandle_t *zh, const char *path, const char *buffer,
+                   int buflen, int version);
+
+/**
+ * \brief sets the data associated with a node. This function is the same
+ * as zoo_set except that it also provides access to stat information
+ * associated with the znode.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param buffer the buffer holding data to be written to the node.
+ * \param buflen the number of bytes from buffer to write. To set NULL as data
+ * use buffer as NULL and buflen as -1.
+ * \param version the expected version of the node. The function will fail if 
+ * the actual version of the node does not match the expected version. If -1 is 
+ * used the version check will not take place. 
+ * \param stat if not NULL, will hold the value of stat for the path on return.
+ * \return the return code for the function call.
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * ZBADVERSION expected version does not match actual version.
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_set2(zhandle_t *zh, const char *path, const char *buffer,
+                   int buflen, int version, struct Stat *stat);
+
+/**
+ * \brief lists the children of a node synchronously.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param watch if nonzero, a watch will be set at the server to notify 
+ * the client if the node changes.
+ * \param strings return value of children paths.
+ * \return the return code of the function.
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_get_children(zhandle_t *zh, const char *path, int watch,
+                            struct String_vector *strings);
+
+/**
+ * \brief lists the children of a node synchronously.
+ * 
+ * This function is similar to \ref zoo_get_children except it allows one specify 
+ * a watcher object rather than a boolean watch flag.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param watcher if non-null, a watch will be set at the server to notify 
+ * the client if the node changes.
+ * \param watcherCtx user specific data, will be passed to the watcher callback.
+ * Unlike the global context set by \ref zookeeper_init, this watcher context
+ * is associated with the given instance of the watcher only.
+ * \param strings return value of children paths.
+ * \return the return code of the function.
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_wget_children(zhandle_t *zh, const char *path, 
+        watcher_fn watcher, void* watcherCtx,
+        struct String_vector *strings);
+
+/**
+ * \brief lists the children of a node and get its stat synchronously.
+ * 
+ * This function is new in version 3.3.0
+ *
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param watch if nonzero, a watch will be set at the server to notify 
+ * the client if the node changes.
+ * \param strings return value of children paths.
+ * \param stat return value of node stat.
+ * \return the return code of the function.
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_get_children2(zhandle_t *zh, const char *path, int watch,
+                            struct String_vector *strings, struct Stat *stat);
+
+/**
+ * \brief lists the children of a node and get its stat synchronously.
+ * 
+ * This function is similar to \ref zoo_get_children except it allows one specify 
+ * a watcher object rather than a boolean watch flag.
+ * 
+ * This function is new in version 3.3.0
+ *
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param watcher if non-null, a watch will be set at the server to notify 
+ * the client if the node changes.
+ * \param watcherCtx user specific data, will be passed to the watcher callback.
+ * Unlike the global context set by \ref zookeeper_init, this watcher context
+ * is associated with the given instance of the watcher only.
+ * \param strings return value of children paths.
+ * \param stat return value of node stat.
+ * \return the return code of the function.
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_wget_children2(zhandle_t *zh, const char *path, 
+        watcher_fn watcher, void* watcherCtx,
+        struct String_vector *strings, struct Stat *stat);
+
+/**
+ * \brief gets the acl associated with a node synchronously.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param acl the return value of acls on the path.
+ * \param stat returns the stat of the path specified.
+ * \return the return code for the function call.
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_get_acl(zhandle_t *zh, const char *path, struct ACL_vector *acl,
+                       struct Stat *stat);
+
+/**
+ * \brief sets the acl associated with a node synchronously.
+ * 
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param path the name of the node. Expressed as a file name with slashes 
+ * separating ancestors of the node.
+ * \param version the expected version of the path.
+ * \param acl the acl to be set on the path. 
+ * \return the return code for the function call.
+ * ZOK operation completed successfully
+ * ZNONODE the node does not exist.
+ * ZNOAUTH the client does not have permission.
+ * ZINVALIDACL invalid ACL specified
+ * ZBADVERSION expected version does not match actual version.
+ * ZBADARGUMENTS - invalid input parameters
+ * ZINVALIDSTATE - zhandle state is either ZOO_SESSION_EXPIRED_STATE or ZOO_AUTH_FAILED_STATE
+ * ZMARSHALLINGERROR - failed to marshall a request; possibly, out of memory
+ */
+ZOOAPI int zoo_set_acl(zhandle_t *zh, const char *path, int version,
+                           const struct ACL_vector *acl);
+
+/**
+ * \brief atomically commits multiple zookeeper operations synchronously.
+ *
+ * \param zh the zookeeper handle obtained by a call to \ref zookeeper_init
+ * \param count the number of operations
+ * \param ops an array of operations to commit
+ * \param results an array to hold the results of the operations
+ * \return the return code for the function call. This can be any of the
+ * values that can be returned by the ops supported by a multi op (see
+ * \ref zoo_acreate, \ref zoo_adelete, \ref zoo_aset).
+ */ 
+ZOOAPI int zoo_multi(zhandle_t *zh, int count, const zoo_op_t *ops, zoo_op_result_t *results);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*ZOOKEEPER_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/include/zookeeper_log.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/include/zookeeper_log.h b/zookeeper-client/zookeeper-client-c/include/zookeeper_log.h
new file mode 100644
index 0000000..e5917cb
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/include/zookeeper_log.h
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ZK_LOG_H_
+#define ZK_LOG_H_
+
+#include <zookeeper.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern ZOOAPI ZooLogLevel logLevel;
+#define LOGSTREAM getLogStream()
+
+#define LOG_ERROR(x) if(logLevel>=ZOO_LOG_LEVEL_ERROR) \
+    log_message(ZOO_LOG_LEVEL_ERROR,__LINE__,__func__,format_log_message x)
+#define LOG_WARN(x) if(logLevel>=ZOO_LOG_LEVEL_WARN) \
+    log_message(ZOO_LOG_LEVEL_WARN,__LINE__,__func__,format_log_message x)
+#define LOG_INFO(x) if(logLevel>=ZOO_LOG_LEVEL_INFO) \
+    log_message(ZOO_LOG_LEVEL_INFO,__LINE__,__func__,format_log_message x)
+#define LOG_DEBUG(x) if(logLevel==ZOO_LOG_LEVEL_DEBUG) \
+    log_message(ZOO_LOG_LEVEL_DEBUG,__LINE__,__func__,format_log_message x)
+
+ZOOAPI void log_message(ZooLogLevel curLevel, int line,const char* funcName,
+    const char* message);
+
+ZOOAPI const char* format_log_message(const char* format,...);
+
+FILE* getLogStream();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*ZK_LOG_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/include/zookeeper_version.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/include/zookeeper_version.h b/zookeeper-client/zookeeper-client-c/include/zookeeper_version.h
new file mode 100644
index 0000000..518f7e6
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/include/zookeeper_version.h
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ZOOKEEPER_VERSION_H_
+#define ZOOKEEPER_VERSION_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZOO_MAJOR_VERSION 3
+#define ZOO_MINOR_VERSION 4
+#define ZOO_PATCH_VERSION 12
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZOOKEEPER_VERSION_H_ */


[03/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/TestClient.cc
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/TestClient.cc b/zookeeper-client/zookeeper-client-c/tests/TestClient.cc
new file mode 100644
index 0000000..154fbed
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/TestClient.cc
@@ -0,0 +1,1135 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "CppAssertHelper.h"
+
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/select.h>
+
+#include "CollectionUtil.h"
+#include "ThreadingUtil.h"
+
+using namespace Util;
+
+#include "Vector.h"
+using namespace std;
+
+#include <cstring>
+#include <list>
+
+#include <zookeeper.h>
+#include <errno.h>
+#include <recordio.h>
+#include "Util.h"
+
+struct buff_struct_2 {
+    int32_t len;
+    int32_t off;
+    char *buffer;
+};
+
+static int Stat_eq(struct Stat* a, struct Stat* b)
+{
+    if (a->czxid != b->czxid) return 0;
+    if (a->mzxid != b->mzxid) return 0;
+    if (a->ctime != b->ctime) return 0;
+    if (a->mtime != b->mtime) return 0;
+    if (a->version != b->version) return 0;
+    if (a->cversion != b->cversion) return 0;
+    if (a->aversion != b->aversion) return 0;
+    if (a->ephemeralOwner != b->ephemeralOwner) return 0;
+    if (a->dataLength != b->dataLength) return 0;
+    if (a->numChildren != b->numChildren) return 0;
+    if (a->pzxid != b->pzxid) return 0;
+    return 1;
+}
+#ifdef THREADED
+    static void yield(zhandle_t *zh, int i)
+    {
+        sleep(i);
+    }
+#else
+    static void yield(zhandle_t *zh, int seconds)
+    {
+        int fd;
+        int interest;
+        int events;
+        struct timeval tv;
+        int rc;
+        time_t expires = time(0) + seconds;
+        time_t timeLeft = seconds;
+        fd_set rfds, wfds, efds;
+        FD_ZERO(&rfds);
+        FD_ZERO(&wfds);
+        FD_ZERO(&efds);
+
+        while(timeLeft >= 0) {
+            zookeeper_interest(zh, &fd, &interest, &tv);
+            if (fd != -1) {
+                if (interest&ZOOKEEPER_READ) {
+                    FD_SET(fd, &rfds);
+                } else {
+                    FD_CLR(fd, &rfds);
+                }
+                if (interest&ZOOKEEPER_WRITE) {
+                    FD_SET(fd, &wfds);
+                } else {
+                    FD_CLR(fd, &wfds);
+                }
+            } else {
+                fd = 0;
+            }
+            FD_SET(0, &rfds);
+            if (tv.tv_sec > timeLeft) {
+                tv.tv_sec = timeLeft;
+            }
+            rc = select(fd+1, &rfds, &wfds, &efds, &tv);
+            timeLeft = expires - time(0);
+            events = 0;
+            if (FD_ISSET(fd, &rfds)) {
+                events |= ZOOKEEPER_READ;
+            }
+            if (FD_ISSET(fd, &wfds)) {
+                events |= ZOOKEEPER_WRITE;
+            }
+            zookeeper_process(zh, events);
+        }
+    }
+#endif
+
+typedef struct evt {
+    string path;
+    int type;
+} evt_t;
+
+typedef struct watchCtx {
+private:
+    list<evt_t> events;
+    watchCtx(const watchCtx&);
+    watchCtx& operator=(const watchCtx&);
+public:
+    bool connected;
+    zhandle_t *zh;
+    Mutex mutex;
+
+    watchCtx() {
+        connected = false;
+        zh = 0;
+    }
+    ~watchCtx() {
+        if (zh) {
+            zookeeper_close(zh);
+            zh = 0;
+        }
+    }
+
+    evt_t getEvent() {
+        evt_t evt;
+        mutex.acquire();
+        CPPUNIT_ASSERT( events.size() > 0);
+        evt = events.front();
+        events.pop_front();
+        mutex.release();
+        return evt;
+    }
+
+    int countEvents() {
+        int count;
+        mutex.acquire();
+        count = events.size();
+        mutex.release();
+        return count;
+    }
+
+    void putEvent(evt_t evt) {
+        mutex.acquire();
+        events.push_back(evt);
+        mutex.release();
+    }
+
+    bool waitForConnected(zhandle_t *zh) {
+        time_t expires = time(0) + 10;
+        while(!connected && time(0) < expires) {
+            yield(zh, 1);
+        }
+        return connected;
+    }
+    bool waitForDisconnected(zhandle_t *zh) {
+        time_t expires = time(0) + 15;
+        while(connected && time(0) < expires) {
+            yield(zh, 1);
+        }
+        return !connected;
+    }
+} watchctx_t;
+
+class Zookeeper_simpleSystem : public CPPUNIT_NS::TestFixture
+{
+    CPPUNIT_TEST_SUITE(Zookeeper_simpleSystem);
+    CPPUNIT_TEST(testAsyncWatcherAutoReset);
+    CPPUNIT_TEST(testDeserializeString);
+    CPPUNIT_TEST(testFirstServerDown);
+#ifdef THREADED
+    CPPUNIT_TEST(testNullData);
+#ifdef ZOO_IPV6_ENABLED
+    CPPUNIT_TEST(testIPV6);
+#endif
+    CPPUNIT_TEST(testPath);
+    CPPUNIT_TEST(testPathValidation);
+    CPPUNIT_TEST(testPing);
+    CPPUNIT_TEST(testAcl);
+    CPPUNIT_TEST(testChroot);
+    CPPUNIT_TEST(testAuth);
+    CPPUNIT_TEST(testHangingClient);
+    CPPUNIT_TEST(testWatcherAutoResetWithGlobal);
+    CPPUNIT_TEST(testWatcherAutoResetWithLocal);
+    CPPUNIT_TEST(testGetChildren2);
+#endif
+    CPPUNIT_TEST_SUITE_END();
+
+    static void watcher(zhandle_t *, int type, int state, const char *path,void*v){
+        watchctx_t *ctx = (watchctx_t*)v;
+
+        if (state == ZOO_CONNECTED_STATE) {
+            ctx->connected = true;
+        } else {
+            ctx->connected = false;
+        }
+        if (type != ZOO_SESSION_EVENT) {
+            evt_t evt;
+            evt.path = path;
+            evt.type = type;
+            ctx->putEvent(evt);
+        }
+    }
+
+    static const char hostPorts[];
+
+    const char *getHostPorts() {
+        return hostPorts;
+    }
+    
+    zhandle_t *createClient(watchctx_t *ctx) {
+        return createClient(hostPorts, ctx);
+    }
+
+    zhandle_t *createClient(const char *hp, watchctx_t *ctx) {
+        zhandle_t *zk = zookeeper_init(hp, watcher, 10000, 0, ctx, 0);
+        ctx->zh = zk;
+        sleep(1);
+        return zk;
+    }
+    
+    zhandle_t *createchClient(watchctx_t *ctx, const char* chroot) {
+        zhandle_t *zk = zookeeper_init(chroot, watcher, 10000, 0, ctx, 0);
+        ctx->zh = zk;
+        sleep(1);
+        return zk;
+    }
+        
+    FILE *logfile;
+public:
+
+    Zookeeper_simpleSystem() {
+      logfile = openlogfile("Zookeeper_simpleSystem");
+    }
+
+    ~Zookeeper_simpleSystem() {
+      if (logfile) {
+        fflush(logfile);
+        fclose(logfile);
+        logfile = 0;
+      }
+    }
+
+    void setUp()
+    {
+        zoo_set_log_stream(logfile);
+    }
+
+
+    void startServer() {
+        char cmd[1024];
+        sprintf(cmd, "%s start %s", ZKSERVER_CMD, getHostPorts());
+        CPPUNIT_ASSERT(system(cmd) == 0);
+    }
+
+    void stopServer() {
+        char cmd[1024];
+        sprintf(cmd, "%s stop %s", ZKSERVER_CMD, getHostPorts());
+        CPPUNIT_ASSERT(system(cmd) == 0);
+    }
+
+    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);
+    }
+
+    /** ZOOKEEPER-1057 This checks that the client connects to the second server when the first is not reachable **/
+    void testFirstServerDown() {
+        watchctx_t ctx;
+
+        zoo_deterministic_conn_order(true);
+
+        zhandle_t* zk = createClient("127.0.0.1:22182,127.0.0.1:22181", &ctx);
+        CPPUNIT_ASSERT(zk != 0);
+        CPPUNIT_ASSERT(ctx.waitForConnected(zk));
+    }
+    
+    /** 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()
+    {
+        watchctx_t ctxIdle;
+        watchctx_t ctxWC;
+        zhandle_t *zkIdle = createClient(&ctxIdle);
+        zhandle_t *zkWatchCreator = createClient(&ctxWC);
+
+        CPPUNIT_ASSERT(zkIdle);
+        CPPUNIT_ASSERT(zkWatchCreator);
+
+        char path[80];
+        sprintf(path, "/testping");
+        int rc = zoo_create(zkWatchCreator, path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        for(int i = 0; i < 30; i++) {
+            sprintf(path, "/testping/%i", i);
+            rc = zoo_create(zkWatchCreator, path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        }
+
+        for(int i = 0; i < 30; i++) {
+            sprintf(path, "/testping/%i", i);
+            struct Stat stat;
+            rc = zoo_exists(zkIdle, path, 1, &stat);
+            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        }
+
+        for(int i = 0; i < 30; i++) {
+            sprintf(path, "/testping/%i", i);
+            usleep(500000);
+            rc = zoo_delete(zkWatchCreator, path, -1);
+            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        }
+        struct Stat stat;
+        CPPUNIT_ASSERT_EQUAL((int)ZNONODE, zoo_exists(zkIdle, "/testping/0", 0, &stat));
+    }
+
+    bool waitForEvent(zhandle_t *zh, watchctx_t *ctx, int seconds) {
+        time_t expires = time(0) + seconds;
+        while(ctx->countEvents() == 0 && time(0) < expires) {
+            yield(zh, 1);
+        }
+        return ctx->countEvents() > 0;
+    }
+
+#define COUNT 100
+
+    static zhandle_t *async_zk;
+    static volatile int count;
+    static const char* hp_chroot;
+
+    static void statCompletion(int rc, const struct Stat *stat, const void *data) {
+        int tmp = (int) (long) data;
+        CPPUNIT_ASSERT_EQUAL(tmp, rc);
+    }
+
+    static void stringCompletion(int rc, const char *value, const void *data) {
+        char *path = (char*)data;
+
+        if (rc == ZCONNECTIONLOSS && path) {
+            // Try again
+            rc = zoo_acreate(async_zk, path, "", 0,  &ZOO_OPEN_ACL_UNSAFE, 0, stringCompletion, 0);
+        } else if (rc != ZOK) {
+            // fprintf(stderr, "rc = %d with path = %s\n", rc, (path ? path : "null"));
+        }
+        if (path) {
+            free(path);
+        }
+    }
+
+    static void create_completion_fn(int rc, const char* value, const void *data) {
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        count++;
+    }
+
+    static void waitForCreateCompletion(int seconds) {
+        time_t expires = time(0) + seconds;
+        while(count == 0 && time(0) < expires) {
+            sleep(1);
+        }
+        count--;
+    }
+
+    static void watcher_chroot_fn(zhandle_t *zh, int type,
+                                    int state, const char *path,void *watcherCtx) {
+        // check for path
+        char *client_path = (char *) watcherCtx;
+        CPPUNIT_ASSERT(strcmp(client_path, path) == 0);
+        count ++;
+    }
+
+    static void waitForChrootWatch(int seconds) {
+        time_t expires = time(0) + seconds;
+        while (count == 0 && time(0) < expires) {
+            sleep(1);
+        }
+        count--;
+    }
+
+    static void waitForVoidCompletion(int seconds) {
+        time_t expires = time(0) + seconds;
+        while(count == 0 && time(0) < expires) {
+            sleep(1);
+        }
+        count--;
+    }
+
+    static void voidCompletion(int rc, const void *data) {
+        int tmp = (int) (long) data;
+        CPPUNIT_ASSERT_EQUAL(tmp, rc);
+        count++;
+    }
+
+    static void verifyCreateFails(const char *path, zhandle_t *zk) {
+      CPPUNIT_ASSERT_EQUAL((int)ZBADARGUMENTS, zoo_create(zk,
+          path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0));
+    }
+
+    static void verifyCreateOk(const char *path, zhandle_t *zk) {
+      CPPUNIT_ASSERT_EQUAL((int)ZOK, zoo_create(zk,
+          path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0));
+    }
+
+    static void verifyCreateFailsSeq(const char *path, zhandle_t *zk) {
+      CPPUNIT_ASSERT_EQUAL((int)ZBADARGUMENTS, zoo_create(zk,
+          path, "", 0, &ZOO_OPEN_ACL_UNSAFE, ZOO_SEQUENCE, 0, 0));
+    }
+
+    static void verifyCreateOkSeq(const char *path, zhandle_t *zk) {
+      CPPUNIT_ASSERT_EQUAL((int)ZOK, zoo_create(zk,
+          path, "", 0, &ZOO_OPEN_ACL_UNSAFE, ZOO_SEQUENCE, 0, 0));
+    }
+
+
+    /**
+       returns false if the vectors dont match
+    **/
+    bool compareAcl(struct ACL_vector acl1, struct ACL_vector acl2) {
+        if (acl1.count != acl2.count) {
+            return false;
+        }
+        struct ACL *aclval1 = acl1.data;
+        struct ACL *aclval2 = acl2.data;
+        if (aclval1->perms != aclval2->perms) {
+            return false;
+        }
+        struct Id id1 = aclval1->id;
+        struct Id id2 = aclval2->id;
+        if (strcmp(id1.scheme, id2.scheme) != 0) {
+            return false;
+        }
+        if (strcmp(id1.id, id2.id) != 0) {
+            return false;
+        }
+        return true;
+    }
+
+    void testDeserializeString() {
+        char *val_str;
+        int rc = 0;
+        int val = -1;
+        struct iarchive *ia;
+        struct buff_struct_2 *b;
+        struct oarchive *oa = create_buffer_oarchive();
+        oa->serialize_Int(oa, "int", &val);
+        b = (struct buff_struct_2 *) oa->priv;
+        ia = create_buffer_iarchive(b->buffer, b->len);
+        rc = ia->deserialize_String(ia, "string", &val_str);
+        CPPUNIT_ASSERT_EQUAL(-EINVAL, rc);
+    }
+        
+    void testAcl() {
+        int rc;
+        struct ACL_vector aclvec;
+        struct Stat stat;
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+        rc = zoo_create(zk, "/acl", "", 0,
+                        &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        rc = zoo_get_acl(zk, "/acl", &aclvec, &stat  );
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        bool cmp = compareAcl(ZOO_OPEN_ACL_UNSAFE, aclvec);
+        CPPUNIT_ASSERT_EQUAL(true, cmp);
+        rc = zoo_set_acl(zk, "/acl", -1, &ZOO_READ_ACL_UNSAFE);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        rc = zoo_get_acl(zk, "/acl", &aclvec, &stat);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        cmp = compareAcl(ZOO_READ_ACL_UNSAFE, aclvec);
+        CPPUNIT_ASSERT_EQUAL(true, cmp);
+    }
+
+
+    void testAuth() {
+        int rc;
+        count = 0;
+        watchctx_t ctx1, ctx2, ctx3, ctx4, ctx5;
+        zhandle_t *zk = createClient(&ctx1);
+        struct ACL_vector nodeAcl;
+        struct ACL acl_val;
+        rc = zoo_add_auth(0, "", 0, 0, voidCompletion, (void*)-1);
+        CPPUNIT_ASSERT_EQUAL((int) ZBADARGUMENTS, rc);
+
+        rc = zoo_add_auth(zk, 0, 0, 0, voidCompletion, (void*)-1);
+        CPPUNIT_ASSERT_EQUAL((int) ZBADARGUMENTS, rc);
+
+        // auth as pat, create /tauth1, close session
+        rc = zoo_add_auth(zk, "digest", "pat:passwd", 10, voidCompletion,
+                          (void*)ZOK);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        waitForVoidCompletion(3);
+        CPPUNIT_ASSERT(count == 0);
+
+        rc = zoo_create(zk, "/tauth1", "", 0, &ZOO_CREATOR_ALL_ACL, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        {
+            //create a new client
+            zk = createClient(&ctx4);
+            rc = zoo_add_auth(zk, "digest", "", 0, voidCompletion, (void*)ZOK);
+            CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+            waitForVoidCompletion(3);
+            CPPUNIT_ASSERT(count == 0);
+
+            rc = zoo_add_auth(zk, "digest", "", 0, voidCompletion, (void*)ZOK);
+            CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+            waitForVoidCompletion(3);
+            CPPUNIT_ASSERT(count == 0);
+        }
+
+        //create a new client
+        zk = createClient(&ctx2);
+
+        rc = zoo_add_auth(zk, "digest", "pat:passwd2", 11, voidCompletion,
+                          (void*)ZOK);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        waitForVoidCompletion(3);
+        CPPUNIT_ASSERT(count == 0);
+
+        char buf[1024];
+        int blen = sizeof(buf);
+        struct Stat stat;
+        rc = zoo_get(zk, "/tauth1", 0, buf, &blen, &stat);
+        CPPUNIT_ASSERT_EQUAL((int)ZNOAUTH, rc);
+        // add auth pat w/correct pass verify success
+        rc = zoo_add_auth(zk, "digest", "pat:passwd", 10, voidCompletion,
+                          (void*)ZOK);
+
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        rc = zoo_get(zk, "/tauth1", 0, buf, &blen, &stat);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        waitForVoidCompletion(3);
+        CPPUNIT_ASSERT(count == 0);
+        //create a new client
+        zk = createClient(&ctx3);
+        rc = zoo_add_auth(zk, "digest", "pat:passwd", 10, voidCompletion, (void*) ZOK);
+        waitForVoidCompletion(3);
+        CPPUNIT_ASSERT(count == 0);
+        rc = zoo_add_auth(zk, "ip", "none", 4, voidCompletion, (void*)ZOK);
+        //make the server forget the auths
+        waitForVoidCompletion(3);
+        CPPUNIT_ASSERT(count == 0);
+
+        stopServer();
+        CPPUNIT_ASSERT(ctx3.waitForDisconnected(zk));
+        startServer();
+        CPPUNIT_ASSERT(ctx3.waitForConnected(zk));
+        // now try getting the data
+        rc = zoo_get(zk, "/tauth1", 0, buf, &blen, &stat);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        // also check for get
+        rc = zoo_get_acl(zk, "/", &nodeAcl, &stat);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        // check if the acl has all the perms
+        CPPUNIT_ASSERT_EQUAL((int)1, (int)nodeAcl.count);
+        acl_val = *(nodeAcl.data);
+        CPPUNIT_ASSERT_EQUAL((int) acl_val.perms, ZOO_PERM_ALL);
+        // verify on root node
+        rc = zoo_set_acl(zk, "/", -1, &ZOO_CREATOR_ALL_ACL);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+
+        rc = zoo_set_acl(zk, "/", -1, &ZOO_OPEN_ACL_UNSAFE);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+
+        //[ZOOKEEPER-1108], test that auth info is sent to server, if client is not
+        //connected to server when zoo_add_auth was called.
+        zhandle_t *zk_auth = zookeeper_init(hostPorts, NULL, 10000, 0, NULL, 0);
+        rc = zoo_add_auth(zk_auth, "digest", "pat:passwd", 10, voidCompletion, (void*)ZOK);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        sleep(2);
+        CPPUNIT_ASSERT(count == 1);
+        count  = 0;
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, zookeeper_close(zk_auth));
+        
+        // [ZOOKEEPER-800] zoo_add_auth should return ZINVALIDSTATE if
+        // the connection is closed. 
+        zhandle_t *zk2 = zookeeper_init(hostPorts, NULL, 10000, 0, NULL, 0);
+        sleep(1);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, zookeeper_close(zk2));
+        CPPUNIT_ASSERT_EQUAL(0, zoo_state(zk2)); // 0 ==> ZOO_CLOSED_STATE
+        rc = zoo_add_auth(zk2, "digest", "pat:passwd", 10, voidCompletion, (void*)ZOK);
+        CPPUNIT_ASSERT_EQUAL((int) ZINVALIDSTATE, rc);
+
+        struct sockaddr addr;
+        socklen_t addr_len = sizeof(addr);
+        zk = createClient(&ctx5);
+        stopServer();
+        CPPUNIT_ASSERT(ctx5.waitForDisconnected(zk));
+        CPPUNIT_ASSERT(zookeeper_get_connected_host(zk, &addr, &addr_len) == NULL);
+        addr_len = sizeof(addr);
+        startServer();
+        CPPUNIT_ASSERT(ctx5.waitForConnected(zk));
+        CPPUNIT_ASSERT(zookeeper_get_connected_host(zk, &addr, &addr_len) != NULL);
+    }
+
+    void testGetChildren2() {
+        int rc;
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+
+        rc = zoo_create(zk, "/parent", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        rc = zoo_create(zk, "/parent/child_a", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        rc = zoo_create(zk, "/parent/child_b", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        rc = zoo_create(zk, "/parent/child_c", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        rc = zoo_create(zk, "/parent/child_d", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        struct String_vector strings;
+        struct Stat stat_a, stat_b;
+
+        rc = zoo_get_children2(zk, "/parent", 0, &strings, &stat_a);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        rc = zoo_exists(zk, "/parent", 0, &stat_b);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        CPPUNIT_ASSERT(Stat_eq(&stat_a, &stat_b));
+        CPPUNIT_ASSERT(stat_a.numChildren == 4);
+    }
+
+    void testIPV6() {
+        watchctx_t ctx;
+        zhandle_t *zk = createClient("::1:22181", &ctx);
+        CPPUNIT_ASSERT(zk);
+        int rc = 0;
+        rc = zoo_create(zk, "/ipv6", NULL, -1,
+                        &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+    }
+
+    void testNullData() {
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+        CPPUNIT_ASSERT(zk);
+        int rc = 0;
+        rc = zoo_create(zk, "/mahadev", NULL, -1,
+                        &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        char buffer[512];
+        struct Stat stat;
+        int len = 512;
+        rc = zoo_wget(zk, "/mahadev", NULL, NULL, buffer, &len, &stat);
+        CPPUNIT_ASSERT_EQUAL( -1, len);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        rc = zoo_set(zk, "/mahadev", NULL, -1, -1);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        rc = zoo_wget(zk, "/mahadev", NULL, NULL, buffer, &len, &stat);
+        CPPUNIT_ASSERT_EQUAL( -1, len);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+    }
+
+    void testPath() {
+        watchctx_t ctx;
+        char pathbuf[20];
+        zhandle_t *zk = createClient(&ctx);
+        CPPUNIT_ASSERT(zk);
+        int rc = 0;
+
+        memset(pathbuf, 'X', 20);
+        rc = zoo_create(zk, "/testpathpath0", "", 0,
+                        &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 0);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        CPPUNIT_ASSERT_EQUAL('X', pathbuf[0]);
+
+        rc = zoo_create(zk, "/testpathpath1", "", 0,
+                        &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 1);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        CPPUNIT_ASSERT(strlen(pathbuf) == 0);
+
+        rc = zoo_create(zk, "/testpathpath2", "", 0,
+                        &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 2);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        CPPUNIT_ASSERT(strcmp(pathbuf, "/") == 0);
+
+        rc = zoo_create(zk, "/testpathpath3", "", 0,
+                        &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 3);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        CPPUNIT_ASSERT(strcmp(pathbuf, "/t") == 0);
+
+        rc = zoo_create(zk, "/testpathpath7", "", 0,
+                        &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 15);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        CPPUNIT_ASSERT(strcmp(pathbuf, "/testpathpath7") == 0);
+
+        rc = zoo_create(zk, "/testpathpath8", "", 0,
+                        &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 16);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        CPPUNIT_ASSERT(strcmp(pathbuf, "/testpathpath8") == 0);
+    }
+
+    void testPathValidation() {
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+        CPPUNIT_ASSERT(zk);
+
+        verifyCreateFails(0, zk);
+        verifyCreateFails("", zk);
+        verifyCreateFails("//", zk);
+        verifyCreateFails("///", zk);
+        verifyCreateFails("////", zk);
+        verifyCreateFails("/.", zk);
+        verifyCreateFails("/..", zk);
+        verifyCreateFails("/./", zk);
+        verifyCreateFails("/../", zk);
+        verifyCreateFails("/foo/./", zk);
+        verifyCreateFails("/foo/../", zk);
+        verifyCreateFails("/foo/.", zk);
+        verifyCreateFails("/foo/..", zk);
+        verifyCreateFails("/./.", zk);
+        verifyCreateFails("/../..", zk);
+        verifyCreateFails("/foo/bar/", zk);
+        verifyCreateFails("/foo//bar", zk);
+        verifyCreateFails("/foo/bar//", zk);
+
+        verifyCreateFails("foo", zk);
+        verifyCreateFails("a", zk);
+
+        // verify that trailing fails, except for seq which adds suffix
+        verifyCreateOk("/createseq", zk);
+        verifyCreateFails("/createseq/", zk);
+        verifyCreateOkSeq("/createseq/", zk);
+        verifyCreateOkSeq("/createseq/.", zk);
+        verifyCreateOkSeq("/createseq/..", zk);
+        verifyCreateFailsSeq("/createseq//", zk);
+        verifyCreateFailsSeq("/createseq/./", zk);
+        verifyCreateFailsSeq("/createseq/../", zk);
+
+        verifyCreateOk("/.foo", zk);
+        verifyCreateOk("/.f.", zk);
+        verifyCreateOk("/..f", zk);
+        verifyCreateOk("/..f..", zk);
+        verifyCreateOk("/f.c", zk);
+        verifyCreateOk("/f", zk);
+        verifyCreateOk("/f/.f", zk);
+        verifyCreateOk("/f/f.", zk);
+        verifyCreateOk("/f/..f", zk);
+        verifyCreateOk("/f/f..", zk);
+        verifyCreateOk("/f/.f/f", zk);
+        verifyCreateOk("/f/f./f", zk);
+    }
+
+    void testChroot() {
+        // the c client async callbacks do
+        // not callback with the path, so
+        // we dont need to test taht for now
+        // we should fix that though soon!
+        watchctx_t ctx, ctx_ch;
+        zhandle_t *zk, *zk_ch;
+        char buf[60];
+        int rc, len;
+        struct Stat stat;
+        const char* data = "garbage";
+        const char* retStr = "/chroot";
+        const char* root= "/";
+        zk_ch = createchClient(&ctx_ch, "127.0.0.1:22181/testch1/mahadev");
+        CPPUNIT_ASSERT(zk_ch != NULL);
+        zk = createClient(&ctx);
+        // first test with a NULL zk handle, make sure client library does not
+        // dereference a null pointer, but instead returns ZBADARGUMENTS
+        rc = zoo_create(NULL, "/testch1", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int) ZBADARGUMENTS, rc);
+        rc = zoo_create(zk, "/testch1", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        rc = zoo_create(zk, "/testch1/mahadev", data, 7, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        // try an exists with /
+        len = 60;
+        rc = zoo_get(zk_ch, "/", 0, buf, &len, &stat);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        //check if the data is the same
+        CPPUNIT_ASSERT(strncmp(buf, data, 7) == 0);
+        //check for watches
+        rc = zoo_wexists(zk_ch, "/chroot", watcher_chroot_fn, (void *) retStr, &stat);
+        //now check if we can do create/delete/get/sets/acls/getChildren and others
+        //check create
+        rc = zoo_create(zk_ch, "/chroot", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0,0);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        waitForChrootWatch(3);
+        CPPUNIT_ASSERT(count == 0);
+        rc = zoo_create(zk_ch, "/chroot/child", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        rc = zoo_exists(zk, "/testch1/mahadev/chroot/child", 0, &stat);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+
+        rc = zoo_delete(zk_ch, "/chroot/child", -1);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        rc = zoo_exists(zk, "/testch1/mahadev/chroot/child", 0, &stat);
+        CPPUNIT_ASSERT_EQUAL((int) ZNONODE, rc);
+        rc = zoo_wget(zk_ch, "/chroot", watcher_chroot_fn, (char*) retStr,
+                      buf, &len, &stat);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        rc = zoo_set(zk_ch, "/chroot",buf, 3, -1);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        waitForChrootWatch(3);
+        CPPUNIT_ASSERT(count == 0);
+        // check for getchildren
+        struct String_vector children;
+        rc = zoo_get_children(zk_ch, "/", 0, &children);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        CPPUNIT_ASSERT_EQUAL((int)1, (int)children.count);
+        //check if te child if chroot
+        CPPUNIT_ASSERT(strcmp((retStr+1), children.data[0]) == 0);
+        // check for get/set acl
+        struct ACL_vector acl;
+        rc = zoo_get_acl(zk_ch, "/", &acl, &stat);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        CPPUNIT_ASSERT_EQUAL((int)1, (int)acl.count);
+        CPPUNIT_ASSERT_EQUAL((int)ZOO_PERM_ALL, (int)acl.data->perms);
+        // set acl
+        rc = zoo_set_acl(zk_ch, "/chroot", -1,  &ZOO_READ_ACL_UNSAFE);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        // see if you add children
+        rc = zoo_create(zk_ch, "/chroot/child1", "",0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int)ZNOAUTH, rc);
+        //add wget children test
+        rc = zoo_wget_children(zk_ch, "/", watcher_chroot_fn, (char*) root, &children);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        //now create a node
+        rc = zoo_create(zk_ch, "/child2", "",0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        waitForChrootWatch(3);
+        CPPUNIT_ASSERT(count == 0);
+        //check for one async call just to make sure
+        rc = zoo_acreate(zk_ch, "/child3", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0,
+                         create_completion_fn, 0);
+        waitForCreateCompletion(3);
+        CPPUNIT_ASSERT(count == 0);
+
+        //ZOOKEEPER-1027 correctly return path_buffer without prefixed chroot
+        const char* path = "/zookeeper1027";
+        char path_buffer[1024];
+        int path_buffer_len=sizeof(path_buffer);
+        rc = zoo_create(zk_ch, path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, path_buffer, path_buffer_len);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        CPPUNIT_ASSERT_EQUAL(string(path), string(path_buffer));
+    }
+
+    void testAsyncWatcherAutoReset()
+    {
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+        watchctx_t lctx[COUNT];
+        int i;
+        char path[80];
+        int rc;
+        evt_t evt;
+
+        async_zk = zk;
+        for(i = 0; i < COUNT; i++) {
+            sprintf(path, "/awar%d", i);
+            rc = zoo_awexists(zk, path, watcher, &lctx[i], statCompletion, (void*)ZNONODE);
+            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        }
+
+        yield(zk, 0);
+
+        for(i = 0; i < COUNT/2; i++) {
+            sprintf(path, "/awar%d", i);
+            rc = zoo_acreate(zk, path, "", 0,  &ZOO_OPEN_ACL_UNSAFE, 0, stringCompletion, strdup(path));
+            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        }
+
+        yield(zk, 3);
+        for(i = 0; i < COUNT/2; i++) {
+            sprintf(path, "/awar%d", i);
+            CPPUNIT_ASSERT_MESSAGE(path, waitForEvent(zk, &lctx[i], 5));
+            evt = lctx[i].getEvent();
+            CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path.c_str(), ZOO_CREATED_EVENT, evt.type);
+            CPPUNIT_ASSERT_EQUAL(string(path), evt.path);
+        }
+
+        for(i = COUNT/2 + 1; i < COUNT*10; i++) {
+            sprintf(path, "/awar%d", i);
+            rc = zoo_acreate(zk, path, "", 0,  &ZOO_OPEN_ACL_UNSAFE, 0, stringCompletion, strdup(path));
+            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        }
+
+        yield(zk, 1);
+        stopServer();
+        CPPUNIT_ASSERT(ctx.waitForDisconnected(zk));
+        startServer();
+        CPPUNIT_ASSERT(ctx.waitForConnected(zk));
+        yield(zk, 3);
+        for(i = COUNT/2+1; i < COUNT; i++) {
+            sprintf(path, "/awar%d", i);
+            CPPUNIT_ASSERT_MESSAGE(path, waitForEvent(zk, &lctx[i], 5));
+            evt = lctx[i].getEvent();
+            CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_CREATED_EVENT, evt.type);
+            CPPUNIT_ASSERT_EQUAL(string(path), evt.path);
+        }
+    }
+
+    void testWatcherAutoReset(zhandle_t *zk, watchctx_t *ctxGlobal,
+                              watchctx_t *ctxLocal)
+    {
+        bool isGlobal = (ctxGlobal == ctxLocal);
+        int rc;
+        struct Stat stat;
+        char buf[1024];
+        int blen;
+        struct String_vector strings;
+        const char *testName;
+
+        rc = zoo_create(zk, "/watchtest", "", 0,
+                        &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        rc = zoo_create(zk, "/watchtest/child", "", 0,
+                        &ZOO_OPEN_ACL_UNSAFE, ZOO_EPHEMERAL, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        if (isGlobal) {
+            testName = "GlobalTest";
+            rc = zoo_get_children(zk, "/watchtest", 1, &strings);
+            deallocate_String_vector(&strings);
+            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+            blen = sizeof(buf);
+            rc = zoo_get(zk, "/watchtest/child", 1, buf, &blen, &stat);
+            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+            rc = zoo_exists(zk, "/watchtest/child2", 1, &stat);
+            CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
+        } else {
+            testName = "LocalTest";
+            rc = zoo_wget_children(zk, "/watchtest", watcher, ctxLocal,
+                                 &strings);
+            deallocate_String_vector(&strings);
+            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+            blen = sizeof(buf);
+            rc = zoo_wget(zk, "/watchtest/child", watcher, ctxLocal,
+                         buf, &blen, &stat);
+            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+            rc = zoo_wexists(zk, "/watchtest/child2", watcher, ctxLocal,
+                            &stat);
+            CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
+        }
+
+        CPPUNIT_ASSERT(ctxLocal->countEvents() == 0);
+
+        stopServer();
+        CPPUNIT_ASSERT_MESSAGE(testName, ctxGlobal->waitForDisconnected(zk));
+        startServer();
+        CPPUNIT_ASSERT_MESSAGE(testName, ctxLocal->waitForConnected(zk));
+
+        CPPUNIT_ASSERT(ctxLocal->countEvents() == 0);
+
+        rc = zoo_set(zk, "/watchtest/child", "1", 1, -1);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        struct Stat stat1, stat2;
+        rc = zoo_set2(zk, "/watchtest/child", "1", 1, -1, &stat1);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        CPPUNIT_ASSERT(stat1.version >= 0);
+        rc = zoo_set2(zk, "/watchtest/child", "1", 1, stat1.version, &stat2);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        rc = zoo_set(zk, "/watchtest/child", "1", 1, stat2.version);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        rc = zoo_create(zk, "/watchtest/child2", "", 0,
+                        &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
+
+        evt_t evt = ctxLocal->getEvent();
+        CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_CHANGED_EVENT, evt.type);
+        CPPUNIT_ASSERT_EQUAL(string("/watchtest/child"), evt.path);
+
+        CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
+        // The create will trigget the get children and the
+        // exists watches
+        evt = ctxLocal->getEvent();
+        CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_CREATED_EVENT, evt.type);
+        CPPUNIT_ASSERT_EQUAL(string("/watchtest/child2"), evt.path);
+        CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
+        evt = ctxLocal->getEvent();
+        CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_CHILD_EVENT, evt.type);
+        CPPUNIT_ASSERT_EQUAL(string("/watchtest"), evt.path);
+
+        // Make sure Pings are giving us problems
+        sleep(5);
+
+        CPPUNIT_ASSERT(ctxLocal->countEvents() == 0);
+
+        stopServer();
+        CPPUNIT_ASSERT_MESSAGE(testName, ctxGlobal->waitForDisconnected(zk));
+        startServer();
+        CPPUNIT_ASSERT_MESSAGE(testName, ctxGlobal->waitForConnected(zk));
+
+        if (isGlobal) {
+            testName = "GlobalTest";
+            rc = zoo_get_children(zk, "/watchtest", 1, &strings);
+            deallocate_String_vector(&strings);
+            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+            blen = sizeof(buf);
+            rc = zoo_get(zk, "/watchtest/child", 1, buf, &blen, &stat);
+            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+            rc = zoo_exists(zk, "/watchtest/child2", 1, &stat);
+            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        } else {
+            testName = "LocalTest";
+            rc = zoo_wget_children(zk, "/watchtest", watcher, ctxLocal,
+                                 &strings);
+            deallocate_String_vector(&strings);
+            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+            blen = sizeof(buf);
+            rc = zoo_wget(zk, "/watchtest/child", watcher, ctxLocal,
+                         buf, &blen, &stat);
+            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+            rc = zoo_wexists(zk, "/watchtest/child2", watcher, ctxLocal,
+                            &stat);
+            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        }
+
+        zoo_delete(zk, "/watchtest/child2", -1);
+
+        CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
+
+        evt = ctxLocal->getEvent();
+        CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_DELETED_EVENT, evt.type);
+        CPPUNIT_ASSERT_EQUAL(string("/watchtest/child2"), evt.path);
+
+        CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
+        evt = ctxLocal->getEvent();
+        CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_CHILD_EVENT, evt.type);
+        CPPUNIT_ASSERT_EQUAL(string("/watchtest"), evt.path);
+
+        stopServer();
+        CPPUNIT_ASSERT_MESSAGE(testName, ctxGlobal->waitForDisconnected(zk));
+        startServer();
+        CPPUNIT_ASSERT_MESSAGE(testName, ctxLocal->waitForConnected(zk));
+
+        zoo_delete(zk, "/watchtest/child", -1);
+        zoo_delete(zk, "/watchtest", -1);
+
+        CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
+
+        evt = ctxLocal->getEvent();
+        CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_DELETED_EVENT, evt.type);
+        CPPUNIT_ASSERT_EQUAL(string("/watchtest/child"), evt.path);
+
+        // Make sure nothing is straggling
+        sleep(1);
+        CPPUNIT_ASSERT(ctxLocal->countEvents() == 0);
+    }
+
+    void testWatcherAutoResetWithGlobal()
+    {
+      {
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+        int rc = zoo_create(zk, "/testarwg", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        rc = zoo_create(zk, "/testarwg/arwg", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+      }
+
+      {
+        watchctx_t ctx;
+        zhandle_t *zk = createchClient(&ctx, "127.0.0.1:22181/testarwg/arwg");
+
+        testWatcherAutoReset(zk, &ctx, &ctx);
+      }
+    }
+
+    void testWatcherAutoResetWithLocal()
+    {
+      {
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+        int rc = zoo_create(zk, "/testarwl", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        rc = zoo_create(zk, "/testarwl/arwl", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+      }
+
+      {
+        watchctx_t ctx;
+        watchctx_t lctx;
+        zhandle_t *zk = createchClient(&ctx, "127.0.0.1:22181/testarwl/arwl");
+        testWatcherAutoReset(zk, &ctx, &lctx);
+      }
+    }
+};
+
+volatile int Zookeeper_simpleSystem::count;
+zhandle_t *Zookeeper_simpleSystem::async_zk;
+const char Zookeeper_simpleSystem::hostPorts[] = "127.0.0.1:22181";
+CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_simpleSystem);

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/TestClientRetry.cc
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/TestClientRetry.cc b/zookeeper-client/zookeeper-client-c/tests/TestClientRetry.cc
new file mode 100644
index 0000000..41d5179
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/TestClientRetry.cc
@@ -0,0 +1,273 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "CppAssertHelper.h"
+
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/select.h>
+
+#include "CollectionUtil.h"
+#include "ThreadingUtil.h"
+
+using namespace Util;
+
+#include "Vector.h"
+using namespace std;
+
+#include <cstring>
+#include <list>
+
+#include <zookeeper.h>
+
+#include "Util.h"
+
+#ifdef THREADED
+    static void yield(zhandle_t *zh, int i)
+    {
+        sleep(i);
+    }
+#else
+    static void yield(zhandle_t *zh, int seconds)
+    {
+        int fd;
+        int interest;
+        int events;
+        struct timeval tv;
+        int rc;
+        time_t expires = time(0) + seconds; 
+        time_t timeLeft = seconds;
+        fd_set rfds, wfds, efds;
+        FD_ZERO(&rfds);
+        FD_ZERO(&wfds);
+        FD_ZERO(&efds);
+
+        while(timeLeft >= 0) {
+            zookeeper_interest(zh, &fd, &interest, &tv);
+            if (fd != -1) {
+                if (interest&ZOOKEEPER_READ) {
+                    FD_SET(fd, &rfds);
+                } else {
+                    FD_CLR(fd, &rfds);
+                }
+                if (interest&ZOOKEEPER_WRITE) {
+                    FD_SET(fd, &wfds);
+                } else {
+                    FD_CLR(fd, &wfds);
+                }
+            } else {
+                fd = 0;
+            }
+            FD_SET(0, &rfds);
+            if (tv.tv_sec > timeLeft) {
+                tv.tv_sec = timeLeft;
+            }
+            rc = select(fd+1, &rfds, &wfds, &efds, &tv);
+            timeLeft = expires - time(0);
+            events = 0;
+            if (FD_ISSET(fd, &rfds)) {
+                events |= ZOOKEEPER_READ;
+            }
+            if (FD_ISSET(fd, &wfds)) {
+                events |= ZOOKEEPER_WRITE;
+            }
+            zookeeper_process(zh, events);
+        }
+    }
+#endif
+
+typedef struct evt {
+    string path;
+    int type;
+} evt_t;
+
+typedef struct watchCtx {
+private:
+    list<evt_t> events;
+public:
+    bool connected;
+    zhandle_t *zh;
+    Mutex mutex;
+
+    watchCtx() {
+        connected = false;
+        zh = 0;
+    }
+    ~watchCtx() {
+        if (zh) {
+            zookeeper_close(zh);
+            zh = 0;
+        }
+    }
+
+    evt_t getEvent() {
+        evt_t evt;
+        mutex.acquire();
+        CPPUNIT_ASSERT( events.size() > 0);
+        evt = events.front();
+        events.pop_front();
+        mutex.release();
+        return evt;
+    }
+
+    int countEvents() {
+        int count;
+        mutex.acquire();
+        count = events.size();
+        mutex.release();
+        return count;
+    }
+
+    void putEvent(evt_t evt) {
+        mutex.acquire();
+        events.push_back(evt);
+        mutex.release();
+    }
+
+    bool waitForConnected(zhandle_t *zh) {
+        time_t expires = time(0) + 10;
+        while(!connected && time(0) < expires) {
+            yield(zh, 1);
+        }
+        return connected;
+    }
+    bool waitForDisconnected(zhandle_t *zh) {
+        time_t expires = time(0) + 15;
+        while(connected && time(0) < expires) {
+            yield(zh, 1);
+        }
+        return !connected;
+    }
+} watchctx_t; 
+
+class Zookeeper_clientretry : public CPPUNIT_NS::TestFixture
+{
+    CPPUNIT_TEST_SUITE(Zookeeper_clientretry);
+#ifdef THREADED
+    CPPUNIT_TEST(testRetry);
+#endif
+    CPPUNIT_TEST_SUITE_END();
+
+    static void watcher(zhandle_t *, int type, int state, const char *path,void*v){
+        watchctx_t *ctx = (watchctx_t*)v;
+
+        if (state == ZOO_CONNECTED_STATE) {
+            ctx->connected = true;
+        } else {
+            ctx->connected = false;
+        }
+        if (type != ZOO_SESSION_EVENT) {
+            evt_t evt;
+            evt.path = path;
+            evt.type = type;
+            ctx->putEvent(evt);
+        }
+    }
+
+    static const char hostPorts[];
+
+    const char *getHostPorts() {
+        return hostPorts;
+    }
+
+    zhandle_t *createClient(watchctx_t *ctx) {
+        zhandle_t *zk = zookeeper_init(hostPorts, watcher, 10000, 0,
+                                       ctx, 0);
+        ctx->zh = zk;
+        sleep(1);
+        return zk;
+    }
+    
+    FILE *logfile;
+public:
+
+    Zookeeper_clientretry() {
+      logfile = openlogfile("Zookeeper_clientretry");
+    }
+
+    ~Zookeeper_clientretry() {
+      if (logfile) {
+        fflush(logfile);
+        fclose(logfile);
+        logfile = 0;
+      }
+    }
+
+    void setUp()
+    {
+        zoo_set_log_stream(logfile);
+
+        char cmd[1024];
+        sprintf(cmd, "%s stop %s", ZKSERVER_CMD, getHostPorts());
+        CPPUNIT_ASSERT(system(cmd) == 0);
+
+        /* we are testing that if max cnxns is exceeded the server does the right thing */
+        sprintf(cmd, "export ZKMAXCNXNS=1;%s startClean %s", ZKSERVER_CMD, getHostPorts());
+        CPPUNIT_ASSERT(system(cmd) == 0);
+
+        struct sigaction act;
+        act.sa_handler = SIG_IGN;
+        sigemptyset(&act.sa_mask);
+        act.sa_flags = 0;
+        CPPUNIT_ASSERT(sigaction(SIGPIPE, &act, NULL) == 0);
+    }
+    
+    void tearDown()
+    {
+        char cmd[1024];
+        sprintf(cmd, "%s stop %s", ZKSERVER_CMD, getHostPorts());
+        CPPUNIT_ASSERT(system(cmd) == 0);
+
+        /* restart the server in "normal" mode */
+        sprintf(cmd, "%s startClean %s", ZKSERVER_CMD, getHostPorts());
+        CPPUNIT_ASSERT(system(cmd) == 0);
+
+        struct sigaction act;
+        act.sa_handler = SIG_IGN;
+        sigemptyset(&act.sa_mask);
+        act.sa_flags = 0;
+        CPPUNIT_ASSERT(sigaction(SIGPIPE, &act, NULL) == 0);
+    }
+
+    bool waitForEvent(zhandle_t *zh, watchctx_t *ctx, int seconds) {
+        time_t expires = time(0) + seconds;
+        while(ctx->countEvents() == 0 && time(0) < expires) {
+            yield(zh, 1);
+        }
+        return ctx->countEvents() > 0;
+    }
+
+    static zhandle_t *async_zk;
+
+    void testRetry()
+    {
+      watchctx_t ctx1, ctx2;
+      zhandle_t *zk1 = createClient(&ctx1);
+      CPPUNIT_ASSERT_EQUAL(true, ctx1.waitForConnected(zk1));
+      zhandle_t *zk2 = createClient(&ctx2);
+      zookeeper_close(zk1);
+      CPPUNIT_ASSERT_EQUAL(true, ctx2.waitForConnected(zk2));
+      ctx1.zh = 0;  
+    }
+};
+
+zhandle_t *Zookeeper_clientretry::async_zk;
+const char Zookeeper_clientretry::hostPorts[] = "127.0.0.1:22181";
+CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_clientretry);

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/TestDriver.cc
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/TestDriver.cc b/zookeeper-client/zookeeper-client-c/tests/TestDriver.cc
new file mode 100644
index 0000000..d60db69
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/TestDriver.cc
@@ -0,0 +1,173 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <cppunit/TestRunner.h>
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/TestResult.h>
+#include <cppunit/TestResultCollector.h>
+#include <cppunit/TextTestProgressListener.h>
+#include <cppunit/BriefTestProgressListener.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <stdexcept>
+#include <unistd.h>
+#include <sys/select.h>
+#include <cppunit/Exception.h>
+#include <cppunit/TestFailure.h>
+#include <cppunit/XmlOutputter.h>
+#include <cppunit/TestAssert.h>
+#include <fstream>
+#include <time.h> 
+
+#include "Util.h"
+#include "zookeeper_log.h"
+
+using namespace std;
+
+CPPUNIT_NS_BEGIN
+
+class EclipseOutputter: public CompilerOutputter
+{
+public:
+  EclipseOutputter(TestResultCollector *result,ostream &stream):
+        CompilerOutputter(result,stream,"%p:%l: "),stream_(stream)
+    {
+    }
+    virtual void printFailedTestName( TestFailure *failure ){}
+    virtual void printFailureMessage( TestFailure *failure )
+    {
+      stream_<<": ";
+      Message msg = failure->thrownException()->message();
+      stream_<< msg.shortDescription();
+
+      string text;
+      for(int i=0; i<msg.detailCount();i++){
+          text+=msg.detailAt(i);
+          if(i+1!=msg.detailCount())
+              text+=", ";
+      }
+      if(text.length()!=0)
+          stream_ <<" ["<<text<<"]";
+      stream_<<"\n";
+    }
+    ostream& stream_;
+};
+
+CPPUNIT_NS_END
+
+class TimingListener : public CPPUNIT_NS::BriefTestProgressListener {
+ public:
+   void startTest( CPPUNIT_NS::Test *test )
+   {
+     gettimeofday(&_start_time, NULL);
+
+     CPPUNIT_NS::BriefTestProgressListener::startTest(test);
+   }
+  
+   void endTest( CPPUNIT_NS::Test *test )
+   {
+     struct timeval end;
+     gettimeofday(&end, NULL);
+
+     long seconds = end.tv_sec - _start_time.tv_sec;
+     long useconds = end.tv_usec - _start_time.tv_usec;
+
+     long mtime = seconds * 1000 + useconds/1000.0;
+     CPPUNIT_NS::stdCOut()  <<  " : elapsed " <<  mtime;
+     CPPUNIT_NS::BriefTestProgressListener::endTest(test);
+   }
+
+ private:
+   struct timeval _start_time;
+};
+
+class ZKServer {
+public:
+    ZKServer() {
+        char cmd[1024];
+        sprintf(cmd, "%s startClean %s", ZKSERVER_CMD, "127.0.0.1:22181");
+        CPPUNIT_ASSERT(system(cmd) == 0);
+
+        struct sigaction act;
+        act.sa_handler = SIG_IGN;
+        sigemptyset(&act.sa_mask);
+        act.sa_flags = 0;
+        CPPUNIT_ASSERT(sigaction(SIGPIPE, &act, NULL) == 0);
+    }
+    virtual ~ZKServer(){
+        char cmd[1024];
+        sprintf(cmd, "%s stop %s", ZKSERVER_CMD, "127.0.0.1:22181");
+        CPPUNIT_ASSERT(system(cmd) == 0);
+    }
+};
+
+int main( int argc, char* argv[] ) { 
+   // if command line contains "-ide" then this is the post build check
+   // => the output must be in the compiler error format.
+   //bool selfTest = (argc > 1) && (std::string("-ide") == argv[1]);
+   globalTestConfig.addConfigFromCmdLine(argc,argv);
+
+   ZKServer zkserver;
+
+   // Create the event manager and test controller
+   CPPUNIT_NS::TestResult controller;
+   // Add a listener that colllects test result
+   CPPUNIT_NS::TestResultCollector result;
+   controller.addListener( &result );
+   
+   // A listener that print dots as tests run.
+   // CPPUNIT_NS::TextTestProgressListener progress;
+   // CPPUNIT_NS::BriefTestProgressListener progress;
+
+   // brief + elapsed time
+   TimingListener progress;
+   controller.addListener( &progress );
+ 
+   CPPUNIT_NS::TestRunner runner;
+   runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
+ 
+   try {
+     CPPUNIT_NS::stdCOut() << endl << "Running " << endl;
+
+     zoo_set_debug_level(ZOO_LOG_LEVEL_INFO);
+     //zoo_set_debug_level(ZOO_LOG_LEVEL_DEBUG);
+
+     runner.run( controller, globalTestConfig.getTestName());
+
+     // Print test in a compiler compatible format.
+     CPPUNIT_NS::EclipseOutputter outputter( &result,cout);
+     outputter.write(); 
+
+ // Uncomment this for XML output
+#ifdef ENABLE_XML_OUTPUT
+     std::ofstream file( "tests.xml" );
+     CPPUNIT_NS::XmlOutputter xml( &result, file );
+     xml.setStyleSheet( "report.xsl" );
+     xml.write();
+     file.close();
+#endif
+   } catch ( std::invalid_argument &e ) {
+     // Test path not resolved
+     cout<<"\nERROR: "<<e.what()<<endl;
+     return 0;
+   }
+
+   return result.wasSuccessful() ? 0 : 1;
+ }

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/TestMulti.cc
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/TestMulti.cc b/zookeeper-client/zookeeper-client-c/tests/TestMulti.cc
new file mode 100644
index 0000000..a54e047
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/TestMulti.cc
@@ -0,0 +1,703 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "CppAssertHelper.h"
+
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/select.h>
+
+#include "CollectionUtil.h"
+#include "ThreadingUtil.h"
+
+using namespace Util;
+
+#include "Vector.h"
+using namespace std;
+
+#include <cstring>
+#include <list>
+
+#include <zookeeper.h>
+#include <errno.h>
+#include <recordio.h>
+#include "Util.h"
+
+#ifdef THREADED
+    static void yield(zhandle_t *zh, int i)
+    {
+        sleep(i);
+    }
+#else
+    static void yield(zhandle_t *zh, int seconds)
+    {
+        int fd;
+        int interest;
+        int events;
+        struct timeval tv;
+        int rc;
+        time_t expires = time(0) + seconds;
+        time_t timeLeft = seconds;
+        fd_set rfds, wfds, efds;
+        FD_ZERO(&rfds);
+        FD_ZERO(&wfds);
+        FD_ZERO(&efds);
+
+        while(timeLeft >= 0) {
+            zookeeper_interest(zh, &fd, &interest, &tv);
+            if (fd != -1) {
+                if (interest&ZOOKEEPER_READ) {
+                    FD_SET(fd, &rfds);
+                } else {
+                    FD_CLR(fd, &rfds);
+                }
+                if (interest&ZOOKEEPER_WRITE) {
+                    FD_SET(fd, &wfds);
+                } else {
+                    FD_CLR(fd, &wfds);
+                }
+            } else {
+                fd = 0;
+            }
+            FD_SET(0, &rfds);
+            if (tv.tv_sec > timeLeft) {
+                tv.tv_sec = timeLeft;
+            }
+            rc = select(fd+1, &rfds, &wfds, &efds, &tv);
+            timeLeft = expires - time(0);
+            events = 0;
+            if (FD_ISSET(fd, &rfds)) {
+                events |= ZOOKEEPER_READ;
+            }
+            if (FD_ISSET(fd, &wfds)) {
+                events |= ZOOKEEPER_WRITE;
+            }
+            zookeeper_process(zh, events);
+        }
+    }
+#endif
+
+typedef struct evt {
+    string path;
+    int type;
+} evt_t;
+
+typedef struct watchCtx {
+private:
+    list<evt_t> events;
+    watchCtx(const watchCtx&);
+    watchCtx& operator=(const watchCtx&);
+public:
+    bool connected;
+    zhandle_t *zh;
+    Mutex mutex;
+
+    watchCtx() {
+        connected = false;
+        zh = 0;
+    }
+    ~watchCtx() {
+        if (zh) {
+            zookeeper_close(zh);
+            zh = 0;
+        }
+    }
+
+    evt_t getEvent() {
+        evt_t evt;
+        mutex.acquire();
+        CPPUNIT_ASSERT( events.size() > 0);
+        evt = events.front();
+        events.pop_front();
+        mutex.release();
+        return evt;
+    }
+
+    int countEvents() {
+        int count;
+        mutex.acquire();
+        count = events.size();
+        mutex.release();
+        return count;
+    }
+
+    void putEvent(evt_t evt) {
+        mutex.acquire();
+        events.push_back(evt);
+        mutex.release();
+    }
+
+    bool waitForConnected(zhandle_t *zh) {
+        time_t expires = time(0) + 10;
+        while(!connected && time(0) < expires) {
+            yield(zh, 1);
+        }
+        return connected;
+    }
+    bool waitForDisconnected(zhandle_t *zh) {
+        time_t expires = time(0) + 15;
+        while(connected && time(0) < expires) {
+            yield(zh, 1);
+        }
+        return !connected;
+    }
+} watchctx_t;
+
+class Zookeeper_multi : public CPPUNIT_NS::TestFixture
+{
+    CPPUNIT_TEST_SUITE(Zookeeper_multi);
+//FIXME: None of these tests pass in single-threaded mode. It seems to be a
+//flaw in the test suite setup.
+#ifdef THREADED
+    CPPUNIT_TEST(testCreate);
+    CPPUNIT_TEST(testCreateDelete);
+    CPPUNIT_TEST(testInvalidVersion);
+    CPPUNIT_TEST(testNestedCreate);
+    CPPUNIT_TEST(testSetData);
+    CPPUNIT_TEST(testUpdateConflict);
+    CPPUNIT_TEST(testDeleteUpdateConflict);
+    CPPUNIT_TEST(testAsyncMulti);
+    CPPUNIT_TEST(testMultiFail);
+    CPPUNIT_TEST(testCheck);
+    CPPUNIT_TEST(testWatch);
+    CPPUNIT_TEST(testSequentialNodeCreateInAsyncMulti);
+#endif
+    CPPUNIT_TEST_SUITE_END();
+
+    static void watcher(zhandle_t *, int type, int state, const char *path,void*v){
+        watchctx_t *ctx = (watchctx_t*)v;
+
+        if (state == ZOO_CONNECTED_STATE) {
+            ctx->connected = true;
+        } else {
+            ctx->connected = false;
+        }
+        if (type != ZOO_SESSION_EVENT) {
+            evt_t evt;
+            evt.path = path;
+            evt.type = type;
+            ctx->putEvent(evt);
+        }
+    }
+
+    static const char hostPorts[];
+
+    const char *getHostPorts() {
+        return hostPorts;
+    }
+    
+    zhandle_t *createClient(watchctx_t *ctx) {
+        return createClient(hostPorts, ctx);
+    }
+
+    zhandle_t *createClient(const char *hp, watchctx_t *ctx) {
+        zhandle_t *zk = zookeeper_init(hp, watcher, 10000, 0, ctx, 0);
+        ctx->zh = zk;
+        CPPUNIT_ASSERT_EQUAL(true, ctx->waitForConnected(zk));
+        return zk;
+    }
+        
+    FILE *logfile;
+public:
+
+    Zookeeper_multi() {
+      logfile = openlogfile("Zookeeper_multi");
+    }
+
+    ~Zookeeper_multi() {
+      if (logfile) {
+        fflush(logfile);
+        fclose(logfile);
+        logfile = 0;
+      }
+    }
+
+    void setUp()
+    {
+        zoo_set_log_stream(logfile);
+    }
+
+    void tearDown()
+    {
+    }
+    
+    static volatile int count;
+
+    static void multi_completion_fn(int rc, const void *data) {
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+        count++;
+    }
+
+    static void multi_completion_fn_no_assert(int rc, const void *data) {
+        count++;
+    }
+
+    static void waitForMultiCompletion(int seconds) {
+        time_t expires = time(0) + seconds;
+        while(count == 0 && time(0) < expires) {
+            sleep(1);
+        }
+        count--;
+    }
+
+    static void resetCounter() {
+        count = 0;
+    }
+
+    /**
+     * Test basic multi-op create functionality 
+     */
+    void testCreate() {
+        int rc;
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+       
+        int sz = 512;
+        char p1[sz];
+        char p2[sz];
+        char p3[sz];
+        p1[0] = p2[0] = p3[0] = '\0';
+
+        int nops = 3 ;
+        zoo_op_t ops[nops];
+        zoo_op_result_t results[nops];
+
+        zoo_create_op_init(&ops[0], "/multi1", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
+        zoo_create_op_init(&ops[1], "/multi1/a", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p2, sz);
+        zoo_create_op_init(&ops[2], "/multi1/b", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p3, sz);
+        
+        rc = zoo_multi(zk, nops, ops, results);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        CPPUNIT_ASSERT(strcmp(p1, "/multi1") == 0);
+        CPPUNIT_ASSERT(strcmp(p2, "/multi1/a") == 0);
+        CPPUNIT_ASSERT(strcmp(p3, "/multi1/b") == 0);
+
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[0].err);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[1].err);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[2].err);
+    }
+
+    /**
+     * Test create followed by delete 
+     */
+    void testCreateDelete() {
+        int rc;
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+        int sz = 512;
+        char p1[sz];
+        p1[0] = '\0';
+        int nops = 2 ;
+        zoo_op_t ops[nops];
+        zoo_op_result_t results[nops];
+
+        zoo_create_op_init(&ops[0], "/multi2", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
+        zoo_delete_op_init(&ops[1], "/multi2", 0);
+        
+        rc = zoo_multi(zk, nops, ops, results);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        // '/multi2' should have been deleted
+        rc = zoo_exists(zk, "/multi2", 0, NULL);
+        CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
+    }
+
+    /** 
+     * Test invalid versions
+     */
+    void testInvalidVersion() {
+        int rc;
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+        int nops = 4;
+        zoo_op_t ops[nops];
+        zoo_op_result_t results[nops];
+
+        zoo_create_op_init(&ops[0], "/multi3", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, NULL, 0);
+        zoo_delete_op_init(&ops[1], "/multi3", 1);
+        zoo_create_op_init(&ops[2], "/multi3", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, NULL, 0);
+        zoo_create_op_init(&ops[3], "/multi3/a", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, NULL, 0);
+        
+        rc = zoo_multi(zk, nops, ops, results);
+        CPPUNIT_ASSERT_EQUAL((int)ZBADVERSION, rc);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[0].err);
+        CPPUNIT_ASSERT_EQUAL((int)ZBADVERSION, results[1].err);
+        CPPUNIT_ASSERT_EQUAL((int)ZRUNTIMEINCONSISTENCY, results[2].err);
+        CPPUNIT_ASSERT_EQUAL((int)ZRUNTIMEINCONSISTENCY, results[3].err);
+    }
+
+    /**
+     * Test nested creates that rely on state in earlier op in multi
+     */
+    void testNestedCreate() {
+        int rc;
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+        int sz = 512;
+        char p1[sz];
+        p1[0] = '\0';
+        int nops = 6;
+        zoo_op_t ops[nops];
+        zoo_op_result_t results[nops];
+
+        /* Create */
+        zoo_create_op_init(&ops[0], "/multi4", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
+        zoo_create_op_init(&ops[1], "/multi4/a", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
+        zoo_create_op_init(&ops[2], "/multi4/a/1", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
+
+        /* Delete */
+        zoo_delete_op_init(&ops[3], "/multi4/a/1", 0);
+        zoo_delete_op_init(&ops[4], "/multi4/a", 0);
+        zoo_delete_op_init(&ops[5], "/multi4", 0);
+        
+        rc = zoo_multi(zk, nops, ops, results);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        // Verify tree deleted
+        rc = zoo_exists(zk, "/multi4/a/1", 0, NULL);
+        CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
+        
+        rc = zoo_exists(zk, "/multi4/a", 0, NULL);
+        CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
+  
+        rc = zoo_exists(zk, "/multi4", 0, NULL);
+        CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
+    }
+
+    /**
+     * Test setdata functionality
+     */
+    void testSetData() {
+        int rc;
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+        int sz = 512;
+        struct Stat s1;
+
+        char buf[sz];
+        int blen = sz ;
+
+        char p1[sz], p2[sz];
+        
+        int nops = 2;
+        zoo_op_t ops[nops];
+        zoo_op_result_t results[nops];
+
+        zoo_create_op_init(&ops[0], "/multi5",   "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
+        zoo_create_op_init(&ops[1], "/multi5/a", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p2, sz);
+       
+        rc = zoo_multi(zk, nops, ops, results);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        
+        yield(zk, 5);
+
+        zoo_op_t setdata_ops[nops];
+        zoo_op_result_t setdata_results[nops];
+
+        zoo_set_op_init(&setdata_ops[0], "/multi5",   "1", 1, 0, &s1);
+        zoo_set_op_init(&setdata_ops[1], "/multi5/a", "2", 1, 0, &s1);
+
+        rc = zoo_multi(zk, nops, setdata_ops, setdata_results);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[0].err);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[1].err);
+        
+        memset(buf, '\0', blen);
+        rc = zoo_get(zk, "/multi5", 0, buf, &blen, &s1);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        CPPUNIT_ASSERT_EQUAL(1, blen);
+        CPPUNIT_ASSERT(strcmp("1", buf) == 0);
+        
+        memset(buf, '\0', blen);
+        rc = zoo_get(zk, "/multi5/a", 0, buf, &blen, &s1);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        CPPUNIT_ASSERT_EQUAL(1, blen);
+        CPPUNIT_ASSERT(strcmp("2", buf) == 0);
+    }
+
+    /**
+     * Test update conflicts
+     */
+    void testUpdateConflict() {
+        int rc;
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+        int sz = 512;
+        char buf[sz];
+        int blen = sz;
+        char p1[sz];
+        p1[0] = '\0';
+        struct Stat s1;
+        int nops = 3;
+        zoo_op_t ops[nops];
+        zoo_op_result_t results[nops];
+
+        zoo_create_op_init(&ops[0], "/multi6", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
+        zoo_set_op_init(&ops[1], "/multi6", "X", 1, 0, &s1);
+        zoo_set_op_init(&ops[2], "/multi6", "Y", 1, 0, &s1);
+        
+        rc = zoo_multi(zk, nops, ops, results);
+        CPPUNIT_ASSERT_EQUAL((int)ZBADVERSION, rc);
+
+        //Updating version solves conflict -- order matters
+        ops[2].set_op.version = 1;
+        rc = zoo_multi(zk, nops, ops, results);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+       
+        memset(buf, 0, sz);
+        rc = zoo_get(zk, "/multi6", 0, buf, &blen, &s1);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        CPPUNIT_ASSERT_EQUAL(blen, 1);
+        CPPUNIT_ASSERT(strncmp(buf, "Y", 1) == 0);
+    }
+
+    /**
+     * Test delete-update conflicts
+     */
+    void testDeleteUpdateConflict() {
+        int rc;
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+        int sz = 512;
+        char buf[sz];
+        int blen;
+        char p1[sz];
+        p1[0] = '\0';
+        struct Stat stat;
+        int nops = 3;
+        zoo_op_t ops[nops];
+        zoo_op_result_t results[nops];
+
+        zoo_create_op_init(&ops[0], "/multi7", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
+        zoo_delete_op_init(&ops[1], "/multi7", 0);
+        zoo_set_op_init(&ops[2], "/multi7", "Y", 1, 0, &stat);
+        
+        rc = zoo_multi(zk, nops, ops, results);
+        CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
+
+        // '/multi' should never have been created as entire op should fail
+        rc = zoo_exists(zk, "/multi7", 0, NULL);
+        CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
+    }
+
+    void testAsyncMulti() {
+        int rc;
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+       
+        int sz = 512;
+        char p1[sz], p2[sz], p3[sz];
+        p1[0] = '\0';
+        p2[0] = '\0';
+        p3[0] = '\0';
+
+        int nops = 3;
+        zoo_op_t ops[nops];
+        zoo_op_result_t results[nops];
+
+        zoo_create_op_init(&ops[0], "/multi8",   "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
+        zoo_create_op_init(&ops[1], "/multi8/a", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p2, sz);
+        zoo_create_op_init(&ops[2], "/multi8/b", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p3, sz);
+ 
+        rc = zoo_amulti(zk, nops, ops, results, multi_completion_fn, 0);
+        waitForMultiCompletion(10);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        CPPUNIT_ASSERT(strcmp(p1, "/multi8") == 0);
+        CPPUNIT_ASSERT(strcmp(p2, "/multi8/a") == 0);
+        CPPUNIT_ASSERT(strcmp(p3, "/multi8/b") == 0);
+
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[0].err);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[1].err);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[2].err);
+    }
+
+    void testMultiFail() {
+        int rc;
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+       
+        int sz = 512;
+        char p1[sz], p2[sz], p3[sz];
+
+        p1[0] = '\0';
+        p2[0] = '\0';
+        p3[0] = '\0';
+
+        int nops = 3;
+        zoo_op_t ops[nops];
+        zoo_op_result_t results[nops];
+
+        zoo_create_op_init(&ops[0], "/multi9",   "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
+        zoo_create_op_init(&ops[1], "/multi9",   "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p2, sz);
+        zoo_create_op_init(&ops[2], "/multi9/b", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p3, sz);
+        
+        rc = zoo_multi(zk, nops, ops, results);
+        CPPUNIT_ASSERT_EQUAL((int)ZNODEEXISTS, rc);
+    }
+    
+    /**
+     * Test basic multi-op check functionality 
+     */
+    void testCheck() {
+        int rc;
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+        int sz = 512;
+        char p1[sz];
+        p1[0] = '\0';
+        struct Stat s1;
+
+        rc = zoo_create(zk, "/multi0", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        // Conditionally create /multi0/a' only if '/multi0' at version 0
+        int nops = 2;
+        zoo_op_t ops[nops];
+        zoo_op_result_t results[nops];
+
+        zoo_check_op_init(&ops[0], "/multi0", 0);
+        zoo_create_op_init(&ops[1], "/multi0/a", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
+        
+        rc = zoo_multi(zk, nops, ops, results);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[0].err);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[1].err);
+
+        // '/multi0/a' should have been created as it passed version check
+        rc = zoo_exists(zk, "/multi0/a", 0, NULL);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+ 
+        // Only create '/multi0/b' if '/multi0' at version 10 (which it's not)
+        zoo_op_t ops2[nops];
+        zoo_check_op_init(&ops2[0], "/multi0", 10);
+        zoo_create_op_init(&ops2[1], "/multi0/b", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
+        
+        rc = zoo_multi(zk, nops, ops2, results);
+        CPPUNIT_ASSERT_EQUAL((int)ZBADVERSION, rc);
+
+        CPPUNIT_ASSERT_EQUAL((int)ZBADVERSION, results[0].err);
+        CPPUNIT_ASSERT_EQUAL((int)ZRUNTIMEINCONSISTENCY, results[1].err);
+
+        // '/multi0/b' should NOT have been created
+        rc = zoo_exists(zk, "/multi0/b", 0, NULL);
+        CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
+    }
+
+    /**
+     * Do a multi op inside a watch callback context.
+     */
+    static void doMultiInWatch(zhandle_t *zk, int type, int state, const char *path, void *ctx) {
+        int rc;
+        int sz = 512;
+        char p1[sz];
+        p1[0] = '\0';
+        struct Stat s1;
+
+        int nops = 1;
+        zoo_op_t ops[nops];
+        zoo_op_result_t results[nops];
+
+        zoo_set_op_init(&ops[0], "/multiwatch", "1", 1, -1, NULL);
+
+        rc = zoo_multi(zk, nops, ops, results);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[0].err);
+
+        memset(p1, '\0', sz);
+        rc = zoo_get(zk, "/multiwatch", 0, p1, &sz, &s1);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+        CPPUNIT_ASSERT_EQUAL(1, sz);
+        CPPUNIT_ASSERT(strcmp("1", p1) == 0);
+        count++;
+    }
+
+    /**
+     * Test multi-op called from a watch
+     */
+     void testWatch() {
+        int rc;
+        watchctx_t ctx;
+        zhandle_t *zk = createClient(&ctx);
+        int sz = 512;
+        char p1[sz];
+        p1[0] = '\0';
+
+        rc = zoo_create(zk, "/multiwatch", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, NULL, 0);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+
+        // create a watch on node '/multiwatch'
+        rc = zoo_wget(zk, "/multiwatch", doMultiInWatch, &ctx, p1, &sz, NULL);
+
+        // setdata on node '/multiwatch' this should trip the watch
+        rc = zoo_set(zk, "/multiwatch", NULL, -1, -1);
+        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
+
+        // wait for multi completion in doMultiInWatch
+        waitForMultiCompletion(5);
+     }
+
+     /**
+      * ZOOKEEPER-1624: PendingChanges of create sequential node request didn't
+      * get rollbacked correctly when multi-op failed. This caused
+      * create sequential node request in subsequent multi-op to failed because
+      * sequential node name generation is incorrect.
+      *
+      * The check is to make sure that each request in multi-op failed with
+      * the correct reason.
+      */
+     void testSequentialNodeCreateInAsyncMulti() {
+         int rc;
+         watchctx_t ctx;
+         zhandle_t *zk = createClient(&ctx);
+
+         int iteration = 4;
+         int nops = 2;
+
+         zoo_op_result_t results[iteration][nops];
+         zoo_op_t ops[nops];
+         zoo_create_op_init(&ops[0], "/node-",   "", 0, &ZOO_OPEN_ACL_UNSAFE, ZOO_SEQUENCE, NULL, 0);
+         zoo_create_op_init(&ops[1], "/dup", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, NULL, 0);
+         for (int i = 0; i < iteration ; ++i) {
+           rc = zoo_amulti(zk, nops, ops, results[i], multi_completion_fn_no_assert, 0);
+           CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
+         }
+
+         waitForMultiCompletion(10);
+
+         CPPUNIT_ASSERT_EQUAL((int)ZOK, results[0][0].err);
+         CPPUNIT_ASSERT_EQUAL((int)ZOK, results[1][0].err);
+         CPPUNIT_ASSERT_EQUAL((int)ZOK, results[2][0].err);
+         CPPUNIT_ASSERT_EQUAL((int)ZOK, results[3][0].err);
+
+         CPPUNIT_ASSERT_EQUAL((int)ZOK, results[0][1].err);
+         CPPUNIT_ASSERT_EQUAL((int)ZNODEEXISTS, results[1][1].err);
+         CPPUNIT_ASSERT_EQUAL((int)ZNODEEXISTS, results[2][1].err);
+         CPPUNIT_ASSERT_EQUAL((int)ZNODEEXISTS, results[3][1].err);
+
+         resetCounter();
+     }
+};
+
+volatile int Zookeeper_multi::count;
+const char Zookeeper_multi::hostPorts[] = "127.0.0.1:22181";
+CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_multi);


[11/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/TestZookeeperInit.cc
----------------------------------------------------------------------
diff --git a/src/c/tests/TestZookeeperInit.cc b/src/c/tests/TestZookeeperInit.cc
deleted file mode 100644
index eadf41d..0000000
--- a/src/c/tests/TestZookeeperInit.cc
+++ /dev/null
@@ -1,301 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <cppunit/extensions/HelperMacros.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <errno.h>
-
-#include "Util.h"
-#include "LibCMocks.h"
-#include "ZKMocks.h"
-
-#ifdef THREADED
-#include "PthreadMocks.h"
-#else
-class MockPthreadsNull;
-#endif
-
-using namespace std;
-
-class Zookeeper_init : public CPPUNIT_NS::TestFixture
-{
-    CPPUNIT_TEST_SUITE(Zookeeper_init);
-    CPPUNIT_TEST(testBasic);
-    CPPUNIT_TEST(testAddressResolution);
-    CPPUNIT_TEST(testMultipleAddressResolution);
-    CPPUNIT_TEST(testNullAddressString);
-    CPPUNIT_TEST(testEmptyAddressString);
-    CPPUNIT_TEST(testOneSpaceAddressString);
-    CPPUNIT_TEST(testTwoSpacesAddressString);
-    CPPUNIT_TEST(testInvalidAddressString1);
-    CPPUNIT_TEST(testInvalidAddressString2);
-    CPPUNIT_TEST(testNonexistentHost);
-    CPPUNIT_TEST(testOutOfMemory_init);
-    CPPUNIT_TEST(testOutOfMemory_getaddrs1);
-#if !defined(__CYGWIN__) // not valid for cygwin
-    CPPUNIT_TEST(testOutOfMemory_getaddrs2);
-#endif
-    CPPUNIT_TEST(testPermuteAddrsList);
-    CPPUNIT_TEST_SUITE_END();
-    zhandle_t *zh;
-    MockPthreadsNull* pthreadMock;
-    static void watcher(zhandle_t *, int , int , const char *,void*){}
-    FILE *logfile;
-public:
-    Zookeeper_init():zh(0),pthreadMock(0){
-      logfile = openlogfile("Zookeeper_init");
-    }
-
-    ~Zookeeper_init() {
-      if (logfile) {
-        fflush(logfile);
-        fclose(logfile);
-        logfile = 0;
-      }
-    }
-
-    void setUp()
-    {
-        zoo_set_log_stream(logfile);
-
-        zoo_deterministic_conn_order(0);
-#ifdef THREADED
-        // disable threading
-        pthreadMock=new MockPthreadZKNull;
-#endif
-        zh=0;
-    }
-
-    void tearDown()
-    {
-        zookeeper_close(zh);
-#ifdef THREADED
-        delete pthreadMock;
-#endif
-    }
-
-    void testBasic()
-    {
-        const string EXPECTED_HOST("127.0.0.1:2121");
-        const int EXPECTED_ADDRS_COUNT =1;
-        const int EXPECTED_RECV_TIMEOUT=10000;
-        clientid_t cid;
-        memset(&cid,0xFE,sizeof(cid));
-
-        zh=zookeeper_init(EXPECTED_HOST.c_str(),watcher,EXPECTED_RECV_TIMEOUT,
-                &cid,(void*)1,0);
-
-        CPPUNIT_ASSERT(zh!=0);
-        CPPUNIT_ASSERT(zh->fd == -1);
-        CPPUNIT_ASSERT(zh->hostname!=0);
-        CPPUNIT_ASSERT_EQUAL(EXPECTED_ADDRS_COUNT,zh->addrs_count);
-        CPPUNIT_ASSERT_EQUAL(EXPECTED_HOST,string(zh->hostname));
-        CPPUNIT_ASSERT(zh->state == NOTCONNECTED_STATE_DEF);
-        CPPUNIT_ASSERT(zh->context == (void*)1);
-        CPPUNIT_ASSERT_EQUAL(EXPECTED_RECV_TIMEOUT,zh->recv_timeout);
-        CPPUNIT_ASSERT(zh->watcher == watcher);
-        CPPUNIT_ASSERT(zh->connect_index==0);
-        CPPUNIT_ASSERT(zh->primer_buffer.buffer==zh->primer_storage_buffer);
-        CPPUNIT_ASSERT(zh->primer_buffer.curr_offset ==0);
-        CPPUNIT_ASSERT(zh->primer_buffer.len == sizeof(zh->primer_storage_buffer));
-        CPPUNIT_ASSERT(zh->primer_buffer.next == 0);
-        CPPUNIT_ASSERT(zh->last_zxid ==0);
-        CPPUNIT_ASSERT(memcmp(&zh->client_id,&cid,sizeof(cid))==0);
-
-#ifdef THREADED
-        // thread specific checks
-        adaptor_threads* adaptor=(adaptor_threads*)zh->adaptor_priv;
-        CPPUNIT_ASSERT(adaptor!=0);
-        CPPUNIT_ASSERT(pthreadMock->pthread_createCounter==2);
-        CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(adaptor->io));
-        CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(adaptor->completion));
-        CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->to_process.lock));
-        CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->to_send.lock));
-        CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->sent_requests.lock));
-        CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->completions_to_process.lock));
-        CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->sent_requests.cond));
-        CPPUNIT_ASSERT(MockPthreadsNull::isInitialized(&zh->completions_to_process.cond));
-#endif
-    }
-    void testAddressResolution()
-    {
-        const char EXPECTED_IPS[][4]={{127,0,0,1}};
-        const int EXPECTED_ADDRS_COUNT =COUNTOF(EXPECTED_IPS);
-
-        zoo_deterministic_conn_order(1);
-        zh=zookeeper_init("127.0.0.1:2121",0,10000,0,0,0);
-
-        CPPUNIT_ASSERT(zh!=0);
-        CPPUNIT_ASSERT_EQUAL(EXPECTED_ADDRS_COUNT,zh->addrs_count);
-        for(int i=0;i<zh->addrs_count;i++){
-            sockaddr_in* addr=(struct sockaddr_in*)&zh->addrs[i];
-            CPPUNIT_ASSERT(memcmp(EXPECTED_IPS[i],&addr->sin_addr,sizeof(addr->sin_addr))==0);
-            CPPUNIT_ASSERT_EQUAL(2121,(int)ntohs(addr->sin_port));
-        }
-    }
-    void testMultipleAddressResolution()
-    {
-        const string EXPECTED_HOST("127.0.0.1:2121,127.0.0.2:3434");
-        const char EXPECTED_IPS[][4]={{127,0,0,1},{127,0,0,2}};
-        const int EXPECTED_ADDRS_COUNT =COUNTOF(EXPECTED_IPS);
-
-        zoo_deterministic_conn_order(1);
-        zh=zookeeper_init(EXPECTED_HOST.c_str(),0,1000,0,0,0);
-
-        CPPUNIT_ASSERT(zh!=0);
-        CPPUNIT_ASSERT_EQUAL(EXPECTED_ADDRS_COUNT,zh->addrs_count);
-
-        for(int i=0;i<zh->addrs_count;i++){
-            sockaddr_in* addr=(struct sockaddr_in*)&zh->addrs[i];
-            CPPUNIT_ASSERT(memcmp(EXPECTED_IPS[i],&addr->sin_addr,sizeof(addr->sin_addr))==0);
-            if(i<1)
-                CPPUNIT_ASSERT_EQUAL(2121,(int)ntohs(addr->sin_port));
-            else
-                CPPUNIT_ASSERT_EQUAL(3434,(int)ntohs(addr->sin_port));
-        }
-    }
-    void testMultipleAddressWithSpace()
-    { 
-        const string EXPECTED_HOST("127.0.0.1:2121,  127.0.0.2:3434");
-        const char EXPECTED_IPS[][4]={{127,0,0,1},{127,0,0,2}};
-        const int EXPECTED_ADDRS_COUNT =COUNTOF(EXPECTED_IPS);
-
-        zoo_deterministic_conn_order(1);
-        zh=zookeeper_init(EXPECTED_HOST.c_str(),0,1000,0,0,0);
-
-        CPPUNIT_ASSERT(zh!=0);
-        CPPUNIT_ASSERT_EQUAL(EXPECTED_ADDRS_COUNT,zh->addrs_count);
-
-        for(int i=0;i<zh->addrs_count;i++){
-            sockaddr_in* addr=(struct sockaddr_in*)&zh->addrs[i];
-            CPPUNIT_ASSERT(memcmp(EXPECTED_IPS[i],&addr->sin_addr,sizeof(addr->sin_addr))==0);
-            if(i<1)
-                CPPUNIT_ASSERT_EQUAL(2121,(int)ntohs(addr->sin_port));
-            else
-                CPPUNIT_ASSERT_EQUAL(3434,(int)ntohs(addr->sin_port));
-        }
-    }
-    void testNullAddressString()
-    {
-        zh=zookeeper_init(NULL,0,0,0,0,0);
-        CPPUNIT_ASSERT(zh==0);
-        CPPUNIT_ASSERT_EQUAL(EINVAL,errno);
-    }
-    void testEmptyAddressString()
-    {
-        const string INVALID_HOST("");
-        zh=zookeeper_init(INVALID_HOST.c_str(),0,0,0,0,0);
-        CPPUNIT_ASSERT(zh==0);
-        CPPUNIT_ASSERT_EQUAL(EINVAL,errno);
-    }
-    void testOneSpaceAddressString()
-    {
-        const string INVALID_HOST(" ");
-        zh=zookeeper_init(INVALID_HOST.c_str(),0,0,0,0,0);
-        CPPUNIT_ASSERT(zh==0);
-        CPPUNIT_ASSERT_EQUAL(EINVAL,errno);
-    }
-    void testTwoSpacesAddressString()
-    {
-        const string INVALID_HOST("  ");
-        zh=zookeeper_init(INVALID_HOST.c_str(),0,0,0,0,0);
-        CPPUNIT_ASSERT(zh==0);
-        CPPUNIT_ASSERT_EQUAL(EINVAL,errno);
-    }
-    void testInvalidAddressString1()
-    {
-        const string INVALID_HOST("host1");
-        zh=zookeeper_init(INVALID_HOST.c_str(),0,0,0,0,0);
-        CPPUNIT_ASSERT(zh==0);
-        CPPUNIT_ASSERT_EQUAL(EINVAL,errno);
-    }
-    void testInvalidAddressString2()
-    {
-        const string INVALID_HOST("host1:1111+host:123");
-        zh=zookeeper_init(INVALID_HOST.c_str(),0,0,0,0,0);
-        CPPUNIT_ASSERT(zh==0);
-        CPPUNIT_ASSERT((ENOENT|EINVAL) & errno);
-    }
-    void testNonexistentHost()
-    {
-        const string EXPECTED_HOST("host1.blabadibla.bla.:1111");
-
-        zh=zookeeper_init(EXPECTED_HOST.c_str(),0,0,0,0,0);
-
-        CPPUNIT_ASSERT(zh==0);
-        //With the switch to thread safe getaddrinfo, we don't get
-        //these global variables
-        //CPPUNIT_ASSERT_EQUAL(EINVAL,errno);
-        //CPPUNIT_ASSERT_EQUAL(HOST_NOT_FOUND,h_errno);
-    }
-    void testOutOfMemory_init()
-    {
-        Mock_calloc mock;
-        mock.callsBeforeFailure=0; // fail first calloc in init()
-
-        zh=zookeeper_init("ahost:123",watcher,10000,0,0,0);
-
-        CPPUNIT_ASSERT(zh==0);
-        CPPUNIT_ASSERT_EQUAL(ENOMEM,errno);
-    }
-    void testOutOfMemory_getaddrs1()
-    {
-        Mock_realloc reallocMock;
-        reallocMock.callsBeforeFailure=0; // fail on first call to realloc
-
-        zh=zookeeper_init("127.0.0.1:123",0,0,0,0,0);
-
-        CPPUNIT_ASSERT(zh==0);
-        CPPUNIT_ASSERT_EQUAL(ENOMEM,errno);
-    }
-    void testOutOfMemory_getaddrs2()
-    {
-        Mock_realloc reallocMock;
-        reallocMock.callsBeforeFailure=1; // fail on the second call to realloc
-
-        zh=zookeeper_init("127.0.0.1:123,127.0.0.2:123,127.0.0.3:123,127.0.0.4:123,127.0.0.5:123,127.0.0.6:123,127.0.0.7:123,127.0.0.8:123,127.0.0.9:123,127.0.0.10:123,127.0.0.11:123,127.0.0.12:123,127.0.0.13:123,127.0.0.14:123,127.0.0.15:123,127.0.0.16:123,127.0.0.17:123",0,0,0,0,0);
-
-        CPPUNIT_ASSERT(zh==0);
-        CPPUNIT_ASSERT_EQUAL(ENOMEM,errno);
-    }
-    void testPermuteAddrsList()
-    {
-        const char EXPECTED[][5]={"\0\0\0\0","\1\1\1\1","\2\2\2\2","\3\3\3\3"};
-        const int EXPECTED_ADDR_COUNT=COUNTOF(EXPECTED);
-
-        const int RAND_SEQ[]={0,1,1,-1};
-        const int RAND_SIZE=COUNTOF(RAND_SEQ);
-        Mock_random randomMock;
-        randomMock.randomReturns.assign(RAND_SEQ,RAND_SEQ+RAND_SIZE-1);
-        zh=zookeeper_init("0.0.0.0:123,1.1.1.1:123,2.2.2.2:123,3.3.3.3:123",0,1000,0,0,0);
-
-        CPPUNIT_ASSERT(zh!=0);
-        CPPUNIT_ASSERT_EQUAL(EXPECTED_ADDR_COUNT,zh->addrs_count);
-        const string EXPECTED_SEQ("3210");
-        char ACTUAL_SEQ[EXPECTED_ADDR_COUNT+1]; ACTUAL_SEQ[EXPECTED_ADDR_COUNT]=0;
-        for(int i=0;i<zh->addrs_count;i++){
-            sockaddr_in* addr=(struct sockaddr_in*)&zh->addrs[i];
-            // match the first byte of the EXPECTED and of the actual address
-            ACTUAL_SEQ[i]=((char*)&addr->sin_addr)[0]+'0';
-        }
-        CPPUNIT_ASSERT_EQUAL(EXPECTED_SEQ,string(ACTUAL_SEQ));
-    }
-};
-
-CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_init);

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/ThreadingUtil.cc
----------------------------------------------------------------------
diff --git a/src/c/tests/ThreadingUtil.cc b/src/c/tests/ThreadingUtil.cc
deleted file mode 100644
index 3b5170a..0000000
--- a/src/c/tests/ThreadingUtil.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sys/types.h>
-#include "ThreadingUtil.h"
-#include "LibCSymTable.h"
-
-#ifdef THREADED
-
-// ****************************************************************************
-// Mutex wrapper
-struct Mutex::Impl{
-    Impl(){
-        LIBC_SYMBOLS.pthread_mutex_init(&mut_, 0);        
-    }
-    ~Impl(){
-        LIBC_SYMBOLS.pthread_mutex_destroy(&mut_);        
-    }
-    pthread_mutex_t mut_;
-};
-
-Mutex::Mutex():impl_(new Impl) {}
-Mutex::~Mutex() { delete impl_;}
-void Mutex::acquire() {
-    LIBC_SYMBOLS.pthread_mutex_lock(&impl_->mut_);
-}
-void Mutex::release() {
-    LIBC_SYMBOLS.pthread_mutex_unlock(&impl_->mut_);
-}
-
-// ****************************************************************************
-// Atomics
-int32_t atomic_post_incr(volatile int32_t* operand, int32_t incr)
-{
-#if defined(__GNUC__)
-    return __sync_fetch_and_add(operand,incr);
-#else
-    int32_t result;
-    __asm__ __volatile__(
-         "lock xaddl %0,%1\n"
-         : "=r"(result), "=m"(*operand)
-         : "0"(incr)
-         : "memory");
-   return result;
-#endif
-}
-int32_t atomic_fetch_store(volatile int32_t *ptr, int32_t value)
-{
-#if defined(__GNUC__)
-    return __sync_lock_test_and_set(ptr,value);
-#else
-    int32_t result;
-    __asm__ __volatile__("lock xchgl %0,%1\n"
-                          : "=r"(result), "=m"(*ptr)
-                          : "0"(value)
-                          : "memory");
-   return result; 
-#endif
-}
-#else
-int32_t atomic_post_incr(volatile int32_t* operand, int32_t incr){
-    int32_t v=*operand;
-    *operand+=incr;
-    return v;
-}
-int32_t atomic_fetch_store(volatile int32_t *ptr, int32_t value)
-{
-    int32_t result=*ptr;
-    *ptr=value;
-    return result;
-}
-#endif // THREADED

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/ThreadingUtil.h
----------------------------------------------------------------------
diff --git a/src/c/tests/ThreadingUtil.h b/src/c/tests/ThreadingUtil.h
deleted file mode 100644
index 9165412..0000000
--- a/src/c/tests/ThreadingUtil.h
+++ /dev/null
@@ -1,261 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef THREADINGUTIL_H_
-#define THREADINGUTIL_H_
-
-#include <vector>
-
-#ifdef THREADED
-#include "pthread.h"
-#endif
-
-// *****************************************************************************
-// Threading primitives
-
-// atomic post-increment; returns the previous value of the operand
-int32_t atomic_post_incr(volatile int32_t* operand, int32_t incr);
-// atomic fetch&store; returns the previous value of the operand
-int32_t atomic_fetch_store(volatile int32_t *operand, int32_t value);
-
-// a partial implementation of an atomic integer type
-class AtomicInt{
-public:
-    explicit AtomicInt(int32_t init=0):v_(init){}
-    AtomicInt(const AtomicInt& other):v_(other){}
-    // assigment
-    AtomicInt& operator=(const AtomicInt& lhs){
-        atomic_fetch_store(&v_,lhs);
-        return *this;
-    }
-    AtomicInt& operator=(int32_t i){
-        atomic_fetch_store(&v_,i);
-        return *this;
-    }
-    // pre-increment
-    AtomicInt& operator++() {
-        atomic_post_incr(&v_,1);
-        return *this;
-    }
-    // pre-decrement
-    AtomicInt& operator--() {
-        atomic_post_incr(&v_,-1);
-        return *this;
-    }
-    // post-increment
-    AtomicInt operator++(int){
-        return AtomicInt(atomic_post_incr(&v_,1));
-    }
-    // post-decrement
-    AtomicInt operator--(int){
-        return AtomicInt(atomic_post_incr(&v_,-1));
-    }
-    
-    operator int() const{
-        return atomic_post_incr(&v_,0);
-    }
-    int get() const{
-        return atomic_post_incr(&v_,0);
-    }
-private:
-    mutable int32_t v_;
-};
-
-#ifdef THREADED
-// ****************************************************************************
-#define VALIDATE_JOBS(jm) jm.validateJobs(__FILE__,__LINE__)
-#define VALIDATE_JOB(j) j.validate(__FILE__,__LINE__)
-
-class Mutex{
-public:
-    Mutex();
-    ~Mutex();
-    void acquire();
-    void release();
-private:
-    Mutex(const Mutex&);
-    Mutex& operator=(const Mutex&);
-    struct Impl;
-    Impl* impl_;
-};
-
-class MTLock{
-public:
-    MTLock(Mutex& m):m_(m){m.acquire();}
-    ~MTLock(){m_.release();}
-    Mutex& m_;
-};
-
-#define synchronized(m) MTLock __lock(m)
-
-// ****************************************************************************
-class Latch {
-public:
-    virtual ~Latch() {}
-    virtual void await() const =0;
-    virtual void signalAndWait() =0;
-    virtual void signal() =0;
-};
-
-class CountDownLatch: public Latch {
-public:
-    CountDownLatch(int count):count_(count) {
-        pthread_cond_init(&cond_,0);
-        pthread_mutex_init(&mut_,0);
-    }
-    virtual ~CountDownLatch() {
-        pthread_mutex_lock(&mut_);
-        if(count_!=0) {
-            count_=0;
-            pthread_cond_broadcast(&cond_);
-        }
-        pthread_mutex_unlock(&mut_);
-
-        pthread_cond_destroy(&cond_);
-        pthread_mutex_destroy(&mut_);
-    }
-
-    virtual void await() const {
-        pthread_mutex_lock(&mut_);
-        awaitImpl();
-        pthread_mutex_unlock(&mut_);
-    }
-    virtual void signalAndWait() {
-        pthread_mutex_lock(&mut_);
-        signalImpl();
-        awaitImpl();
-        pthread_mutex_unlock(&mut_);
-    }
-    virtual void signal() {
-        pthread_mutex_lock(&mut_);
-        signalImpl();
-        pthread_mutex_unlock(&mut_);
-    }
-private:
-    void awaitImpl() const{
-        while(count_!=0)
-        pthread_cond_wait(&cond_,&mut_);
-    }
-    void signalImpl() {
-        if(count_>0) {
-            count_--;
-            pthread_cond_broadcast(&cond_);
-        }
-    }
-    int count_;
-    mutable pthread_mutex_t mut_;
-    mutable pthread_cond_t cond_;
-};
-
-class TestJob {
-public:
-    typedef long JobId;
-    TestJob():hasRun_(false),startLatch_(0),endLatch_(0) {}
-    virtual ~TestJob() {
-        join();
-    }
-    virtual TestJob* clone() const =0;
-
-    virtual void run() =0;
-    virtual void validate(const char* file, int line) const =0;
-
-    virtual void start(Latch* startLatch=0,Latch* endLatch=0) {
-        startLatch_=startLatch;endLatch_=endLatch;
-        hasRun_=true;
-        pthread_create(&thread_, 0, thread, this);
-    }
-    virtual JobId getJobId() const {
-        return (JobId)thread_;
-    }
-    virtual void join() {
-        if(!hasRun_)
-        return;
-        if(!pthread_equal(thread_,pthread_self()))
-        pthread_join(thread_,0);
-        else
-        pthread_detach(thread_);
-    }
-private:
-    void awaitStart() {
-        if(startLatch_==0) return;
-        startLatch_->signalAndWait();
-    }
-    void signalFinished() {
-        if(endLatch_==0) return;
-        endLatch_->signal();
-    }
-    static void* thread(void* p) {
-        TestJob* j=(TestJob*)p;
-        j->awaitStart(); // wait for the start command
-        j->run();
-        j->signalFinished();
-        return 0;
-    }
-    bool hasRun_;
-    Latch* startLatch_;
-    Latch* endLatch_;
-    pthread_t thread_;
-};
-
-class TestJobManager {
-    typedef std::vector<TestJob*> JobList;
-public:
-    TestJobManager(const TestJob& tj,int threadCount=1):
-        startLatch_(threadCount),endLatch_(threadCount)
-    {
-        for(int i=0;i<threadCount;++i)
-            jobs_.push_back(tj.clone());
-    }
-    virtual ~TestJobManager(){
-        for(unsigned  i=0;i<jobs_.size();++i)
-            delete jobs_[i];
-    }
-    
-    virtual void startAllJobs() {
-        for(unsigned i=0;i<jobs_.size();++i)
-            jobs_[i]->start(&startLatch_,&endLatch_);
-    }
-    virtual void startJobsImmediately() {
-        for(unsigned i=0;i<jobs_.size();++i)
-            jobs_[i]->start(0,&endLatch_);
-    }
-    virtual void wait() const {
-        endLatch_.await();
-    }
-    virtual void validateJobs(const char* file, int line) const{
-        for(unsigned i=0;i<jobs_.size();++i)
-            jobs_[i]->validate(file,line);        
-    }
-private:
-    JobList jobs_;
-    CountDownLatch startLatch_;
-    CountDownLatch endLatch_;
-};
-
-#else // THREADED
-// single THREADED
-class Mutex{
-public:
-    void acquire(){}
-    void release(){}
-};
-#define synchronized(m)
-
-#endif // THREADED
-
-#endif /*THREADINGUTIL_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/Util.cc
----------------------------------------------------------------------
diff --git a/src/c/tests/Util.cc b/src/c/tests/Util.cc
deleted file mode 100644
index 2b9da84..0000000
--- a/src/c/tests/Util.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Util.h"
-#include "string.h"
-
-const std::string EMPTY_STRING;
-
-TestConfig globalTestConfig;
-
-void millisleep(int ms){
-    timespec ts;
-    ts.tv_sec=ms/1000;
-    ts.tv_nsec=(ms%1000)*1000000; // to nanoseconds
-    nanosleep(&ts,0);
-}
-
-FILE *openlogfile(const char* testname) {
-  char name[1024];
-  strcpy(name, "TEST-");
-  strncpy(name + 5, testname, sizeof(name) - 5);
-#ifdef THREADED
-  strcpy(name + strlen(name), "-mt.txt");
-#else
-  strcpy(name + strlen(name), "-st.txt");
-#endif
-
-  FILE *logfile = fopen(name, "a");
-
-  if (logfile == 0) {
-    fprintf(stderr, "Can't open log file %s!\n", name);
-    return 0;
-  }
-
-  return logfile;
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/Util.h
----------------------------------------------------------------------
diff --git a/src/c/tests/Util.h b/src/c/tests/Util.h
deleted file mode 100644
index 01e21ce..0000000
--- a/src/c/tests/Util.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef UTIL_H_
-#define UTIL_H_
-
-#include <map>
-#include <vector>
-#include <string>
-
-#include "zookeeper_log.h"
-
-// number of elements in array
-#define COUNTOF(array) sizeof(array)/sizeof(array[0])
-
-#define DECLARE_WRAPPER(ret,sym,sig) \
-    extern "C" ret __real_##sym sig; \
-    extern "C" ret __wrap_##sym sig
-
-#define CALL_REAL(sym,params) \
-    __real_##sym params
-
-// must include "src/zookeeper_log.h" to be able to use this macro
-#define TEST_TRACE(x) \
-    log_message(ZOO_LOG_LEVEL_DEBUG,__LINE__,__func__,format_log_message x)
-
-extern const std::string EMPTY_STRING;
-
-// *****************************************************************************
-// A bit of wizardry to get to the bare type from a reference or a pointer 
-// to the type
-template <class T>
-struct TypeOp {
-    typedef T BareT;
-    typedef T ArgT;
-};
-
-// partial specialization for reference types
-template <class T>
-struct TypeOp<T&>{
-    typedef T& ArgT;
-    typedef typename TypeOp<T>::BareT BareT;
-};
-
-// partial specialization for pointers
-template <class T>
-struct TypeOp<T*>{
-    typedef T* ArgT;
-    typedef typename TypeOp<T>::BareT BareT;
-};
-
-// *****************************************************************************
-// Container utilities
-
-template <class K, class V>
-void putValue(std::map<K,V>& map,const K& k, const V& v){
-    typedef std::map<K,V> Map;
-    typename Map::const_iterator it=map.find(k);
-    if(it==map.end())
-        map.insert(typename Map::value_type(k,v));
-    else
-        map[k]=v;
-}
-
-template <class K, class V>
-bool getValue(const std::map<K,V>& map,const K& k,V& v){
-    typedef std::map<K,V> Map;
-    typename Map::const_iterator it=map.find(k);
-    if(it==map.end())
-        return false;
-    v=it->second;
-    return true;
-}
-
-// *****************************************************************************
-// misc utils
-
-// millisecond sleep
-void millisleep(int ms);
-FILE *openlogfile(const char* name);
-// evaluate given predicate until it returns true or the timeout 
-// (in millis) has expired
-template<class Predicate>
-int ensureCondition(const Predicate& p,int timeout){
-    int elapsed=0;
-    while(!p() && elapsed<timeout){
-        millisleep(2);
-        elapsed+=2;
-    }
-    return elapsed;
-};
-
-// *****************************************************************************
-// test global configuration data 
-class TestConfig{
-    typedef std::vector<std::string> CmdLineOptList;
-public:
-    typedef CmdLineOptList::const_iterator const_iterator;
-    TestConfig(){}
-    ~TestConfig(){}
-    void addConfigFromCmdLine(int argc, char* argv[]){
-        if(argc>=2)
-            testName_=argv[1];
-        for(int i=2; i<argc;++i)
-            cmdOpts_.push_back(argv[i]);
-    }
-    const_iterator getExtraOptBegin() const {return cmdOpts_.begin();}
-    const_iterator getExtraOptEnd() const {return cmdOpts_.end();}
-    size_t getExtraOptCount() const {
-        return cmdOpts_.size();
-    }
-    const std::string& getTestName() const {
-        return testName_=="all"?EMPTY_STRING:testName_;
-    }
-private:
-    CmdLineOptList cmdOpts_;
-    std::string testName_;
-};
-
-extern TestConfig globalTestConfig;
-
-#endif /*UTIL_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/Vector.h
----------------------------------------------------------------------
diff --git a/src/c/tests/Vector.h b/src/c/tests/Vector.h
deleted file mode 100644
index d75fe07..0000000
--- a/src/c/tests/Vector.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef _VECTOR_UTIL_H
-#define _VECTOR_UTIL_H
-
-#include <vector>
-
-// function to conveniently stream vectors
-template <class U>
-std::ostream& operator<<(std::ostream& os,const std::vector<U>& c){
-  typedef std::vector<U> V;
-  os<<"[";
-  if(c.size()>0){
-      for(typename V::const_iterator it=c.begin();it!=c.end();++it)
-          os<<*it<<",";
-      os.seekp(-1,std::ios::cur);
-  }
-  os<<"]";
-  return os;
-}
-
-#endif // _VECTOR_UTIL_H

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/ZKMocks.cc
----------------------------------------------------------------------
diff --git a/src/c/tests/ZKMocks.cc b/src/c/tests/ZKMocks.cc
deleted file mode 100644
index 69bea16..0000000
--- a/src/c/tests/ZKMocks.cc
+++ /dev/null
@@ -1,519 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <arpa/inet.h>  // for htonl
-#include <memory>
-
-#include <zookeeper.h>
-#include <proto.h>
-
-#ifdef THREADED
-#include "PthreadMocks.h"
-#endif
-#include "ZKMocks.h"
-
-using namespace std;
-
-TestClientId testClientId;
-const char* TestClientId::PASSWD="1234567890123456";
-
-HandshakeRequest* HandshakeRequest::parse(const std::string& buf){
-    auto_ptr<HandshakeRequest> req(new HandshakeRequest);
-
-    memcpy(&req->protocolVersion,buf.data(), sizeof(req->protocolVersion));
-    req->protocolVersion = htonl(req->protocolVersion);
-    
-    int offset=sizeof(req->protocolVersion);
-    
-    memcpy(&req->lastZxidSeen,buf.data()+offset,sizeof(req->lastZxidSeen));
-    req->lastZxidSeen = zoo_htonll(req->lastZxidSeen);
-    offset+=sizeof(req->lastZxidSeen);
-    
-    memcpy(&req->timeOut,buf.data()+offset,sizeof(req->timeOut));
-    req->timeOut = htonl(req->timeOut);
-    offset+=sizeof(req->timeOut);
-    
-    memcpy(&req->sessionId,buf.data()+offset,sizeof(req->sessionId));
-    req->sessionId = zoo_htonll(req->sessionId);
-    offset+=sizeof(req->sessionId);
-    
-    memcpy(&req->passwd_len,buf.data()+offset,sizeof(req->passwd_len));
-    req->passwd_len = htonl(req->passwd_len);
-    offset+=sizeof(req->passwd_len);
-    
-    memcpy(req->passwd,buf.data()+offset,sizeof(req->passwd));
-    if(testClientId.client_id==req->sessionId &&
-            !memcmp(testClientId.passwd,req->passwd,sizeof(req->passwd)))
-        return req.release();
-    // the request didn't match -- may not be a handshake request after all
-    return 0;
-}
-
-// *****************************************************************************
-// watcher action implementation
-void activeWatcher(zhandle_t *zh, int type, int state, const char *path,void* ctx){
-    if(zh==0 || ctx==0) return;
-    WatcherAction* action=(WatcherAction*)ctx;
-    
-    if(type==ZOO_SESSION_EVENT){
-        if(state==ZOO_EXPIRED_SESSION_STATE)
-            action->onSessionExpired(zh);
-        else if(state==ZOO_CONNECTING_STATE)
-            action->onConnectionLost(zh);
-        else if(state==ZOO_CONNECTED_STATE)
-            action->onConnectionEstablished(zh);
-    }else if(type==ZOO_CHANGED_EVENT)
-        action->onNodeValueChanged(zh,path);
-    else if(type==ZOO_DELETED_EVENT)
-        action->onNodeDeleted(zh,path);
-    else if(type==ZOO_CHILD_EVENT)
-        action->onChildChanged(zh,path);
-    // TODO: implement for the rest of the event types
-    // ...
-    action->setWatcherTriggered();    
-}
-SyncedBoolCondition WatcherAction::isWatcherTriggered() const{
-    return SyncedBoolCondition(triggered_,mx_);
-}
-
-// *****************************************************************************
-// a set of async completion signatures
-void asyncCompletion(int rc, ACL_vector *acl,Stat *stat, const void *data){
-    assert("Completion data is NULL"&&data);
-    static_cast<AsyncCompletion*>((void*)data)->aclCompl(rc,acl,stat);
-}
-void asyncCompletion(int rc, const char *value, int len, const Stat *stat, 
-        const void *data){    
-    assert("Completion data is NULL"&&data);
-    static_cast<AsyncCompletion*>((void*)data)->dataCompl(rc,value,len,stat);    
-}
-void asyncCompletion(int rc, const Stat *stat, const void *data){    
-    assert("Completion data is NULL"&&data);
-    static_cast<AsyncCompletion*>((void*)data)->statCompl(rc,stat);
-}
-void asyncCompletion(int rc, const char *value, const void *data){
-    assert("Completion data is NULL"&&data);
-    static_cast<AsyncCompletion*>((void*)data)->stringCompl(rc,value);
-}
-void asyncCompletion(int rc,const String_vector *strings, const void *data){    
-    assert("Completion data is NULL"&&data);
-    static_cast<AsyncCompletion*>((void*)data)->stringsCompl(rc,strings);
-}
-void asyncCompletion(int rc, const void *data){    
-    assert("Completion data is NULL"&&data);
-    static_cast<AsyncCompletion*>((void*)data)->voidCompl(rc);
-}
-
-// *****************************************************************************
-// a predicate implementation
-bool IOThreadStopped::operator()() const{
-#ifdef THREADED
-    adaptor_threads* adaptor=(adaptor_threads*)zh_->adaptor_priv;
-    return CheckedPthread::isTerminated(adaptor->io);
-#else
-    assert("IOThreadStopped predicate is only for use with THREADED client"&& false);
-    return false;
-#endif
-}
-
-//******************************************************************************
-//
-DECLARE_WRAPPER(int,flush_send_queue,(zhandle_t*zh, int timeout))
-{
-    if(!Mock_flush_send_queue::mock_)
-        return CALL_REAL(flush_send_queue,(zh,timeout));
-    return Mock_flush_send_queue::mock_->call(zh,timeout);
-}
-
-Mock_flush_send_queue* Mock_flush_send_queue::mock_=0;
-
-//******************************************************************************
-//
-DECLARE_WRAPPER(int32_t,get_xid,())
-{
-    if(!Mock_get_xid::mock_)
-        return CALL_REAL(get_xid,());
-    return Mock_get_xid::mock_->call();
-}
-
-Mock_get_xid* Mock_get_xid::mock_=0;
-
-//******************************************************************************
-// activateWatcher mock
-
-DECLARE_WRAPPER(void,activateWatcher,(zhandle_t *zh, watcher_registration_t* reg, int rc))
-{
-    if(!Mock_activateWatcher::mock_){
-        CALL_REAL(activateWatcher,(zh, reg,rc));
-    }else{
-        Mock_activateWatcher::mock_->call(zh, reg,rc);
-    }
-}
-Mock_activateWatcher* Mock_activateWatcher::mock_=0;
-
-class ActivateWatcherWrapper: public Mock_activateWatcher{
-public:
-    ActivateWatcherWrapper():ctx_(0),activated_(false){}
-    
-    virtual void call(zhandle_t *zh, watcher_registration_t* reg, int rc){
-        CALL_REAL(activateWatcher,(zh, reg,rc));
-        synchronized(mx_);
-        if(reg->context==ctx_){
-            activated_=true;
-            ctx_=0;
-        }
-    }
-    
-    void setContext(void* ctx){
-        synchronized(mx_);
-        ctx_=ctx;
-        activated_=false;
-    }
-    
-    SyncedBoolCondition isActivated() const{
-        return SyncedBoolCondition(activated_,mx_);
-    }
-    mutable Mutex mx_;
-    void* ctx_;
-    bool activated_;
-};
-
-WatcherActivationTracker::WatcherActivationTracker():
-    wrapper_(new ActivateWatcherWrapper)
-{    
-}
-
-WatcherActivationTracker::~WatcherActivationTracker(){
-    delete wrapper_;
-}
-
-void WatcherActivationTracker::track(void* ctx){
-    wrapper_->setContext(ctx);
-}
-
-SyncedBoolCondition WatcherActivationTracker::isWatcherActivated() const{
-    return wrapper_->isActivated();
-}
-
-//******************************************************************************
-//
-DECLARE_WRAPPER(void,deliverWatchers,(zhandle_t* zh,int type,int state, const char* path, watcher_object_list_t **list))
-{
-    if(!Mock_deliverWatchers::mock_){
-        CALL_REAL(deliverWatchers,(zh,type,state,path, list));
-    }else{
-        Mock_deliverWatchers::mock_->call(zh,type,state,path, list);
-    }
-}
-
-Mock_deliverWatchers* Mock_deliverWatchers::mock_=0;
-
-struct RefCounterValue{
-    RefCounterValue(zhandle_t* const& zh,int32_t expectedCounter,Mutex& mx):
-        zh_(zh),expectedCounter_(expectedCounter),mx_(mx){}
-    bool operator()() const{
-        {
-            synchronized(mx_);
-            if(zh_==0)
-                return false;
-        }
-        return inc_ref_counter(zh_,0)==expectedCounter_;
-    }
-    zhandle_t* const& zh_;
-    int32_t expectedCounter_;
-    Mutex& mx_;
-};
-
-
-class DeliverWatchersWrapper: public Mock_deliverWatchers{
-public:
-    DeliverWatchersWrapper(int type,int state,bool terminate):
-        type_(type),state_(state),
-        allDelivered_(false),terminate_(terminate),zh_(0),deliveryCounter_(0){}
-    virtual void call(zhandle_t* zh,int type,int state, const char* path, watcher_object_list **list){
-        {
-            synchronized(mx_);
-            zh_=zh;
-            allDelivered_=false;
-        }
-        CALL_REAL(deliverWatchers,(zh,type,state,path, list));
-        if(type_==type && state_==state){
-            if(terminate_){
-                // prevent zhandle_t from being prematurely distroyed;
-                // this will also ensure that zookeeper_close() cleanups the thread
-                // resources by calling finish_adaptor()
-                inc_ref_counter(zh,1);
-                terminateZookeeperThreads(zh);
-            }
-            synchronized(mx_);
-            allDelivered_=true;
-            deliveryCounter_++;
-        }
-    }
-    SyncedBoolCondition isDelivered() const{
-        if(terminate_){
-            int i=ensureCondition(RefCounterValue(zh_,1,mx_),1000);
-            assert(i<1000);
-        }
-        return SyncedBoolCondition(allDelivered_,mx_);
-    }
-    void resetDeliveryCounter(){
-        synchronized(mx_);
-        deliveryCounter_=0;
-    }
-    SyncedIntegerEqual deliveryCounterEquals(int expected) const{
-        if(terminate_){
-            int i=ensureCondition(RefCounterValue(zh_,1,mx_),1000);
-            assert(i<1000);
-        }
-        return SyncedIntegerEqual(deliveryCounter_,expected,mx_);
-    }
-    int type_;
-    int state_;
-    mutable Mutex mx_;
-    bool allDelivered_;
-    bool terminate_;
-    zhandle_t* zh_;
-    int deliveryCounter_;
-};
-
-WatcherDeliveryTracker::WatcherDeliveryTracker(
-        int type,int state,bool terminateCompletionThread):
-    deliveryWrapper_(new DeliverWatchersWrapper(
-            type,state,terminateCompletionThread)){
-}
-
-WatcherDeliveryTracker::~WatcherDeliveryTracker(){
-    delete deliveryWrapper_;
-}
-
-SyncedBoolCondition WatcherDeliveryTracker::isWatcherProcessingCompleted() const{
-    return deliveryWrapper_->isDelivered();
-}
-
-void WatcherDeliveryTracker::resetDeliveryCounter(){
-    deliveryWrapper_->resetDeliveryCounter();
-}
-
-SyncedIntegerEqual WatcherDeliveryTracker::deliveryCounterEquals(int expected) const{
-    return deliveryWrapper_->deliveryCounterEquals(expected);
-}
-
-//******************************************************************************
-//
-string HandshakeResponse::toString() const {
-    string buf;
-    int32_t tmp=htonl(protocolVersion);
-    buf.append((char*)&tmp,sizeof(tmp));
-    tmp=htonl(timeOut);
-    buf.append((char*)&tmp,sizeof(tmp));
-    int64_t tmp64=zoo_htonll(sessionId);
-    buf.append((char*)&tmp64,sizeof(sessionId));
-    tmp=htonl(passwd_len);
-    buf.append((char*)&tmp,sizeof(tmp));
-    buf.append(passwd,sizeof(passwd));
-    // finally set the buffer length
-    tmp=htonl(buf.size()+sizeof(tmp));
-    buf.insert(0,(char*)&tmp, sizeof(tmp));
-    return buf;
-}
-
-string ZooGetResponse::toString() const{
-    oarchive* oa=create_buffer_oarchive();
-    
-    ReplyHeader h = {xid_,1,ZOK};
-    serialize_ReplyHeader(oa, "hdr", &h);
-    
-    GetDataResponse resp;
-	char buf[1024];
-    assert("GetDataResponse is too long"&&data_.size()<=sizeof(buf));
-    resp.data.len=data_.size();
-    resp.data.buff=buf;
-    data_.copy(resp.data.buff, data_.size());
-    resp.stat=stat_;
-    serialize_GetDataResponse(oa, "reply", &resp);
-    int32_t len=htonl(get_buffer_len(oa));
-    string res((char*)&len,sizeof(len));
-    res.append(get_buffer(oa),get_buffer_len(oa));
-    
-    close_buffer_oarchive(&oa,1);
-    return res;
-}
-
-string ZooStatResponse::toString() const{
-    oarchive* oa=create_buffer_oarchive();
-    
-    ReplyHeader h = {xid_,1,rc_};
-    serialize_ReplyHeader(oa, "hdr", &h);
-    
-    SetDataResponse resp;
-    resp.stat=stat_;
-    serialize_SetDataResponse(oa, "reply", &resp);
-    int32_t len=htonl(get_buffer_len(oa));
-    string res((char*)&len,sizeof(len));
-    res.append(get_buffer(oa),get_buffer_len(oa));
-    
-    close_buffer_oarchive(&oa,1);
-    return res;
-}
-
-string ZooGetChildrenResponse::toString() const{
-    oarchive* oa=create_buffer_oarchive();
-    
-    ReplyHeader h = {xid_,1,rc_};
-    serialize_ReplyHeader(oa, "hdr", &h);
- 
-    GetChildrenResponse resp;
-    // populate the string vector
-    allocate_String_vector(&resp.children,strings_.size());
-    for(int i=0;i<(int)strings_.size();++i)
-        resp.children.data[i]=strdup(strings_[i].c_str());
-    serialize_GetChildrenResponse(oa, "reply", &resp);
-    deallocate_GetChildrenResponse(&resp);
-    
-    int32_t len=htonl(get_buffer_len(oa));
-    string res((char*)&len,sizeof(len));
-    res.append(get_buffer(oa),get_buffer_len(oa));
-    
-    close_buffer_oarchive(&oa,1);
-    return res;
-}
-
-string ZNodeEvent::toString() const{
-    oarchive* oa=create_buffer_oarchive();
-    struct WatcherEvent evt = {type_,0,(char*)path_.c_str()};
-    struct ReplyHeader h = {WATCHER_EVENT_XID,0,ZOK };
-    
-    serialize_ReplyHeader(oa, "hdr", &h);
-    serialize_WatcherEvent(oa, "event", &evt);
-    
-    int32_t len=htonl(get_buffer_len(oa));
-    string res((char*)&len,sizeof(len));
-    res.append(get_buffer(oa),get_buffer_len(oa));
-    
-    close_buffer_oarchive(&oa,1);
-    return res;
-}
-
-string PingResponse::toString() const{
-    oarchive* oa=create_buffer_oarchive();
-    
-    ReplyHeader h = {PING_XID,1,ZOK};
-    serialize_ReplyHeader(oa, "hdr", &h);
-    
-    int32_t len=htonl(get_buffer_len(oa));
-    string res((char*)&len,sizeof(len));
-    res.append(get_buffer(oa),get_buffer_len(oa));
-    
-    close_buffer_oarchive(&oa,1);
-    return res;
-}
-
-//******************************************************************************
-// Zookeeper server simulator
-// 
-bool ZookeeperServer::hasMoreRecv() const{
-  return recvHasMore.get()!=0  || connectionLost;
-}
-
-ssize_t ZookeeperServer::callRecv(int s,void *buf,size_t len,int flags){
-    if(connectionLost){
-        recvReturnBuffer.erase();
-        return 0;
-    }
-    // done transmitting the current buffer?
-    if(recvReturnBuffer.size()==0){
-        synchronized(recvQMx);
-        if(recvQueue.empty()){
-            recvErrno=EAGAIN;
-            return Mock_socket::callRecv(s,buf,len,flags);
-        }
-        --recvHasMore;
-        Element& el=recvQueue.front();
-        if(el.first!=0){
-            recvReturnBuffer=el.first->toString();
-            delete el.first;
-        }
-        recvErrno=el.second;
-        recvQueue.pop_front();
-    }
-    return Mock_socket::callRecv(s,buf,len,flags);
-}
-
-void ZookeeperServer::onMessageReceived(const RequestHeader& rh, iarchive* ia){
-    // no-op by default
-}
-
-void ZookeeperServer::notifyBufferSent(const std::string& buffer){
-    if(HandshakeRequest::isValid(buffer)){
-        // could be a connect request
-        auto_ptr<HandshakeRequest> req(HandshakeRequest::parse(buffer));
-        if(req.get()!=0){
-            // handle the handshake
-            int64_t sessId=sessionExpired?req->sessionId+1:req->sessionId;
-            sessionExpired=false;
-            addRecvResponse(new HandshakeResponse(sessId));            
-            return;
-        }
-        // not a connect request -- fall thru
-    }
-    // parse the buffer to extract the request type and its xid
-    iarchive *ia=create_buffer_iarchive((char*)buffer.data(), buffer.size());
-    RequestHeader rh;
-    deserialize_RequestHeader(ia,"hdr",&rh);
-    // notify the "server" a client request has arrived
-    if (rh.xid == -8) {
-        Element e = Element(new ZooStatResponse,0);
-        e.first->setXID(-8);
-        addRecvResponse(e);
-        close_buffer_iarchive(&ia);
-        return;
-    } else {
-        onMessageReceived(rh,ia);
-    }
-    close_buffer_iarchive(&ia);
-    if(rh.type==ZOO_CLOSE_OP){
-        ++closeSent;
-        return; // no reply for close requests
-    }
-    // get the next response from the response queue and append it to the receive list
-    Element e;
-    {
-        synchronized(respQMx);
-        if(respQueue.empty())
-            return;
-        e=respQueue.front();
-        respQueue.pop_front();
-    }
-    e.first->setXID(rh.xid);
-    addRecvResponse(e);
-}
-
-void forceConnected(zhandle_t* zh){
-    // simulate connected state
-    zh->state=ZOO_CONNECTED_STATE;
-    zh->fd=ZookeeperServer::FD;
-    zh->input_buffer=0;
-    gettimeofday(&zh->last_recv,0);    
-    gettimeofday(&zh->last_send,0);    
-}
-
-void terminateZookeeperThreads(zhandle_t* zh){
-    // this will cause the zookeeper threads to terminate
-    zh->close_requested=1;
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/ZKMocks.h
----------------------------------------------------------------------
diff --git a/src/c/tests/ZKMocks.h b/src/c/tests/ZKMocks.h
deleted file mode 100644
index fbcfc4f..0000000
--- a/src/c/tests/ZKMocks.h
+++ /dev/null
@@ -1,509 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ZKMOCKS_H_
-#define ZKMOCKS_H_
-
-#include <zookeeper.h>
-#include "src/zk_adaptor.h"
-
-#include "Util.h"
-#include "LibCMocks.h"
-#include "MocksBase.h"
-
-// *****************************************************************************
-// sets internal zhandle_t members to certain values to simulate the client 
-// connected state. This function should only be used with the single-threaded
-// Async API tests!
-void forceConnected(zhandle_t* zh); 
-
-/**
- * Gracefully terminates zookeeper I/O and completion threads. 
- */
-void terminateZookeeperThreads(zhandle_t* zh);
-
-// *****************************************************************************
-// Abstract watcher action
-struct SyncedBoolCondition;
-
-class WatcherAction{
-public:
-    WatcherAction():triggered_(false){}
-    virtual ~WatcherAction(){}
-    
-    virtual void onSessionExpired(zhandle_t*){}
-    virtual void onConnectionEstablished(zhandle_t*){}
-    virtual void onConnectionLost(zhandle_t*){}
-    virtual void onNodeValueChanged(zhandle_t*,const char* path){}
-    virtual void onNodeDeleted(zhandle_t*,const char* path){}
-    virtual void onChildChanged(zhandle_t*,const char* path){}
-    
-    SyncedBoolCondition isWatcherTriggered() const;
-    void setWatcherTriggered(){
-        synchronized(mx_);
-        triggered_=true;
-    }
-
-protected:
-    mutable Mutex mx_;
-    bool triggered_;
-};
-// zh->context is a pointer to a WatcherAction instance
-// based on the event type and state, the watcher calls a specific watcher 
-// action method
-void activeWatcher(zhandle_t *zh, int type, int state, const char *path,void* ctx);
-
-// *****************************************************************************
-// a set of async completion signatures
-class AsyncCompletion{
-public:
-    virtual ~AsyncCompletion(){}
-    virtual void aclCompl(int rc, ACL_vector *acl,Stat *stat){}
-    virtual void dataCompl(int rc, const char *value, int len, const Stat *stat){}
-    virtual void statCompl(int rc, const Stat *stat){}
-    virtual void stringCompl(int rc, const char *value){}
-    virtual void stringsCompl(int rc,const String_vector *strings){}
-    virtual void voidCompl(int rc){}
-};
-void asyncCompletion(int rc, ACL_vector *acl,Stat *stat, const void *data);
-void asyncCompletion(int rc, const char *value, int len, const Stat *stat, 
-        const void *data);
-void asyncCompletion(int rc, const Stat *stat, const void *data);
-void asyncCompletion(int rc, const char *value, const void *data);
-void asyncCompletion(int rc,const String_vector *strings, const void *data);
-void asyncCompletion(int rc, const void *data);
-
-// *****************************************************************************
-// some common predicates to use with ensureCondition():
-// checks if the connection is established
-struct ClientConnected{
-    ClientConnected(zhandle_t* zh):zh_(zh){}
-    bool operator()() const{
-        return zoo_state(zh_)==ZOO_CONNECTED_STATE;
-    }
-    zhandle_t* zh_;
-};
-// check in the session expired
-struct SessionExpired{
-    SessionExpired(zhandle_t* zh):zh_(zh){}
-    bool operator()() const{
-        return zoo_state(zh_)==ZOO_EXPIRED_SESSION_STATE;
-    }
-    zhandle_t* zh_;
-};
-// checks if the IO thread has stopped; CheckedPthread must be active
-struct IOThreadStopped{
-    IOThreadStopped(zhandle_t* zh):zh_(zh){}
-    bool operator()() const;
-    zhandle_t* zh_;
-};
-
-// a synchronized boolean condition
-struct SyncedBoolCondition{
-    SyncedBoolCondition(const bool& cond,Mutex& mx):cond_(cond),mx_(mx){}
-    bool operator()() const{
-        synchronized(mx_);
-        return cond_;
-    }
-    const bool& cond_;
-    Mutex& mx_;
-};
-
-// a synchronized integer comparison
-struct SyncedIntegerEqual{
-    SyncedIntegerEqual(const int& cond,int expected,Mutex& mx):
-        cond_(cond),expected_(expected),mx_(mx){}
-    bool operator()() const{
-        synchronized(mx_);
-        return cond_==expected_;
-    }
-    const int& cond_;
-    const int expected_;
-    Mutex& mx_;
-};
-
-// *****************************************************************************
-// make sure to call zookeeper_close() even in presence of exceptions 
-struct CloseFinally{
-    CloseFinally(zhandle_t** zh):zh_(zh){}
-    ~CloseFinally(){
-        execute();
-    }
-    int execute(){
-        if(zh_==0)return ZOK;
-        zhandle_t* lzh=*zh_;
-        *zh_=0;
-        disarm();
-        return zookeeper_close(lzh);
-    }
-    void disarm(){zh_=0;}
-    zhandle_t ** zh_;
-};
-
-struct TestClientId: clientid_t{
-    static const int SESSION_ID=123456789;
-    static const char* PASSWD;
-    TestClientId(){
-        client_id=SESSION_ID;
-        memcpy(passwd,PASSWD,sizeof(passwd));
-    }
-};
-
-// *****************************************************************************
-// special client id recongnized by the ZK server simulator 
-extern TestClientId testClientId;
-#define TEST_CLIENT_ID &testClientId
-
-// *****************************************************************************
-//
-struct HandshakeRequest: public connect_req
-{
-    static HandshakeRequest* parse(const std::string& buf);
-    static bool isValid(const std::string& buf){
-        // this is just quick and dirty check before we go and parse the request
-        return buf.size()==HANDSHAKE_REQ_SIZE;
-    }
-};
-
-// *****************************************************************************
-// flush_send_queue
-class Mock_flush_send_queue: public Mock
-{
-public:
-    Mock_flush_send_queue():counter(0),callReturns(ZOK){mock_=this;}
-    ~Mock_flush_send_queue(){mock_=0;}
-    
-    int counter;
-    int callReturns;
-    virtual int call(zhandle_t* zh, int timeout){
-        counter++;
-        return callReturns;
-    }
-
-    static Mock_flush_send_queue* mock_;
-};
-
-// *****************************************************************************
-// get_xid
-class Mock_get_xid: public Mock
-{
-public:
-    static const int32_t XID=123456;
-    Mock_get_xid(int retValue=XID):callReturns(retValue){mock_=this;}
-    ~Mock_get_xid(){mock_=0;}
-    
-    int callReturns;
-    virtual int call(){
-        return callReturns;
-    }
-
-    static Mock_get_xid* mock_;
-};
-
-// *****************************************************************************
-// activateWatcher
-class Mock_activateWatcher: public Mock{
-public:
-    Mock_activateWatcher(){mock_=this;}
-    virtual ~Mock_activateWatcher(){mock_=0;}
-    
-    virtual void call(zhandle_t *zh, watcher_registration_t* reg, int rc){}
-    static Mock_activateWatcher* mock_;
-};
-
-class ActivateWatcherWrapper;
-class WatcherActivationTracker{
-public:
-    WatcherActivationTracker();
-    ~WatcherActivationTracker();
-    
-    void track(void* ctx);
-    SyncedBoolCondition isWatcherActivated() const;
-private:
-    ActivateWatcherWrapper* wrapper_;
-};
-
-// *****************************************************************************
-// deliverWatchers
-class Mock_deliverWatchers: public Mock{
-public:
-    Mock_deliverWatchers(){mock_=this;}
-    virtual ~Mock_deliverWatchers(){mock_=0;}
-    
-    virtual void call(zhandle_t* zh,int type,int state, const char* path, watcher_object_list **){}
-    static Mock_deliverWatchers* mock_;
-};
-
-class DeliverWatchersWrapper;
-class WatcherDeliveryTracker{
-public:
-    // filters deliveries by state and type
-    WatcherDeliveryTracker(int type,int state,bool terminateCompletionThread=true);
-    ~WatcherDeliveryTracker();
-    
-    // if the thread termination requested (see the ctor params)
-    // this function will wait for the I/O and completion threads to 
-    // terminate before returning a SyncBoolCondition instance
-    SyncedBoolCondition isWatcherProcessingCompleted() const;
-    void resetDeliveryCounter();
-    SyncedIntegerEqual deliveryCounterEquals(int expected) const;
-private:
-    DeliverWatchersWrapper* deliveryWrapper_;
-};
-
-// *****************************************************************************
-// a zookeeper Stat wrapper
-struct NodeStat: public Stat
-{
-    NodeStat(){
-        czxid=0;
-        mzxid=0;
-        ctime=0;
-        mtime=0;
-        version=1;
-        cversion=0;
-        aversion=0;
-        ephemeralOwner=0;
-    }
-    NodeStat(const Stat& other){
-        memcpy(this,&other,sizeof(*this));
-    }
-};
-
-// *****************************************************************************
-// Abstract server Response
-class Response
-{
-public:
-    virtual ~Response(){}
-    
-    virtual void setXID(int32_t xid){}
-    // this method is used by the ZookeeperServer class to serialize 
-    // the instance of Response
-    virtual std::string toString() const =0;
-};
-
-// *****************************************************************************
-// Handshake response
-class HandshakeResponse: public Response
-{
-public:
-    HandshakeResponse(int64_t sessId=1)
-        :protocolVersion(1),timeOut(10000),sessionId(sessId),passwd_len(sizeof(passwd))
-    {
-        memcpy(passwd,"1234567890123456",sizeof(passwd));
-    }
-    int32_t protocolVersion;
-    int32_t timeOut;
-    int64_t sessionId;
-    int32_t passwd_len;
-    char passwd[16];
-    virtual std::string toString() const ;
-};
-
-// zoo_get() response
-class ZooGetResponse: public Response
-{
-public:
-    ZooGetResponse(const char* data, int len,int32_t xid=0,int rc=ZOK,const Stat& stat=NodeStat())
-        :xid_(xid),data_(data,len),rc_(rc),stat_(stat)
-    {
-    }
-    virtual std::string toString() const;
-    virtual void setXID(int32_t xid) {xid_=xid;}
-    
-private:
-    int32_t xid_;
-    std::string data_;
-    int rc_;
-    Stat stat_;
-};
-
-// zoo_exists(), zoo_set() response
-class ZooStatResponse: public Response
-{
-public:
-    ZooStatResponse(int32_t xid=0,int rc=ZOK,const Stat& stat=NodeStat())
-        :xid_(xid),rc_(rc),stat_(stat)
-    {
-    }
-    virtual std::string toString() const;
-    virtual void setXID(int32_t xid) {xid_=xid;}
-    
-private:
-    int32_t xid_;
-    int rc_;
-    Stat stat_;
-};
-
-// zoo_get_children()
-class ZooGetChildrenResponse: public Response
-{
-public:
-    typedef std::vector<std::string> StringVector;
-    ZooGetChildrenResponse(const StringVector& v,int rc=ZOK):
-        xid_(0),strings_(v),rc_(rc)
-    {
-    }
-    
-    virtual std::string toString() const;
-    virtual void setXID(int32_t xid) {xid_=xid;}
-
-    int32_t xid_;
-    StringVector strings_;
-    int rc_;
-};
-
-// PING response
-class PingResponse: public Response
-{
-public:
-    virtual std::string toString() const;    
-};
-
-// watcher znode event
-class ZNodeEvent: public Response
-{
-public:
-    ZNodeEvent(int type,const char* path):type_(type),path_(path){}
-    
-    virtual std::string toString() const;
-    
-private:
-    int type_;
-    std::string path_;
-};
-
-// ****************************************************************************
-// Zookeeper server simulator
-
-class ZookeeperServer: public Mock_socket
-{
-public:
-    ZookeeperServer():
-        serverDownSkipCount_(-1),sessionExpired(false),connectionLost(false)
-    {
-        connectReturns=-1;
-        connectErrno=EWOULDBLOCK;        
-    }
-    virtual ~ZookeeperServer(){
-        clearRecvQueue();
-        clearRespQueue();
-    }
-    virtual int callClose(int fd){
-        if(fd!=FD)
-            return LIBC_SYMBOLS.close(fd);
-        clearRecvQueue();
-        clearRespQueue();
-        return Mock_socket::callClose(fd);
-    }
-    // connection handling
-    // what to do when the handshake request comes in?
-    int serverDownSkipCount_;
-    // this will cause getsockopt(zh->fd,SOL_SOCKET,SO_ERROR,&error,&len) return 
-    // a failure after skipCount dropped to zero, thus simulating a server down 
-    // condition
-    // passing skipCount==-1 will make every connect attempt succeed
-    void setServerDown(int skipCount=0){ 
-        serverDownSkipCount_=skipCount;
-        optvalSO_ERROR=0;            
-    }
-    virtual void setSO_ERROR(void *optval,socklen_t len){
-        if(serverDownSkipCount_!=-1){
-            if(serverDownSkipCount_==0)
-                optvalSO_ERROR=ECONNREFUSED;
-            else
-                serverDownSkipCount_--;
-        }
-        Mock_socket::setSO_ERROR(optval,len);
-    }
-
-    // this is a trigger that gets reset back to false
-    // a connect request will return a non-matching session id thus causing 
-    // the client throw SESSION_EXPIRED
-    volatile bool sessionExpired;
-    void returnSessionExpired(){ sessionExpired=true; }
-    
-    // this is a one shot trigger that gets reset back to false
-    // next recv call will return 0 length, thus simulating a connecton loss
-    volatile bool connectionLost;
-    void setConnectionLost() {connectionLost=true;}
-    
-    // recv
-    // this queue is used for server responses: client's recv() system call 
-    // returns next available message from this queue
-    typedef std::pair<Response*,int> Element;
-    typedef std::deque<Element> ResponseList;
-    ResponseList recvQueue;
-    mutable Mutex recvQMx;
-    AtomicInt recvHasMore;
-    ZookeeperServer& addRecvResponse(Response* resp, int errnum=0){
-        synchronized(recvQMx);
-        recvQueue.push_back(Element(resp,errnum));
-        ++recvHasMore;
-        return *this;
-    }
-    ZookeeperServer& addRecvResponse(int errnum){
-        synchronized(recvQMx);
-        recvQueue.push_back(Element(0,errnum));
-        ++recvHasMore;
-        return *this;
-    }
-    ZookeeperServer& addRecvResponse(const Element& e){
-        synchronized(recvQMx);
-        recvQueue.push_back(e);
-        ++recvHasMore;
-        return *this;
-    }
-    void clearRecvQueue(){
-        synchronized(recvQMx);
-        recvHasMore=0;
-        for(unsigned i=0; i<recvQueue.size();i++)
-            delete recvQueue[i].first;
-        recvQueue.clear();
-    }
-
-    virtual ssize_t callRecv(int s,void *buf,size_t len,int flags);
-    virtual bool hasMoreRecv() const;
-    
-    // the operation response queue holds zookeeper operation responses till the
-    // operation request has been sent to the server. After that, the operation
-    // response gets moved on to the recv queue (see above) ready to be read by 
-    // the next recv() system call
-    // send operation doesn't try to match request to the response
-    ResponseList respQueue;
-    mutable Mutex respQMx;
-    ZookeeperServer& addOperationResponse(Response* resp, int errnum=0){
-        synchronized(respQMx);
-        respQueue.push_back(Element(resp,errnum));
-        return *this;
-    }
-    void clearRespQueue(){
-        synchronized(respQMx);
-        for(unsigned i=0; i<respQueue.size();i++)
-            delete respQueue[i].first;
-        respQueue.clear();
-    }
-    AtomicInt closeSent;
-    virtual void notifyBufferSent(const std::string& buffer);
-    // simulates an arrival of a client request
-    // a callback to be implemented by subclasses (no-op by default)
-    virtual void onMessageReceived(const RequestHeader& rh, iarchive* ia);
-};
-
-#endif /*ZKMOCKS_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/wrappers-mt.opt
----------------------------------------------------------------------
diff --git a/src/c/tests/wrappers-mt.opt b/src/c/tests/wrappers-mt.opt
deleted file mode 100644
index 01046fb..0000000
--- a/src/c/tests/wrappers-mt.opt
+++ /dev/null
@@ -1,3 +0,0 @@
--Wl,--wrap -Wl,pthread_mutex_lock
--Wl,--wrap -Wl,pthread_mutex_trylock
--Wl,--wrap -Wl,pthread_mutex_unlock

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/wrappers.opt
----------------------------------------------------------------------
diff --git a/src/c/tests/wrappers.opt b/src/c/tests/wrappers.opt
deleted file mode 100644
index bce192f..0000000
--- a/src/c/tests/wrappers.opt
+++ /dev/null
@@ -1,7 +0,0 @@
--Wl,--wrap -Wl,calloc
--Wl,--wrap -Wl,free
--Wl,--wrap -Wl,flush_send_queue
--Wl,--wrap -Wl,get_xid
--Wl,--wrap -Wl,deliverWatchers
--Wl,--wrap -Wl,activateWatcher
--Wl,--wrap -Wl,realloc

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/zkServer.sh
----------------------------------------------------------------------
diff --git a/src/c/tests/zkServer.sh b/src/c/tests/zkServer.sh
deleted file mode 100755
index 4872fba..0000000
--- a/src/c/tests/zkServer.sh
+++ /dev/null
@@ -1,161 +0,0 @@
-#!/bin/bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# This is the port where zookeeper server runs on.
-ZOOPORT=22181
-
-if [ "x$1" == "x" ]
-then
-    echo "USAGE: $0 startClean|start|stop hostPorts"
-    exit 2
-fi
-
-case "`uname`" in
-    CYGWIN*) cygwin=true ;;
-    *) cygwin=false ;;
-esac
-
-if [ "x$1" == "xstartClean" ]
-then
-    if [ "x${base_dir}" == "x" ]
-    then
-    rm -rf /tmp/zkdata
-    else
-    rm -rf "${base_dir}/build/tmp"
-    fi
-fi
-
-if $cygwin
-then
-    # cygwin has a "kill" in the shell itself, gets confused
-    KILL=/bin/kill
-else
-    KILL=kill
-fi
-
-# Make sure nothing is left over from before
-if [ -r "/tmp/zk.pid" ]
-then
-pid=`cat /tmp/zk.pid`
-$KILL -9 $pid
-rm -f /tmp/zk.pid
-fi
-
-if [ -r "${base_dir}/build/tmp/zk.pid" ]
-then
-pid=`cat "${base_dir}/build/tmp/zk.pid"`
-$KILL -9 $pid
-rm -f "${base_dir}/build/tmp/zk.pid"
-fi
-
-# [ZOOKEEPER-820] If lsof command is present, look for a process listening
-# on ZOOPORT and kill it. 
-which lsof &> /dev/null
-if [ $? -eq 0  ]
-then
-    pid=`lsof -i :$ZOOPORT | grep LISTEN | awk '{print $2}'`
-    if [ -n "$pid" ]
-    then
-        $KILL -9 $pid
-    fi
-fi
-
-if [ "x${base_dir}" == "x" ]
-then
-zk_base="../../"
-else
-zk_base="${base_dir}"
-fi
-
-CLASSPATH="$CLASSPATH:${zk_base}/build/classes"
-CLASSPATH="$CLASSPATH:${zk_base}/conf"
-
-for i in "${zk_base}"/build/lib/*.jar
-do
-    CLASSPATH="$CLASSPATH:$i"
-done
-
-for i in "${zk_base}"/src/java/lib/*.jar
-do
-    CLASSPATH="$CLASSPATH:$i"
-done
-
-CLASSPATH="$CLASSPATH:${CLOVER_HOME}/lib/clover.jar"
-
-if $cygwin
-then
-    CLASSPATH=`cygpath -wp "$CLASSPATH"`
-fi
-
-case $1 in
-start|startClean)
-    if [ "x${base_dir}" == "x" ]
-    then
-        mkdir -p /tmp/zkdata
-        java -cp "$CLASSPATH" org.apache.zookeeper.server.ZooKeeperServerMain $ZOOPORT /tmp/zkdata 3000 $ZKMAXCNXNS &> /tmp/zk.log &
-        pid=$!
-        echo -n $! > /tmp/zk.pid
-    else
-        mkdir -p "${base_dir}/build/tmp/zkdata"
-        java -cp "$CLASSPATH" org.apache.zookeeper.server.ZooKeeperServerMain $ZOOPORT "${base_dir}/build/tmp/zkdata" 3000 $ZKMAXCNXNS &> "${base_dir}/build/tmp/zk.log" &
-        pid=$!
-        echo -n $pid > "${base_dir}/build/tmp/zk.pid"
-    fi
-
-    # wait max 120 seconds for server to be ready to server clients
-    # this handles testing on slow hosts
-    success=false
-    for i in {1..120}
-    do
-        if ps -p $pid > /dev/null
-        then
-            java -cp "$CLASSPATH" org.apache.zookeeper.ZooKeeperMain -server localhost:$ZOOPORT ls / > /dev/null 2>&1
-            if [ $? -ne 0  ]
-            then
-                # server not up yet - wait
-                sleep 1
-            else
-                # server is up and serving client connections
-                success=true
-                break
-            fi
-        else
-            # server died - exit now
-            echo -n " ZooKeeper server process failed"
-            break
-        fi
-    done
-
-    if $success
-    then
-        ## in case for debug, but generally don't use as it messes up the
-        ## console test output
-        echo -n " ZooKeeper server started"
-    else
-        echo -n " ZooKeeper server NOT started"
-    fi
-
-    ;;
-stop)
-    # Already killed above
-    ;;
-*)
-    echo "Unknown command " + $1
-    exit 2
-esac
-

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/CMakeLists.txt b/zookeeper-client/zookeeper-client-c/CMakeLists.txt
new file mode 100644
index 0000000..e7dfbeb
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/CMakeLists.txt
@@ -0,0 +1,237 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cmake_minimum_required(VERSION 3.6)
+
+project(zookeeper VERSION 3.4.13)
+set(email user@zookeeper.apache.org)
+set(description "zookeeper C client")
+
+# general options
+include_directories(include tests generated ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})
+if(UNIX)
+  add_compile_options(-Wall -fPIC)
+elseif(WIN32)
+  add_compile_options(/W3)
+endif()
+add_definitions(-DUSE_STATIC_LIB)
+
+# TODO: Enable /WX and /W4 on Windows. Currently there are ~1000 warnings.
+# TODO: Add Solaris support.
+# TODO: Add a shared library option.
+# TODO: Specify symbols to export.
+# TODO: Generate doxygen documentation.
+
+# Sync API option
+option(WANT_SYNCAPI "Enables Sync API support" ON)
+if(WANT_SYNCAPI)
+  add_definitions(-DTHREADED)
+  if(WIN32)
+    # Note that the generator expression ensures that `/MTd` is used when Debug
+    # configurations are built.
+    add_compile_options(/MT$<$<CONFIG:Debug>:d>)
+  endif()
+endif()
+
+# CppUnit option
+if(WIN32 OR APPLE)
+  # The tests do not yet compile on Windows or macOS,
+  # so we set this to off by default.
+  #
+  # Note that CMake does not have expressions except in conditionals,
+  # so we're left with this if/else/endif pattern.
+  set(DEFAULT_WANT_CPPUNIT OFF)
+else()
+  set(DEFAULT_WANT_CPPUNIT ON)
+endif()
+option(WANT_CPPUNIT "Enables CppUnit and tests" ${DEFAULT_WANT_CPPUNIT})
+
+# The function `to_have(in out)` converts a header name like `arpa/inet.h`
+# into an Autotools style preprocessor definition `HAVE_ARPA_INET_H`.
+# This is then set or unset in `configure_file()` step.
+#
+# Note that CMake functions do not have return values; instead an "out"
+# variable must be passed, and explicitly set with parent scope.
+function(to_have in out)
+  string(TOUPPER ${in} str)
+  string(REGEX REPLACE "/|\\." "_" str ${str})
+  set(${out} "HAVE_${str}" PARENT_SCOPE)
+endfunction()
+
+# include file checks
+foreach(f generated/zookeeper.jute.h generated/zookeeper.jute.c)
+  if(EXISTS "${CMAKE_SOURCE_DIR}/${f}")
+    to_have(${f} name)
+    set(${name} 1)
+  else()
+    message(FATAL_ERROR
+      "jute files are missing!\n"
+      "Please run 'ant compile_jute' while in the ZooKeeper top level directory.")
+  endif()
+endforeach()
+
+# header checks
+include(CheckIncludeFile)
+set(check_headers
+  arpa/inet.h
+  dlfcn.h
+  fcntl.h
+  inttypes.h
+  memory.h
+  netdb.h
+  netinet/in.h
+  stdint.h
+  stdlib.h
+  string.h
+  strings.h
+  sys/socket.h
+  sys/stat.h
+  sys/time.h
+  sys/types.h
+  unistd.h
+  sys/utsname.h)
+
+foreach(f ${check_headers})
+  to_have(${f} name)
+  check_include_file(${f} ${name})
+endforeach()
+
+# function checks
+include(CheckFunctionExists)
+set(check_functions
+  getcwd
+  gethostbyname
+  gethostname
+  getlogin
+  getpwuid_r
+  gettimeofday
+  getuid
+  memmove
+  memset
+  poll
+  socket
+  strchr
+  strdup
+  strerror
+  strtol)
+
+foreach(fn ${check_functions})
+  to_have(${fn} name)
+  check_function_exists(${fn} ${name})
+endforeach()
+
+# library checks
+set(check_libraries rt m pthread)
+foreach(lib ${check_libraries})
+  to_have("lib${lib}" name)
+  find_library(${name} ${lib})
+endforeach()
+
+# IPv6 check
+include(CheckStructHasMember)
+check_struct_has_member("struct sockaddr_in6" sin6_addr "netinet/in.h" ZOO_IPV6_ENABLED)
+
+# configure
+configure_file(cmake_config.h.in ${CMAKE_SOURCE_DIR}/include/config.h)
+
+# hashtable library
+set(hashtable_sources src/hashtable/hashtable_itr.c src/hashtable/hashtable.c)
+add_library(hashtable STATIC ${hashtable_sources})
+target_link_libraries(hashtable PUBLIC $<$<PLATFORM_ID:Linux>:m>)
+
+# zookeeper library
+set(zookeeper_sources
+  src/zookeeper.c
+  src/recordio.c
+  generated/zookeeper.jute.c
+  src/zk_log.c
+  src/zk_hashtable.c)
+
+if(WANT_SYNCAPI)
+  list(APPEND zookeeper_sources src/mt_adaptor.c)
+else()
+  list(APPEND zookeeper_sources src/st_adaptor.c)
+endif()
+
+if(WIN32)
+  list(APPEND zookeeper_sources src/winport.c)
+endif()
+
+add_library(zookeeper STATIC ${zookeeper_sources})
+target_link_libraries(zookeeper PUBLIC
+  hashtable
+  $<$<PLATFORM_ID:Linux>:rt> # clock_gettime
+  $<$<PLATFORM_ID:Windows>:ws2_32>) # Winsock 2.0
+
+if(WANT_SYNCAPI AND NOT WIN32)
+  find_package(Threads REQUIRED)
+  target_link_libraries(zookeeper PUBLIC Threads::Threads)
+endif()
+
+# cli executable
+add_executable(cli src/cli.c)
+target_link_libraries(cli zookeeper)
+
+# load_gen executable
+if(WANT_SYNCAPI AND NOT WIN32)
+  add_executable(load_gen src/load_gen.c)
+  target_link_libraries(load_gen zookeeper)
+endif()
+
+# tests
+set(test_sources
+  tests/TestDriver.cc
+  tests/LibCMocks.cc
+  tests/LibCSymTable.cc
+  tests/MocksBase.cc
+  tests/ZKMocks.cc
+  tests/Util.cc
+  tests/ThreadingUtil.cc
+  tests/TestZookeeperInit.cc
+  tests/TestZookeeperClose.cc
+  tests/TestClientRetry.cc
+  tests/TestOperations.cc
+  tests/TestMulti.cc
+  tests/TestWatchers.cc
+  tests/TestClient.cc)
+
+if(WANT_SYNCAPI)
+  list(APPEND test_sources tests/PthreadMocks.cc)
+endif()
+
+if(WANT_CPPUNIT)
+  add_executable(zktest ${test_sources})
+  target_compile_definitions(zktest
+    PRIVATE -DZKSERVER_CMD="${CMAKE_SOURCE_DIR}/tests/zkServer.sh")
+  # TODO: Use `find_library()` for `cppunit`.
+  target_link_libraries(zktest zookeeper cppunit dl)
+
+  # This reads the link flags from the file `tests/wrappers.opt` into
+  # the variable `symbol_wrappers` for use in `target_link_libraries`.
+  # It is a holdover from the original build system.
+  file(STRINGS tests/wrappers.opt symbol_wrappers)
+  if(WANT_SYNCAPI)
+    file(STRINGS tests/wrappers-mt.opt symbol_wrappers_mt)
+  endif()
+
+  target_link_libraries(zktest ${symbol_wrappers} ${symbol_wrappers_mt})
+
+  enable_testing()
+  add_test(NAME zktest_runner COMMAND zktest)
+  set_property(TEST zktest_runner PROPERTY ENVIRONMENT
+    "ZKROOT=${CMAKE_SOURCE_DIR}/../.."
+    "CLASSPATH=$CLASSPATH:$CLOVER_HOME/lib/clover.jar")
+endif()

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/ChangeLog
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/ChangeLog b/zookeeper-client/zookeeper-client-c/ChangeLog
new file mode 100644
index 0000000..c85a6c0
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/ChangeLog
@@ -0,0 +1,116 @@
+Release 2.1.1
+2008-04-30 Andrew Kornev <ak...@users.sourceforge.net>
+
+    * changed the distributino package name to "c-client-src"
+    
+Release 2.1.0
+2008-04-30 Andrew Kornev <ak...@users.sourceforge.net>
+
+    * added the client latency diagnostics; the client prints a warning when the
+      reponse latency exceeds 20ms
+
+    * modified logging format to report the znode path for which the zookeeper 
+      operation is called
+
+    * fixed a minor bug where error messages were missing for some of the newer 
+      zookeeper error codes (ZCLOSING and ZNOTHING).
+
+    * improved logging by adding the XID to the message to make it easy to match
+      requests to responses
+
+    * fixed the bug causing sporadic session termination and timeouts
+
+    * added a new return code to zookeeper_process() -- ZNOTHING -- 
+      that indicates that the socket has no more data to read
+
+    * more unit tests added    
+
+Release 1.1.3
+2008-02-07 Andrew Kornev <ak...@users.sourceforge.net>
+
+    * get_xid() is not thread-safe (xid initialization race condition 
+      in the multi-threaded mode).
+    
+    * the I/O thread doesn�t automatically terminate on AUTH_FAILURE and 
+      SESSION_EXPIRED events.
+      
+    * all session events should be processed on the completion thread. 
+    
+    * PING operation doesn�t atomically enqueue the completion and 
+      send buffers like other operations do.
+      
+    * corrected zookeeper_init() doxygen docs.
+    
+    * new unit tests added.
+      
+
+Release 1.1.2
+2008-01-24 Andrew Kornev <ak...@users.sourceforge.net>
+
+    * fixed a race condition caused by the code in zookeeper_process()
+      and free_completions() setting sc->complete to 1 without proper
+      synchronization;
+
+    * fixed zoo_get() not updating buffer_len value with the actual
+      buffer length on return; added missing enter_critical/leave_critical
+      calls to the async ZK operations.
+
+    * Replaced select() with poll() to fix the problem with the FD_SET
+      macro causing stack corruption for FDs higher than 1024
+
+    * Added zoo_set_log_stream() to the public API. The function allows
+      applications to specify a different log file.
+
+    * Removed unused declarations from zookeeper.h (ACL related)
+
+    * changed zoo_get() signature to take a pointer to buffer length.
+      The function sets the parameter to the actual data length upon return.
+
+    * the watcher callback now takes the zhandle as its first parameter. This
+      is to avoid a race condition in the multi-threaded client when a watcher
+      is called before zookeeper_init() has returned.
+
+    * fixed zookeeper_close() resource leaks and race conditions,
+      fixed the race condition causing xid mismatch.
+
+    * added support for cppunit, added new targets: "check" and "run-check"
+      to build and run unit tests.
+
+    * Changed the signature of zookeeper_init(): it now takes a context pointer
+      as a parameter. This is to avoid a race condition in the multi-threaded client.
+
+    * Using a self-pipe rather than SIGUSR1 to wake up select() in the I/O thread
+
+    * Added the doxygen target to the autoconf scripts
+
+    * Pulled out the logging functionality from zookeeper.c to zk_log.c/.h.
+      Fixed a minor issue with PING responses being unnecessarily put on
+      the completion queue rather than simply dropped. Make use of DLL_EXPORT
+      symbol for building shared lib on cygwin.
+
+    * Implemented new Zookeeper operation sync() to flush the leader channel
+      to ensure that all updates have reached the followers.
+
+    * Synchronous methods not being handled properly on disconnect
+
+    * breed: fixed an incorrect parameter passed to zookeeper API by
+      the Sync API wrapper functions
+
+    * breed: the set and delete commands now support both Sync and Async API.
+      Prefix the command name with an 'a' to call the Async API: aset, adelete
+
+    * Make sure mutexes and condition variables are properly initialized
+      and destroyed
+
+    * Fixed zookeeper_close() causing core dumps with mt_adaptor
+
+
+Release 1.0.0
+2007-11-27 Andrew Kornev <ak...@users.sourceforge.net>
+
+    * configure.ac and Makefile.am added support for GNU autotools
+
+    * recordio.c/.h updated jute IO routines to use bit-explicit integer types
+      (int32_t vs. int, and int64_t vs. long long)
+
+    * README rough draft
\ No newline at end of file


[07/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/cli.c
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/cli.c b/zookeeper-client/zookeeper-client-c/src/cli.c
new file mode 100644
index 0000000..ef32a10
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/cli.c
@@ -0,0 +1,697 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * cli.c is a example/sample C client shell for ZooKeeper. It contains
+ * basic shell functionality which exercises some of the features of
+ * the ZooKeeper C client API. It is not a full fledged client and is
+ * not meant for production usage - see the Java client shell for a
+ * fully featured shell.
+ */
+
+#include <zookeeper.h>
+#include <proto.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifndef WIN32
+#include <sys/time.h>
+#include <unistd.h>
+#include <sys/select.h>
+#else
+#include "winport.h"
+//#include <io.h> <-- can't include, conflicting definitions of close()
+int read(int _FileHandle, void * _DstBuf, unsigned int _MaxCharCount);
+int write(int _Filehandle, const void * _Buf, unsigned int _MaxCharCount);
+#define ctime_r(tctime, buffer) ctime_s (buffer, 40, tctime)
+#endif
+
+#include <time.h>
+#include <errno.h>
+#include <assert.h>
+
+#ifdef YCA
+#include <yca/yca.h>
+#endif
+
+#define _LL_CAST_ (long long)
+
+static zhandle_t *zh;
+static clientid_t myid;
+static const char *clientIdFile = 0;
+struct timeval startTime;
+static char cmd[1024];
+static int batchMode=0;
+
+static int to_send=0;
+static int sent=0;
+static int recvd=0;
+
+static int shutdownThisThing=0;
+
+static __attribute__ ((unused)) void 
+printProfileInfo(struct timeval start, struct timeval end, int thres,
+                 const char* msg)
+{
+  int delay=(end.tv_sec*1000+end.tv_usec/1000)-
+    (start.tv_sec*1000+start.tv_usec/1000);
+  if(delay>thres)
+    fprintf(stderr,"%s: execution time=%dms\n",msg,delay);
+}
+
+static const char* state2String(int state){
+  if (state == 0)
+    return "CLOSED_STATE";
+  if (state == ZOO_CONNECTING_STATE)
+    return "CONNECTING_STATE";
+  if (state == ZOO_ASSOCIATING_STATE)
+    return "ASSOCIATING_STATE";
+  if (state == ZOO_CONNECTED_STATE)
+    return "CONNECTED_STATE";
+  if (state == ZOO_EXPIRED_SESSION_STATE)
+    return "EXPIRED_SESSION_STATE";
+  if (state == ZOO_AUTH_FAILED_STATE)
+    return "AUTH_FAILED_STATE";
+
+  return "INVALID_STATE";
+}
+
+static const char* type2String(int state){
+  if (state == ZOO_CREATED_EVENT)
+    return "CREATED_EVENT";
+  if (state == ZOO_DELETED_EVENT)
+    return "DELETED_EVENT";
+  if (state == ZOO_CHANGED_EVENT)
+    return "CHANGED_EVENT";
+  if (state == ZOO_CHILD_EVENT)
+    return "CHILD_EVENT";
+  if (state == ZOO_SESSION_EVENT)
+    return "SESSION_EVENT";
+  if (state == ZOO_NOTWATCHING_EVENT)
+    return "NOTWATCHING_EVENT";
+
+  return "UNKNOWN_EVENT_TYPE";
+}
+
+void watcher(zhandle_t *zzh, int type, int state, const char *path,
+             void* context)
+{
+    /* Be careful using zh here rather than zzh - as this may be mt code
+     * the client lib may call the watcher before zookeeper_init returns */
+
+    fprintf(stderr, "Watcher %s state = %s", type2String(type), state2String(state));
+    if (path && strlen(path) > 0) {
+      fprintf(stderr, " for path %s", path);
+    }
+    fprintf(stderr, "\n");
+
+    if (type == ZOO_SESSION_EVENT) {
+        if (state == ZOO_CONNECTED_STATE) {
+            const clientid_t *id = zoo_client_id(zzh);
+            if (myid.client_id == 0 || myid.client_id != id->client_id) {
+                myid = *id;
+                fprintf(stderr, "Got a new session id: 0x%llx\n",
+                        _LL_CAST_ myid.client_id);
+                if (clientIdFile) {
+                    FILE *fh = fopen(clientIdFile, "w");
+                    if (!fh) {
+                        perror(clientIdFile);
+                    } else {
+                        int rc = fwrite(&myid, sizeof(myid), 1, fh);
+                        if (rc != sizeof(myid)) {
+                            perror("writing client id");
+                        }
+                        fclose(fh);
+                    }
+                }
+            }
+        } else if (state == ZOO_AUTH_FAILED_STATE) {
+            fprintf(stderr, "Authentication failure. Shutting down...\n");
+            zookeeper_close(zzh);
+            shutdownThisThing=1;
+            zh=0;
+        } else if (state == ZOO_EXPIRED_SESSION_STATE) {
+            fprintf(stderr, "Session expired. Shutting down...\n");
+            zookeeper_close(zzh);
+            shutdownThisThing=1;
+            zh=0;
+        }
+    }
+}
+
+void dumpStat(const struct Stat *stat) {
+    char tctimes[40];
+    char tmtimes[40];
+    time_t tctime;
+    time_t tmtime;
+
+    if (!stat) {
+        fprintf(stderr,"null\n");
+        return;
+    }
+    tctime = stat->ctime/1000;
+    tmtime = stat->mtime/1000;
+       
+    ctime_r(&tmtime, tmtimes);
+    ctime_r(&tctime, tctimes);
+       
+    fprintf(stderr, "\tctime = %s\tczxid=%llx\n"
+    "\tmtime=%s\tmzxid=%llx\n"
+    "\tversion=%x\taversion=%x\n"
+    "\tephemeralOwner = %llx\n",
+     tctimes, _LL_CAST_ stat->czxid, tmtimes,
+    _LL_CAST_ stat->mzxid,
+    (unsigned int)stat->version, (unsigned int)stat->aversion,
+    _LL_CAST_ stat->ephemeralOwner);
+}
+
+void my_string_completion(int rc, const char *name, const void *data) {
+    fprintf(stderr, "[%s]: rc = %d\n", (char*)(data==0?"null":data), rc);
+    if (!rc) {
+        fprintf(stderr, "\tname = %s\n", name);
+    }
+    if(batchMode)
+      shutdownThisThing=1;
+}
+
+void my_string_completion_free_data(int rc, const char *name, const void *data) {
+    my_string_completion(rc, name, data);
+    free((void*)data);
+}
+
+void my_data_completion(int rc, const char *value, int value_len,
+        const struct Stat *stat, const void *data) {
+    struct timeval tv;
+    int sec;
+    int usec;
+    gettimeofday(&tv, 0);
+    sec = tv.tv_sec - startTime.tv_sec;
+    usec = tv.tv_usec - startTime.tv_usec;
+    fprintf(stderr, "time = %d msec\n", sec*1000 + usec/1000);
+    fprintf(stderr, "%s: rc = %d\n", (char*)data, rc);
+    if (value) {
+        fprintf(stderr, " value_len = %d\n", value_len);
+        assert(write(2, value, value_len) == value_len);
+    }
+    fprintf(stderr, "\nStat:\n");
+    dumpStat(stat);
+    free((void*)data);
+    if(batchMode)
+      shutdownThisThing=1;
+}
+
+void my_silent_data_completion(int rc, const char *value, int value_len,
+        const struct Stat *stat, const void *data) {
+    recvd++;
+    fprintf(stderr, "Data completion %s rc = %d\n",(char*)data,rc);
+    free((void*)data);
+    if (recvd==to_send) {
+        fprintf(stderr,"Recvd %d responses for %d requests sent\n",recvd,to_send);
+        if(batchMode)
+          shutdownThisThing=1;
+    }
+}
+
+void my_strings_completion(int rc, const struct String_vector *strings,
+        const void *data) {
+    struct timeval tv;
+    int sec;
+    int usec;
+    int i;
+
+    gettimeofday(&tv, 0);
+    sec = tv.tv_sec - startTime.tv_sec;
+    usec = tv.tv_usec - startTime.tv_usec;
+    fprintf(stderr, "time = %d msec\n", sec*1000 + usec/1000);
+    fprintf(stderr, "%s: rc = %d\n", (char*)data, rc);
+    if (strings)
+        for (i=0; i < strings->count; i++) {
+            fprintf(stderr, "\t%s\n", strings->data[i]);
+        }
+    free((void*)data);
+    gettimeofday(&tv, 0);
+    sec = tv.tv_sec - startTime.tv_sec;
+    usec = tv.tv_usec - startTime.tv_usec;
+    fprintf(stderr, "time = %d msec\n", sec*1000 + usec/1000);
+    if(batchMode)
+      shutdownThisThing=1;
+}
+
+void my_strings_stat_completion(int rc, const struct String_vector *strings,
+        const struct Stat *stat, const void *data) {
+    my_strings_completion(rc, strings, data);
+    dumpStat(stat);
+    if(batchMode)
+      shutdownThisThing=1;
+}
+
+void my_void_completion(int rc, const void *data) {
+    fprintf(stderr, "%s: rc = %d\n", (char*)data, rc);
+    free((void*)data);
+    if(batchMode)
+      shutdownThisThing=1;
+}
+
+void my_stat_completion(int rc, const struct Stat *stat, const void *data) {
+    fprintf(stderr, "%s: rc = %d Stat:\n", (char*)data, rc);
+    dumpStat(stat);
+    free((void*)data);
+    if(batchMode)
+      shutdownThisThing=1;
+}
+
+void my_silent_stat_completion(int rc, const struct Stat *stat,
+        const void *data) {
+    //    fprintf(stderr, "State completion: [%s] rc = %d\n", (char*)data, rc);
+    sent++;
+    free((void*)data);
+}
+
+static void sendRequest(const char* data) {
+    zoo_aset(zh, "/od", data, strlen(data), -1, my_silent_stat_completion,
+            strdup("/od"));
+    zoo_aget(zh, "/od", 1, my_silent_data_completion, strdup("/od"));
+}
+
+void od_completion(int rc, const struct Stat *stat, const void *data) {
+    int i;
+    fprintf(stderr, "od command response: rc = %d Stat:\n", rc);
+    dumpStat(stat);
+    // send a whole bunch of requests
+    recvd=0;
+    sent=0;
+    to_send=200;
+    for (i=0; i<to_send; i++) {
+        char buf[4096*16];
+        memset(buf, -1, sizeof(buf)-1);
+        buf[sizeof(buf)-1]=0;
+        sendRequest(buf);
+    }
+}
+
+int startsWith(const char *line, const char *prefix) {
+    int len = strlen(prefix);
+    return strncmp(line, prefix, len) == 0;
+}
+
+static const char *hostPort;
+static int verbose = 0;
+
+void processline(char *line) {
+    int rc;
+    int async = ((line[0] == 'a') && !(startsWith(line, "addauth ")));
+    if (async) {
+        line++;
+    }
+    if (startsWith(line, "help")) {
+      fprintf(stderr, "    create [+[e|s]] <path>\n");
+      fprintf(stderr, "    delete <path>\n");
+      fprintf(stderr, "    set <path> <data>\n");
+      fprintf(stderr, "    get <path>\n");
+      fprintf(stderr, "    ls <path>\n");
+      fprintf(stderr, "    ls2 <path>\n");
+      fprintf(stderr, "    sync <path>\n");
+      fprintf(stderr, "    exists <path>\n");
+      fprintf(stderr, "    wexists <path>\n");
+      fprintf(stderr, "    myid\n");
+      fprintf(stderr, "    verbose\n");
+      fprintf(stderr, "    addauth <id> <scheme>\n");
+      fprintf(stderr, "    quit\n");
+      fprintf(stderr, "\n");
+      fprintf(stderr, "    prefix the command with the character 'a' to run the command asynchronously.\n");
+      fprintf(stderr, "    run the 'verbose' command to toggle verbose logging.\n");
+      fprintf(stderr, "    i.e. 'aget /foo' to get /foo asynchronously\n");
+    } else if (startsWith(line, "verbose")) {
+      if (verbose) {
+        verbose = 0;
+        zoo_set_debug_level(ZOO_LOG_LEVEL_WARN);
+        fprintf(stderr, "logging level set to WARN\n");
+      } else {
+        verbose = 1;
+        zoo_set_debug_level(ZOO_LOG_LEVEL_DEBUG);
+        fprintf(stderr, "logging level set to DEBUG\n");
+      }
+    } else if (startsWith(line, "get ")) {
+        line += 4;
+        if (line[0] != '/') {
+            fprintf(stderr, "Path must start with /, found: %s\n", line);
+            return;
+        }
+               
+        rc = zoo_aget(zh, line, 1, my_data_completion, strdup(line));
+        if (rc) {
+            fprintf(stderr, "Error %d for %s\n", rc, line);
+        }
+    } else if (startsWith(line, "set ")) {
+        char *ptr;
+        line += 4;
+        if (line[0] != '/') {
+            fprintf(stderr, "Path must start with /, found: %s\n", line);
+            return;
+        }
+        ptr = strchr(line, ' ');
+        if (!ptr) {
+            fprintf(stderr, "No data found after path\n");
+            return;
+        }
+        *ptr = '\0';
+        ptr++;
+        if (async) {
+            rc = zoo_aset(zh, line, ptr, strlen(ptr), -1, my_stat_completion,
+                    strdup(line));
+        } else {
+            struct Stat stat;
+            rc = zoo_set2(zh, line, ptr, strlen(ptr), -1, &stat);
+        }
+        if (rc) {
+            fprintf(stderr, "Error %d for %s\n", rc, line);
+        }
+    } else if (startsWith(line, "ls ")) {
+        line += 3;
+        if (line[0] != '/') {
+            fprintf(stderr, "Path must start with /, found: %s\n", line);
+            return;
+        }
+        gettimeofday(&startTime, 0);
+        rc= zoo_aget_children(zh, line, 1, my_strings_completion, strdup(line));
+        if (rc) {
+            fprintf(stderr, "Error %d for %s\n", rc, line);
+        }
+    } else if (startsWith(line, "ls2 ")) {
+        line += 4;
+        if (line[0] != '/') {
+            fprintf(stderr, "Path must start with /, found: %s\n", line);
+            return;
+        }
+        gettimeofday(&startTime, 0);
+        rc= zoo_aget_children2(zh, line, 1, my_strings_stat_completion, strdup(line));
+        if (rc) {
+            fprintf(stderr, "Error %d for %s\n", rc, line);
+        }
+    } else if (startsWith(line, "create ")) {
+        int flags = 0;
+        line += 7;
+        if (line[0] == '+') {
+            line++;
+            if (line[0] == 'e') {
+                flags |= ZOO_EPHEMERAL;
+                line++;
+            }
+            if (line[0] == 's') {
+                flags |= ZOO_SEQUENCE;
+                line++;
+            }
+            line++;
+        }
+        if (line[0] != '/') {
+            fprintf(stderr, "Path must start with /, found: %s\n", line);
+            return;
+        }
+        fprintf(stderr, "Creating [%s] node\n", line);
+//        {
+//            struct ACL _CREATE_ONLY_ACL_ACL[] = {{ZOO_PERM_CREATE, ZOO_ANYONE_ID_UNSAFE}};
+//            struct ACL_vector CREATE_ONLY_ACL = {1,_CREATE_ONLY_ACL_ACL};
+//            rc = zoo_acreate(zh, line, "new", 3, &CREATE_ONLY_ACL, flags,
+//                    my_string_completion, strdup(line));
+//        }
+        rc = zoo_acreate(zh, line, "new", 3, &ZOO_OPEN_ACL_UNSAFE, flags,
+                my_string_completion_free_data, strdup(line));
+        if (rc) {
+            fprintf(stderr, "Error %d for %s\n", rc, line);
+        }
+    } else if (startsWith(line, "delete ")) {
+        line += 7;
+        if (line[0] != '/') {
+            fprintf(stderr, "Path must start with /, found: %s\n", line);
+            return;
+        }
+        if (async) {
+            rc = zoo_adelete(zh, line, -1, my_void_completion, strdup(line));
+        } else {
+            rc = zoo_delete(zh, line, -1);
+        }
+        if (rc) {
+            fprintf(stderr, "Error %d for %s\n", rc, line);
+        }
+    } else if (startsWith(line, "sync ")) {
+        line += 5;
+        if (line[0] != '/') {
+            fprintf(stderr, "Path must start with /, found: %s\n", line);
+            return;
+        }
+        rc = zoo_async(zh, line, my_string_completion_free_data, strdup(line));
+        if (rc) {
+            fprintf(stderr, "Error %d for %s\n", rc, line);
+        }
+    } else if (startsWith(line, "wexists ")) {
+#ifdef THREADED
+        struct Stat stat;
+#endif
+        line += 8;
+        if (line[0] != '/') {
+            fprintf(stderr, "Path must start with /, found: %s\n", line);
+            return;
+        }
+#ifndef THREADED
+        rc = zoo_awexists(zh, line, watcher, (void*) 0, my_stat_completion, strdup(line));
+#else
+        rc = zoo_wexists(zh, line, watcher, (void*) 0, &stat);
+#endif
+        if (rc) {
+            fprintf(stderr, "Error %d for %s\n", rc, line);
+        }
+    } else if (startsWith(line, "exists ")) {
+#ifdef THREADED
+        struct Stat stat;
+#endif
+        line += 7;
+        if (line[0] != '/') {
+            fprintf(stderr, "Path must start with /, found: %s\n", line);
+            return;
+        }
+#ifndef THREADED
+        rc = zoo_aexists(zh, line, 1, my_stat_completion, strdup(line));
+#else
+        rc = zoo_exists(zh, line, 1, &stat);
+#endif
+        if (rc) {
+            fprintf(stderr, "Error %d for %s\n", rc, line);
+        }
+    } else if (strcmp(line, "myid") == 0) {
+        printf("session Id = %llx\n", _LL_CAST_ zoo_client_id(zh)->client_id);
+    } else if (strcmp(line, "reinit") == 0) {
+        zookeeper_close(zh);
+        // we can't send myid to the server here -- zookeeper_close() removes 
+        // the session on the server. We must start anew.
+        zh = zookeeper_init(hostPort, watcher, 30000, 0, 0, 0);
+    } else if (startsWith(line, "quit")) {
+        fprintf(stderr, "Quitting...\n");
+        shutdownThisThing=1;
+    } else if (startsWith(line, "od")) {
+        const char val[]="fire off";
+        fprintf(stderr, "Overdosing...\n");
+        rc = zoo_aset(zh, "/od", val, sizeof(val)-1, -1, od_completion, 0);
+        if (rc)
+            fprintf(stderr, "od command failed: %d\n", rc);
+    } else if (startsWith(line, "addauth ")) {
+      char *ptr;
+      line += 8;
+      ptr = strchr(line, ' ');
+      if (ptr) {
+        *ptr = '\0';
+        ptr++;
+      }
+      zoo_add_auth(zh, line, ptr, ptr ? strlen(ptr) : 0, NULL, NULL);
+    }
+}
+
+int main(int argc, char **argv) {
+#ifndef THREADED
+    fd_set rfds, wfds, efds;
+    int processed=0;
+#endif
+    char buffer[4096];
+    char p[2048];
+#ifdef YCA  
+    char *cert=0;
+    char appId[64];
+#endif
+    int bufoff = 0;
+    FILE *fh;
+
+    if (argc < 2) {
+        fprintf(stderr,
+                "USAGE %s zookeeper_host_list [clientid_file|cmd:(ls|ls2|create|od|...)]\n", 
+                argv[0]);
+        fprintf(stderr,
+                "Version: ZooKeeper cli (c client) version %d.%d.%d\n", 
+                ZOO_MAJOR_VERSION,
+                ZOO_MINOR_VERSION,
+                ZOO_PATCH_VERSION);
+        return 2;
+    }
+    if (argc > 2) {
+      if(strncmp("cmd:",argv[2],4)==0){
+        size_t cmdlen = strlen(argv[2]);
+        if (cmdlen > sizeof(cmd)) {
+          fprintf(stderr,
+                  "Command length %zu exceeds max length of %zu\n",
+                  cmdlen,
+                  sizeof(cmd));
+          return 2;
+        }
+        strncpy(cmd, argv[2]+4, sizeof(cmd));
+        batchMode=1;
+        fprintf(stderr,"Batch mode: %s\n",cmd);
+      }else{
+        clientIdFile = argv[2];
+        fh = fopen(clientIdFile, "r");
+        if (fh) {
+            if (fread(&myid, sizeof(myid), 1, fh) != sizeof(myid)) {
+                memset(&myid, 0, sizeof(myid));
+            }
+            fclose(fh);
+        }
+      }
+    }
+#ifdef YCA
+    strcpy(appId,"yahoo.example.yca_test");
+    cert = yca_get_cert_once(appId);
+    if(cert!=0) {
+        fprintf(stderr,"Certificate for appid [%s] is [%s]\n",appId,cert);
+        strncpy(p,cert,sizeof(p)-1);
+        free(cert);
+    } else {
+      fprintf(stderr,"Certificate for appid [%s] not found\n",appId);
+      strcpy(p,"dummy");
+    }
+#else
+    strcpy(p, "dummy");
+#endif
+    verbose = 0;
+    zoo_set_debug_level(ZOO_LOG_LEVEL_WARN);
+    zoo_deterministic_conn_order(1); // enable deterministic order
+    hostPort = argv[1];
+    zh = zookeeper_init(hostPort, watcher, 30000, &myid, 0, 0);
+    if (!zh) {
+        return errno;
+    }
+
+#ifdef YCA
+    if(zoo_add_auth(zh,"yca",p,strlen(p),0,0)!=ZOK)
+    return 2;
+#endif
+
+#ifdef THREADED
+    while(!shutdownThisThing) {
+        int rc;
+        int len = sizeof(buffer) - bufoff -1;
+        if (len <= 0) {
+            fprintf(stderr, "Can't handle lines that long!\n");
+            exit(2);
+        }
+        rc = read(0, buffer+bufoff, len);
+        if (rc <= 0) {
+            fprintf(stderr, "bye\n");
+            shutdownThisThing=1;
+            break;
+        }
+        bufoff += rc;
+        buffer[bufoff] = '\0';
+        while (strchr(buffer, '\n')) {
+            char *ptr = strchr(buffer, '\n');
+            *ptr = '\0';
+            processline(buffer);
+            ptr++;
+            memmove(buffer, ptr, strlen(ptr)+1);
+            bufoff = 0;
+        }
+    }
+#else
+    FD_ZERO(&rfds);
+    FD_ZERO(&wfds);
+    FD_ZERO(&efds);
+    while (!shutdownThisThing) {
+        int fd;
+        int interest;
+        int events;
+        struct timeval tv;
+        int rc;
+        zookeeper_interest(zh, &fd, &interest, &tv);
+        if (fd != -1) {
+            if (interest&ZOOKEEPER_READ) {
+                FD_SET(fd, &rfds);
+            } else {
+                FD_CLR(fd, &rfds);
+            }
+            if (interest&ZOOKEEPER_WRITE) {
+                FD_SET(fd, &wfds);
+            } else {
+                FD_CLR(fd, &wfds);
+            }
+        } else {
+            fd = 0;
+        }
+        FD_SET(0, &rfds);
+        rc = select(fd+1, &rfds, &wfds, &efds, &tv);
+        events = 0;
+        if (rc > 0) {
+            if (FD_ISSET(fd, &rfds)) {
+                events |= ZOOKEEPER_READ;
+            }
+            if (FD_ISSET(fd, &wfds)) {
+                events |= ZOOKEEPER_WRITE;
+            }
+        }
+        if(batchMode && processed==0){
+          //batch mode
+          processline(cmd);
+          processed=1;
+        }
+        if (FD_ISSET(0, &rfds)) {
+            int rc;
+            int len = sizeof(buffer) - bufoff -1;
+            if (len <= 0) {
+                fprintf(stderr, "Can't handle lines that long!\n");
+                exit(2);
+            }
+            rc = read(0, buffer+bufoff, len);
+            if (rc <= 0) {
+                fprintf(stderr, "bye\n");
+                break;
+            }
+            bufoff += rc;
+            buffer[bufoff] = '\0';
+            while (strchr(buffer, '\n')) {
+                char *ptr = strchr(buffer, '\n');
+                *ptr = '\0';
+                processline(buffer);
+                ptr++;
+                memmove(buffer, ptr, strlen(ptr)+1);
+                bufoff = 0;
+            }
+        }
+        zookeeper_process(zh, events);
+    }
+#endif
+    if (to_send!=0)
+        fprintf(stderr,"Recvd %d responses for %d requests sent\n",recvd,sent);
+    zookeeper_close(zh);
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/hashtable/LICENSE.txt
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/hashtable/LICENSE.txt b/zookeeper-client/zookeeper-client-c/src/hashtable/LICENSE.txt
new file mode 100644
index 0000000..674a624
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/hashtable/LICENSE.txt
@@ -0,0 +1,30 @@
+Copyright (c) 2002, 2004, Christopher Clark
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+	* Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+	* Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+	* Neither the name of the original author; nor the names of any contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable.c
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable.c b/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable.c
new file mode 100644
index 0000000..763357e
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable.c
@@ -0,0 +1,274 @@
+/* Copyright (C) 2004 Christopher Clark <fi...@cl.cam.ac.uk> */
+
+#include "hashtable.h"
+#include "hashtable_private.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+/*
+Credit for primes table: Aaron Krowne
+ http://br.endernet.org/~akrowne/
+ http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
+*/
+static const unsigned int primes[] = {
+53, 97, 193, 389,
+769, 1543, 3079, 6151,
+12289, 24593, 49157, 98317,
+196613, 393241, 786433, 1572869,
+3145739, 6291469, 12582917, 25165843,
+50331653, 100663319, 201326611, 402653189,
+805306457, 1610612741
+};
+const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]);
+const float max_load_factor = 0.65;
+
+/*****************************************************************************/
+struct hashtable *
+create_hashtable(unsigned int minsize,
+                 unsigned int (*hashf) (void*),
+                 int (*eqf) (void*,void*))
+{
+    struct hashtable *h;
+    unsigned int pindex, size = primes[0];
+    /* Check requested hashtable isn't too large */
+    if (minsize > (1u << 30)) return NULL;
+    /* Enforce size as prime */
+    for (pindex=0; pindex < prime_table_length; pindex++) {
+        if (primes[pindex] > minsize) { size = primes[pindex]; break; }
+    }
+    h = (struct hashtable *)malloc(sizeof(struct hashtable));
+    if (NULL == h) return NULL; /*oom*/
+    h->table = (struct entry **)malloc(sizeof(struct entry*) * size);
+    if (NULL == h->table) { free(h); return NULL; } /*oom*/
+    memset(h->table, 0, size * sizeof(struct entry *));
+    h->tablelength  = size;
+    h->primeindex   = pindex;
+    h->entrycount   = 0;
+    h->hashfn       = hashf;
+    h->eqfn         = eqf;
+    h->loadlimit    = (unsigned int) ceil(size * max_load_factor);
+    return h;
+}
+
+/*****************************************************************************/
+unsigned int
+hash(struct hashtable *h, void *k)
+{
+    /* Aim to protect against poor hash functions by adding logic here
+     * - logic taken from java 1.4 hashtable source */
+    unsigned int i = h->hashfn(k);
+    i += ~(i << 9);
+    i ^=  ((i >> 14) | (i << 18)); /* >>> */
+    i +=  (i << 4);
+    i ^=  ((i >> 10) | (i << 22)); /* >>> */
+    return i;
+}
+
+/*****************************************************************************/
+static int
+hashtable_expand(struct hashtable *h)
+{
+    /* Double the size of the table to accomodate more entries */
+    struct entry **newtable;
+    struct entry *e;
+    struct entry **pE;
+    unsigned int newsize, i, index;
+    /* Check we're not hitting max capacity */
+    if (h->primeindex == (prime_table_length - 1)) return 0;
+    newsize = primes[++(h->primeindex)];
+
+    newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize);
+    if (NULL != newtable)
+    {
+        memset(newtable, 0, newsize * sizeof(struct entry *));
+        /* This algorithm is not 'stable'. ie. it reverses the list
+         * when it transfers entries between the tables */
+        for (i = 0; i < h->tablelength; i++) {
+            while (NULL != (e = h->table[i])) {
+                h->table[i] = e->next;
+                index = indexFor(newsize,e->h);
+                e->next = newtable[index];
+                newtable[index] = e;
+            }
+        }
+        free(h->table);
+        h->table = newtable;
+    }
+    /* Plan B: realloc instead */
+    else 
+    {
+        newtable = (struct entry **)
+                   realloc(h->table, newsize * sizeof(struct entry *));
+        if (NULL == newtable) { (h->primeindex)--; return 0; }
+        h->table = newtable;
+        memset(newtable[h->tablelength], 0, newsize - h->tablelength);
+        for (i = 0; i < h->tablelength; i++) {
+            for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
+                index = indexFor(newsize,e->h);
+                if (index == i)
+                {
+                    pE = &(e->next);
+                }
+                else
+                {
+                    *pE = e->next;
+                    e->next = newtable[index];
+                    newtable[index] = e;
+                }
+            }
+        }
+    }
+    h->tablelength = newsize;
+    h->loadlimit   = (unsigned int) ceil(newsize * max_load_factor);
+    return -1;
+}
+
+/*****************************************************************************/
+unsigned int
+hashtable_count(struct hashtable *h)
+{
+    return h->entrycount;
+}
+
+/*****************************************************************************/
+int
+hashtable_insert(struct hashtable *h, void *k, void *v)
+{
+    /* This method allows duplicate keys - but they shouldn't be used */
+    unsigned int index;
+    struct entry *e;
+    if (++(h->entrycount) > h->loadlimit)
+    {
+        /* Ignore the return value. If expand fails, we should
+         * still try cramming just this value into the existing table
+         * -- we may not have memory for a larger table, but one more
+         * element may be ok. Next time we insert, we'll try expanding again.*/
+        hashtable_expand(h);
+    }
+    e = (struct entry *)malloc(sizeof(struct entry));
+    if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
+    e->h = hash(h,k);
+    index = indexFor(h->tablelength,e->h);
+    e->k = k;
+    e->v = v;
+    e->next = h->table[index];
+    h->table[index] = e;
+    return -1;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_search(struct hashtable *h, void *k)
+{
+    struct entry *e;
+    unsigned int hashvalue, index;
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hashvalue);
+    e = h->table[index];
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;
+        e = e->next;
+    }
+    return NULL;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_remove(struct hashtable *h, void *k)
+{
+    /* TODO: consider compacting the table when the load factor drops enough,
+     *       or provide a 'compact' method. */
+
+    struct entry *e;
+    struct entry **pE;
+    void *v;
+    unsigned int hashvalue, index;
+
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hash(h,k));
+    pE = &(h->table[index]);
+    e = *pE;
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+        {
+            *pE = e->next;
+            h->entrycount--;
+            v = e->v;
+            freekey(e->k);
+            free(e);
+            return v;
+        }
+        pE = &(e->next);
+        e = e->next;
+    }
+    return NULL;
+}
+
+/*****************************************************************************/
+/* destroy */
+void
+hashtable_destroy(struct hashtable *h, int free_values)
+{
+    unsigned int i;
+    struct entry *e, *f;
+    struct entry **table = h->table;
+    if (free_values)
+    {
+        for (i = 0; i < h->tablelength; i++)
+        {
+            e = table[i];
+            while (NULL != e)
+            { f = e; e = e->next; freekey(f->k); free(f->v); free(f); }
+        }
+    }
+    else
+    {
+        for (i = 0; i < h->tablelength; i++)
+        {
+            e = table[i];
+            while (NULL != e)
+            { f = e; e = e->next; freekey(f->k); free(f); }
+        }
+    }
+    free(h->table);
+    free(h);
+}
+
+/*
+ * Copyright (c) 2002, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable.h b/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable.h
new file mode 100644
index 0000000..cbead18
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable.h
@@ -0,0 +1,209 @@
+/* Copyright (C) 2002 Christopher Clark <fi...@cl.cam.ac.uk> */
+
+#ifndef __HASHTABLE_CWC22_H__
+#define __HASHTABLE_CWC22_H__
+#ifdef WIN32
+#include "winconfig.h"
+#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hashtable;
+
+/* Example of use:
+ *
+ *      struct hashtable  *h;
+ *      struct some_key   *k;
+ *      struct some_value *v;
+ *
+ *      static unsigned int         hash_from_key_fn( void *k );
+ *      static int                  keys_equal_fn ( void *key1, void *key2 );
+ *
+ *      h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
+ *      k = (struct some_key *)     malloc(sizeof(struct some_key));
+ *      v = (struct some_value *)   malloc(sizeof(struct some_value));
+ *
+ *      (initialise k and v to suitable values)
+ * 
+ *      if (! hashtable_insert(h,k,v) )
+ *      {     exit(-1);               }
+ *
+ *      if (NULL == (found = hashtable_search(h,k) ))
+ *      {    printf("not found!");                  }
+ *
+ *      if (NULL == (found = hashtable_remove(h,k) ))
+ *      {    printf("Not found\n");                 }
+ *
+ */
+
+/* Macros may be used to define type-safe(r) hashtable access functions, with
+ * methods specialized to take known key and value types as parameters.
+ * 
+ * Example:
+ *
+ * Insert this at the start of your file:
+ *
+ * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
+ *
+ * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
+ * These operate just like hashtable_insert etc., with the same parameters,
+ * but their function signatures have 'struct some_key *' rather than
+ * 'void *', and hence can generate compile time errors if your program is
+ * supplying incorrect data as a key (and similarly for value).
+ *
+ * Note that the hash and key equality functions passed to create_hashtable
+ * still take 'void *' parameters instead of 'some key *'. This shouldn't be
+ * a difficult issue as they're only defined and passed once, and the other
+ * functions will ensure that only valid keys are supplied to them.
+ *
+ * The cost for this checking is increased code size and runtime overhead
+ * - if performance is important, it may be worth switching back to the
+ * unsafe methods once your program has been debugged with the safe methods.
+ * This just requires switching to some simple alternative defines - eg:
+ * #define insert_some hashtable_insert
+ *
+ */
+
+/*****************************************************************************
+ * create_hashtable
+   
+ * @name                    create_hashtable
+ * @param   minsize         minimum initial size of hashtable
+ * @param   hashfunction    function for hashing keys
+ * @param   key_eq_fn       function for determining key equality
+ * @return                  newly created hashtable or NULL on failure
+ */
+
+struct hashtable *
+create_hashtable(unsigned int minsize,
+                 unsigned int (*hashfunction) (void*),
+                 int (*key_eq_fn) (void*,void*));
+
+/*****************************************************************************
+ * hashtable_insert
+   
+ * @name        hashtable_insert
+ * @param   h   the hashtable to insert into
+ * @param   k   the key - hashtable claims ownership and will free on removal
+ * @param   v   the value - does not claim ownership
+ * @return      non-zero for successful insertion
+ *
+ * This function will cause the table to expand if the insertion would take
+ * the ratio of entries to table size over the maximum load factor.
+ *
+ * This function does not check for repeated insertions with a duplicate key.
+ * The value returned when using a duplicate key is undefined -- when
+ * the hashtable changes size, the order of retrieval of duplicate key
+ * entries is reversed.
+ * If in doubt, remove before insert.
+ */
+
+int 
+hashtable_insert(struct hashtable *h, void *k, void *v);
+
+#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
+int fnname (struct hashtable *h, keytype *k, valuetype *v) \
+{ \
+    return hashtable_insert(h,k,v); \
+}
+
+/*****************************************************************************
+ * hashtable_search
+   
+ * @name        hashtable_search
+ * @param   h   the hashtable to search
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void *
+hashtable_search(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_search(h,k)); \
+}
+
+/*****************************************************************************
+ * hashtable_remove
+   
+ * @name        hashtable_remove
+ * @param   h   the hashtable to remove the item from
+ * @param   k   the key to search for  - does not claim ownership
+ * @return      the value associated with the key, or NULL if none found
+ */
+
+void * /* returns value */
+hashtable_remove(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+    return (valuetype *) (hashtable_remove(h,k)); \
+}
+
+
+/*****************************************************************************
+ * hashtable_count
+   
+ * @name        hashtable_count
+ * @param   h   the hashtable
+ * @return      the number of items stored in the hashtable
+ */
+unsigned int
+hashtable_count(struct hashtable *h);
+
+
+/*****************************************************************************
+ * hashtable_destroy
+   
+ * @name        hashtable_destroy
+ * @param   h   the hashtable
+ * @param       free_values     whether to call 'free' on the remaining values
+ */
+
+void
+hashtable_destroy(struct hashtable *h, int free_values);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HASHTABLE_CWC22_H__ */
+
+/*
+ * Copyright (c) 2002, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable_itr.c
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable_itr.c b/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable_itr.c
new file mode 100644
index 0000000..defac69
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable_itr.c
@@ -0,0 +1,176 @@
+/* Copyright (C) 2002, 2004 Christopher Clark  <fi...@cl.cam.ac.uk> */
+
+#include "hashtable.h"
+#include "hashtable_private.h"
+#include "hashtable_itr.h"
+#include <stdlib.h> /* defines NULL */
+
+/*****************************************************************************/
+/* hashtable_iterator    - iterator constructor */
+
+struct hashtable_itr *
+hashtable_iterator(struct hashtable *h)
+{
+    unsigned int i, tablelength;
+    struct hashtable_itr *itr = (struct hashtable_itr *)
+        malloc(sizeof(struct hashtable_itr));
+    if (NULL == itr) return NULL;
+    itr->h = h;
+    itr->e = NULL;
+    itr->parent = NULL;
+    tablelength = h->tablelength;
+    itr->index = tablelength;
+    if (0 == h->entrycount) return itr;
+
+    for (i = 0; i < tablelength; i++)
+    {
+        if (NULL != h->table[i])
+        {
+            itr->e = h->table[i];
+            itr->index = i;
+            break;
+        }
+    }
+    return itr;
+}
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ *           returns zero if advanced to end of table */
+
+int
+hashtable_iterator_advance(struct hashtable_itr *itr)
+{
+    unsigned int j,tablelength;
+    struct entry **table;
+    struct entry *next;
+    if (NULL == itr->e) return 0; /* stupidity check */
+
+    next = itr->e->next;
+    if (NULL != next)
+    {
+        itr->parent = itr->e;
+        itr->e = next;
+        return -1;
+    }
+    tablelength = itr->h->tablelength;
+    itr->parent = NULL;
+    if (tablelength <= (j = ++(itr->index)))
+    {
+        itr->e = NULL;
+        return 0;
+    }
+    table = itr->h->table;
+    while (NULL == (next = table[j]))
+    {
+        if (++j >= tablelength)
+        {
+            itr->index = tablelength;
+            itr->e = NULL;
+            return 0;
+        }
+    }
+    itr->index = j;
+    itr->e = next;
+    return -1;
+}
+
+/*****************************************************************************/
+/* remove - remove the entry at the current iterator position
+ *          and advance the iterator, if there is a successive
+ *          element.
+ *          If you want the value, read it before you remove:
+ *          beware memory leaks if you don't.
+ *          Returns zero if end of iteration. */
+
+int
+hashtable_iterator_remove(struct hashtable_itr *itr)
+{
+    struct entry *remember_e, *remember_parent;
+    int ret;
+
+    /* Do the removal */
+    if (NULL == (itr->parent))
+    {
+        /* element is head of a chain */
+        itr->h->table[itr->index] = itr->e->next;
+    } else {
+        /* element is mid-chain */
+        itr->parent->next = itr->e->next;
+    }
+    /* itr->e is now outside the hashtable */
+    remember_e = itr->e;
+    itr->h->entrycount--;
+    freekey(remember_e->k);
+
+    /* Advance the iterator, correcting the parent */
+    remember_parent = itr->parent;
+    ret = hashtable_iterator_advance(itr);
+    if (itr->parent == remember_e) { itr->parent = remember_parent; }
+    free(remember_e);
+    return ret;
+}
+
+/*****************************************************************************/
+int /* returns zero if not found */
+hashtable_iterator_search(struct hashtable_itr *itr,
+                          struct hashtable *h, void *k)
+{
+    struct entry *e, *parent;
+    unsigned int hashvalue, index;
+
+    hashvalue = hash(h,k);
+    index = indexFor(h->tablelength,hashvalue);
+
+    e = h->table[index];
+    parent = NULL;
+    while (NULL != e)
+    {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+        {
+            itr->index = index;
+            itr->e = e;
+            itr->parent = parent;
+            itr->h = h;
+            return -1;
+        }
+        parent = e;
+        e = e->next;
+    }
+    return 0;
+}
+
+
+/*
+ * Copyright (c) 2002, 2004, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable_itr.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable_itr.h b/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable_itr.h
new file mode 100644
index 0000000..30379c7
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable_itr.h
@@ -0,0 +1,119 @@
+/* Copyright (C) 2002, 2004 Christopher Clark <fi...@cl.cam.ac.uk> */
+
+#ifndef __HASHTABLE_ITR_CWC22__
+#define __HASHTABLE_ITR_CWC22__
+#include "hashtable.h"
+#include "hashtable_private.h" /* needed to enable inlining */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*****************************************************************************/
+/* This struct is only concrete here to allow the inlining of two of the
+ * accessor functions. */
+struct hashtable_itr
+{
+    struct hashtable *h;
+    struct entry *e;
+    struct entry *parent;
+    unsigned int index;
+};
+
+
+/*****************************************************************************/
+/* hashtable_iterator
+ */
+
+struct hashtable_itr *
+hashtable_iterator(struct hashtable *h);
+
+/*****************************************************************************/
+/* hashtable_iterator_key
+ * - return the value of the (key,value) pair at the current position */
+
+static inline void *
+hashtable_iterator_key(struct hashtable_itr *i)
+{
+    return i->e->k;
+}
+
+/*****************************************************************************/
+/* value - return the value of the (key,value) pair at the current position */
+
+static inline void *
+hashtable_iterator_value(struct hashtable_itr *i)
+{
+    return i->e->v;
+}
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ *           returns zero if advanced to end of table */
+
+int
+hashtable_iterator_advance(struct hashtable_itr *itr);
+
+/*****************************************************************************/
+/* remove - remove current element and advance the iterator to the next element
+ *          NB: if you need the value to free it, read it before
+ *          removing. ie: beware memory leaks!
+ *          returns zero if advanced to end of table */
+
+int
+hashtable_iterator_remove(struct hashtable_itr *itr);
+
+/*****************************************************************************/
+/* search - overwrite the supplied iterator, to point to the entry
+ *          matching the supplied key.
+            h points to the hashtable to be searched.
+ *          returns zero if not found. */
+int
+hashtable_iterator_search(struct hashtable_itr *itr,
+                          struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
+int fnname (struct hashtable_itr *i, struct hashtable *h, keytype *k) \
+{ \
+    return (hashtable_iterator_search(i,h,k)); \
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __HASHTABLE_ITR_CWC22__*/
+
+/*
+ * Copyright (c) 2002, 2004, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable_private.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable_private.h b/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable_private.h
new file mode 100644
index 0000000..3e95f60
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/hashtable/hashtable_private.h
@@ -0,0 +1,85 @@
+/* Copyright (C) 2002, 2004 Christopher Clark <fi...@cl.cam.ac.uk> */
+
+#ifndef __HASHTABLE_PRIVATE_CWC22_H__
+#define __HASHTABLE_PRIVATE_CWC22_H__
+
+#include "hashtable.h"
+
+/*****************************************************************************/
+struct entry
+{
+    void *k, *v;
+    unsigned int h;
+    struct entry *next;
+};
+
+struct hashtable {
+    unsigned int tablelength;
+    struct entry **table;
+    unsigned int entrycount;
+    unsigned int loadlimit;
+    unsigned int primeindex;
+    unsigned int (*hashfn) (void *k);
+    int (*eqfn) (void *k1, void *k2);
+};
+
+/*****************************************************************************/
+unsigned int
+hash(struct hashtable *h, void *k);
+
+/*****************************************************************************/
+/* indexFor */
+static inline unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue) {
+    return (hashvalue % tablelength);
+};
+
+/* Only works if tablelength == 2^N */
+/*static inline unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue)
+{
+    return (hashvalue & (tablelength - 1u));
+}
+*/
+
+/*****************************************************************************/
+#define freekey(X) free(X)
+/*define freekey(X) ; */
+
+
+/*****************************************************************************/
+
+#endif /* __HASHTABLE_PRIVATE_CWC22_H__*/
+
+/*
+ * Copyright (c) 2002, Christopher Clark
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * 
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/load_gen.c
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/load_gen.c b/zookeeper-client/zookeeper-client-c/src/load_gen.c
new file mode 100644
index 0000000..546d5d1
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/load_gen.c
@@ -0,0 +1,282 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <zookeeper.h>
+#include "zookeeper_log.h"
+#include <errno.h>
+#ifdef THREADED 
+#include <pthread.h>
+#endif
+#include <string.h>
+#include <stdlib.h>
+
+static zhandle_t *zh;
+
+static int shutdownThisThing=0;
+
+// *****************************************************************************
+//
+static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
+
+static pthread_cond_t counterCond=PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t counterLock=PTHREAD_MUTEX_INITIALIZER;
+static int counter; 
+
+
+
+void ensureConnected(){
+    pthread_mutex_lock(&lock);
+    while (zoo_state(zh)!=ZOO_CONNECTED_STATE) {
+        pthread_cond_wait(&cond,&lock);
+    }
+    pthread_mutex_unlock(&lock);
+}
+
+void incCounter(int delta){
+    pthread_mutex_lock(&counterLock);
+    counter+=delta;
+    pthread_cond_broadcast(&counterCond);
+    pthread_mutex_unlock(&counterLock);        
+    
+}
+void setCounter(int cnt){
+    pthread_mutex_lock(&counterLock);
+    counter=cnt;
+    pthread_cond_broadcast(&counterCond);
+    pthread_mutex_unlock(&counterLock);        
+    
+}
+void waitCounter(){
+    pthread_mutex_lock(&counterLock);
+    while (counter>0) {
+        pthread_cond_wait(&counterCond,&counterLock);
+    }
+    pthread_mutex_unlock(&counterLock);    
+}
+
+void listener(zhandle_t *zzh, int type, int state, const char *path,void* ctx) {
+    if(type == ZOO_SESSION_EVENT){
+        if(state == ZOO_CONNECTED_STATE){
+            pthread_mutex_lock(&lock);
+            pthread_cond_broadcast(&cond);
+            pthread_mutex_unlock(&lock);
+        }
+        setCounter(0);
+    }
+}
+
+void create_completion(int rc, const char *name, const void *data) {
+    incCounter(-1);
+    if(rc!=ZOK){
+        LOG_ERROR(("Failed to create a node rc=%d",rc));
+    }
+}
+
+int doCreateNodes(const char* root, int count){
+    char nodeName[1024];
+    int i;
+    for(i=0; i<count;i++){
+        int rc = 0;
+        snprintf(nodeName, sizeof(nodeName),"%s/%d",root,i);
+        incCounter(1);
+        rc=zoo_acreate(zh, nodeName, "first", 5, &ZOO_OPEN_ACL_UNSAFE, 0,
+                            create_completion, 0);
+        if(i%1000==0){
+            LOG_INFO(("Created %s",nodeName));
+        }
+        if(rc!=ZOK) return rc;        
+    }
+    return ZOK;
+}
+
+int createRoot(const char* root){
+    char realpath[1024];
+    return zoo_create(zh,root,"root",4,&ZOO_OPEN_ACL_UNSAFE,0,realpath,sizeof(realpath)-1);
+}
+
+void write_completion(int rc, const struct Stat *stat, const void *data) {
+    incCounter(-1);
+    if(rc!=ZOK){
+        LOG_ERROR(("Failed to write a node rc=%d",rc));
+    }
+}
+
+int doWrites(const char* root, int count){
+    char nodeName[1024];
+    int i;
+    counter=0;
+    for(i=0; i<count;i++){
+        int rc = 0;
+        snprintf(nodeName, sizeof(nodeName),"%s/%d",root,i);
+        incCounter(1);
+        rc=zoo_aset(zh, nodeName, "second", 6,-1,write_completion, 0);
+        if(rc!=ZOK) return rc;        
+    }
+    return ZOK;
+}
+
+void read_completion(int rc, const char *value, int value_len,
+        const struct Stat *stat, const void *data) {
+    incCounter(-1);    
+    if(rc!=ZOK){
+        LOG_ERROR(("Failed to read a node rc=%d",rc));
+        return;
+    }
+    if(memcmp(value,"second",6)!=0){
+        char buf[value_len+1];
+        memcpy(buf,value,value_len);buf[value_len]=0;
+        LOG_ERROR(("Invalid read, expected [second], received [%s]\n",buf));
+        exit(1);
+    }
+}
+
+int doReads(const char* root, int count){
+    char nodeName[1024];
+    int i;
+    counter=0;
+    for(i=0; i<count;i++){
+        int rc = 0;
+        snprintf(nodeName, sizeof(nodeName),"%s/%d",root,i);
+        incCounter(1);
+        rc=zoo_aget(zh, nodeName,0,read_completion, 0);
+        if(rc!=ZOK) return rc;        
+    }
+    return ZOK;
+}
+
+void delete_completion(int rc, const void *data) {
+    incCounter(-1);    
+}
+
+int doDeletes(const char* root, int count){
+    char nodeName[1024];
+    int i;
+    counter=0;
+    for(i=0; i<count;i++){
+        int rc = 0;
+        snprintf(nodeName, sizeof(nodeName),"%s/%d",root,i);
+        incCounter(1);
+        rc=zoo_adelete(zh, nodeName,-1,delete_completion, 0);
+        if(rc!=ZOK) return rc;        
+    }
+    return ZOK;
+}
+
+static int free_String_vector(struct String_vector *v) {
+    if (v->data) {
+        int32_t i;
+        for(i=0;i<v->count; i++) {
+            free(v->data[i]);
+        }
+        free(v->data);
+        v->data = 0;
+    }
+    return 0;
+}
+
+static int deletedCounter;
+
+int recursiveDelete(const char* root){
+    struct String_vector children;
+    int i;
+    int rc=zoo_get_children(zh,root,0,&children);
+    if(rc!=ZNONODE){
+        if(rc!=ZOK){
+            LOG_ERROR(("Failed to get children of %s, rc=%d",root,rc));
+            return rc;
+        }
+        for(i=0;i<children.count; i++){
+            int rc = 0;
+            char nodeName[2048];
+            snprintf(nodeName, sizeof(nodeName),"%s/%s",root,children.data[i]);
+            rc=recursiveDelete(nodeName);
+            if(rc!=ZOK){
+                free_String_vector(&children);
+                return rc;
+            }
+        }
+        free_String_vector(&children);
+    }
+    if(deletedCounter%1000==0)
+        LOG_INFO(("Deleting %s",root));
+    rc=zoo_delete(zh,root,-1);
+    if(rc!=ZOK){
+        LOG_ERROR(("Failed to delete znode %s, rc=%d",root,rc));
+    }else
+        deletedCounter++;
+    return rc;
+}
+
+void usage(char *argv[]){
+    fprintf(stderr, "USAGE:\t%s zookeeper_host_list path #children\nor", argv[0]);
+    fprintf(stderr, "\t%s zookeeper_host_list path clean\n", argv[0]);
+    exit(0);
+}
+
+int main(int argc, char **argv) {
+    int nodeCount;
+    int cleaning=0;
+    if (argc < 4) {
+        usage(argv);
+    }
+    if(strcmp("clean",argv[3])==0){
+        cleaning=1;
+    }
+    zoo_set_debug_level(ZOO_LOG_LEVEL_INFO);
+    zoo_deterministic_conn_order(1); // enable deterministic order
+
+    zh = zookeeper_init(argv[1], listener, 10000, 0, 0, 0);
+    if (!zh)
+        return errno;
+
+    LOG_INFO(("Checking server connection..."));
+    ensureConnected();
+    if(cleaning==1){
+        int rc = 0;
+        deletedCounter=0;
+        rc=recursiveDelete(argv[2]);
+        if(rc==ZOK){
+            LOG_INFO(("Successfully deleted a subtree starting at %s (%d nodes)",
+                    argv[2],deletedCounter));
+            exit(0);
+        }
+        exit(1);
+    }
+    nodeCount=atoi(argv[3]);
+    createRoot(argv[2]);
+    while(1) {
+        ensureConnected();
+        LOG_INFO(("Creating children for path %s",argv[2]));
+        doCreateNodes(argv[2],nodeCount);
+        waitCounter();
+        
+        LOG_INFO(("Starting the write cycle for path %s",argv[2]));
+        doWrites(argv[2],nodeCount);
+        waitCounter();
+        LOG_INFO(("Starting the read cycle for path %s",argv[2]));
+        doReads(argv[2],nodeCount);
+        waitCounter();
+
+        LOG_INFO(("Starting the delete cycle for path %s",argv[2]));
+        doDeletes(argv[2],nodeCount);
+        waitCounter();
+    }
+    zookeeper_close(zh);
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/mt_adaptor.c
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/mt_adaptor.c b/zookeeper-client/zookeeper-client-c/src/mt_adaptor.c
new file mode 100644
index 0000000..52d86d5
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/mt_adaptor.c
@@ -0,0 +1,519 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef THREADED
+#define THREADED
+#endif
+
+#if !defined(DLL_EXPORT) && !defined(USE_STATIC_LIB)
+#  define USE_STATIC_LIB
+#endif
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include "zk_adaptor.h"
+#include "zookeeper_log.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <errno.h>
+
+#ifndef WIN32
+#include <signal.h>
+#include <poll.h>
+#include <unistd.h>
+#include <sys/time.h>
+#endif
+
+int zoo_lock_auth(zhandle_t *zh)
+{
+    return pthread_mutex_lock(&zh->auth_h.lock);
+}
+int zoo_unlock_auth(zhandle_t *zh)
+{
+    return pthread_mutex_unlock(&zh->auth_h.lock);
+}
+int lock_buffer_list(buffer_head_t *l)
+{
+    return pthread_mutex_lock(&l->lock);
+}
+int  unlock_buffer_list(buffer_head_t *l)
+{
+    return pthread_mutex_unlock(&l->lock);
+}
+int lock_completion_list(completion_head_t *l)
+{
+    return pthread_mutex_lock(&l->lock);
+}
+int unlock_completion_list(completion_head_t *l)
+{
+    pthread_cond_broadcast(&l->cond);
+    return pthread_mutex_unlock(&l->lock);
+}
+struct sync_completion *alloc_sync_completion(void)
+{
+    struct sync_completion *sc = (struct sync_completion*)calloc(1, sizeof(struct sync_completion));
+    if (sc) {
+       pthread_cond_init(&sc->cond, 0);
+       pthread_mutex_init(&sc->lock, 0);
+    }
+    return sc;
+}
+int wait_sync_completion(struct sync_completion *sc)
+{
+    pthread_mutex_lock(&sc->lock);
+    while (!sc->complete) {
+        pthread_cond_wait(&sc->cond, &sc->lock);
+    }
+    pthread_mutex_unlock(&sc->lock);
+    return 0;
+}
+
+void free_sync_completion(struct sync_completion *sc)
+{
+    if (sc) {
+        pthread_mutex_destroy(&sc->lock);
+        pthread_cond_destroy(&sc->cond);
+        free(sc);
+    }
+}
+
+void notify_sync_completion(struct sync_completion *sc)
+{
+    pthread_mutex_lock(&sc->lock);
+    sc->complete = 1;
+    pthread_cond_broadcast(&sc->cond);
+    pthread_mutex_unlock(&sc->lock);
+}
+
+int process_async(int outstanding_sync)
+{
+    return 0;
+}
+
+#ifdef WIN32
+unsigned __stdcall do_io( void * );
+unsigned __stdcall do_completion( void * );
+
+int handle_error(SOCKET sock, char* message)
+{
+       LOG_ERROR(("%s. %d",message, WSAGetLastError()));
+       closesocket (sock);
+       return -1;
+}
+
+//--create socket pair for interupting selects.
+int create_socket_pair(SOCKET fds[2]) 
+{ 
+    struct sockaddr_in inaddr; 
+    struct sockaddr addr; 
+    int yes=1; 
+    int len=0;
+       
+    SOCKET lst=socket(AF_INET, SOCK_STREAM,IPPROTO_TCP); 
+    if (lst ==  INVALID_SOCKET ){
+       LOG_ERROR(("Error creating socket. %d",WSAGetLastError()));
+       return -1;
+    }
+    memset(&inaddr, 0, sizeof(inaddr)); 
+    memset(&addr, 0, sizeof(addr)); 
+    inaddr.sin_family = AF_INET; 
+    inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 
+    inaddr.sin_port = 0; //--system assigns the port
+
+    if ( setsockopt(lst,SOL_SOCKET,SO_REUSEADDR,(char*)&yes,sizeof(yes)) == SOCKET_ERROR  ) {
+       return handle_error(lst,"Error trying to set socket option.");          
+    }  
+    if (bind(lst,(struct sockaddr *)&inaddr,sizeof(inaddr)) == SOCKET_ERROR){
+       return handle_error(lst,"Error trying to bind socket.");                
+    }
+    if (listen(lst,1) == SOCKET_ERROR){
+       return handle_error(lst,"Error trying to listen on socket.");
+    }
+    len=sizeof(inaddr); 
+    getsockname(lst, &addr,&len); 
+    fds[0]=socket(AF_INET, SOCK_STREAM,0); 
+    if (connect(fds[0],&addr,len) == SOCKET_ERROR){
+       return handle_error(lst, "Error while connecting to socket.");
+    }
+    if ((fds[1]=accept(lst,0,0)) == INVALID_SOCKET){
+       closesocket(fds[0]);
+       return handle_error(lst, "Error while accepting socket connection.");
+    }
+    closesocket(lst);  
+    return 0;
+} 
+#else
+void *do_io(void *);
+void *do_completion(void *);
+#endif
+
+
+int wakeup_io_thread(zhandle_t *zh);
+
+#ifdef WIN32
+static int set_nonblock(SOCKET fd){
+    ULONG nonblocking_flag = 1;
+    if (ioctlsocket(fd, FIONBIO, &nonblocking_flag) == 0)
+        return 1;
+    else 
+        return -1;
+}
+#else
+static int set_nonblock(int fd){
+    long l = fcntl(fd, F_GETFL);
+    if(l & O_NONBLOCK) return 0;
+    return fcntl(fd, F_SETFL, l | O_NONBLOCK);
+}
+#endif
+
+void wait_for_others(zhandle_t* zh)
+{
+    struct adaptor_threads* adaptor=zh->adaptor_priv;
+    pthread_mutex_lock(&adaptor->lock);
+    while(adaptor->threadsToWait>0) 
+        pthread_cond_wait(&adaptor->cond,&adaptor->lock);
+    pthread_mutex_unlock(&adaptor->lock);    
+}
+
+void notify_thread_ready(zhandle_t* zh)
+{
+    struct adaptor_threads* adaptor=zh->adaptor_priv;
+    pthread_mutex_lock(&adaptor->lock);
+    adaptor->threadsToWait--;
+    pthread_cond_broadcast(&adaptor->cond);
+    while(adaptor->threadsToWait>0) 
+        pthread_cond_wait(&adaptor->cond,&adaptor->lock);
+    pthread_mutex_unlock(&adaptor->lock);
+}
+
+
+void start_threads(zhandle_t* zh)
+{
+    int rc = 0;
+    struct adaptor_threads* adaptor=zh->adaptor_priv;
+    pthread_cond_init(&adaptor->cond,0);
+    pthread_mutex_init(&adaptor->lock,0);
+    adaptor->threadsToWait=2;  // wait for 2 threads before opening the barrier
+    
+    // use api_prolog() to make sure zhandle doesn't get destroyed
+    // while initialization is in progress
+    api_prolog(zh);
+    LOG_DEBUG(("starting threads..."));
+    rc=pthread_create(&adaptor->io, 0, do_io, zh);
+    assert("pthread_create() failed for the IO thread"&&!rc);
+    rc=pthread_create(&adaptor->completion, 0, do_completion, zh);
+    assert("pthread_create() failed for the completion thread"&&!rc);
+    wait_for_others(zh);
+    api_epilog(zh, 0);    
+}
+
+int adaptor_init(zhandle_t *zh)
+{
+    pthread_mutexattr_t recursive_mx_attr;
+    struct adaptor_threads *adaptor_threads = calloc(1, sizeof(*adaptor_threads));
+    if (!adaptor_threads) {
+        LOG_ERROR(("Out of memory"));
+        return -1;
+    }
+
+    /* We use a pipe for interrupting select() in unix/sol and socketpair in windows. */
+#ifdef WIN32   
+    if (create_socket_pair(adaptor_threads->self_pipe) == -1){
+       LOG_ERROR(("Can't make a socket."));
+#else
+    if(pipe(adaptor_threads->self_pipe)==-1) {
+        LOG_ERROR(("Can't make a pipe %d",errno));
+#endif
+        free(adaptor_threads);
+        return -1;
+    }
+    set_nonblock(adaptor_threads->self_pipe[1]);
+    set_nonblock(adaptor_threads->self_pipe[0]);
+
+    pthread_mutex_init(&zh->auth_h.lock,0);
+
+    zh->adaptor_priv = adaptor_threads;
+    pthread_mutex_init(&zh->to_process.lock,0);
+    pthread_mutex_init(&adaptor_threads->zh_lock,0);
+    // to_send must be recursive mutex    
+    pthread_mutexattr_init(&recursive_mx_attr);
+    pthread_mutexattr_settype(&recursive_mx_attr, PTHREAD_MUTEX_RECURSIVE);
+    pthread_mutex_init(&zh->to_send.lock,&recursive_mx_attr);
+    pthread_mutexattr_destroy(&recursive_mx_attr);
+    
+    pthread_mutex_init(&zh->sent_requests.lock,0);
+    pthread_cond_init(&zh->sent_requests.cond,0);
+    pthread_mutex_init(&zh->completions_to_process.lock,0);
+    pthread_cond_init(&zh->completions_to_process.cond,0);
+    start_threads(zh);
+    return 0;
+}
+
+void adaptor_finish(zhandle_t *zh)
+{
+    struct adaptor_threads *adaptor_threads;
+    // make sure zh doesn't get destroyed until after we're done here
+    api_prolog(zh); 
+    adaptor_threads = zh->adaptor_priv;
+    if(adaptor_threads==0) {
+        api_epilog(zh,0);
+        return;
+    }
+
+    if(!pthread_equal(adaptor_threads->io,pthread_self())){
+        wakeup_io_thread(zh);
+        pthread_join(adaptor_threads->io, 0);
+    }else
+        pthread_detach(adaptor_threads->io);
+    
+    if(!pthread_equal(adaptor_threads->completion,pthread_self())){
+        pthread_mutex_lock(&zh->completions_to_process.lock);
+        pthread_cond_broadcast(&zh->completions_to_process.cond);
+        pthread_mutex_unlock(&zh->completions_to_process.lock);
+        pthread_join(adaptor_threads->completion, 0);
+    }else
+        pthread_detach(adaptor_threads->completion);
+    
+    api_epilog(zh,0);
+}
+
+void adaptor_destroy(zhandle_t *zh)
+{
+    struct adaptor_threads *adaptor = zh->adaptor_priv;
+    if(adaptor==0) return;
+    
+    pthread_cond_destroy(&adaptor->cond);
+    pthread_mutex_destroy(&adaptor->lock);
+    pthread_mutex_destroy(&zh->to_process.lock);
+    pthread_mutex_destroy(&zh->to_send.lock);
+    pthread_mutex_destroy(&zh->sent_requests.lock);
+    pthread_cond_destroy(&zh->sent_requests.cond);
+    pthread_mutex_destroy(&zh->completions_to_process.lock);
+    pthread_cond_destroy(&zh->completions_to_process.cond);
+    pthread_mutex_destroy(&adaptor->zh_lock);
+
+    pthread_mutex_destroy(&zh->auth_h.lock);
+
+    close(adaptor->self_pipe[0]);
+    close(adaptor->self_pipe[1]);
+    free(adaptor);
+    zh->adaptor_priv=0;
+}
+
+int wakeup_io_thread(zhandle_t *zh)
+{
+    struct adaptor_threads *adaptor_threads = zh->adaptor_priv;
+    char c=0;
+#ifndef WIN32
+    return write(adaptor_threads->self_pipe[1],&c,1)==1? ZOK: ZSYSTEMERROR;    
+#else
+    return send(adaptor_threads->self_pipe[1], &c, 1, 0)==1? ZOK: ZSYSTEMERROR;    
+#endif         
+}
+
+int adaptor_send_queue(zhandle_t *zh, int timeout)
+{
+    if(!zh->close_requested)
+        return wakeup_io_thread(zh);
+    // don't rely on the IO thread to send the messages if the app has
+    // requested to close 
+    return flush_send_queue(zh, timeout);
+}
+
+/* These two are declared here because we will run the event loop
+ * and not the client */
+#ifdef WIN32
+int zookeeper_interest(zhandle_t *zh, SOCKET *fd, int *interest,
+        struct timeval *tv);
+#else
+int zookeeper_interest(zhandle_t *zh, int *fd, int *interest,
+        struct timeval *tv);
+#endif
+int zookeeper_process(zhandle_t *zh, int events);
+
+#ifdef WIN32
+unsigned __stdcall do_io( void * v)
+#else
+void *do_io(void *v)
+#endif
+{
+    zhandle_t *zh = (zhandle_t*)v;
+#ifndef WIN32
+    struct pollfd fds[2];
+    struct adaptor_threads *adaptor_threads = zh->adaptor_priv;
+
+    api_prolog(zh);
+    notify_thread_ready(zh);
+    LOG_DEBUG(("started IO thread"));
+    fds[0].fd=adaptor_threads->self_pipe[0];
+    fds[0].events=POLLIN;
+    while(!zh->close_requested) {
+        struct timeval tv;
+        int fd;
+        int interest;
+        int timeout;
+        int maxfd=1;
+
+        zookeeper_interest(zh, &fd, &interest, &tv);
+        if (fd != -1) {
+            fds[1].fd=fd;
+            fds[1].events=(interest&ZOOKEEPER_READ)?POLLIN:0;
+            fds[1].events|=(interest&ZOOKEEPER_WRITE)?POLLOUT:0;
+            maxfd=2;
+        }
+        timeout=tv.tv_sec * 1000 + (tv.tv_usec/1000);
+        
+        poll(fds,maxfd,timeout);
+        if (fd != -1) {
+            interest=(fds[1].revents&POLLIN)?ZOOKEEPER_READ:0;
+            interest|=((fds[1].revents&POLLOUT)||(fds[1].revents&POLLHUP))?ZOOKEEPER_WRITE:0;
+        }
+        if(fds[0].revents&POLLIN){
+            // flush the pipe
+            char b[128];
+            while(read(adaptor_threads->self_pipe[0],b,sizeof(b))==sizeof(b)){}
+        }        
+#else
+    fd_set rfds, wfds, efds;
+    struct adaptor_threads *adaptor_threads = zh->adaptor_priv;
+    api_prolog(zh);
+    notify_thread_ready(zh);
+    LOG_DEBUG(("started IO thread"));
+    FD_ZERO(&rfds);   FD_ZERO(&wfds);    FD_ZERO(&efds);
+    while(!zh->close_requested) {      
+        struct timeval tv;
+        SOCKET fd;
+        SOCKET maxfd=adaptor_threads->self_pipe[0];
+        int interest;        
+        int rc;
+               
+       zookeeper_interest(zh, &fd, &interest, &tv);
+       if (fd != -1) {
+           if (interest&ZOOKEEPER_READ) {
+                FD_SET(fd, &rfds);
+            } else {
+                FD_CLR(fd, &rfds);
+            }
+           if (interest&ZOOKEEPER_WRITE) {
+                FD_SET(fd, &wfds);
+            } else {
+                FD_CLR(fd, &wfds);
+            }                  
+        }
+       FD_SET( adaptor_threads->self_pipe[0] ,&rfds );        
+       rc = select((int)maxfd, &rfds, &wfds, &efds, &tv);
+       if (fd != -1) 
+       {
+           interest = (FD_ISSET(fd, &rfds))? ZOOKEEPER_READ:0;
+           interest|= (FD_ISSET(fd, &wfds))? ZOOKEEPER_WRITE:0;
+        }
+               
+       if (FD_ISSET(adaptor_threads->self_pipe[0], &rfds)){
+            // flush the pipe/socket
+            char b[128];
+           while(recv(adaptor_threads->self_pipe[0],b,sizeof(b), 0)==sizeof(b)){}
+       }
+#endif
+        // dispatch zookeeper events
+        zookeeper_process(zh, interest);
+        // check the current state of the zhandle and terminate 
+        // if it is_unrecoverable()
+        if(is_unrecoverable(zh))
+            break;
+    }
+    api_epilog(zh, 0);    
+    LOG_DEBUG(("IO thread terminated"));
+    return 0;
+}
+
+#ifdef WIN32
+unsigned __stdcall do_completion( void * v)
+#else
+void *do_completion(void *v)
+#endif
+{
+    zhandle_t *zh = v;
+    api_prolog(zh);
+    notify_thread_ready(zh);
+    LOG_DEBUG(("started completion thread"));
+    while(!zh->close_requested) {
+        pthread_mutex_lock(&zh->completions_to_process.lock);
+        while(!zh->completions_to_process.head && !zh->close_requested) {
+            pthread_cond_wait(&zh->completions_to_process.cond, &zh->completions_to_process.lock);
+        }
+        pthread_mutex_unlock(&zh->completions_to_process.lock);
+        process_completions(zh);
+    }
+    api_epilog(zh, 0);    
+    LOG_DEBUG(("completion thread terminated"));
+    return 0;
+}
+
+int32_t inc_ref_counter(zhandle_t* zh,int i)
+{
+    int incr=(i<0?-1:(i>0?1:0));
+    // fetch_and_add implements atomic post-increment
+    int v=fetch_and_add(&zh->ref_counter,incr);
+    // inc_ref_counter wants pre-increment
+    v+=incr;   // simulate pre-increment
+    return v;
+}
+
+int32_t fetch_and_add(volatile int32_t* operand, int incr)
+{
+#ifndef WIN32
+    return __sync_fetch_and_add(operand, incr);
+#else
+    return InterlockedExchangeAdd(operand, incr);
+#endif
+}
+
+// make sure the static xid is initialized before any threads started
+__attribute__((constructor)) int32_t get_xid()
+{
+    static int32_t xid = -1;
+    if (xid == -1) {
+        xid = time(0);
+    }
+    return fetch_and_add(&xid,1);
+}
+
+int enter_critical(zhandle_t* zh)
+{
+    struct adaptor_threads *adaptor = zh->adaptor_priv;
+    if (adaptor) {
+        return pthread_mutex_lock(&adaptor->zh_lock);
+    } else {
+        return 0;
+    }
+}
+
+int leave_critical(zhandle_t* zh)
+{
+    struct adaptor_threads *adaptor = zh->adaptor_priv;
+    if (adaptor) {
+        return pthread_mutex_unlock(&adaptor->zh_lock);
+    } else {
+        return 0;
+    }
+}


[15/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/zookeeper.c
----------------------------------------------------------------------
diff --git a/src/c/src/zookeeper.c b/src/c/src/zookeeper.c
deleted file mode 100644
index c087864..0000000
--- a/src/c/src/zookeeper.c
+++ /dev/null
@@ -1,3767 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#if !defined(DLL_EXPORT) && !defined(USE_STATIC_LIB)
-#  define USE_STATIC_LIB
-#endif
-
-#if defined(__CYGWIN__)
-#define USE_IPV6
-#endif
-
-#include "config.h"
-#include <zookeeper.h>
-#include <zookeeper.jute.h>
-#include <proto.h>
-#include "zk_adaptor.h"
-#include "zookeeper_log.h"
-#include "zk_hashtable.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <stdarg.h>
-#include <limits.h>
-
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#ifdef HAVE_POLL
-#include <poll.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#endif
-
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h> // needed for _POSIX_MONOTONIC_CLOCK
-#endif
-
-#ifdef HAVE_SYS_UTSNAME_H
-#include <sys/utsname.h>
-#endif
-
-#ifdef HAVE_GETPWUID_R
-#include <pwd.h>
-#endif
-
-#ifdef WIN32
-#define random rand /* replace POSIX random with Windows rand */
-#include <process.h> /* for getpid */
-#include <direct.h> /* for getcwd */
-#define EAI_ADDRFAMILY WSAEINVAL /* is this still needed? */
-#define EHOSTDOWN EPIPE
-#define ESTALE ENODEV
-#endif
-
-#define IF_DEBUG(x) if(logLevel==ZOO_LOG_LEVEL_DEBUG) {x;}
-
-const int ZOOKEEPER_WRITE = 1 << 0;
-const int ZOOKEEPER_READ = 1 << 1;
-
-const int ZOO_EPHEMERAL = 1 << 0;
-const int ZOO_SEQUENCE = 1 << 1;
-
-const int ZOO_EXPIRED_SESSION_STATE = EXPIRED_SESSION_STATE_DEF;
-const int ZOO_AUTH_FAILED_STATE = AUTH_FAILED_STATE_DEF;
-const int ZOO_CONNECTING_STATE = CONNECTING_STATE_DEF;
-const int ZOO_ASSOCIATING_STATE = ASSOCIATING_STATE_DEF;
-const int ZOO_CONNECTED_STATE = CONNECTED_STATE_DEF;
-static __attribute__ ((unused)) const char* state2String(int state){
-    switch(state){
-    case 0:
-        return "ZOO_CLOSED_STATE";
-    case CONNECTING_STATE_DEF:
-        return "ZOO_CONNECTING_STATE";
-    case ASSOCIATING_STATE_DEF:
-        return "ZOO_ASSOCIATING_STATE";
-    case CONNECTED_STATE_DEF:
-        return "ZOO_CONNECTED_STATE";
-    case EXPIRED_SESSION_STATE_DEF:
-        return "ZOO_EXPIRED_SESSION_STATE";
-    case AUTH_FAILED_STATE_DEF:
-        return "ZOO_AUTH_FAILED_STATE";
-    }
-    return "INVALID_STATE";
-}
-
-const int ZOO_CREATED_EVENT = CREATED_EVENT_DEF;
-const int ZOO_DELETED_EVENT = DELETED_EVENT_DEF;
-const int ZOO_CHANGED_EVENT = CHANGED_EVENT_DEF;
-const int ZOO_CHILD_EVENT = CHILD_EVENT_DEF;
-const int ZOO_SESSION_EVENT = SESSION_EVENT_DEF;
-const int ZOO_NOTWATCHING_EVENT = NOTWATCHING_EVENT_DEF;
-static __attribute__ ((unused)) const char* watcherEvent2String(int ev){
-    switch(ev){
-    case 0:
-        return "ZOO_ERROR_EVENT";
-    case CREATED_EVENT_DEF:
-        return "ZOO_CREATED_EVENT";
-    case DELETED_EVENT_DEF:
-        return "ZOO_DELETED_EVENT";
-    case CHANGED_EVENT_DEF:
-        return "ZOO_CHANGED_EVENT";
-    case CHILD_EVENT_DEF:
-        return "ZOO_CHILD_EVENT";
-    case SESSION_EVENT_DEF:
-        return "ZOO_SESSION_EVENT";
-    case NOTWATCHING_EVENT_DEF:
-        return "ZOO_NOTWATCHING_EVENT";
-    }
-    return "INVALID_EVENT";
-}
-
-const int ZOO_PERM_READ = 1 << 0;
-const int ZOO_PERM_WRITE = 1 << 1;
-const int ZOO_PERM_CREATE = 1 << 2;
-const int ZOO_PERM_DELETE = 1 << 3;
-const int ZOO_PERM_ADMIN = 1 << 4;
-const int ZOO_PERM_ALL = 0x1f;
-struct Id ZOO_ANYONE_ID_UNSAFE = {"world", "anyone"};
-struct Id ZOO_AUTH_IDS = {"auth", ""};
-static struct ACL _OPEN_ACL_UNSAFE_ACL[] = {{0x1f, {"world", "anyone"}}};
-static struct ACL _READ_ACL_UNSAFE_ACL[] = {{0x01, {"world", "anyone"}}};
-static struct ACL _CREATOR_ALL_ACL_ACL[] = {{0x1f, {"auth", ""}}};
-struct ACL_vector ZOO_OPEN_ACL_UNSAFE = { 1, _OPEN_ACL_UNSAFE_ACL};
-struct ACL_vector ZOO_READ_ACL_UNSAFE = { 1, _READ_ACL_UNSAFE_ACL};
-struct ACL_vector ZOO_CREATOR_ALL_ACL = { 1, _CREATOR_ALL_ACL_ACL};
-
-#define COMPLETION_WATCH -1
-#define COMPLETION_VOID 0
-#define COMPLETION_STAT 1
-#define COMPLETION_DATA 2
-#define COMPLETION_STRINGLIST 3
-#define COMPLETION_STRINGLIST_STAT 4
-#define COMPLETION_ACLLIST 5
-#define COMPLETION_STRING 6
-#define COMPLETION_MULTI 7
-
-typedef struct _auth_completion_list {
-    void_completion_t completion;
-    const char *auth_data;
-    struct _auth_completion_list *next;
-} auth_completion_list_t;
-
-typedef struct completion {
-    int type; /* one of COMPLETION_* values above */
-    union {
-        void_completion_t void_result;
-        stat_completion_t stat_result;
-        data_completion_t data_result;
-        strings_completion_t strings_result;
-        strings_stat_completion_t strings_stat_result;
-        acl_completion_t acl_result;
-        string_completion_t string_result;
-        struct watcher_object_list *watcher_result;
-    };
-    completion_head_t clist; /* For multi-op */
-} completion_t;
-
-typedef struct _completion_list {
-    int xid;
-    completion_t c;
-    const void *data;
-    buffer_list_t *buffer;
-    struct _completion_list *next;
-    watcher_registration_t* watcher;
-} completion_list_t;
-
-const char*err2string(int err);
-static int queue_session_event(zhandle_t *zh, int state);
-static const char* format_endpoint_info(const struct sockaddr_storage* ep);
-static const char* format_current_endpoint_info(zhandle_t* zh);
-
-/* deserialize forward declarations */
-static void deserialize_response(int type, int xid, int failed, int rc, completion_list_t *cptr, struct iarchive *ia);
-static int deserialize_multi(int xid, completion_list_t *cptr, struct iarchive *ia);
-
-/* completion routine forward declarations */
-static int add_completion(zhandle_t *zh, int xid, int completion_type,
-        const void *dc, const void *data, int add_to_front, 
-        watcher_registration_t* wo, completion_head_t *clist);
-static completion_list_t* create_completion_entry(int xid, int completion_type,
-        const void *dc, const void *data, watcher_registration_t* wo, 
-        completion_head_t *clist);
-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);
-
-static int disable_conn_permute=0; // permute enabled by default
-
-static __attribute__((unused)) void print_completion_queue(zhandle_t *zh);
-
-static void *SYNCHRONOUS_MARKER = (void*)&SYNCHRONOUS_MARKER;
-static int isValidPath(const char* path, const int flags);
-
-#ifdef _WINDOWS
-static int zookeeper_send(SOCKET s, const char* buf, int len)
-#else
-static ssize_t zookeeper_send(int s, const void* buf, size_t len)
-#endif
-{
-#ifdef __linux__
-  return send(s, buf, len, MSG_NOSIGNAL);
-#else
-  return send(s, buf, len, 0);
-#endif
-}
-
-const void *zoo_get_context(zhandle_t *zh)
-{
-    return zh->context;
-}
-
-void zoo_set_context(zhandle_t *zh, void *context)
-{
-    if (zh != NULL) {
-        zh->context = context;
-    }
-}
-
-int zoo_recv_timeout(zhandle_t *zh)
-{
-    return zh->recv_timeout;
-}
-
-/** these functions are thread unsafe, so make sure that
-    zoo_lock_auth is called before you access them **/
-static auth_info* get_last_auth(auth_list_head_t *auth_list) {
-    auth_info *element;
-    element = auth_list->auth;
-    if (element == NULL) {
-        return NULL;
-    }
-    while (element->next != NULL) {
-        element = element->next;
-    }
-    return element;
-}
-
-static void free_auth_completion(auth_completion_list_t *a_list) {
-    auth_completion_list_t *tmp, *ftmp;
-    if (a_list == NULL) {
-        return;
-    }
-    tmp = a_list->next;
-    while (tmp != NULL) {
-        ftmp = tmp;
-        tmp = tmp->next;
-        ftmp->completion = NULL;
-        ftmp->auth_data = NULL;
-        free(ftmp);
-    }
-    a_list->completion = NULL;
-    a_list->auth_data = NULL;
-    a_list->next = NULL;
-    return;
-}
-
-static void add_auth_completion(auth_completion_list_t* a_list, void_completion_t* completion,
-                                const char *data) {
-    auth_completion_list_t *element;
-    auth_completion_list_t *n_element;
-    element = a_list;
-    if (a_list->completion == NULL) {
-        //this is the first element
-        a_list->completion = *completion;
-        a_list->next = NULL;
-        a_list->auth_data = data;
-        return;
-    }
-    while (element->next != NULL) {
-        element = element->next;
-    }
-    n_element = (auth_completion_list_t*) malloc(sizeof(auth_completion_list_t));
-    n_element->next = NULL;
-    n_element->completion = *completion;
-    n_element->auth_data = data;
-    element->next = n_element;
-    return;
-}
-
-static void get_auth_completions(auth_list_head_t *auth_list, auth_completion_list_t *a_list) {
-    auth_info *element;
-    element = auth_list->auth;
-    if (element == NULL) {
-        return;
-    }
-    while (element) {
-        if (element->completion) {
-            add_auth_completion(a_list, &element->completion, element->data);
-        }
-        element->completion = NULL;
-        element = element->next;
-    }
-    return;
-}
-
-static void add_last_auth(auth_list_head_t *auth_list, auth_info *add_el) {
-    auth_info  *element;
-    element = auth_list->auth;
-    if (element == NULL) {
-        //first element in the list
-        auth_list->auth = add_el;
-        return;
-    }
-    while (element->next != NULL) {
-        element = element->next;
-    }
-    element->next = add_el;
-    return;
-}
-
-static void init_auth_info(auth_list_head_t *auth_list)
-{
-    auth_list->auth = NULL;
-}
-
-static void mark_active_auth(zhandle_t *zh) {
-    auth_list_head_t auth_h = zh->auth_h;
-    auth_info *element;
-    if (auth_h.auth == NULL) {
-        return;
-    }
-    element = auth_h.auth;
-    while (element != NULL) {
-        element->state = 1;
-        element = element->next;
-    }
-}
-
-static void free_auth_info(auth_list_head_t *auth_list)
-{
-    auth_info *auth = auth_list->auth;
-    while (auth != NULL) {
-        auth_info* old_auth = NULL;
-        if(auth->scheme!=NULL)
-            free(auth->scheme);
-        deallocate_Buffer(&auth->auth);
-        old_auth = auth;
-        auth = auth->next;
-        free(old_auth);
-    }
-    init_auth_info(auth_list);
-}
-
-int is_unrecoverable(zhandle_t *zh)
-{
-    return (zh->state<0)? ZINVALIDSTATE: ZOK;
-}
-
-zk_hashtable *exists_result_checker(zhandle_t *zh, int rc)
-{
-    if (rc == ZOK) {
-        return zh->active_node_watchers;
-    } else if (rc == ZNONODE) {
-        return zh->active_exist_watchers;
-    }
-    return 0;
-}
-
-zk_hashtable *data_result_checker(zhandle_t *zh, int rc)
-{
-    return rc==ZOK ? zh->active_node_watchers : 0;
-}
-
-zk_hashtable *child_result_checker(zhandle_t *zh, int rc)
-{
-    return rc==ZOK ? zh->active_child_watchers : 0;
-}
-
-/**
- * Frees and closes everything associated with a handle,
- * including the handle itself.
- */
-static void destroy(zhandle_t *zh)
-{
-    if (zh == NULL) {
-        return;
-    }
-    /* call any outstanding completions with a special error code */
-    cleanup_bufs(zh,1,ZCLOSING);
-    if (zh->hostname != 0) {
-        free(zh->hostname);
-        zh->hostname = NULL;
-    }
-    if (zh->fd != -1) {
-        close(zh->fd);
-        zh->fd = -1;
-        zh->state = 0;
-    }
-    if (zh->addrs != 0) {
-        free(zh->addrs);
-        zh->addrs = NULL;
-    }
-
-    if (zh->chroot != 0) {
-        free(zh->chroot);
-        zh->chroot = NULL;
-    }
-
-    free_auth_info(&zh->auth_h);
-    destroy_zk_hashtable(zh->active_node_watchers);
-    destroy_zk_hashtable(zh->active_exist_watchers);
-    destroy_zk_hashtable(zh->active_child_watchers);
-}
-
-static void setup_random()
-{
-#ifndef WIN32          // TODO: better seed
-    int seed;
-    int fd = open("/dev/urandom", O_RDONLY);
-    if (fd == -1) {
-        seed = getpid();
-    } else {
-        int seed_len = 0;
-
-        /* Enter a loop to fill in seed with random data from /dev/urandom.
-         * This is done in a loop so that we can safely handle short reads
-         * which can happen due to signal interruptions.
-         */
-        while (seed_len < sizeof(seed)) {
-            /* Assert we either read something or we were interrupted due to a
-             * signal (errno == EINTR) in which case we need to retry.
-             */
-            int rc = read(fd, &seed + seed_len, sizeof(seed) - seed_len);
-            assert(rc > 0 || errno == EINTR);
-            if (rc > 0) {
-                seed_len += rc;
-            }
-        }
-        close(fd);
-    }
-    srandom(seed);
-#endif
-}
-
-#ifndef __CYGWIN__
-/**
- * get the errno from the return code 
- * of get addrinfo. Errno is not set
- * with the call to getaddrinfo, so thats
- * why we have to do this.
- */
-static int getaddrinfo_errno(int rc) { 
-    switch(rc) {
-    case EAI_NONAME:
-// ZOOKEEPER-1323 EAI_NODATA and EAI_ADDRFAMILY are deprecated in FreeBSD.
-#if defined EAI_NODATA && EAI_NODATA != EAI_NONAME
-    case EAI_NODATA:
-#endif
-        return ENOENT;
-    case EAI_MEMORY:
-        return ENOMEM;
-    default:
-        return EINVAL;
-    }
-}
-#endif
-
-/**
- * fill in the addrs array of the zookeeper servers in the zhandle. after filling
- * them in, we will permute them for load balancing.
- */
-int getaddrs(zhandle_t *zh)
-{
-    char *hosts = strdup(zh->hostname);
-    char *host;
-    char *strtok_last;
-    struct sockaddr_storage *addr;
-    int i;
-    int rc;
-    int alen = 0; /* the allocated length of the addrs array */
-
-    zh->addrs_count = 0;
-    if (zh->addrs) {
-        free(zh->addrs);
-        zh->addrs = 0;
-    }
-    if (!hosts) {
-         LOG_ERROR(("out of memory"));
-        errno=ENOMEM;
-        return ZSYSTEMERROR;
-    }
-    zh->addrs = 0;
-    host=strtok_r(hosts, ",", &strtok_last);
-    while(host) {
-        char *port_spec = strrchr(host, ':');
-        char *end_port_spec;
-        int port;
-        if (!port_spec) {
-            LOG_ERROR(("no port in %s", host));
-            errno=EINVAL;
-            rc=ZBADARGUMENTS;
-            goto fail;
-        }
-        *port_spec = '\0';
-        port_spec++;
-        port = strtol(port_spec, &end_port_spec, 0);
-        if (!*port_spec || *end_port_spec || port == 0) {
-            LOG_ERROR(("invalid port in %s", host));
-            errno=EINVAL;
-            rc=ZBADARGUMENTS;
-            goto fail;
-        }
-#if defined(__CYGWIN__)
-        // sadly CYGWIN doesn't have getaddrinfo
-        // but happily gethostbyname is threadsafe in windows
-        {
-        struct hostent *he;
-        char **ptr;
-        struct sockaddr_in *addr4;
-
-        he = gethostbyname(host);
-        if (!he) {
-            LOG_ERROR(("could not resolve %s", host));
-            errno=ENOENT;
-            rc=ZBADARGUMENTS;
-            goto fail;
-        }
-
-        /* Setup the address array */
-        for(ptr = he->h_addr_list;*ptr != 0; ptr++) {
-            if (zh->addrs_count == alen) {
-                alen += 16;
-                zh->addrs = realloc(zh->addrs, sizeof(*zh->addrs)*alen);
-                if (zh->addrs == 0) {
-                    LOG_ERROR(("out of memory"));
-                    errno=ENOMEM;
-                    rc=ZSYSTEMERROR;
-                    goto fail;
-                }
-            }
-            addr = &zh->addrs[zh->addrs_count];
-            addr4 = (struct sockaddr_in*)addr;
-            addr->ss_family = he->h_addrtype;
-            if (addr->ss_family == AF_INET) {
-                addr4->sin_port = htons(port);
-                memset(&addr4->sin_zero, 0, sizeof(addr4->sin_zero));
-                memcpy(&addr4->sin_addr, *ptr, he->h_length);
-                zh->addrs_count++;
-            }
-#if defined(AF_INET6)
-            else if (addr->ss_family == AF_INET6) {
-                struct sockaddr_in6 *addr6;
-
-                addr6 = (struct sockaddr_in6*)addr;
-                addr6->sin6_port = htons(port);
-                addr6->sin6_scope_id = 0;
-                addr6->sin6_flowinfo = 0;
-                memcpy(&addr6->sin6_addr, *ptr, he->h_length);
-                zh->addrs_count++;
-            }
-#endif
-            else {
-                LOG_WARN(("skipping unknown address family %x for %s",
-                         addr->ss_family, zh->hostname));
-            }
-        }
-        host = strtok_r(0, ",", &strtok_last);
-        }
-#else
-        {
-        struct addrinfo hints, *res, *res0;
-
-        memset(&hints, 0, sizeof(hints));
-#ifdef AI_ADDRCONFIG
-        hints.ai_flags = AI_ADDRCONFIG;
-#else
-        hints.ai_flags = 0;
-#endif
-        hints.ai_family = AF_UNSPEC;
-        hints.ai_socktype = SOCK_STREAM;
-        hints.ai_protocol = IPPROTO_TCP;
-
-        while(isspace(*host) && host != strtok_last)
-            host++;
-
-        if ((rc = getaddrinfo(host, port_spec, &hints, &res0)) != 0) {
-            //bug in getaddrinfo implementation when it returns
-            //EAI_BADFLAGS or EAI_ADDRFAMILY with AF_UNSPEC and 
-            // ai_flags as AI_ADDRCONFIG
-#ifdef AI_ADDRCONFIG
-            if ((hints.ai_flags == AI_ADDRCONFIG) && 
-// ZOOKEEPER-1323 EAI_NODATA and EAI_ADDRFAMILY are deprecated in FreeBSD.
-#ifdef EAI_ADDRFAMILY
-                ((rc ==EAI_BADFLAGS) || (rc == EAI_ADDRFAMILY))) {
-#else
-                (rc == EAI_BADFLAGS)) {
-#endif
-                //reset ai_flags to null
-                hints.ai_flags = 0;
-                //retry getaddrinfo
-                rc = getaddrinfo(host, port_spec, &hints, &res0);
-            }
-#endif
-            if (rc != 0) {
-                errno = getaddrinfo_errno(rc);
-#ifdef WIN32
-                LOG_ERROR(("Win32 message: %s\n", gai_strerror(rc)));
-#else
-                LOG_ERROR(("getaddrinfo: %s\n", strerror(errno)));
-#endif
-                rc=ZSYSTEMERROR;
-                goto fail;
-            }
-        }
-
-        for (res = res0; res; res = res->ai_next) {
-            // Expand address list if needed
-            if (zh->addrs_count == alen) {
-                void *tmpaddr;
-                alen += 16;
-                tmpaddr = realloc(zh->addrs, sizeof(*zh->addrs)*alen);
-                if (tmpaddr == 0) {
-                    LOG_ERROR(("out of memory"));
-                    errno=ENOMEM;
-                    rc=ZSYSTEMERROR;
-                    goto fail;
-                }
-                zh->addrs=tmpaddr;
-            }
-
-            // Copy addrinfo into address list
-            addr = &zh->addrs[zh->addrs_count];
-            switch (res->ai_family) {
-            case AF_INET:
-#if defined(AF_INET6)
-            case AF_INET6:
-#endif
-                memcpy(addr, res->ai_addr, res->ai_addrlen);
-                ++zh->addrs_count;
-                break;
-            default:
-                LOG_WARN(("skipping unknown address family %x for %s",
-                res->ai_family, zh->hostname));
-                break;
-            }
-        }
-
-        freeaddrinfo(res0);
-
-        host = strtok_r(0, ",", &strtok_last);
-        }
-#endif
-    }
-    free(hosts);
-
-    if(!disable_conn_permute){
-        setup_random();
-        /* Permute */
-        for (i = zh->addrs_count - 1; i > 0; --i) {
-            long int j = random()%(i+1);
-            if (i != j) {
-                struct sockaddr_storage t = zh->addrs[i];
-                zh->addrs[i] = zh->addrs[j];
-                zh->addrs[j] = t;
-            }
-        }
-    }
-    return ZOK;
-fail:
-    if (zh->addrs) {
-        free(zh->addrs);
-        zh->addrs=0;
-    }
-    if (hosts) {
-        free(hosts);
-    }
-    return rc;
-}
-
-const clientid_t *zoo_client_id(zhandle_t *zh)
-{
-    return &zh->client_id;
-}
-
-static void null_watcher_fn(zhandle_t* p1, int p2, int p3,const char* p4,void*p5){}
-
-watcher_fn zoo_set_watcher(zhandle_t *zh,watcher_fn newFn)
-{
-    watcher_fn oldWatcher=zh->watcher;
-    if (newFn) {
-       zh->watcher = newFn;
-    } else {
-       zh->watcher = null_watcher_fn;
-    }
-    return oldWatcher;
-}
-
-struct sockaddr* zookeeper_get_connected_host(zhandle_t *zh,
-                 struct sockaddr *addr, socklen_t *addr_len)
-{
-    if (zh->state!=ZOO_CONNECTED_STATE) {
-        return NULL;
-    }
-    if (getpeername(zh->fd, addr, addr_len)==-1) {
-        return NULL;
-    }
-    return addr;
-}
-
-static void log_env() {
-  char buf[2048];
-#ifdef HAVE_SYS_UTSNAME_H
-  struct utsname utsname;
-#endif
-
-#if defined(HAVE_GETUID) && defined(HAVE_GETPWUID_R)
-  struct passwd pw;
-  struct passwd *pwp = NULL;
-  uid_t uid = 0;
-#endif
-
-  LOG_INFO(("Client environment:zookeeper.version=%s", PACKAGE_STRING));
-
-#ifdef HAVE_GETHOSTNAME
-  gethostname(buf, sizeof(buf));
-  LOG_INFO(("Client environment:host.name=%s", buf));
-#else
-  LOG_INFO(("Client environment:host.name=<not implemented>"));
-#endif
-
-#ifdef HAVE_SYS_UTSNAME_H
-  uname(&utsname);
-  LOG_INFO(("Client environment:os.name=%s", utsname.sysname));
-  LOG_INFO(("Client environment:os.arch=%s", utsname.release));
-  LOG_INFO(("Client environment:os.version=%s", utsname.version));
-#else
-  LOG_INFO(("Client environment:os.name=<not implemented>"));
-  LOG_INFO(("Client environment:os.arch=<not implemented>"));
-  LOG_INFO(("Client environment:os.version=<not implemented>"));
-#endif
-
-#ifdef HAVE_GETLOGIN
-  LOG_INFO(("Client environment:user.name=%s", getlogin()));
-#else
-  LOG_INFO(("Client environment:user.name=<not implemented>"));
-#endif
-
-#if defined(HAVE_GETUID) && defined(HAVE_GETPWUID_R)
-  uid = getuid();
-  if (!getpwuid_r(uid, &pw, buf, sizeof(buf), &pwp)) {
-    LOG_INFO(("Client environment:user.home=%s", pw.pw_dir));
-  } else {
-    LOG_INFO(("Client environment:user.home=<NA>"));
-  }
-#else
-  LOG_INFO(("Client environment:user.home=<not implemented>"));
-#endif
-
-#ifdef HAVE_GETCWD
-  if (!getcwd(buf, sizeof(buf))) {
-    LOG_INFO(("Client environment:user.dir=<toolong>"));
-  } else {
-    LOG_INFO(("Client environment:user.dir=%s", buf));
-  }
-#else
-  LOG_INFO(("Client environment:user.dir=<not implemented>"));
-#endif
-}
-
-/**
- * Create a zookeeper handle associated with the given host and port.
- */
-zhandle_t *zookeeper_init(const char *host, watcher_fn watcher,
-  int recv_timeout, const clientid_t *clientid, void *context, int flags)
-{
-    int errnosave = 0;
-    zhandle_t *zh = NULL;
-    char *index_chroot = NULL;
-
-    log_env();
-#ifdef WIN32
-       if (Win32WSAStartup()){
-               LOG_ERROR(("Error initializing ws2_32.dll"));
-               return 0;
-       }
-#endif
-    LOG_INFO(("Initiating client connection, host=%s sessionTimeout=%d watcher=%p"
-          " sessionId=%#llx sessionPasswd=%s context=%p flags=%d",
-              host,
-              recv_timeout,
-              watcher,
-              (clientid == 0 ? 0 : clientid->client_id),
-              ((clientid == 0) || (clientid->passwd[0] == 0) ?
-               "<null>" : "<hidden>"),
-              context,
-              flags));
-
-    zh = calloc(1, sizeof(*zh));
-    if (!zh) {
-        return 0;
-    }
-    zh->fd = -1;
-    zh->state = NOTCONNECTED_STATE_DEF;
-    zh->context = context;
-    zh->recv_timeout = recv_timeout;
-    init_auth_info(&zh->auth_h);
-    if (watcher) {
-       zh->watcher = watcher;
-    } else {
-       zh->watcher = null_watcher_fn;
-    }
-    if (host == 0 || *host == 0) { // what we shouldn't dup
-        errno=EINVAL;
-        goto abort;
-    }
-    //parse the host to get the chroot if
-    //available
-    index_chroot = strchr(host, '/');
-    if (index_chroot) {
-        zh->chroot = strdup(index_chroot);
-        if (zh->chroot == NULL) {
-            goto abort;
-        }
-        // if chroot is just / set it to null
-        if (strlen(zh->chroot) == 1) {
-            free(zh->chroot);
-            zh->chroot = NULL;
-        }
-        // cannot use strndup so allocate and strcpy
-        zh->hostname = (char *) malloc(index_chroot - host + 1);
-        zh->hostname = strncpy(zh->hostname, host, (index_chroot - host));
-        //strncpy does not null terminate
-        *(zh->hostname + (index_chroot - host)) = '\0';
-
-    } else {
-        zh->chroot = NULL;
-        zh->hostname = strdup(host);
-    }
-    if (zh->chroot && !isValidPath(zh->chroot, 0)) {
-        errno = EINVAL;
-        goto abort;
-    }
-    if (zh->hostname == 0) {
-        goto abort;
-    }
-    if(getaddrs(zh)!=0) {
-        goto abort;
-    }
-    zh->connect_index = 0;
-    if (clientid) {
-        memcpy(&zh->client_id, clientid, sizeof(zh->client_id));
-    } else {
-        memset(&zh->client_id, 0, sizeof(zh->client_id));
-    }
-    zh->primer_buffer.buffer = zh->primer_storage_buffer;
-    zh->primer_buffer.curr_offset = 0;
-    zh->primer_buffer.len = sizeof(zh->primer_storage_buffer);
-    zh->primer_buffer.next = 0;
-    zh->last_zxid = 0;
-    zh->next_deadline.tv_sec=zh->next_deadline.tv_usec=0;
-    zh->socket_readable.tv_sec=zh->socket_readable.tv_usec=0;
-    zh->active_node_watchers=create_zk_hashtable();
-    zh->active_exist_watchers=create_zk_hashtable();
-    zh->active_child_watchers=create_zk_hashtable();
-
-    if (adaptor_init(zh) == -1) {
-        goto abort;
-    }
-
-    return zh;
-abort:
-    errnosave=errno;
-    destroy(zh);
-    free(zh);
-    errno=errnosave;
-    return 0;
-}
-
-/**
- * deallocated the free_path only its beeen allocated
- * and not equal to path
- */
-void free_duplicate_path(const char *free_path, const char* path) {
-    if (free_path != path) {
-        free((void*)free_path);
-    }
-}
-
-/**
-  prepend the chroot path if available else return the path
-*/
-static char* prepend_string(zhandle_t *zh, const char* client_path) {
-    char *ret_str;
-    if (zh == NULL || zh->chroot == NULL)
-        return (char *) client_path;
-    // handle the chroot itself, client_path = "/"
-    if (strlen(client_path) == 1) {
-        return strdup(zh->chroot);
-    }
-    ret_str = (char *) malloc(strlen(zh->chroot) + strlen(client_path) + 1);
-    strcpy(ret_str, zh->chroot);
-    return strcat(ret_str, client_path);
-}
-
-/**
-   strip off the chroot string from the server path
-   if there is one else return the exact path
- */
-char* sub_string(zhandle_t *zh, const char* server_path) {
-    char *ret_str;
-    if (zh->chroot == NULL)
-        return (char *) server_path;
-    //ZOOKEEPER-1027
-    if (strncmp(server_path, zh->chroot, strlen(zh->chroot)) != 0) {
-        LOG_ERROR(("server path %s does not include chroot path %s",
-                   server_path, zh->chroot));
-        return (char *) server_path;
-    }
-    if (strlen(server_path) == strlen(zh->chroot)) {
-        //return "/"
-        ret_str = strdup("/");
-        return ret_str;
-    }
-    ret_str = strdup(server_path + strlen(zh->chroot));
-    return ret_str;
-}
-
-static buffer_list_t *allocate_buffer(char *buff, int len)
-{
-    buffer_list_t *buffer = calloc(1, sizeof(*buffer));
-    if (buffer == 0)
-        return 0;
-
-    buffer->len = len==0?sizeof(*buffer):len;
-    buffer->curr_offset = 0;
-    buffer->buffer = buff;
-    buffer->next = 0;
-    return buffer;
-}
-
-static void free_buffer(buffer_list_t *b)
-{
-    if (!b) {
-        return;
-    }
-    if (b->buffer) {
-        free(b->buffer);
-    }
-    free(b);
-}
-
-static buffer_list_t *dequeue_buffer(buffer_head_t *list)
-{
-    buffer_list_t *b;
-    lock_buffer_list(list);
-    b = list->head;
-    if (b) {
-        list->head = b->next;
-        if (!list->head) {
-            assert(b == list->last);
-            list->last = 0;
-        }
-    }
-    unlock_buffer_list(list);
-    return b;
-}
-
-static int remove_buffer(buffer_head_t *list)
-{
-    buffer_list_t *b = dequeue_buffer(list);
-    if (!b) {
-        return 0;
-    }
-    free_buffer(b);
-    return 1;
-}
-
-static void queue_buffer(buffer_head_t *list, buffer_list_t *b, int add_to_front)
-{
-    b->next = 0;
-    lock_buffer_list(list);
-    if (list->head) {
-        assert(list->last);
-        // The list is not empty
-        if (add_to_front) {
-            b->next = list->head;
-            list->head = b;
-        } else {
-            list->last->next = b;
-            list->last = b;
-        }
-    }else{
-        // The list is empty
-        assert(!list->head);
-        list->head = b;
-        list->last = b;
-    }
-    unlock_buffer_list(list);
-}
-
-static int queue_buffer_bytes(buffer_head_t *list, char *buff, int len)
-{
-    buffer_list_t *b  = allocate_buffer(buff,len);
-    if (!b)
-        return ZSYSTEMERROR;
-    queue_buffer(list, b, 0);
-    return ZOK;
-}
-
-static int queue_front_buffer_bytes(buffer_head_t *list, char *buff, int len)
-{
-    buffer_list_t *b  = allocate_buffer(buff,len);
-    if (!b)
-        return ZSYSTEMERROR;
-    queue_buffer(list, b, 1);
-    return ZOK;
-}
-
-static __attribute__ ((unused)) int get_queue_len(buffer_head_t *list)
-{
-    int i;
-    buffer_list_t *ptr;
-    lock_buffer_list(list);
-    ptr = list->head;
-    for (i=0; ptr!=0; ptr=ptr->next, i++)
-        ;
-    unlock_buffer_list(list);
-    return i;
-}
-/* returns:
- * -1 if send failed,
- * 0 if send would block while sending the buffer (or a send was incomplete),
- * 1 if success
- */
-#ifdef WIN32
-static int send_buffer(SOCKET fd, buffer_list_t *buff)
-#else
-static int send_buffer(int fd, buffer_list_t *buff)
-#endif
-{
-    int len = buff->len;
-    int off = buff->curr_offset;
-    int rc = -1;
-
-    if (off < 4) {
-        /* we need to send the length at the beginning */
-        int nlen = htonl(len);
-        char *b = (char*)&nlen;
-        rc = zookeeper_send(fd, b + off, sizeof(nlen) - off);
-        if (rc == -1) {
-#ifndef _WINDOWS
-            if (errno != EAGAIN) {
-#else            
-            if (WSAGetLastError() != WSAEWOULDBLOCK) {
-#endif            
-                return -1;
-            } else {
-                return 0;
-            }
-        } else {
-            buff->curr_offset  += rc;
-        }
-        off = buff->curr_offset;
-    }
-    if (off >= 4) {
-        /* want off to now represent the offset into the buffer */
-        off -= sizeof(buff->len);
-        rc = zookeeper_send(fd, buff->buffer + off, len - off);
-        if (rc == -1) {
-#ifndef _WINDOWS
-            if (errno != EAGAIN) {
-#else            
-            if (WSAGetLastError() != WSAEWOULDBLOCK) {
-#endif            
-                return -1;
-            }
-        } else {
-            buff->curr_offset += rc;
-        }
-    }
-    return buff->curr_offset == len + sizeof(buff->len);
-}
-
-/* returns:
- * -1 if recv call failed,
- * 0 if recv would block,
- * 1 if success
- */
-#ifdef WIN32
-static int recv_buffer(SOCKET fd, buffer_list_t *buff)
-#else
-static int recv_buffer(int fd, buffer_list_t *buff)
-#endif
-{
-    int off = buff->curr_offset;
-    int rc = 0;
-    //fprintf(LOGSTREAM, "rc = %d, off = %d, line %d\n", rc, off, __LINE__);
-
-    /* if buffer is less than 4, we are reading in the length */
-    if (off < 4) {
-        char *buffer = (char*)&(buff->len);
-        rc = recv(fd, buffer+off, sizeof(int)-off, 0);
-        //fprintf(LOGSTREAM, "rc = %d, off = %d, line %d\n", rc, off, __LINE__);
-        switch(rc) {
-        case 0:
-            errno = EHOSTDOWN;
-        case -1:
-#ifndef _WINDOWS
-            if (errno == EAGAIN) {
-#else
-            if (WSAGetLastError() == WSAEWOULDBLOCK) {
-#endif
-                return 0;
-            }
-            return -1;
-        default:
-            buff->curr_offset += rc;
-        }
-        off = buff->curr_offset;
-        if (buff->curr_offset == sizeof(buff->len)) {
-            buff->len = ntohl(buff->len);
-            buff->buffer = calloc(1, buff->len);
-        }
-    }
-    if (buff->buffer) {
-        /* want off to now represent the offset into the buffer */
-        off -= sizeof(buff->len);
-
-        rc = recv(fd, buff->buffer+off, buff->len-off, 0);
-        switch(rc) {
-        case 0:
-            errno = EHOSTDOWN;
-        case -1:
-#ifndef _WINDOWS
-            if (errno == EAGAIN) {
-#else
-            if (WSAGetLastError() == WSAEWOULDBLOCK) {
-#endif
-                break;
-            }
-            return -1;
-        default:
-            buff->curr_offset += rc;
-        }
-    }
-    return buff->curr_offset == buff->len + sizeof(buff->len);
-}
-
-void free_buffers(buffer_head_t *list)
-{
-    while (remove_buffer(list))
-        ;
-}
-
-void free_completions(zhandle_t *zh,int callCompletion,int reason)
-{
-    completion_head_t tmp_list;
-    struct oarchive *oa;
-    struct ReplyHeader h;
-    void_completion_t auth_completion = NULL;
-    auth_completion_list_t a_list, *a_tmp;
-
-    if (lock_completion_list(&zh->sent_requests) == 0) {
-        tmp_list = zh->sent_requests;
-        zh->sent_requests.head = 0;
-        zh->sent_requests.last = 0;
-        unlock_completion_list(&zh->sent_requests);
-    
-        while (tmp_list.head) {
-            completion_list_t *cptr = tmp_list.head;
-
-            tmp_list.head = cptr->next;
-            if (cptr->c.data_result == SYNCHRONOUS_MARKER) {
-                struct sync_completion
-                            *sc = (struct sync_completion*)cptr->data;
-                sc->rc = reason;
-                notify_sync_completion(sc);
-                zh->outstanding_sync--;
-                destroy_completion_entry(cptr);
-            } else if (callCompletion) {
-                // Fake the response
-                buffer_list_t *bptr;
-                h.xid = cptr->xid;
-                h.zxid = -1;
-                h.err = reason;
-                oa = create_buffer_oarchive();
-                serialize_ReplyHeader(oa, "header", &h);
-                bptr = calloc(sizeof(*bptr), 1);
-                assert(bptr);
-                bptr->len = get_buffer_len(oa);
-                bptr->buffer = get_buffer(oa);
-                close_buffer_oarchive(&oa, 0);
-                cptr->buffer = bptr;
-                queue_completion(&zh->completions_to_process, cptr, 0);
-            }
-        }
-    }
-    if (zoo_lock_auth(zh) == 0) {
-        a_list.completion = NULL;
-        a_list.next = NULL;
-    
-        get_auth_completions(&zh->auth_h, &a_list);
-        zoo_unlock_auth(zh);
-    
-        a_tmp = &a_list;
-        // chain call user's completion function
-        while (a_tmp->completion != NULL) {
-            auth_completion = a_tmp->completion;
-            auth_completion(reason, a_tmp->auth_data);
-            a_tmp = a_tmp->next;
-            if (a_tmp == NULL)
-                break;
-        }
-    }
-    free_auth_completion(&a_list);
-}
-
-static void cleanup_bufs(zhandle_t *zh,int callCompletion,int rc)
-{
-    enter_critical(zh);
-    free_buffers(&zh->to_send);
-    free_buffers(&zh->to_process);
-    free_completions(zh,callCompletion,rc);
-    leave_critical(zh);
-    if (zh->input_buffer && zh->input_buffer != &zh->primer_buffer) {
-        free_buffer(zh->input_buffer);
-        zh->input_buffer = 0;
-    }
-}
-
-static void handle_error(zhandle_t *zh,int rc)
-{
-    close(zh->fd);
-    if (is_unrecoverable(zh)) {
-        LOG_DEBUG(("Calling a watcher for a ZOO_SESSION_EVENT and the state=%s",
-                state2String(zh->state)));
-        PROCESS_SESSION_EVENT(zh, zh->state);
-    } else if (zh->state == ZOO_CONNECTED_STATE) {
-        LOG_DEBUG(("Calling a watcher for a ZOO_SESSION_EVENT and the state=CONNECTING_STATE"));
-        PROCESS_SESSION_EVENT(zh, ZOO_CONNECTING_STATE);
-    }
-    cleanup_bufs(zh,1,rc);
-    zh->fd = -1;
-    zh->connect_index++;
-    if (!is_unrecoverable(zh)) {
-        zh->state = 0;
-    }
-    if (process_async(zh->outstanding_sync)) {
-        process_completions(zh);
-    }
-}
-
-static int handle_socket_error_msg(zhandle_t *zh, int line, int rc,
-        const char* format, ...)
-{
-    if(logLevel>=ZOO_LOG_LEVEL_ERROR){
-        va_list va;
-        char buf[1024];
-        va_start(va,format);
-        vsnprintf(buf, sizeof(buf)-1,format,va);
-        log_message(ZOO_LOG_LEVEL_ERROR,line,__func__,
-            format_log_message("Socket [%s] zk retcode=%d, errno=%d(%s): %s",
-            format_current_endpoint_info(zh),rc,errno,strerror(errno),buf));
-        va_end(va);
-    }
-    handle_error(zh,rc);
-    return rc;
-}
-
-static void auth_completion_func(int rc, zhandle_t* zh)
-{
-    void_completion_t auth_completion = NULL;
-    auth_completion_list_t a_list;
-    auth_completion_list_t *a_tmp;
-
-    if(zh==NULL)
-        return;
-
-    zoo_lock_auth(zh);
-
-    if(rc!=0){
-        zh->state=ZOO_AUTH_FAILED_STATE;
-    }else{
-        //change state for all auths
-        mark_active_auth(zh);
-    }
-    a_list.completion = NULL;
-    a_list.next = NULL;
-    get_auth_completions(&zh->auth_h, &a_list);
-    zoo_unlock_auth(zh);
-    if (rc) {
-        LOG_ERROR(("Authentication scheme %s failed. Connection closed.",
-                   zh->auth_h.auth->scheme));
-    }
-    else {
-        LOG_INFO(("Authentication scheme %s succeeded", zh->auth_h.auth->scheme));
-    }
-    a_tmp = &a_list;
-    // chain call user's completion function
-    while (a_tmp->completion != NULL) {
-        auth_completion = a_tmp->completion;
-        auth_completion(rc, a_tmp->auth_data);
-        a_tmp = a_tmp->next;
-        if (a_tmp == NULL)
-            break;
-    }
-    free_auth_completion(&a_list);
-}
-
-static int send_info_packet(zhandle_t *zh, auth_info* auth) {
-    struct oarchive *oa;
-    struct RequestHeader h = { STRUCT_INITIALIZER(xid , AUTH_XID), STRUCT_INITIALIZER(type , ZOO_SETAUTH_OP)};
-    struct AuthPacket req;
-    int rc;
-    oa = create_buffer_oarchive();
-    rc = serialize_RequestHeader(oa, "header", &h);
-    req.type=0;   // ignored by the server
-    req.scheme = auth->scheme;
-    req.auth = auth->auth;
-    rc = rc < 0 ? rc : serialize_AuthPacket(oa, "req", &req);
-    /* add this buffer to the head of the send queue */
-    rc = rc < 0 ? rc : queue_front_buffer_bytes(&zh->to_send, get_buffer(oa),
-            get_buffer_len(oa));
-    /* We queued the buffer, so don't free it */
-    close_buffer_oarchive(&oa, 0);
-
-    return rc;
-}
-
-/** send all auths, not just the last one **/
-static int send_auth_info(zhandle_t *zh) {
-    int rc = 0;
-    auth_info *auth = NULL;
-
-    zoo_lock_auth(zh);
-    auth = zh->auth_h.auth;
-    if (auth == NULL) {
-        zoo_unlock_auth(zh);
-        return ZOK;
-    }
-    while (auth != NULL) {
-        rc = send_info_packet(zh, auth);
-        auth = auth->next;
-    }
-    zoo_unlock_auth(zh);
-    LOG_DEBUG(("Sending all auth info request to %s", format_current_endpoint_info(zh)));
-    return (rc <0) ? ZMARSHALLINGERROR:ZOK;
-}
-
-static int send_last_auth_info(zhandle_t *zh)
-{    
-    int rc = 0;
-    auth_info *auth = NULL;
-
-    zoo_lock_auth(zh);
-    auth = get_last_auth(&zh->auth_h);
-    if(auth==NULL) {
-      zoo_unlock_auth(zh);
-      return ZOK; // there is nothing to send
-    }
-    rc = send_info_packet(zh, auth);
-    zoo_unlock_auth(zh);
-    LOG_DEBUG(("Sending auth info request to %s",format_current_endpoint_info(zh)));
-    return (rc < 0)?ZMARSHALLINGERROR:ZOK;
-}
-
-static void free_key_list(char **list, int count)
-{
-    int i;
-
-    for(i = 0; i < count; i++) {
-        free(list[i]);
-    }
-    free(list);
-}
-
-static int send_set_watches(zhandle_t *zh)
-{
-    struct oarchive *oa;
-    struct RequestHeader h = { STRUCT_INITIALIZER(xid , SET_WATCHES_XID), STRUCT_INITIALIZER(type , ZOO_SETWATCHES_OP)};
-    struct SetWatches req;
-    int rc;
-
-    req.relativeZxid = zh->last_zxid;
-    req.dataWatches.data = collect_keys(zh->active_node_watchers, (int*)&req.dataWatches.count);
-    req.existWatches.data = collect_keys(zh->active_exist_watchers, (int*)&req.existWatches.count);
-    req.childWatches.data = collect_keys(zh->active_child_watchers, (int*)&req.childWatches.count);
-
-    // return if there are no pending watches
-    if (!req.dataWatches.count && !req.existWatches.count &&
-        !req.childWatches.count) {
-        free_key_list(req.dataWatches.data, req.dataWatches.count);
-        free_key_list(req.existWatches.data, req.existWatches.count);
-        free_key_list(req.childWatches.data, req.childWatches.count);
-        return ZOK;
-    }
-
-
-    oa = create_buffer_oarchive();
-    rc = serialize_RequestHeader(oa, "header", &h);
-    rc = rc < 0 ? rc : serialize_SetWatches(oa, "req", &req);
-    /* add this buffer to the head of the send queue */
-    rc = rc < 0 ? rc : queue_front_buffer_bytes(&zh->to_send, get_buffer(oa),
-            get_buffer_len(oa));
-    /* We queued the buffer, so don't free it */   
-    close_buffer_oarchive(&oa, 0);
-    free_key_list(req.dataWatches.data, req.dataWatches.count);
-    free_key_list(req.existWatches.data, req.existWatches.count);
-    free_key_list(req.childWatches.data, req.childWatches.count);
-    LOG_DEBUG(("Sending set watches request to %s",format_current_endpoint_info(zh)));
-    return (rc < 0)?ZMARSHALLINGERROR:ZOK;
-}
-
-static int serialize_prime_connect(struct connect_req *req, char* buffer){
-    //this should be the order of serialization
-    int offset = 0;
-    req->protocolVersion = htonl(req->protocolVersion);
-    memcpy(buffer + offset, &req->protocolVersion, sizeof(req->protocolVersion));
-    offset = offset +  sizeof(req->protocolVersion);
-
-    req->lastZxidSeen = zoo_htonll(req->lastZxidSeen);
-    memcpy(buffer + offset, &req->lastZxidSeen, sizeof(req->lastZxidSeen));
-    offset = offset +  sizeof(req->lastZxidSeen);
-
-    req->timeOut = htonl(req->timeOut);
-    memcpy(buffer + offset, &req->timeOut, sizeof(req->timeOut));
-    offset = offset +  sizeof(req->timeOut);
-
-    req->sessionId = zoo_htonll(req->sessionId);
-    memcpy(buffer + offset, &req->sessionId, sizeof(req->sessionId));
-    offset = offset +  sizeof(req->sessionId);
-
-    req->passwd_len = htonl(req->passwd_len);
-    memcpy(buffer + offset, &req->passwd_len, sizeof(req->passwd_len));
-    offset = offset +  sizeof(req->passwd_len);
-
-    memcpy(buffer + offset, req->passwd, sizeof(req->passwd));
-
-    return 0;
-}
-
- static int deserialize_prime_response(struct prime_struct *req, char* buffer){
-     //this should be the order of deserialization
-     int offset = 0;
-     memcpy(&req->len, buffer + offset, sizeof(req->len));
-     offset = offset +  sizeof(req->len);
-
-     req->len = ntohl(req->len);
-     memcpy(&req->protocolVersion, buffer + offset, sizeof(req->protocolVersion));
-     offset = offset +  sizeof(req->protocolVersion);
-
-     req->protocolVersion = ntohl(req->protocolVersion);
-     memcpy(&req->timeOut, buffer + offset, sizeof(req->timeOut));
-     offset = offset +  sizeof(req->timeOut);
-
-     req->timeOut = ntohl(req->timeOut);
-     memcpy(&req->sessionId, buffer + offset, sizeof(req->sessionId));
-     offset = offset +  sizeof(req->sessionId);
-
-     req->sessionId = zoo_htonll(req->sessionId);
-     memcpy(&req->passwd_len, buffer + offset, sizeof(req->passwd_len));
-     offset = offset +  sizeof(req->passwd_len);
-
-     req->passwd_len = ntohl(req->passwd_len);
-     memcpy(req->passwd, buffer + offset, sizeof(req->passwd));
-     return 0;
- }
-
-static int prime_connection(zhandle_t *zh)
-{
-    int rc;
-    /*this is the size of buffer to serialize req into*/
-    char buffer_req[HANDSHAKE_REQ_SIZE];
-    int len = sizeof(buffer_req);
-    int hlen = 0;
-    struct connect_req req;
-    req.protocolVersion = 0;
-    req.sessionId = zh->client_id.client_id;
-    req.passwd_len = sizeof(req.passwd);
-    memcpy(req.passwd, zh->client_id.passwd, sizeof(zh->client_id.passwd));
-    req.timeOut = zh->recv_timeout;
-    req.lastZxidSeen = zh->last_zxid;
-    hlen = htonl(len);
-    /* We are running fast and loose here, but this string should fit in the initial buffer! */
-    rc=zookeeper_send(zh->fd, &hlen, sizeof(len));
-    serialize_prime_connect(&req, buffer_req);
-    rc=rc<0 ? rc : zookeeper_send(zh->fd, buffer_req, len);
-    if (rc<0) {
-        return handle_socket_error_msg(zh, __LINE__, ZCONNECTIONLOSS,
-                "failed to send a handshake packet: %s", strerror(errno));
-    }
-    zh->state = ZOO_ASSOCIATING_STATE;
-
-    zh->input_buffer = &zh->primer_buffer;
-    /* This seems a bit weird to to set the offset to 4, but we already have a
-     * length, so we skip reading the length (and allocating the buffer) by
-     * saying that we are already at offset 4 */
-    zh->input_buffer->curr_offset = 4;
-
-    return ZOK;
-}
-
-static inline int calculate_interval(const struct timeval *start,
-        const struct timeval *end)
-{
-    int interval;
-    struct timeval i = *end;
-    i.tv_sec -= start->tv_sec;
-    i.tv_usec -= start->tv_usec;
-    interval = i.tv_sec * 1000 + (i.tv_usec/1000);
-    return interval;
-}
-
-static struct timeval get_timeval(int interval)
-{
-    struct timeval tv;
-    if (interval < 0) {
-        interval = 0;
-    }
-    tv.tv_sec = interval/1000;
-    tv.tv_usec = (interval%1000)*1000;
-    return tv;
-}
-
- static int add_void_completion(zhandle_t *zh, int xid, void_completion_t dc,
-     const void *data);
- static int add_string_completion(zhandle_t *zh, int xid,
-     string_completion_t dc, const void *data);
-
- int send_ping(zhandle_t* zh)
- {
-    int rc;
-    struct oarchive *oa = create_buffer_oarchive();
-    struct RequestHeader h = { STRUCT_INITIALIZER(xid ,PING_XID), STRUCT_INITIALIZER (type , ZOO_PING_OP) };
-
-    rc = serialize_RequestHeader(oa, "header", &h);
-    enter_critical(zh);
-    gettimeofday(&zh->last_ping, 0);
-    rc = rc < 0 ? rc : queue_buffer_bytes(&zh->to_send, get_buffer(oa),
-            get_buffer_len(oa));
-    leave_critical(zh);
-    close_buffer_oarchive(&oa, 0);
-    return rc<0 ? rc : adaptor_send_queue(zh, 0);
-}
-
-#ifdef WIN32
-int zookeeper_interest(zhandle_t *zh, SOCKET *fd, int *interest,
-     struct timeval *tv)
-{
-
-    ULONG nonblocking_flag = 1;
-#else
-int zookeeper_interest(zhandle_t *zh, int *fd, int *interest,
-     struct timeval *tv)
-{
-#endif
-    struct timeval now;
-    if(zh==0 || fd==0 ||interest==0 || tv==0)
-        return ZBADARGUMENTS;
-    if (is_unrecoverable(zh))
-        return ZINVALIDSTATE;
-    gettimeofday(&now, 0);
-    if(zh->next_deadline.tv_sec!=0 || zh->next_deadline.tv_usec!=0){
-        int time_left = calculate_interval(&zh->next_deadline, &now);
-        if (time_left > 10)
-            LOG_WARN(("Exceeded deadline by %dms", time_left));
-    }
-    api_prolog(zh);
-    *fd = zh->fd;
-    *interest = 0;
-    tv->tv_sec = 0;
-    tv->tv_usec = 0;
-    if (*fd == -1) {
-        if (zh->connect_index == zh->addrs_count) {
-            /* Wait a bit before trying again so that we don't spin */
-            zh->connect_index = 0;
-        }else {
-            int rc;
-#ifdef WIN32
-            char enable_tcp_nodelay = 1;
-#else
-            int enable_tcp_nodelay = 1;
-#endif
-            int ssoresult;
-
-            zh->fd = socket(zh->addrs[zh->connect_index].ss_family, SOCK_STREAM, 0);
-            if (zh->fd < 0) {
-                return api_epilog(zh,handle_socket_error_msg(zh,__LINE__,
-                                                             ZSYSTEMERROR, "socket() call failed"));
-            }
-            ssoresult = setsockopt(zh->fd, IPPROTO_TCP, TCP_NODELAY, &enable_tcp_nodelay, sizeof(enable_tcp_nodelay));
-            if (ssoresult != 0) {
-                LOG_WARN(("Unable to set TCP_NODELAY, operation latency may be effected"));
-            }
-#ifdef WIN32
-            ioctlsocket(zh->fd, FIONBIO, &nonblocking_flag);                    
-#else
-            fcntl(zh->fd, F_SETFL, O_NONBLOCK|fcntl(zh->fd, F_GETFL, 0));
-#endif
-#if defined(AF_INET6)
-            if (zh->addrs[zh->connect_index].ss_family == AF_INET6) {
-                rc = connect(zh->fd, (struct sockaddr*) &zh->addrs[zh->connect_index], sizeof(struct sockaddr_in6));
-            } else {
-#else
-               LOG_DEBUG(("[zk] connect()\n"));
-            {
-#endif
-                rc = connect(zh->fd, (struct sockaddr*) &zh->addrs[zh->connect_index], sizeof(struct sockaddr_in));
-#ifdef WIN32
-                errno = GetLastError();
-
-#ifndef EWOULDBLOCK
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#endif
-
-#ifndef EINPROGRESS
-#define EINPROGRESS WSAEINPROGRESS
-#endif
-
-#if _MSC_VER >= 1600
-                switch (errno) {
-                case WSAEWOULDBLOCK:
-                    errno = EWOULDBLOCK;
-                    break;
-                case WSAEINPROGRESS:
-                    errno = EINPROGRESS;
-                    break;
-                }
-#endif
-#endif
-            }
-            if (rc == -1) {
-                /* we are handling the non-blocking connect according to
-                 * the description in section 16.3 "Non-blocking connect"
-                 * in UNIX Network Programming vol 1, 3rd edition */
-                if (errno == EWOULDBLOCK || errno == EINPROGRESS)
-                    zh->state = ZOO_CONNECTING_STATE;
-                else
-                    return api_epilog(zh,handle_socket_error_msg(zh,__LINE__,
-                            ZCONNECTIONLOSS,"connect() call failed"));
-            } else {
-                if((rc=prime_connection(zh))!=0)
-                    return api_epilog(zh,rc);
-
-                LOG_INFO(("Initiated connection to server [%s]",
-                        format_endpoint_info(&zh->addrs[zh->connect_index])));
-            }
-        }
-        *fd = zh->fd;
-        *tv = get_timeval(zh->recv_timeout/3);
-        zh->last_recv = now;
-        zh->last_send = now;
-        zh->last_ping = now;
-    }
-    if (zh->fd != -1) {
-        int idle_recv = calculate_interval(&zh->last_recv, &now);
-        int idle_send = calculate_interval(&zh->last_send, &now);
-        int recv_to = zh->recv_timeout*2/3 - idle_recv;
-        int send_to = zh->recv_timeout/3;
-        // have we exceeded the receive timeout threshold?
-        if (recv_to <= 0) {
-            // We gotta cut our losses and connect to someone else
-#ifdef WIN32
-            errno = WSAETIMEDOUT;
-#else
-            errno = ETIMEDOUT;
-#endif
-            *interest=0;
-            *tv = get_timeval(0);
-            return api_epilog(zh,handle_socket_error_msg(zh,
-                    __LINE__,ZOPERATIONTIMEOUT,
-                    "connection to %s timed out (exceeded timeout by %dms)",
-                    format_endpoint_info(&zh->addrs[zh->connect_index]),
-                    -recv_to));
-
-        }
-        // We only allow 1/3 of our timeout time to expire before sending
-        // a PING
-        if (zh->state==ZOO_CONNECTED_STATE) {
-            send_to = zh->recv_timeout/3 - idle_send;
-            if (send_to <= 0) {
-                if (zh->sent_requests.head==0) {
-//                    LOG_DEBUG(("Sending PING to %s (exceeded idle by %dms)",
-//                                    format_current_endpoint_info(zh),-send_to));
-                    int rc=send_ping(zh);
-                    if (rc < 0){
-                        LOG_ERROR(("failed to send PING request (zk retcode=%d)",rc));
-                        return api_epilog(zh,rc);
-                    }
-                }
-                send_to = zh->recv_timeout/3;
-            }
-        }
-        // choose the lesser value as the timeout
-        *tv = get_timeval(recv_to < send_to? recv_to:send_to);
-        zh->next_deadline.tv_sec = now.tv_sec + tv->tv_sec;
-        zh->next_deadline.tv_usec = now.tv_usec + tv->tv_usec;
-        if (zh->next_deadline.tv_usec > 1000000) {
-            zh->next_deadline.tv_sec += zh->next_deadline.tv_usec / 1000000;
-            zh->next_deadline.tv_usec = zh->next_deadline.tv_usec % 1000000;
-        }
-        *interest = ZOOKEEPER_READ;
-        /* we are interested in a write if we are connected and have something
-         * to send, or we are waiting for a connect to finish. */
-        if ((zh->to_send.head && (zh->state == ZOO_CONNECTED_STATE))
-        || zh->state == ZOO_CONNECTING_STATE) {
-            *interest |= ZOOKEEPER_WRITE;
-        }
-    }
-    return api_epilog(zh,ZOK);
-}
-
-static int check_events(zhandle_t *zh, int events)
-{
-    if (zh->fd == -1)
-        return ZINVALIDSTATE;
-    if ((events&ZOOKEEPER_WRITE)&&(zh->state == ZOO_CONNECTING_STATE)) {
-        int rc, error;
-        socklen_t len = sizeof(error);
-        rc = getsockopt(zh->fd, SOL_SOCKET, SO_ERROR, &error, &len);
-        /* the description in section 16.4 "Non-blocking connect"
-         * in UNIX Network Programming vol 1, 3rd edition, points out
-         * that sometimes the error is in errno and sometimes in error */
-        if (rc < 0 || error) {
-            if (rc == 0)
-                errno = error;
-            return handle_socket_error_msg(zh, __LINE__,ZCONNECTIONLOSS,
-                "server refused to accept the client");
-        }
-        if((rc=prime_connection(zh))!=0)
-            return rc;
-        LOG_INFO(("initiated connection to server [%s]",
-                format_endpoint_info(&zh->addrs[zh->connect_index])));
-        return ZOK;
-    }
-    if (zh->to_send.head && (events&ZOOKEEPER_WRITE)) {
-        /* make the flush call non-blocking by specifying a 0 timeout */
-        int rc=flush_send_queue(zh,0);
-        if (rc < 0)
-            return handle_socket_error_msg(zh,__LINE__,ZCONNECTIONLOSS,
-                "failed while flushing send queue");
-    }
-    if (events&ZOOKEEPER_READ) {
-        int rc;
-        if (zh->input_buffer == 0) {
-            zh->input_buffer = allocate_buffer(0,0);
-        }
-
-        rc = recv_buffer(zh->fd, zh->input_buffer);
-        if (rc < 0) {
-            return handle_socket_error_msg(zh, __LINE__,ZCONNECTIONLOSS,
-                "failed while receiving a server response");
-        }
-        if (rc > 0) {
-            gettimeofday(&zh->last_recv, 0);
-            if (zh->input_buffer != &zh->primer_buffer) {
-                queue_buffer(&zh->to_process, zh->input_buffer, 0);
-            } else  {
-                int64_t oldid,newid;
-                //deserialize
-                deserialize_prime_response(&zh->primer_storage, zh->primer_buffer.buffer);
-                /* We are processing the primer_buffer, so we need to finish
-                 * the connection handshake */
-                oldid = zh->client_id.client_id;
-                newid = zh->primer_storage.sessionId;
-                if (oldid != 0 && oldid != newid) {
-                    zh->state = ZOO_EXPIRED_SESSION_STATE;
-                    errno = ESTALE;
-                    return handle_socket_error_msg(zh,__LINE__,ZSESSIONEXPIRED,
-                            "sessionId=%#llx has expired.",oldid);
-                } else {
-                    zh->recv_timeout = zh->primer_storage.timeOut;
-                    zh->client_id.client_id = newid;
-                 
-                    memcpy(zh->client_id.passwd, &zh->primer_storage.passwd,
-                           sizeof(zh->client_id.passwd));
-                    zh->state = ZOO_CONNECTED_STATE;
-                    LOG_INFO(("session establishment complete on server [%s], sessionId=%#llx, negotiated timeout=%d",
-                              format_endpoint_info(&zh->addrs[zh->connect_index]),
-                              newid, zh->recv_timeout));
-                    /* we want the auth to be sent for, but since both call push to front
-                       we need to call send_watch_set first */
-                    send_set_watches(zh);
-                    /* send the authentication packet now */
-                    send_auth_info(zh);
-                    LOG_DEBUG(("Calling a watcher for a ZOO_SESSION_EVENT and the state=ZOO_CONNECTED_STATE"));
-                    zh->input_buffer = 0; // just in case the watcher calls zookeeper_process() again
-                    PROCESS_SESSION_EVENT(zh, ZOO_CONNECTED_STATE);
-                }
-            }
-            zh->input_buffer = 0;
-        } else {
-            // zookeeper_process was called but there was nothing to read
-            // from the socket
-            return ZNOTHING;
-        }
-    }
-    return ZOK;
-}
-
-void api_prolog(zhandle_t* zh)
-{
-    inc_ref_counter(zh,1);
-}
-
-int api_epilog(zhandle_t *zh,int rc)
-{
-    if(inc_ref_counter(zh,-1)==0 && zh->close_requested!=0)
-        zookeeper_close(zh);
-    return rc;
-}
-
-static __attribute__((unused)) void print_completion_queue(zhandle_t *zh)
-{
-    completion_list_t* cptr;
-
-    if(logLevel<ZOO_LOG_LEVEL_DEBUG) return;
-
-    fprintf(LOGSTREAM,"Completion queue: ");
-    if (zh->sent_requests.head==0) {
-        fprintf(LOGSTREAM,"empty\n");
-        return;
-    }
-
-    cptr=zh->sent_requests.head;
-    while(cptr){
-        fprintf(LOGSTREAM,"%d,",cptr->xid);
-        cptr=cptr->next;
-    }
-    fprintf(LOGSTREAM,"end\n");
-}
-
-//#ifdef THREADED
-// IO thread queues session events to be processed by the completion thread
-static int queue_session_event(zhandle_t *zh, int state)
-{
-    int rc;
-    struct WatcherEvent evt = { ZOO_SESSION_EVENT, state, "" };
-    struct ReplyHeader hdr = { WATCHER_EVENT_XID, 0, 0 };
-    struct oarchive *oa;
-    completion_list_t *cptr;
-
-    if ((oa=create_buffer_oarchive())==NULL) {
-        LOG_ERROR(("out of memory"));
-        goto error;
-    }
-    rc = serialize_ReplyHeader(oa, "hdr", &hdr);
-    rc = rc<0?rc: serialize_WatcherEvent(oa, "event", &evt);
-    if(rc<0){
-        close_buffer_oarchive(&oa, 1);
-        goto error;
-    }
-    cptr = create_completion_entry(WATCHER_EVENT_XID,-1,0,0,0,0);
-    cptr->buffer = allocate_buffer(get_buffer(oa), get_buffer_len(oa));
-    cptr->buffer->curr_offset = get_buffer_len(oa);
-    if (!cptr->buffer) {
-        free(cptr);
-        close_buffer_oarchive(&oa, 1);
-        goto error;
-    }
-    /* We queued the buffer, so don't free it */
-    close_buffer_oarchive(&oa, 0);
-    cptr->c.watcher_result = collectWatchers(zh, ZOO_SESSION_EVENT, "");
-    queue_completion(&zh->completions_to_process, cptr, 0);
-    if (process_async(zh->outstanding_sync)) {
-        process_completions(zh);
-    }
-    return ZOK;
-error:
-    errno=ENOMEM;
-    return ZSYSTEMERROR;
-}
-//#endif
-
-completion_list_t *dequeue_completion(completion_head_t *list)
-{
-    completion_list_t *cptr;
-    lock_completion_list(list);
-    cptr = list->head;
-    if (cptr) {
-        list->head = cptr->next;
-        if (!list->head) {
-            assert(list->last == cptr);
-            list->last = 0;
-        }
-    }
-    unlock_completion_list(list);
-    return cptr;
-}
-
-static void process_sync_completion(
-        completion_list_t *cptr,
-        struct sync_completion *sc,
-        struct iarchive *ia,
-	zhandle_t *zh)
-{
-    LOG_DEBUG(("Processing sync_completion with type=%d xid=%#x rc=%d",
-            cptr->c.type, cptr->xid, sc->rc));
-
-    switch(cptr->c.type) {
-    case COMPLETION_DATA: 
-        if (sc->rc==0) {
-            struct GetDataResponse res;
-            int len;
-            deserialize_GetDataResponse(ia, "reply", &res);
-            if (res.data.len <= sc->u.data.buff_len) {
-                len = res.data.len;
-            } else {
-                len = sc->u.data.buff_len;
-            }
-            sc->u.data.buff_len = len;
-            // check if len is negative
-            // just of NULL which is -1 int
-            if (len == -1) {
-                sc->u.data.buffer = NULL;
-            } else {
-                memcpy(sc->u.data.buffer, res.data.buff, len);
-            }
-            sc->u.data.stat = res.stat;
-            deallocate_GetDataResponse(&res);
-        }
-        break;
-    case COMPLETION_STAT:
-        if (sc->rc==0) {
-            struct SetDataResponse res;
-            deserialize_SetDataResponse(ia, "reply", &res);
-            sc->u.stat = res.stat;
-            deallocate_SetDataResponse(&res);
-        }
-        break;
-    case COMPLETION_STRINGLIST:
-        if (sc->rc==0) {
-            struct GetChildrenResponse res;
-            deserialize_GetChildrenResponse(ia, "reply", &res);
-            sc->u.strs2 = res.children;
-            /* We don't deallocate since we are passing it back */
-            // deallocate_GetChildrenResponse(&res);
-        }
-        break;
-    case COMPLETION_STRINGLIST_STAT:
-        if (sc->rc==0) {
-            struct GetChildren2Response res;
-            deserialize_GetChildren2Response(ia, "reply", &res);
-            sc->u.strs_stat.strs2 = res.children;
-            sc->u.strs_stat.stat2 = res.stat;
-            /* We don't deallocate since we are passing it back */
-            // deallocate_GetChildren2Response(&res);
-        }
-        break;
-    case COMPLETION_STRING:
-        if (sc->rc==0) {
-            struct CreateResponse res;
-            int len;
-            const char * client_path;
-            deserialize_CreateResponse(ia, "reply", &res);
-            //ZOOKEEPER-1027
-            client_path = sub_string(zh, res.path); 
-            len = strlen(client_path) + 1;if (len > sc->u.str.str_len) {
-                len = sc->u.str.str_len;
-            }
-            if (len > 0) {
-                memcpy(sc->u.str.str, client_path, len - 1);
-                sc->u.str.str[len - 1] = '\0';
-            }
-            free_duplicate_path(client_path, res.path);
-            deallocate_CreateResponse(&res);
-        }
-        break;
-    case COMPLETION_ACLLIST:
-        if (sc->rc==0) {
-            struct GetACLResponse res;
-            deserialize_GetACLResponse(ia, "reply", &res);
-            sc->u.acl.acl = res.acl;
-            sc->u.acl.stat = res.stat;
-            /* We don't deallocate since we are passing it back */
-            //deallocate_GetACLResponse(&res);
-        }
-        break;
-    case COMPLETION_VOID:
-        break;
-    case COMPLETION_MULTI:
-        sc->rc = deserialize_multi(cptr->xid, cptr, ia);
-        break;
-    default:
-        LOG_DEBUG(("Unsupported completion type=%d", cptr->c.type));
-        break;
-    }
-}
-
-static int deserialize_multi(int xid, completion_list_t *cptr, struct iarchive *ia)
-{
-    int rc = 0;
-    completion_head_t *clist = &cptr->c.clist;
-    struct MultiHeader mhdr = { STRUCT_INITIALIZER(type , 0), STRUCT_INITIALIZER(done , 0), STRUCT_INITIALIZER(err , 0) };
-    assert(clist);
-    deserialize_MultiHeader(ia, "multiheader", &mhdr);
-    while (!mhdr.done) {
-        completion_list_t *entry = dequeue_completion(clist);
-        assert(entry);
-
-        if (mhdr.type == -1) {
-            struct ErrorResponse er;
-            deserialize_ErrorResponse(ia, "error", &er);
-            mhdr.err = er.err ;
-            if (rc == 0 && er.err != 0 && er.err != ZRUNTIMEINCONSISTENCY) {
-                rc = er.err;
-            }
-        }
-
-        deserialize_response(entry->c.type, xid, mhdr.type == -1, mhdr.err, entry, ia);
-        deserialize_MultiHeader(ia, "multiheader", &mhdr);
-        //While deserializing the response we must destroy completion entry for each operation in 
-        //the zoo_multi transaction. Otherwise this results in memory leak when client invokes zoo_multi
-        //operation.
-        destroy_completion_entry(entry);
-    }
-
-    return rc;
-}
-
-static void deserialize_response(int type, int xid, int failed, int rc, completion_list_t *cptr, struct iarchive *ia)
-{
-    switch (type) {
-    case COMPLETION_DATA:
-        LOG_DEBUG(("Calling COMPLETION_DATA for xid=%#x failed=%d rc=%d",
-                    cptr->xid, failed, rc));
-        if (failed) {
-            cptr->c.data_result(rc, 0, 0, 0, cptr->data);
-        } else {
-            struct GetDataResponse res;
-            deserialize_GetDataResponse(ia, "reply", &res);
-            cptr->c.data_result(rc, res.data.buff, res.data.len,
-                    &res.stat, cptr->data);
-            deallocate_GetDataResponse(&res);
-        }
-        break;
-    case COMPLETION_STAT:
-        LOG_DEBUG(("Calling COMPLETION_STAT for xid=%#x failed=%d rc=%d",
-                    cptr->xid, failed, rc));
-        if (failed) {
-            cptr->c.stat_result(rc, 0, cptr->data);
-        } else {
-            struct SetDataResponse res;
-            deserialize_SetDataResponse(ia, "reply", &res);
-            cptr->c.stat_result(rc, &res.stat, cptr->data);
-            deallocate_SetDataResponse(&res);
-        }
-        break;
-    case COMPLETION_STRINGLIST:
-        LOG_DEBUG(("Calling COMPLETION_STRINGLIST for xid=%#x failed=%d rc=%d",
-                    cptr->xid, failed, rc));
-        if (failed) {
-            cptr->c.strings_result(rc, 0, cptr->data);
-        } else {
-            struct GetChildrenResponse res;
-            deserialize_GetChildrenResponse(ia, "reply", &res);
-            cptr->c.strings_result(rc, &res.children, cptr->data);
-            deallocate_GetChildrenResponse(&res);
-        }
-        break;
-    case COMPLETION_STRINGLIST_STAT:
-        LOG_DEBUG(("Calling COMPLETION_STRINGLIST_STAT for xid=%#x failed=%d rc=%d",
-                    cptr->xid, failed, rc));
-        if (failed) {
-            cptr->c.strings_stat_result(rc, 0, 0, cptr->data);
-        } else {
-            struct GetChildren2Response res;
-            deserialize_GetChildren2Response(ia, "reply", &res);
-            cptr->c.strings_stat_result(rc, &res.children, &res.stat, cptr->data);
-            deallocate_GetChildren2Response(&res);
-        }
-        break;
-    case COMPLETION_STRING:
-        LOG_DEBUG(("Calling COMPLETION_STRING for xid=%#x failed=%d, rc=%d",
-                    cptr->xid, failed, rc));
-        if (failed) {
-            cptr->c.string_result(rc, 0, cptr->data);
-        } else {
-            struct CreateResponse res;
-            memset(&res, 0, sizeof(res));
-            deserialize_CreateResponse(ia, "reply", &res);
-            cptr->c.string_result(rc, res.path, cptr->data);
-            deallocate_CreateResponse(&res);
-        }
-        break;
-    case COMPLETION_ACLLIST:
-        LOG_DEBUG(("Calling COMPLETION_ACLLIST for xid=%#x failed=%d rc=%d",
-                    cptr->xid, failed, rc));
-        if (failed) {
-            cptr->c.acl_result(rc, 0, 0, cptr->data);
-        } else {
-            struct GetACLResponse res;
-            deserialize_GetACLResponse(ia, "reply", &res);
-            cptr->c.acl_result(rc, &res.acl, &res.stat, cptr->data);
-            deallocate_GetACLResponse(&res);
-        }
-        break;
-    case COMPLETION_VOID:
-        LOG_DEBUG(("Calling COMPLETION_VOID for xid=%#x failed=%d rc=%d",
-                    cptr->xid, failed, rc));
-        assert(cptr->c.void_result);
-        cptr->c.void_result(rc, cptr->data);
-        break;
-    case COMPLETION_MULTI:
-        LOG_DEBUG(("Calling COMPLETION_MULTI for xid=%#x failed=%d rc=%d",
-                    cptr->xid, failed, rc));
-        rc = deserialize_multi(xid, cptr, ia);
-        assert(cptr->c.void_result);
-        cptr->c.void_result(rc, cptr->data);
-        break;
-    default:
-        LOG_DEBUG(("Unsupported completion type=%d", cptr->c.type));
-    }
-}
-
-
-/* handles async completion (both single- and multithreaded) */
-void process_completions(zhandle_t *zh)
-{
-    completion_list_t *cptr;
-    while ((cptr = dequeue_completion(&zh->completions_to_process)) != 0) {
-        struct ReplyHeader hdr;
-        buffer_list_t *bptr = cptr->buffer;
-        struct iarchive *ia = create_buffer_iarchive(bptr->buffer,
-                bptr->len);
-        deserialize_ReplyHeader(ia, "hdr", &hdr);
-
-        if (hdr.xid == WATCHER_EVENT_XID) {
-            int type, state;
-            struct WatcherEvent evt;
-            deserialize_WatcherEvent(ia, "event", &evt);
-            /* We are doing a notification, so there is no pending request */
-            type = evt.type;
-            state = evt.state;
-            /* This is a notification so there aren't any pending requests */
-            LOG_DEBUG(("Calling a watcher for node [%s], type = %d event=%s",
-                       (evt.path==NULL?"NULL":evt.path), cptr->c.type,
-                       watcherEvent2String(type)));
-            deliverWatchers(zh,type,state,evt.path, &cptr->c.watcher_result);
-            deallocate_WatcherEvent(&evt);
-        } else {
-            deserialize_response(cptr->c.type, hdr.xid, hdr.err != 0, hdr.err, cptr, ia);
-        }
-        destroy_completion_entry(cptr);
-        close_buffer_iarchive(&ia);
-    }
-}
-
-static void isSocketReadable(zhandle_t* zh)
-{
-#ifndef WIN32
-    struct pollfd fds;
-    fds.fd = zh->fd;
-    fds.events = POLLIN;
-    if (poll(&fds,1,0)<=0) {
-        // socket not readable -- no more responses to process
-        zh->socket_readable.tv_sec=zh->socket_readable.tv_usec=0;
-    }
-#else
-    fd_set rfds;
-    struct timeval waittime = {0, 0};
-    FD_ZERO(&rfds);
-    FD_SET( zh->fd , &rfds);
-    if (select(0, &rfds, NULL, NULL, &waittime) <= 0){
-        // socket not readable -- no more responses to process
-        zh->socket_readable.tv_sec=zh->socket_readable.tv_usec=0;
-    }
-#endif
-    else{
-        gettimeofday(&zh->socket_readable,0);
-    }
-}
-
-static void checkResponseLatency(zhandle_t* zh)
-{
-    int delay;
-    struct timeval now;
-
-    if(zh->socket_readable.tv_sec==0)
-        return;
-
-    gettimeofday(&now,0);
-    delay=calculate_interval(&zh->socket_readable, &now);
-    if(delay>20)
-        LOG_DEBUG(("The following server response has spent at least %dms sitting in the client socket recv buffer",delay));
-
-    zh->socket_readable.tv_sec=zh->socket_readable.tv_usec=0;
-}
-
-int zookeeper_process(zhandle_t *zh, int events)
-{
-    buffer_list_t *bptr;
-    int rc;
-
-    if (zh==NULL)
-        return ZBADARGUMENTS;
-    if (is_unrecoverable(zh))
-        return ZINVALIDSTATE;
-    api_prolog(zh);
-    IF_DEBUG(checkResponseLatency(zh));
-    rc = check_events(zh, events);
-    if (rc!=ZOK)
-        return api_epilog(zh, rc);
-
-    IF_DEBUG(isSocketReadable(zh));
-
-    while (rc >= 0 && (bptr=dequeue_buffer(&zh->to_process))) {
-        struct ReplyHeader hdr;
-        struct iarchive *ia = create_buffer_iarchive(
-                                    bptr->buffer, bptr->curr_offset);
-        deserialize_ReplyHeader(ia, "hdr", &hdr);
-        if (hdr.zxid > 0) {
-            zh->last_zxid = hdr.zxid;
-        } else {
-            // fprintf(stderr, "Got %#x for %#x\n", hdr.zxid, hdr.xid);
-        }
-
-        if (hdr.xid == PING_XID) {
-            // Ping replies can arrive out-of-order
-            int elapsed = 0;
-            struct timeval now;
-            gettimeofday(&now, 0);
-            elapsed = calculate_interval(&zh->last_ping, &now);
-            LOG_DEBUG(("Got ping response in %d ms", elapsed));
-            free_buffer(bptr);
-        } else if (hdr.xid == WATCHER_EVENT_XID) {
-            struct WatcherEvent evt;
-            int type = 0;
-            char *path = NULL;
-            completion_list_t *c = NULL;
-
-            LOG_DEBUG(("Processing WATCHER_EVENT"));
-
-            deserialize_WatcherEvent(ia, "event", &evt);
-            type = evt.type;
-            path = evt.path;
-            /* We are doing a notification, so there is no pending request */
-            c = create_completion_entry(WATCHER_EVENT_XID,-1,0,0,0,0);
-            c->buffer = bptr;
-            c->c.watcher_result = collectWatchers(zh, type, path);
-
-            // We cannot free until now, otherwise path will become invalid
-            deallocate_WatcherEvent(&evt);
-            queue_completion(&zh->completions_to_process, c, 0);
-        } else if (hdr.xid == SET_WATCHES_XID) {
-            LOG_DEBUG(("Processing SET_WATCHES"));
-            free_buffer(bptr);
-        } else if (hdr.xid == AUTH_XID){
-            LOG_DEBUG(("Processing AUTH_XID"));
-
-            /* special handling for the AUTH response as it may come back
-             * out-of-band */
-            auth_completion_func(hdr.err,zh);
-            free_buffer(bptr);
-            /* authentication completion may change the connection state to
-             * unrecoverable */
-            if(is_unrecoverable(zh)){
-                handle_error(zh, ZAUTHFAILED);
-                close_buffer_iarchive(&ia);
-                return api_epilog(zh, ZAUTHFAILED);
-            }
-        } else {
-            int rc = hdr.err;
-            /* Find the request corresponding to the response */
-            completion_list_t *cptr = dequeue_completion(&zh->sent_requests);
-
-            /* [ZOOKEEPER-804] Don't assert if zookeeper_close has been called. */
-            if (zh->close_requested == 1 && cptr == NULL) {
-                LOG_DEBUG(("Completion queue has been cleared by zookeeper_close()"));
-                close_buffer_iarchive(&ia);
-                free_buffer(bptr);
-                return api_epilog(zh,ZINVALIDSTATE);
-            }
-            assert(cptr);
-            /* The requests are going to come back in order */
-            if (cptr->xid != hdr.xid) {
-                LOG_DEBUG(("Processing unexpected or out-of-order response!"));
-
-                // received unexpected (or out-of-order) response
-                close_buffer_iarchive(&ia);
-                free_buffer(bptr);
-                // put the completion back on the queue (so it gets properly
-                // signaled and deallocated) and disconnect from the server
-                queue_completion(&zh->sent_requests,cptr,1);
-                return api_epilog(zh,
-                                  handle_socket_error_msg(zh, __LINE__,ZRUNTIMEINCONSISTENCY,
-                                  "unexpected server response: expected %#x, but received %#x",
-                                  hdr.xid,cptr->xid));
-            }
-
-            activateWatcher(zh, cptr->watcher, rc);
-
-            if (cptr->c.void_result != SYNCHRONOUS_MARKER) {
-                LOG_DEBUG(("Queueing asynchronous response"));
-                cptr->buffer = bptr;
-                queue_completion(&zh->completions_to_process, cptr, 0);
-            } else {
-                struct sync_completion
-                        *sc = (struct sync_completion*)cptr->data;
-                sc->rc = rc;
-                
-                process_sync_completion(cptr, sc, ia, zh); 
-                
-                notify_sync_completion(sc);
-                free_buffer(bptr);
-                zh->outstanding_sync--;
-                destroy_completion_entry(cptr);
-            }
-        }
-
-        close_buffer_iarchive(&ia);
-
-    }
-    if (process_async(zh->outstanding_sync)) {
-        process_completions(zh);
-    }
-    return api_epilog(zh,ZOK);}
-
-int zoo_state(zhandle_t *zh)
-{
-    if(zh!=0)
-        return zh->state;
-    return 0;
-}
-
-static watcher_registration_t* create_watcher_registration(const char* path,
-        result_checker_fn checker,watcher_fn watcher,void* ctx){
-    watcher_registration_t* wo;
-    if(watcher==0)
-        return 0;
-    wo=calloc(1,sizeof(watcher_registration_t));
-    wo->path=strdup(path);
-    wo->watcher=watcher;
-    wo->context=ctx;
-    wo->checker=checker;
-    return wo;
-}
-
-static void destroy_watcher_registration(watcher_registration_t* wo){
-    if(wo!=0){
-        free((void*)wo->path);
-        free(wo);
-    }
-}
-
-static completion_list_t* create_completion_entry(int xid, int completion_type,
-        const void *dc, const void *data,watcher_registration_t* wo, completion_head_t *clist)
-{
-    completion_list_t *c = calloc(1,sizeof(completion_list_t));
-    if (!c) {
-        LOG_ERROR(("out of memory"));
-        return 0;
-    }
-    c->c.type = completion_type;
-    c->data = data;
-    switch(c->c.type) {
-    case COMPLETION_VOID:
-        c->c.void_result = (void_completion_t)dc;
-        break;
-    case COMPLETION_STRING:
-        c->c.string_result = (string_completion_t)dc;
-        break;
-    case COMPLETION_DATA:
-        c->c.data_result = (data_completion_t)dc;
-        break;
-    case COMPLETION_STAT:
-        c->c.stat_result = (stat_completion_t)dc;
-        break;
-    case COMPLETION_STRINGLIST:
-        c->c.strings_result = (strings_completion_t)dc;
-        break;
-    case COMPLETION_STRINGLIST_STAT:
-        c->c.strings_stat_result = (strings_stat_completion_t)dc;
-        break;
-    case COMPLETION_ACLLIST:
-        c->c.acl_result = (acl_completion_t)dc;
-        break;
-    case COMPLETION_MULTI:
-        assert(clist);
-        c->c.void_result = (void_completion_t)dc;
-        c->c.clist = *clist;
-        break;
-    }
-    c->xid = xid;
-    c->watcher = wo;
-    
-    return c;
-}
-
-static void destroy_completion_entry(completion_list_t* c){
-    if(c!=0){
-        destroy_watcher_registration(c->watcher);
-        if(c->buffer!=0)
-            free_buffer(c->buffer);
-        free(c);
-    }
-}
-
-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 */
-    if (list->last) {
-        assert(list->head);
-        // List is not empty
-        if (!add_to_front) {
-            list->last->next = c;
-            list->last = c;
-        } else {
-            c->next = list->head;
-            list->head = c;
-        }
-    } else {
-        // List is empty
-        assert(!list->head);
-        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);
-}
-
-static int add_completion(zhandle_t *zh, int xid, int completion_type,
-        const void *dc, const void *data, int add_to_front,
-        watcher_registration_t* wo, completion_head_t *clist)
-{
-    completion_list_t *c =create_completion_entry(xid, completion_type, dc,
-            data, wo, clist);
-    int rc = 0;
-    if (!c)
-        return ZSYSTEMERROR;
-    lock_completion_list(&zh->sent_requests);
-    if (zh->close_requested != 1) {
-        queue_completion_nolock(&zh->sent_requests, c, add_to_front);
-        if (dc == SYNCHRONOUS_MARKER) {
-            zh->outstanding_sync++;
-        }
-        rc = ZOK;
-    } else {
-        free(c);
-        rc = ZINVALIDSTATE;
-    }
-    unlock_completion_list(&zh->sent_requests);
-    return rc;
-}
-
-static int add_data_completion(zhandle_t *zh, int xid, data_completion_t dc,
-        const void *data,watcher_registration_t* wo)
-{
-    return add_completion(zh, xid, COMPLETION_DATA, dc, data, 0, wo, 0);
-}
-
-static int add_stat_completion(zhandle_t *zh, int xid, stat_completion_t dc,
-        const void *data,watcher_registration_t* wo)
-{
-    return add_completion(zh, xid, COMPLETION_STAT, dc, data, 0, wo, 0);
-}
-
-static int add_strings_completion(zhandle_t *zh, int xid,
-        strings_completion_t dc, const void *data,watcher_registration_t* wo)
-{
-    return add_completion(zh, xid, COMPLETION_STRINGLIST, dc, data, 0, wo, 0);
-}
-
-static int add_strings_stat_completion(zhandle_t *zh, int xid,
-        strings_stat_completion_t dc, const void *data,watcher_registration_t* wo)
-{
-    return add_completion(zh, xid, COMPLETION_STRINGLIST_STAT, dc, data, 0, wo, 0);
-}
-
-static int add_acl_completion(zhandle_t *zh, int xid, acl_completion_t dc,
-        const void *data)
-{
-    return add_completion(zh, xid, COMPLETION_ACLLIST, dc, data, 0, 0, 0);
-}
-
-static int add_void_completion(zhandle_t *zh, int xid, void_completion_t dc,
-        const void *data)
-{
-    return add_completion(zh, xid, COMPLETION_VOID, dc, data, 0, 0, 0);
-}
-
-static int add_string_completion(zhandle_t *zh, int xid,
-        string_completion_t dc, const void *data)
-{
-    return add_completion(zh, xid, COMPLETION_STRING, dc, data, 0, 0, 0);
-}
-
-static int add_multi_completion(zhandle_t *zh, int xid, void_completion_t dc,
-        const void *data, completion_head_t *clist)
-{
-    return add_completion(zh, xid, COMPLETION_MULTI, dc, data, 0,0, clist);
-}
-
-int zookeeper_close(zhandle_t *zh)
-{
-    int rc=ZOK;
-    if (zh==0)
-        return ZBADARGUMENTS;
-
-    zh->close_requested=1;
-    if (inc_ref_counter(zh,1)>1) {
-        /* We have incremented the ref counter to prevent the
-         * completions from calling zookeeper_close before we have
-         * completed the adaptor_finish call below. */
-
-	/* Signal any syncronous completions before joining the threads */
-        enter_critical(zh);
-        free_completions(zh,1,ZCLOSING);
-        leave_critical(zh);
-
-        adaptor_finish(zh);
-        /* Now we can allow the handle to be cleaned up, if the completion
-         * threads finished during the adaptor_finish call. */
-        api_epilog(zh, 0);
-        return ZOK;
-    }
-    /* No need to decrement the counter since we're just going to
-     * destroy the handle later. */
-    if(zh->state==ZOO_CONNECTED_STATE){
-        struct oarchive *oa;
-        struct RequestHeader h = { STRUCT_INITIALIZER (xid , get_xid()), STRUCT_INITIALIZER (type , ZOO_CLOSE_OP)};
-        LOG_INFO(("Closing zookeeper sessionId=%#llx to [%s]\n",
-                zh->client_id.client_id,format_current_endpoint_info(zh)));
-        oa = create_buffer_oarchive();
-        rc = serialize_RequestHeader(oa, "header", &h);
-        rc = rc < 0 ? rc : queue_buffer_bytes(&zh->to_send, get_buffer(oa),
-                get_buffer_len(oa));
-        /* We queued the buffer, so don't free it */
-        close_buffer_oarchive(&oa, 0);
-        if (rc < 0) {
-            rc = ZMARSHALLINGERROR;
-            goto finish;
-        }
-
-        /* make sure the close request is sent; we set timeout to an arbitrary
-         * (but reasonable) number of milliseconds since we want the call to block*/
-        rc=adaptor_send_queue(zh, 3000);
-    }else{
-        LOG_INFO(("Freeing zookeeper resources for sessionId=%#llx\n",
-                zh->client_id.client_id));
-        rc = ZOK;
-    }
-
-finish:
-    destroy(zh);
-    adaptor_destroy(zh);
-    free(zh);
-#ifdef WIN32
-    Win32WSACleanup();
-#endif
-    return rc;
-}
-
-static int isValidPath(const char* path, const int flags) {
-    int len = 0;
-    char lastc = '/';
-    char c;
-    int i = 0;
-
-  if (path == 0)
-    return 0;
-  len = strlen(path);
-  if (len == 0)
-    return 0;
-  if (path[0] != '/')
-    return 0;
-  if (len == 1) // done checking - it's the root
-    return 1;
-  if (path[len - 1] == '/' && !(flags & ZOO_SEQUENCE))
-    return 0;
-
-  i = 1;
-  for (; i < len; lastc = path[i], i++) {
-    c = path[i];
-
-    if (c == 0) {
-      return 0;
-    } else if (c == '/' && lastc == '/') {
-      return 0;
-    } else if (c == '.' && lastc == '.') {
-      if (path[i-2] == '/' && (((i + 1 == len) && !(flags & ZOO_SEQUENCE))
-                               || path[i+1] == '/')) {
-        return 0;
-      }
-    } else if (c == '.') {
-      if ((path[i-1] == '/') && (((i + 1 == len) && !(flags & ZOO_SEQUENCE))
-                                 || path[i+1] == '/')) {
-        return 0;
-      }
-    } else if (c > 0x00 && c < 0x1f) {
-      return 0;
-    }
-  }
-
-  return 1;
-}
-
-/*---------------------------------------------------------------------------*
- * REQUEST INIT HELPERS
- *---------------------------------------------------------------------------*/
-/* Common Request init helper functions to reduce code duplication */
-static int Request_path_init(zhandle_t *zh, int flags, 
-        char **path_out, const char *path)
-{
-    assert(path_out);
-    
-    *path_out = prepend_string(zh, path);
-    if (zh == NULL || !isValidPath(*path_out, flags)) {
-        free_duplicate_path(*path_out, path);
-        return ZBADARGUMENTS;
-    }
-    if (is_unrecoverable(zh)) {
-        free_duplicate_path(*path_out, path);
-        return ZINVALIDSTATE;
-    }
-
-    return ZOK;
-}
-
-static int Request_path_watch_init(zhandle_t *zh, int flags,
-        char **path_out, const char *path,
-        int32_t *watch_out, uint32_t watch)
-{
-    int rc = Request_path_init(zh, flags, path_out, path);
-    if (rc != ZOK) {
-        return rc;
-    }
-    *watch_out = watch;
-    return ZOK;
-}
-
-/*---------------------------------------------------------------------------*
- * ASYNC API
- *---------------------------------------------------------------------------*/
-int zoo_aget(zhandle_t *zh, const char *path, int watch, data_completion_t dc,
-        const void *data)
-{
-    return zoo_awget(zh,path,watch?zh->watcher:0,zh->context,dc,data);
-}
-
-int zoo_awget(zhandle_t *zh, const char *path,
-        watcher_fn watcher, void* watcherCtx,
-        data_completion_t dc, const void *data)
-{
-    struct oarchive *oa;
-    char *server_path = prepend_string(zh, path);
-    struct RequestHeader h = { STRUCT_INITIALIZER (xid , get_xid()), STRUCT_INITIALIZER (type ,ZOO_GETDATA_OP)};
-    struct GetDataRequest req =  { (char*)server_path, watcher!=0 };
-    int rc;
-
-    if (zh==0 || !isValidPath(server_path, 0)) {
-        free_duplicate_path(server_path, path);
-        return ZBADARGUMENTS;
-    }
-    if (is_unrecoverable(zh)) {
-        free_duplicate_path(server_path, path);
-        return ZINVALIDSTATE;
-    }
-    oa=create_buffer_oarchive();
-    rc = serialize_RequestHeader(oa, "header", &h);
-    rc = rc < 0 ? rc : serialize_GetDataRequest(oa, "req", &req);
-    enter_critical(zh);
-    rc = rc < 0 ? rc : add_data_completion(zh, h.xid, dc, data,
-        create_watcher_registration(server_path,data_result_checker,watcher,watcherCtx));
-    rc = rc < 0 ? rc : queue_buffer_bytes(&zh->to_send, get_buffer(oa),
-            get_buffer_len(oa));
-    leave_critical(zh);
-    free_duplicate_path(server_path, path);
-    /* We queued the buffer, so don't free it */
-    close_buffer_oarchive(&oa, 0);
-
-    LOG_DEBUG(("Sending request xid=%#x for path [%s] to %s",h.xid,path,
-            format_current_endpoint_info(zh)));
-    /* make a best (non-blocking) effort to send the requests asap */
-    adaptor_send_queue(zh, 0);
-    return (rc < 0)?ZMARSHALLINGERROR:ZOK;
-}
-
-static int SetDataRequest_init(zhandle_t *zh, struct SetDataRequest *req,
-        const char *path, const char *buffer, int buflen, int version)
-{
-    int rc;
-    assert(req);
-    rc = Request_path_init(zh, 0, &req->path, path);
-    if (rc != ZOK) {
-        return rc;
-    }
-    req->data.buff = (char*)buffer;
-    req->data.len = buflen;
-    req->version = version;
-
-    return ZOK;
-}
-
-int zoo_aset(zhandle_t *zh, const char *path, const char *buffer, int buflen,
-        int version, stat_completion_t dc, const void *data)
-{
-    struct oarchive *oa;
-    struct RequestHeader h = { STRUCT_INITIALIZER(xid , get_xid()), STRUCT_INITIALIZER (type , ZOO_SETDATA_OP)};
-    struct SetDataRequest req;
-    int rc = SetDataRequest_init(zh, &req, path, buffer, buflen, version);
-    if (rc != ZOK) {
-        return rc;
-    }
-    oa = create_buffer_oarchive();
-    rc = serialize_RequestHeader(oa, "header", &h);
-    rc = rc < 0 ? rc : serialize_SetDataRequest(oa, "req", &req);
-    enter_critical(zh);
-    rc = rc < 0 ? rc : add_stat_completion(zh, h.xid, dc, data,0);
-    rc = rc < 0 ? rc : queue_buffer_bytes(&zh->to_send, get_buffer(oa),
-            get_buffer_len(oa));
-    leave_criti

<TRUNCATED>

[13/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/TestClient.cc
----------------------------------------------------------------------
diff --git a/src/c/tests/TestClient.cc b/src/c/tests/TestClient.cc
deleted file mode 100644
index 154fbed..0000000
--- a/src/c/tests/TestClient.cc
+++ /dev/null
@@ -1,1135 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <cppunit/extensions/HelperMacros.h>
-#include "CppAssertHelper.h"
-
-#include <signal.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/select.h>
-
-#include "CollectionUtil.h"
-#include "ThreadingUtil.h"
-
-using namespace Util;
-
-#include "Vector.h"
-using namespace std;
-
-#include <cstring>
-#include <list>
-
-#include <zookeeper.h>
-#include <errno.h>
-#include <recordio.h>
-#include "Util.h"
-
-struct buff_struct_2 {
-    int32_t len;
-    int32_t off;
-    char *buffer;
-};
-
-static int Stat_eq(struct Stat* a, struct Stat* b)
-{
-    if (a->czxid != b->czxid) return 0;
-    if (a->mzxid != b->mzxid) return 0;
-    if (a->ctime != b->ctime) return 0;
-    if (a->mtime != b->mtime) return 0;
-    if (a->version != b->version) return 0;
-    if (a->cversion != b->cversion) return 0;
-    if (a->aversion != b->aversion) return 0;
-    if (a->ephemeralOwner != b->ephemeralOwner) return 0;
-    if (a->dataLength != b->dataLength) return 0;
-    if (a->numChildren != b->numChildren) return 0;
-    if (a->pzxid != b->pzxid) return 0;
-    return 1;
-}
-#ifdef THREADED
-    static void yield(zhandle_t *zh, int i)
-    {
-        sleep(i);
-    }
-#else
-    static void yield(zhandle_t *zh, int seconds)
-    {
-        int fd;
-        int interest;
-        int events;
-        struct timeval tv;
-        int rc;
-        time_t expires = time(0) + seconds;
-        time_t timeLeft = seconds;
-        fd_set rfds, wfds, efds;
-        FD_ZERO(&rfds);
-        FD_ZERO(&wfds);
-        FD_ZERO(&efds);
-
-        while(timeLeft >= 0) {
-            zookeeper_interest(zh, &fd, &interest, &tv);
-            if (fd != -1) {
-                if (interest&ZOOKEEPER_READ) {
-                    FD_SET(fd, &rfds);
-                } else {
-                    FD_CLR(fd, &rfds);
-                }
-                if (interest&ZOOKEEPER_WRITE) {
-                    FD_SET(fd, &wfds);
-                } else {
-                    FD_CLR(fd, &wfds);
-                }
-            } else {
-                fd = 0;
-            }
-            FD_SET(0, &rfds);
-            if (tv.tv_sec > timeLeft) {
-                tv.tv_sec = timeLeft;
-            }
-            rc = select(fd+1, &rfds, &wfds, &efds, &tv);
-            timeLeft = expires - time(0);
-            events = 0;
-            if (FD_ISSET(fd, &rfds)) {
-                events |= ZOOKEEPER_READ;
-            }
-            if (FD_ISSET(fd, &wfds)) {
-                events |= ZOOKEEPER_WRITE;
-            }
-            zookeeper_process(zh, events);
-        }
-    }
-#endif
-
-typedef struct evt {
-    string path;
-    int type;
-} evt_t;
-
-typedef struct watchCtx {
-private:
-    list<evt_t> events;
-    watchCtx(const watchCtx&);
-    watchCtx& operator=(const watchCtx&);
-public:
-    bool connected;
-    zhandle_t *zh;
-    Mutex mutex;
-
-    watchCtx() {
-        connected = false;
-        zh = 0;
-    }
-    ~watchCtx() {
-        if (zh) {
-            zookeeper_close(zh);
-            zh = 0;
-        }
-    }
-
-    evt_t getEvent() {
-        evt_t evt;
-        mutex.acquire();
-        CPPUNIT_ASSERT( events.size() > 0);
-        evt = events.front();
-        events.pop_front();
-        mutex.release();
-        return evt;
-    }
-
-    int countEvents() {
-        int count;
-        mutex.acquire();
-        count = events.size();
-        mutex.release();
-        return count;
-    }
-
-    void putEvent(evt_t evt) {
-        mutex.acquire();
-        events.push_back(evt);
-        mutex.release();
-    }
-
-    bool waitForConnected(zhandle_t *zh) {
-        time_t expires = time(0) + 10;
-        while(!connected && time(0) < expires) {
-            yield(zh, 1);
-        }
-        return connected;
-    }
-    bool waitForDisconnected(zhandle_t *zh) {
-        time_t expires = time(0) + 15;
-        while(connected && time(0) < expires) {
-            yield(zh, 1);
-        }
-        return !connected;
-    }
-} watchctx_t;
-
-class Zookeeper_simpleSystem : public CPPUNIT_NS::TestFixture
-{
-    CPPUNIT_TEST_SUITE(Zookeeper_simpleSystem);
-    CPPUNIT_TEST(testAsyncWatcherAutoReset);
-    CPPUNIT_TEST(testDeserializeString);
-    CPPUNIT_TEST(testFirstServerDown);
-#ifdef THREADED
-    CPPUNIT_TEST(testNullData);
-#ifdef ZOO_IPV6_ENABLED
-    CPPUNIT_TEST(testIPV6);
-#endif
-    CPPUNIT_TEST(testPath);
-    CPPUNIT_TEST(testPathValidation);
-    CPPUNIT_TEST(testPing);
-    CPPUNIT_TEST(testAcl);
-    CPPUNIT_TEST(testChroot);
-    CPPUNIT_TEST(testAuth);
-    CPPUNIT_TEST(testHangingClient);
-    CPPUNIT_TEST(testWatcherAutoResetWithGlobal);
-    CPPUNIT_TEST(testWatcherAutoResetWithLocal);
-    CPPUNIT_TEST(testGetChildren2);
-#endif
-    CPPUNIT_TEST_SUITE_END();
-
-    static void watcher(zhandle_t *, int type, int state, const char *path,void*v){
-        watchctx_t *ctx = (watchctx_t*)v;
-
-        if (state == ZOO_CONNECTED_STATE) {
-            ctx->connected = true;
-        } else {
-            ctx->connected = false;
-        }
-        if (type != ZOO_SESSION_EVENT) {
-            evt_t evt;
-            evt.path = path;
-            evt.type = type;
-            ctx->putEvent(evt);
-        }
-    }
-
-    static const char hostPorts[];
-
-    const char *getHostPorts() {
-        return hostPorts;
-    }
-    
-    zhandle_t *createClient(watchctx_t *ctx) {
-        return createClient(hostPorts, ctx);
-    }
-
-    zhandle_t *createClient(const char *hp, watchctx_t *ctx) {
-        zhandle_t *zk = zookeeper_init(hp, watcher, 10000, 0, ctx, 0);
-        ctx->zh = zk;
-        sleep(1);
-        return zk;
-    }
-    
-    zhandle_t *createchClient(watchctx_t *ctx, const char* chroot) {
-        zhandle_t *zk = zookeeper_init(chroot, watcher, 10000, 0, ctx, 0);
-        ctx->zh = zk;
-        sleep(1);
-        return zk;
-    }
-        
-    FILE *logfile;
-public:
-
-    Zookeeper_simpleSystem() {
-      logfile = openlogfile("Zookeeper_simpleSystem");
-    }
-
-    ~Zookeeper_simpleSystem() {
-      if (logfile) {
-        fflush(logfile);
-        fclose(logfile);
-        logfile = 0;
-      }
-    }
-
-    void setUp()
-    {
-        zoo_set_log_stream(logfile);
-    }
-
-
-    void startServer() {
-        char cmd[1024];
-        sprintf(cmd, "%s start %s", ZKSERVER_CMD, getHostPorts());
-        CPPUNIT_ASSERT(system(cmd) == 0);
-    }
-
-    void stopServer() {
-        char cmd[1024];
-        sprintf(cmd, "%s stop %s", ZKSERVER_CMD, getHostPorts());
-        CPPUNIT_ASSERT(system(cmd) == 0);
-    }
-
-    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);
-    }
-
-    /** ZOOKEEPER-1057 This checks that the client connects to the second server when the first is not reachable **/
-    void testFirstServerDown() {
-        watchctx_t ctx;
-
-        zoo_deterministic_conn_order(true);
-
-        zhandle_t* zk = createClient("127.0.0.1:22182,127.0.0.1:22181", &ctx);
-        CPPUNIT_ASSERT(zk != 0);
-        CPPUNIT_ASSERT(ctx.waitForConnected(zk));
-    }
-    
-    /** 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()
-    {
-        watchctx_t ctxIdle;
-        watchctx_t ctxWC;
-        zhandle_t *zkIdle = createClient(&ctxIdle);
-        zhandle_t *zkWatchCreator = createClient(&ctxWC);
-
-        CPPUNIT_ASSERT(zkIdle);
-        CPPUNIT_ASSERT(zkWatchCreator);
-
-        char path[80];
-        sprintf(path, "/testping");
-        int rc = zoo_create(zkWatchCreator, path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        for(int i = 0; i < 30; i++) {
-            sprintf(path, "/testping/%i", i);
-            rc = zoo_create(zkWatchCreator, path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        }
-
-        for(int i = 0; i < 30; i++) {
-            sprintf(path, "/testping/%i", i);
-            struct Stat stat;
-            rc = zoo_exists(zkIdle, path, 1, &stat);
-            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        }
-
-        for(int i = 0; i < 30; i++) {
-            sprintf(path, "/testping/%i", i);
-            usleep(500000);
-            rc = zoo_delete(zkWatchCreator, path, -1);
-            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        }
-        struct Stat stat;
-        CPPUNIT_ASSERT_EQUAL((int)ZNONODE, zoo_exists(zkIdle, "/testping/0", 0, &stat));
-    }
-
-    bool waitForEvent(zhandle_t *zh, watchctx_t *ctx, int seconds) {
-        time_t expires = time(0) + seconds;
-        while(ctx->countEvents() == 0 && time(0) < expires) {
-            yield(zh, 1);
-        }
-        return ctx->countEvents() > 0;
-    }
-
-#define COUNT 100
-
-    static zhandle_t *async_zk;
-    static volatile int count;
-    static const char* hp_chroot;
-
-    static void statCompletion(int rc, const struct Stat *stat, const void *data) {
-        int tmp = (int) (long) data;
-        CPPUNIT_ASSERT_EQUAL(tmp, rc);
-    }
-
-    static void stringCompletion(int rc, const char *value, const void *data) {
-        char *path = (char*)data;
-
-        if (rc == ZCONNECTIONLOSS && path) {
-            // Try again
-            rc = zoo_acreate(async_zk, path, "", 0,  &ZOO_OPEN_ACL_UNSAFE, 0, stringCompletion, 0);
-        } else if (rc != ZOK) {
-            // fprintf(stderr, "rc = %d with path = %s\n", rc, (path ? path : "null"));
-        }
-        if (path) {
-            free(path);
-        }
-    }
-
-    static void create_completion_fn(int rc, const char* value, const void *data) {
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        count++;
-    }
-
-    static void waitForCreateCompletion(int seconds) {
-        time_t expires = time(0) + seconds;
-        while(count == 0 && time(0) < expires) {
-            sleep(1);
-        }
-        count--;
-    }
-
-    static void watcher_chroot_fn(zhandle_t *zh, int type,
-                                    int state, const char *path,void *watcherCtx) {
-        // check for path
-        char *client_path = (char *) watcherCtx;
-        CPPUNIT_ASSERT(strcmp(client_path, path) == 0);
-        count ++;
-    }
-
-    static void waitForChrootWatch(int seconds) {
-        time_t expires = time(0) + seconds;
-        while (count == 0 && time(0) < expires) {
-            sleep(1);
-        }
-        count--;
-    }
-
-    static void waitForVoidCompletion(int seconds) {
-        time_t expires = time(0) + seconds;
-        while(count == 0 && time(0) < expires) {
-            sleep(1);
-        }
-        count--;
-    }
-
-    static void voidCompletion(int rc, const void *data) {
-        int tmp = (int) (long) data;
-        CPPUNIT_ASSERT_EQUAL(tmp, rc);
-        count++;
-    }
-
-    static void verifyCreateFails(const char *path, zhandle_t *zk) {
-      CPPUNIT_ASSERT_EQUAL((int)ZBADARGUMENTS, zoo_create(zk,
-          path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0));
-    }
-
-    static void verifyCreateOk(const char *path, zhandle_t *zk) {
-      CPPUNIT_ASSERT_EQUAL((int)ZOK, zoo_create(zk,
-          path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0));
-    }
-
-    static void verifyCreateFailsSeq(const char *path, zhandle_t *zk) {
-      CPPUNIT_ASSERT_EQUAL((int)ZBADARGUMENTS, zoo_create(zk,
-          path, "", 0, &ZOO_OPEN_ACL_UNSAFE, ZOO_SEQUENCE, 0, 0));
-    }
-
-    static void verifyCreateOkSeq(const char *path, zhandle_t *zk) {
-      CPPUNIT_ASSERT_EQUAL((int)ZOK, zoo_create(zk,
-          path, "", 0, &ZOO_OPEN_ACL_UNSAFE, ZOO_SEQUENCE, 0, 0));
-    }
-
-
-    /**
-       returns false if the vectors dont match
-    **/
-    bool compareAcl(struct ACL_vector acl1, struct ACL_vector acl2) {
-        if (acl1.count != acl2.count) {
-            return false;
-        }
-        struct ACL *aclval1 = acl1.data;
-        struct ACL *aclval2 = acl2.data;
-        if (aclval1->perms != aclval2->perms) {
-            return false;
-        }
-        struct Id id1 = aclval1->id;
-        struct Id id2 = aclval2->id;
-        if (strcmp(id1.scheme, id2.scheme) != 0) {
-            return false;
-        }
-        if (strcmp(id1.id, id2.id) != 0) {
-            return false;
-        }
-        return true;
-    }
-
-    void testDeserializeString() {
-        char *val_str;
-        int rc = 0;
-        int val = -1;
-        struct iarchive *ia;
-        struct buff_struct_2 *b;
-        struct oarchive *oa = create_buffer_oarchive();
-        oa->serialize_Int(oa, "int", &val);
-        b = (struct buff_struct_2 *) oa->priv;
-        ia = create_buffer_iarchive(b->buffer, b->len);
-        rc = ia->deserialize_String(ia, "string", &val_str);
-        CPPUNIT_ASSERT_EQUAL(-EINVAL, rc);
-    }
-        
-    void testAcl() {
-        int rc;
-        struct ACL_vector aclvec;
-        struct Stat stat;
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-        rc = zoo_create(zk, "/acl", "", 0,
-                        &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        rc = zoo_get_acl(zk, "/acl", &aclvec, &stat  );
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        bool cmp = compareAcl(ZOO_OPEN_ACL_UNSAFE, aclvec);
-        CPPUNIT_ASSERT_EQUAL(true, cmp);
-        rc = zoo_set_acl(zk, "/acl", -1, &ZOO_READ_ACL_UNSAFE);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        rc = zoo_get_acl(zk, "/acl", &aclvec, &stat);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        cmp = compareAcl(ZOO_READ_ACL_UNSAFE, aclvec);
-        CPPUNIT_ASSERT_EQUAL(true, cmp);
-    }
-
-
-    void testAuth() {
-        int rc;
-        count = 0;
-        watchctx_t ctx1, ctx2, ctx3, ctx4, ctx5;
-        zhandle_t *zk = createClient(&ctx1);
-        struct ACL_vector nodeAcl;
-        struct ACL acl_val;
-        rc = zoo_add_auth(0, "", 0, 0, voidCompletion, (void*)-1);
-        CPPUNIT_ASSERT_EQUAL((int) ZBADARGUMENTS, rc);
-
-        rc = zoo_add_auth(zk, 0, 0, 0, voidCompletion, (void*)-1);
-        CPPUNIT_ASSERT_EQUAL((int) ZBADARGUMENTS, rc);
-
-        // auth as pat, create /tauth1, close session
-        rc = zoo_add_auth(zk, "digest", "pat:passwd", 10, voidCompletion,
-                          (void*)ZOK);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        waitForVoidCompletion(3);
-        CPPUNIT_ASSERT(count == 0);
-
-        rc = zoo_create(zk, "/tauth1", "", 0, &ZOO_CREATOR_ALL_ACL, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        {
-            //create a new client
-            zk = createClient(&ctx4);
-            rc = zoo_add_auth(zk, "digest", "", 0, voidCompletion, (void*)ZOK);
-            CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-            waitForVoidCompletion(3);
-            CPPUNIT_ASSERT(count == 0);
-
-            rc = zoo_add_auth(zk, "digest", "", 0, voidCompletion, (void*)ZOK);
-            CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-            waitForVoidCompletion(3);
-            CPPUNIT_ASSERT(count == 0);
-        }
-
-        //create a new client
-        zk = createClient(&ctx2);
-
-        rc = zoo_add_auth(zk, "digest", "pat:passwd2", 11, voidCompletion,
-                          (void*)ZOK);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        waitForVoidCompletion(3);
-        CPPUNIT_ASSERT(count == 0);
-
-        char buf[1024];
-        int blen = sizeof(buf);
-        struct Stat stat;
-        rc = zoo_get(zk, "/tauth1", 0, buf, &blen, &stat);
-        CPPUNIT_ASSERT_EQUAL((int)ZNOAUTH, rc);
-        // add auth pat w/correct pass verify success
-        rc = zoo_add_auth(zk, "digest", "pat:passwd", 10, voidCompletion,
-                          (void*)ZOK);
-
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        rc = zoo_get(zk, "/tauth1", 0, buf, &blen, &stat);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        waitForVoidCompletion(3);
-        CPPUNIT_ASSERT(count == 0);
-        //create a new client
-        zk = createClient(&ctx3);
-        rc = zoo_add_auth(zk, "digest", "pat:passwd", 10, voidCompletion, (void*) ZOK);
-        waitForVoidCompletion(3);
-        CPPUNIT_ASSERT(count == 0);
-        rc = zoo_add_auth(zk, "ip", "none", 4, voidCompletion, (void*)ZOK);
-        //make the server forget the auths
-        waitForVoidCompletion(3);
-        CPPUNIT_ASSERT(count == 0);
-
-        stopServer();
-        CPPUNIT_ASSERT(ctx3.waitForDisconnected(zk));
-        startServer();
-        CPPUNIT_ASSERT(ctx3.waitForConnected(zk));
-        // now try getting the data
-        rc = zoo_get(zk, "/tauth1", 0, buf, &blen, &stat);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        // also check for get
-        rc = zoo_get_acl(zk, "/", &nodeAcl, &stat);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        // check if the acl has all the perms
-        CPPUNIT_ASSERT_EQUAL((int)1, (int)nodeAcl.count);
-        acl_val = *(nodeAcl.data);
-        CPPUNIT_ASSERT_EQUAL((int) acl_val.perms, ZOO_PERM_ALL);
-        // verify on root node
-        rc = zoo_set_acl(zk, "/", -1, &ZOO_CREATOR_ALL_ACL);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-
-        rc = zoo_set_acl(zk, "/", -1, &ZOO_OPEN_ACL_UNSAFE);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-
-        //[ZOOKEEPER-1108], test that auth info is sent to server, if client is not
-        //connected to server when zoo_add_auth was called.
-        zhandle_t *zk_auth = zookeeper_init(hostPorts, NULL, 10000, 0, NULL, 0);
-        rc = zoo_add_auth(zk_auth, "digest", "pat:passwd", 10, voidCompletion, (void*)ZOK);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        sleep(2);
-        CPPUNIT_ASSERT(count == 1);
-        count  = 0;
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, zookeeper_close(zk_auth));
-        
-        // [ZOOKEEPER-800] zoo_add_auth should return ZINVALIDSTATE if
-        // the connection is closed. 
-        zhandle_t *zk2 = zookeeper_init(hostPorts, NULL, 10000, 0, NULL, 0);
-        sleep(1);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, zookeeper_close(zk2));
-        CPPUNIT_ASSERT_EQUAL(0, zoo_state(zk2)); // 0 ==> ZOO_CLOSED_STATE
-        rc = zoo_add_auth(zk2, "digest", "pat:passwd", 10, voidCompletion, (void*)ZOK);
-        CPPUNIT_ASSERT_EQUAL((int) ZINVALIDSTATE, rc);
-
-        struct sockaddr addr;
-        socklen_t addr_len = sizeof(addr);
-        zk = createClient(&ctx5);
-        stopServer();
-        CPPUNIT_ASSERT(ctx5.waitForDisconnected(zk));
-        CPPUNIT_ASSERT(zookeeper_get_connected_host(zk, &addr, &addr_len) == NULL);
-        addr_len = sizeof(addr);
-        startServer();
-        CPPUNIT_ASSERT(ctx5.waitForConnected(zk));
-        CPPUNIT_ASSERT(zookeeper_get_connected_host(zk, &addr, &addr_len) != NULL);
-    }
-
-    void testGetChildren2() {
-        int rc;
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-
-        rc = zoo_create(zk, "/parent", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        rc = zoo_create(zk, "/parent/child_a", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        rc = zoo_create(zk, "/parent/child_b", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        rc = zoo_create(zk, "/parent/child_c", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        rc = zoo_create(zk, "/parent/child_d", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        struct String_vector strings;
-        struct Stat stat_a, stat_b;
-
-        rc = zoo_get_children2(zk, "/parent", 0, &strings, &stat_a);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        rc = zoo_exists(zk, "/parent", 0, &stat_b);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        CPPUNIT_ASSERT(Stat_eq(&stat_a, &stat_b));
-        CPPUNIT_ASSERT(stat_a.numChildren == 4);
-    }
-
-    void testIPV6() {
-        watchctx_t ctx;
-        zhandle_t *zk = createClient("::1:22181", &ctx);
-        CPPUNIT_ASSERT(zk);
-        int rc = 0;
-        rc = zoo_create(zk, "/ipv6", NULL, -1,
-                        &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-    }
-
-    void testNullData() {
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-        CPPUNIT_ASSERT(zk);
-        int rc = 0;
-        rc = zoo_create(zk, "/mahadev", NULL, -1,
-                        &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        char buffer[512];
-        struct Stat stat;
-        int len = 512;
-        rc = zoo_wget(zk, "/mahadev", NULL, NULL, buffer, &len, &stat);
-        CPPUNIT_ASSERT_EQUAL( -1, len);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        rc = zoo_set(zk, "/mahadev", NULL, -1, -1);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        rc = zoo_wget(zk, "/mahadev", NULL, NULL, buffer, &len, &stat);
-        CPPUNIT_ASSERT_EQUAL( -1, len);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-    }
-
-    void testPath() {
-        watchctx_t ctx;
-        char pathbuf[20];
-        zhandle_t *zk = createClient(&ctx);
-        CPPUNIT_ASSERT(zk);
-        int rc = 0;
-
-        memset(pathbuf, 'X', 20);
-        rc = zoo_create(zk, "/testpathpath0", "", 0,
-                        &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 0);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        CPPUNIT_ASSERT_EQUAL('X', pathbuf[0]);
-
-        rc = zoo_create(zk, "/testpathpath1", "", 0,
-                        &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 1);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        CPPUNIT_ASSERT(strlen(pathbuf) == 0);
-
-        rc = zoo_create(zk, "/testpathpath2", "", 0,
-                        &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 2);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        CPPUNIT_ASSERT(strcmp(pathbuf, "/") == 0);
-
-        rc = zoo_create(zk, "/testpathpath3", "", 0,
-                        &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 3);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        CPPUNIT_ASSERT(strcmp(pathbuf, "/t") == 0);
-
-        rc = zoo_create(zk, "/testpathpath7", "", 0,
-                        &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 15);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        CPPUNIT_ASSERT(strcmp(pathbuf, "/testpathpath7") == 0);
-
-        rc = zoo_create(zk, "/testpathpath8", "", 0,
-                        &ZOO_OPEN_ACL_UNSAFE, 0, pathbuf, 16);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        CPPUNIT_ASSERT(strcmp(pathbuf, "/testpathpath8") == 0);
-    }
-
-    void testPathValidation() {
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-        CPPUNIT_ASSERT(zk);
-
-        verifyCreateFails(0, zk);
-        verifyCreateFails("", zk);
-        verifyCreateFails("//", zk);
-        verifyCreateFails("///", zk);
-        verifyCreateFails("////", zk);
-        verifyCreateFails("/.", zk);
-        verifyCreateFails("/..", zk);
-        verifyCreateFails("/./", zk);
-        verifyCreateFails("/../", zk);
-        verifyCreateFails("/foo/./", zk);
-        verifyCreateFails("/foo/../", zk);
-        verifyCreateFails("/foo/.", zk);
-        verifyCreateFails("/foo/..", zk);
-        verifyCreateFails("/./.", zk);
-        verifyCreateFails("/../..", zk);
-        verifyCreateFails("/foo/bar/", zk);
-        verifyCreateFails("/foo//bar", zk);
-        verifyCreateFails("/foo/bar//", zk);
-
-        verifyCreateFails("foo", zk);
-        verifyCreateFails("a", zk);
-
-        // verify that trailing fails, except for seq which adds suffix
-        verifyCreateOk("/createseq", zk);
-        verifyCreateFails("/createseq/", zk);
-        verifyCreateOkSeq("/createseq/", zk);
-        verifyCreateOkSeq("/createseq/.", zk);
-        verifyCreateOkSeq("/createseq/..", zk);
-        verifyCreateFailsSeq("/createseq//", zk);
-        verifyCreateFailsSeq("/createseq/./", zk);
-        verifyCreateFailsSeq("/createseq/../", zk);
-
-        verifyCreateOk("/.foo", zk);
-        verifyCreateOk("/.f.", zk);
-        verifyCreateOk("/..f", zk);
-        verifyCreateOk("/..f..", zk);
-        verifyCreateOk("/f.c", zk);
-        verifyCreateOk("/f", zk);
-        verifyCreateOk("/f/.f", zk);
-        verifyCreateOk("/f/f.", zk);
-        verifyCreateOk("/f/..f", zk);
-        verifyCreateOk("/f/f..", zk);
-        verifyCreateOk("/f/.f/f", zk);
-        verifyCreateOk("/f/f./f", zk);
-    }
-
-    void testChroot() {
-        // the c client async callbacks do
-        // not callback with the path, so
-        // we dont need to test taht for now
-        // we should fix that though soon!
-        watchctx_t ctx, ctx_ch;
-        zhandle_t *zk, *zk_ch;
-        char buf[60];
-        int rc, len;
-        struct Stat stat;
-        const char* data = "garbage";
-        const char* retStr = "/chroot";
-        const char* root= "/";
-        zk_ch = createchClient(&ctx_ch, "127.0.0.1:22181/testch1/mahadev");
-        CPPUNIT_ASSERT(zk_ch != NULL);
-        zk = createClient(&ctx);
-        // first test with a NULL zk handle, make sure client library does not
-        // dereference a null pointer, but instead returns ZBADARGUMENTS
-        rc = zoo_create(NULL, "/testch1", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int) ZBADARGUMENTS, rc);
-        rc = zoo_create(zk, "/testch1", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        rc = zoo_create(zk, "/testch1/mahadev", data, 7, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        // try an exists with /
-        len = 60;
-        rc = zoo_get(zk_ch, "/", 0, buf, &len, &stat);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        //check if the data is the same
-        CPPUNIT_ASSERT(strncmp(buf, data, 7) == 0);
-        //check for watches
-        rc = zoo_wexists(zk_ch, "/chroot", watcher_chroot_fn, (void *) retStr, &stat);
-        //now check if we can do create/delete/get/sets/acls/getChildren and others
-        //check create
-        rc = zoo_create(zk_ch, "/chroot", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0,0);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        waitForChrootWatch(3);
-        CPPUNIT_ASSERT(count == 0);
-        rc = zoo_create(zk_ch, "/chroot/child", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        rc = zoo_exists(zk, "/testch1/mahadev/chroot/child", 0, &stat);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-
-        rc = zoo_delete(zk_ch, "/chroot/child", -1);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        rc = zoo_exists(zk, "/testch1/mahadev/chroot/child", 0, &stat);
-        CPPUNIT_ASSERT_EQUAL((int) ZNONODE, rc);
-        rc = zoo_wget(zk_ch, "/chroot", watcher_chroot_fn, (char*) retStr,
-                      buf, &len, &stat);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        rc = zoo_set(zk_ch, "/chroot",buf, 3, -1);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        waitForChrootWatch(3);
-        CPPUNIT_ASSERT(count == 0);
-        // check for getchildren
-        struct String_vector children;
-        rc = zoo_get_children(zk_ch, "/", 0, &children);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        CPPUNIT_ASSERT_EQUAL((int)1, (int)children.count);
-        //check if te child if chroot
-        CPPUNIT_ASSERT(strcmp((retStr+1), children.data[0]) == 0);
-        // check for get/set acl
-        struct ACL_vector acl;
-        rc = zoo_get_acl(zk_ch, "/", &acl, &stat);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        CPPUNIT_ASSERT_EQUAL((int)1, (int)acl.count);
-        CPPUNIT_ASSERT_EQUAL((int)ZOO_PERM_ALL, (int)acl.data->perms);
-        // set acl
-        rc = zoo_set_acl(zk_ch, "/chroot", -1,  &ZOO_READ_ACL_UNSAFE);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        // see if you add children
-        rc = zoo_create(zk_ch, "/chroot/child1", "",0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int)ZNOAUTH, rc);
-        //add wget children test
-        rc = zoo_wget_children(zk_ch, "/", watcher_chroot_fn, (char*) root, &children);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        //now create a node
-        rc = zoo_create(zk_ch, "/child2", "",0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        waitForChrootWatch(3);
-        CPPUNIT_ASSERT(count == 0);
-        //check for one async call just to make sure
-        rc = zoo_acreate(zk_ch, "/child3", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0,
-                         create_completion_fn, 0);
-        waitForCreateCompletion(3);
-        CPPUNIT_ASSERT(count == 0);
-
-        //ZOOKEEPER-1027 correctly return path_buffer without prefixed chroot
-        const char* path = "/zookeeper1027";
-        char path_buffer[1024];
-        int path_buffer_len=sizeof(path_buffer);
-        rc = zoo_create(zk_ch, path, "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, path_buffer, path_buffer_len);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        CPPUNIT_ASSERT_EQUAL(string(path), string(path_buffer));
-    }
-
-    void testAsyncWatcherAutoReset()
-    {
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-        watchctx_t lctx[COUNT];
-        int i;
-        char path[80];
-        int rc;
-        evt_t evt;
-
-        async_zk = zk;
-        for(i = 0; i < COUNT; i++) {
-            sprintf(path, "/awar%d", i);
-            rc = zoo_awexists(zk, path, watcher, &lctx[i], statCompletion, (void*)ZNONODE);
-            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        }
-
-        yield(zk, 0);
-
-        for(i = 0; i < COUNT/2; i++) {
-            sprintf(path, "/awar%d", i);
-            rc = zoo_acreate(zk, path, "", 0,  &ZOO_OPEN_ACL_UNSAFE, 0, stringCompletion, strdup(path));
-            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        }
-
-        yield(zk, 3);
-        for(i = 0; i < COUNT/2; i++) {
-            sprintf(path, "/awar%d", i);
-            CPPUNIT_ASSERT_MESSAGE(path, waitForEvent(zk, &lctx[i], 5));
-            evt = lctx[i].getEvent();
-            CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path.c_str(), ZOO_CREATED_EVENT, evt.type);
-            CPPUNIT_ASSERT_EQUAL(string(path), evt.path);
-        }
-
-        for(i = COUNT/2 + 1; i < COUNT*10; i++) {
-            sprintf(path, "/awar%d", i);
-            rc = zoo_acreate(zk, path, "", 0,  &ZOO_OPEN_ACL_UNSAFE, 0, stringCompletion, strdup(path));
-            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        }
-
-        yield(zk, 1);
-        stopServer();
-        CPPUNIT_ASSERT(ctx.waitForDisconnected(zk));
-        startServer();
-        CPPUNIT_ASSERT(ctx.waitForConnected(zk));
-        yield(zk, 3);
-        for(i = COUNT/2+1; i < COUNT; i++) {
-            sprintf(path, "/awar%d", i);
-            CPPUNIT_ASSERT_MESSAGE(path, waitForEvent(zk, &lctx[i], 5));
-            evt = lctx[i].getEvent();
-            CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_CREATED_EVENT, evt.type);
-            CPPUNIT_ASSERT_EQUAL(string(path), evt.path);
-        }
-    }
-
-    void testWatcherAutoReset(zhandle_t *zk, watchctx_t *ctxGlobal,
-                              watchctx_t *ctxLocal)
-    {
-        bool isGlobal = (ctxGlobal == ctxLocal);
-        int rc;
-        struct Stat stat;
-        char buf[1024];
-        int blen;
-        struct String_vector strings;
-        const char *testName;
-
-        rc = zoo_create(zk, "/watchtest", "", 0,
-                        &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        rc = zoo_create(zk, "/watchtest/child", "", 0,
-                        &ZOO_OPEN_ACL_UNSAFE, ZOO_EPHEMERAL, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        if (isGlobal) {
-            testName = "GlobalTest";
-            rc = zoo_get_children(zk, "/watchtest", 1, &strings);
-            deallocate_String_vector(&strings);
-            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-            blen = sizeof(buf);
-            rc = zoo_get(zk, "/watchtest/child", 1, buf, &blen, &stat);
-            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-            rc = zoo_exists(zk, "/watchtest/child2", 1, &stat);
-            CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
-        } else {
-            testName = "LocalTest";
-            rc = zoo_wget_children(zk, "/watchtest", watcher, ctxLocal,
-                                 &strings);
-            deallocate_String_vector(&strings);
-            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-            blen = sizeof(buf);
-            rc = zoo_wget(zk, "/watchtest/child", watcher, ctxLocal,
-                         buf, &blen, &stat);
-            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-            rc = zoo_wexists(zk, "/watchtest/child2", watcher, ctxLocal,
-                            &stat);
-            CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
-        }
-
-        CPPUNIT_ASSERT(ctxLocal->countEvents() == 0);
-
-        stopServer();
-        CPPUNIT_ASSERT_MESSAGE(testName, ctxGlobal->waitForDisconnected(zk));
-        startServer();
-        CPPUNIT_ASSERT_MESSAGE(testName, ctxLocal->waitForConnected(zk));
-
-        CPPUNIT_ASSERT(ctxLocal->countEvents() == 0);
-
-        rc = zoo_set(zk, "/watchtest/child", "1", 1, -1);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        struct Stat stat1, stat2;
-        rc = zoo_set2(zk, "/watchtest/child", "1", 1, -1, &stat1);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        CPPUNIT_ASSERT(stat1.version >= 0);
-        rc = zoo_set2(zk, "/watchtest/child", "1", 1, stat1.version, &stat2);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        rc = zoo_set(zk, "/watchtest/child", "1", 1, stat2.version);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        rc = zoo_create(zk, "/watchtest/child2", "", 0,
-                        &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
-
-        evt_t evt = ctxLocal->getEvent();
-        CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_CHANGED_EVENT, evt.type);
-        CPPUNIT_ASSERT_EQUAL(string("/watchtest/child"), evt.path);
-
-        CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
-        // The create will trigget the get children and the
-        // exists watches
-        evt = ctxLocal->getEvent();
-        CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_CREATED_EVENT, evt.type);
-        CPPUNIT_ASSERT_EQUAL(string("/watchtest/child2"), evt.path);
-        CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
-        evt = ctxLocal->getEvent();
-        CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_CHILD_EVENT, evt.type);
-        CPPUNIT_ASSERT_EQUAL(string("/watchtest"), evt.path);
-
-        // Make sure Pings are giving us problems
-        sleep(5);
-
-        CPPUNIT_ASSERT(ctxLocal->countEvents() == 0);
-
-        stopServer();
-        CPPUNIT_ASSERT_MESSAGE(testName, ctxGlobal->waitForDisconnected(zk));
-        startServer();
-        CPPUNIT_ASSERT_MESSAGE(testName, ctxGlobal->waitForConnected(zk));
-
-        if (isGlobal) {
-            testName = "GlobalTest";
-            rc = zoo_get_children(zk, "/watchtest", 1, &strings);
-            deallocate_String_vector(&strings);
-            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-            blen = sizeof(buf);
-            rc = zoo_get(zk, "/watchtest/child", 1, buf, &blen, &stat);
-            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-            rc = zoo_exists(zk, "/watchtest/child2", 1, &stat);
-            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        } else {
-            testName = "LocalTest";
-            rc = zoo_wget_children(zk, "/watchtest", watcher, ctxLocal,
-                                 &strings);
-            deallocate_String_vector(&strings);
-            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-            blen = sizeof(buf);
-            rc = zoo_wget(zk, "/watchtest/child", watcher, ctxLocal,
-                         buf, &blen, &stat);
-            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-            rc = zoo_wexists(zk, "/watchtest/child2", watcher, ctxLocal,
-                            &stat);
-            CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        }
-
-        zoo_delete(zk, "/watchtest/child2", -1);
-
-        CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
-
-        evt = ctxLocal->getEvent();
-        CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_DELETED_EVENT, evt.type);
-        CPPUNIT_ASSERT_EQUAL(string("/watchtest/child2"), evt.path);
-
-        CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
-        evt = ctxLocal->getEvent();
-        CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_CHILD_EVENT, evt.type);
-        CPPUNIT_ASSERT_EQUAL(string("/watchtest"), evt.path);
-
-        stopServer();
-        CPPUNIT_ASSERT_MESSAGE(testName, ctxGlobal->waitForDisconnected(zk));
-        startServer();
-        CPPUNIT_ASSERT_MESSAGE(testName, ctxLocal->waitForConnected(zk));
-
-        zoo_delete(zk, "/watchtest/child", -1);
-        zoo_delete(zk, "/watchtest", -1);
-
-        CPPUNIT_ASSERT_MESSAGE(testName, waitForEvent(zk, ctxLocal, 5));
-
-        evt = ctxLocal->getEvent();
-        CPPUNIT_ASSERT_EQUAL_MESSAGE(evt.path, ZOO_DELETED_EVENT, evt.type);
-        CPPUNIT_ASSERT_EQUAL(string("/watchtest/child"), evt.path);
-
-        // Make sure nothing is straggling
-        sleep(1);
-        CPPUNIT_ASSERT(ctxLocal->countEvents() == 0);
-    }
-
-    void testWatcherAutoResetWithGlobal()
-    {
-      {
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-        int rc = zoo_create(zk, "/testarwg", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        rc = zoo_create(zk, "/testarwg/arwg", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-      }
-
-      {
-        watchctx_t ctx;
-        zhandle_t *zk = createchClient(&ctx, "127.0.0.1:22181/testarwg/arwg");
-
-        testWatcherAutoReset(zk, &ctx, &ctx);
-      }
-    }
-
-    void testWatcherAutoResetWithLocal()
-    {
-      {
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-        int rc = zoo_create(zk, "/testarwl", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        rc = zoo_create(zk, "/testarwl/arwl", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-      }
-
-      {
-        watchctx_t ctx;
-        watchctx_t lctx;
-        zhandle_t *zk = createchClient(&ctx, "127.0.0.1:22181/testarwl/arwl");
-        testWatcherAutoReset(zk, &ctx, &lctx);
-      }
-    }
-};
-
-volatile int Zookeeper_simpleSystem::count;
-zhandle_t *Zookeeper_simpleSystem::async_zk;
-const char Zookeeper_simpleSystem::hostPorts[] = "127.0.0.1:22181";
-CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_simpleSystem);

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/TestClientRetry.cc
----------------------------------------------------------------------
diff --git a/src/c/tests/TestClientRetry.cc b/src/c/tests/TestClientRetry.cc
deleted file mode 100644
index 41d5179..0000000
--- a/src/c/tests/TestClientRetry.cc
+++ /dev/null
@@ -1,273 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <cppunit/extensions/HelperMacros.h>
-#include "CppAssertHelper.h"
-
-#include <signal.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/select.h>
-
-#include "CollectionUtil.h"
-#include "ThreadingUtil.h"
-
-using namespace Util;
-
-#include "Vector.h"
-using namespace std;
-
-#include <cstring>
-#include <list>
-
-#include <zookeeper.h>
-
-#include "Util.h"
-
-#ifdef THREADED
-    static void yield(zhandle_t *zh, int i)
-    {
-        sleep(i);
-    }
-#else
-    static void yield(zhandle_t *zh, int seconds)
-    {
-        int fd;
-        int interest;
-        int events;
-        struct timeval tv;
-        int rc;
-        time_t expires = time(0) + seconds; 
-        time_t timeLeft = seconds;
-        fd_set rfds, wfds, efds;
-        FD_ZERO(&rfds);
-        FD_ZERO(&wfds);
-        FD_ZERO(&efds);
-
-        while(timeLeft >= 0) {
-            zookeeper_interest(zh, &fd, &interest, &tv);
-            if (fd != -1) {
-                if (interest&ZOOKEEPER_READ) {
-                    FD_SET(fd, &rfds);
-                } else {
-                    FD_CLR(fd, &rfds);
-                }
-                if (interest&ZOOKEEPER_WRITE) {
-                    FD_SET(fd, &wfds);
-                } else {
-                    FD_CLR(fd, &wfds);
-                }
-            } else {
-                fd = 0;
-            }
-            FD_SET(0, &rfds);
-            if (tv.tv_sec > timeLeft) {
-                tv.tv_sec = timeLeft;
-            }
-            rc = select(fd+1, &rfds, &wfds, &efds, &tv);
-            timeLeft = expires - time(0);
-            events = 0;
-            if (FD_ISSET(fd, &rfds)) {
-                events |= ZOOKEEPER_READ;
-            }
-            if (FD_ISSET(fd, &wfds)) {
-                events |= ZOOKEEPER_WRITE;
-            }
-            zookeeper_process(zh, events);
-        }
-    }
-#endif
-
-typedef struct evt {
-    string path;
-    int type;
-} evt_t;
-
-typedef struct watchCtx {
-private:
-    list<evt_t> events;
-public:
-    bool connected;
-    zhandle_t *zh;
-    Mutex mutex;
-
-    watchCtx() {
-        connected = false;
-        zh = 0;
-    }
-    ~watchCtx() {
-        if (zh) {
-            zookeeper_close(zh);
-            zh = 0;
-        }
-    }
-
-    evt_t getEvent() {
-        evt_t evt;
-        mutex.acquire();
-        CPPUNIT_ASSERT( events.size() > 0);
-        evt = events.front();
-        events.pop_front();
-        mutex.release();
-        return evt;
-    }
-
-    int countEvents() {
-        int count;
-        mutex.acquire();
-        count = events.size();
-        mutex.release();
-        return count;
-    }
-
-    void putEvent(evt_t evt) {
-        mutex.acquire();
-        events.push_back(evt);
-        mutex.release();
-    }
-
-    bool waitForConnected(zhandle_t *zh) {
-        time_t expires = time(0) + 10;
-        while(!connected && time(0) < expires) {
-            yield(zh, 1);
-        }
-        return connected;
-    }
-    bool waitForDisconnected(zhandle_t *zh) {
-        time_t expires = time(0) + 15;
-        while(connected && time(0) < expires) {
-            yield(zh, 1);
-        }
-        return !connected;
-    }
-} watchctx_t; 
-
-class Zookeeper_clientretry : public CPPUNIT_NS::TestFixture
-{
-    CPPUNIT_TEST_SUITE(Zookeeper_clientretry);
-#ifdef THREADED
-    CPPUNIT_TEST(testRetry);
-#endif
-    CPPUNIT_TEST_SUITE_END();
-
-    static void watcher(zhandle_t *, int type, int state, const char *path,void*v){
-        watchctx_t *ctx = (watchctx_t*)v;
-
-        if (state == ZOO_CONNECTED_STATE) {
-            ctx->connected = true;
-        } else {
-            ctx->connected = false;
-        }
-        if (type != ZOO_SESSION_EVENT) {
-            evt_t evt;
-            evt.path = path;
-            evt.type = type;
-            ctx->putEvent(evt);
-        }
-    }
-
-    static const char hostPorts[];
-
-    const char *getHostPorts() {
-        return hostPorts;
-    }
-
-    zhandle_t *createClient(watchctx_t *ctx) {
-        zhandle_t *zk = zookeeper_init(hostPorts, watcher, 10000, 0,
-                                       ctx, 0);
-        ctx->zh = zk;
-        sleep(1);
-        return zk;
-    }
-    
-    FILE *logfile;
-public:
-
-    Zookeeper_clientretry() {
-      logfile = openlogfile("Zookeeper_clientretry");
-    }
-
-    ~Zookeeper_clientretry() {
-      if (logfile) {
-        fflush(logfile);
-        fclose(logfile);
-        logfile = 0;
-      }
-    }
-
-    void setUp()
-    {
-        zoo_set_log_stream(logfile);
-
-        char cmd[1024];
-        sprintf(cmd, "%s stop %s", ZKSERVER_CMD, getHostPorts());
-        CPPUNIT_ASSERT(system(cmd) == 0);
-
-        /* we are testing that if max cnxns is exceeded the server does the right thing */
-        sprintf(cmd, "export ZKMAXCNXNS=1;%s startClean %s", ZKSERVER_CMD, getHostPorts());
-        CPPUNIT_ASSERT(system(cmd) == 0);
-
-        struct sigaction act;
-        act.sa_handler = SIG_IGN;
-        sigemptyset(&act.sa_mask);
-        act.sa_flags = 0;
-        CPPUNIT_ASSERT(sigaction(SIGPIPE, &act, NULL) == 0);
-    }
-    
-    void tearDown()
-    {
-        char cmd[1024];
-        sprintf(cmd, "%s stop %s", ZKSERVER_CMD, getHostPorts());
-        CPPUNIT_ASSERT(system(cmd) == 0);
-
-        /* restart the server in "normal" mode */
-        sprintf(cmd, "%s startClean %s", ZKSERVER_CMD, getHostPorts());
-        CPPUNIT_ASSERT(system(cmd) == 0);
-
-        struct sigaction act;
-        act.sa_handler = SIG_IGN;
-        sigemptyset(&act.sa_mask);
-        act.sa_flags = 0;
-        CPPUNIT_ASSERT(sigaction(SIGPIPE, &act, NULL) == 0);
-    }
-
-    bool waitForEvent(zhandle_t *zh, watchctx_t *ctx, int seconds) {
-        time_t expires = time(0) + seconds;
-        while(ctx->countEvents() == 0 && time(0) < expires) {
-            yield(zh, 1);
-        }
-        return ctx->countEvents() > 0;
-    }
-
-    static zhandle_t *async_zk;
-
-    void testRetry()
-    {
-      watchctx_t ctx1, ctx2;
-      zhandle_t *zk1 = createClient(&ctx1);
-      CPPUNIT_ASSERT_EQUAL(true, ctx1.waitForConnected(zk1));
-      zhandle_t *zk2 = createClient(&ctx2);
-      zookeeper_close(zk1);
-      CPPUNIT_ASSERT_EQUAL(true, ctx2.waitForConnected(zk2));
-      ctx1.zh = 0;  
-    }
-};
-
-zhandle_t *Zookeeper_clientretry::async_zk;
-const char Zookeeper_clientretry::hostPorts[] = "127.0.0.1:22181";
-CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_clientretry);

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/TestDriver.cc
----------------------------------------------------------------------
diff --git a/src/c/tests/TestDriver.cc b/src/c/tests/TestDriver.cc
deleted file mode 100644
index d60db69..0000000
--- a/src/c/tests/TestDriver.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <string>
-#include <cppunit/TestRunner.h>
-#include <cppunit/CompilerOutputter.h>
-#include <cppunit/TestResult.h>
-#include <cppunit/TestResultCollector.h>
-#include <cppunit/TextTestProgressListener.h>
-#include <cppunit/BriefTestProgressListener.h>
-#include <cppunit/extensions/TestFactoryRegistry.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <stdexcept>
-#include <unistd.h>
-#include <sys/select.h>
-#include <cppunit/Exception.h>
-#include <cppunit/TestFailure.h>
-#include <cppunit/XmlOutputter.h>
-#include <cppunit/TestAssert.h>
-#include <fstream>
-#include <time.h> 
-
-#include "Util.h"
-#include "zookeeper_log.h"
-
-using namespace std;
-
-CPPUNIT_NS_BEGIN
-
-class EclipseOutputter: public CompilerOutputter
-{
-public:
-  EclipseOutputter(TestResultCollector *result,ostream &stream):
-        CompilerOutputter(result,stream,"%p:%l: "),stream_(stream)
-    {
-    }
-    virtual void printFailedTestName( TestFailure *failure ){}
-    virtual void printFailureMessage( TestFailure *failure )
-    {
-      stream_<<": ";
-      Message msg = failure->thrownException()->message();
-      stream_<< msg.shortDescription();
-
-      string text;
-      for(int i=0; i<msg.detailCount();i++){
-          text+=msg.detailAt(i);
-          if(i+1!=msg.detailCount())
-              text+=", ";
-      }
-      if(text.length()!=0)
-          stream_ <<" ["<<text<<"]";
-      stream_<<"\n";
-    }
-    ostream& stream_;
-};
-
-CPPUNIT_NS_END
-
-class TimingListener : public CPPUNIT_NS::BriefTestProgressListener {
- public:
-   void startTest( CPPUNIT_NS::Test *test )
-   {
-     gettimeofday(&_start_time, NULL);
-
-     CPPUNIT_NS::BriefTestProgressListener::startTest(test);
-   }
-  
-   void endTest( CPPUNIT_NS::Test *test )
-   {
-     struct timeval end;
-     gettimeofday(&end, NULL);
-
-     long seconds = end.tv_sec - _start_time.tv_sec;
-     long useconds = end.tv_usec - _start_time.tv_usec;
-
-     long mtime = seconds * 1000 + useconds/1000.0;
-     CPPUNIT_NS::stdCOut()  <<  " : elapsed " <<  mtime;
-     CPPUNIT_NS::BriefTestProgressListener::endTest(test);
-   }
-
- private:
-   struct timeval _start_time;
-};
-
-class ZKServer {
-public:
-    ZKServer() {
-        char cmd[1024];
-        sprintf(cmd, "%s startClean %s", ZKSERVER_CMD, "127.0.0.1:22181");
-        CPPUNIT_ASSERT(system(cmd) == 0);
-
-        struct sigaction act;
-        act.sa_handler = SIG_IGN;
-        sigemptyset(&act.sa_mask);
-        act.sa_flags = 0;
-        CPPUNIT_ASSERT(sigaction(SIGPIPE, &act, NULL) == 0);
-    }
-    virtual ~ZKServer(){
-        char cmd[1024];
-        sprintf(cmd, "%s stop %s", ZKSERVER_CMD, "127.0.0.1:22181");
-        CPPUNIT_ASSERT(system(cmd) == 0);
-    }
-};
-
-int main( int argc, char* argv[] ) { 
-   // if command line contains "-ide" then this is the post build check
-   // => the output must be in the compiler error format.
-   //bool selfTest = (argc > 1) && (std::string("-ide") == argv[1]);
-   globalTestConfig.addConfigFromCmdLine(argc,argv);
-
-   ZKServer zkserver;
-
-   // Create the event manager and test controller
-   CPPUNIT_NS::TestResult controller;
-   // Add a listener that colllects test result
-   CPPUNIT_NS::TestResultCollector result;
-   controller.addListener( &result );
-   
-   // A listener that print dots as tests run.
-   // CPPUNIT_NS::TextTestProgressListener progress;
-   // CPPUNIT_NS::BriefTestProgressListener progress;
-
-   // brief + elapsed time
-   TimingListener progress;
-   controller.addListener( &progress );
- 
-   CPPUNIT_NS::TestRunner runner;
-   runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
- 
-   try {
-     CPPUNIT_NS::stdCOut() << endl << "Running " << endl;
-
-     zoo_set_debug_level(ZOO_LOG_LEVEL_INFO);
-     //zoo_set_debug_level(ZOO_LOG_LEVEL_DEBUG);
-
-     runner.run( controller, globalTestConfig.getTestName());
-
-     // Print test in a compiler compatible format.
-     CPPUNIT_NS::EclipseOutputter outputter( &result,cout);
-     outputter.write(); 
-
- // Uncomment this for XML output
-#ifdef ENABLE_XML_OUTPUT
-     std::ofstream file( "tests.xml" );
-     CPPUNIT_NS::XmlOutputter xml( &result, file );
-     xml.setStyleSheet( "report.xsl" );
-     xml.write();
-     file.close();
-#endif
-   } catch ( std::invalid_argument &e ) {
-     // Test path not resolved
-     cout<<"\nERROR: "<<e.what()<<endl;
-     return 0;
-   }
-
-   return result.wasSuccessful() ? 0 : 1;
- }

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/TestMulti.cc
----------------------------------------------------------------------
diff --git a/src/c/tests/TestMulti.cc b/src/c/tests/TestMulti.cc
deleted file mode 100644
index a54e047..0000000
--- a/src/c/tests/TestMulti.cc
+++ /dev/null
@@ -1,703 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <cppunit/extensions/HelperMacros.h>
-#include "CppAssertHelper.h"
-
-#include <signal.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/select.h>
-
-#include "CollectionUtil.h"
-#include "ThreadingUtil.h"
-
-using namespace Util;
-
-#include "Vector.h"
-using namespace std;
-
-#include <cstring>
-#include <list>
-
-#include <zookeeper.h>
-#include <errno.h>
-#include <recordio.h>
-#include "Util.h"
-
-#ifdef THREADED
-    static void yield(zhandle_t *zh, int i)
-    {
-        sleep(i);
-    }
-#else
-    static void yield(zhandle_t *zh, int seconds)
-    {
-        int fd;
-        int interest;
-        int events;
-        struct timeval tv;
-        int rc;
-        time_t expires = time(0) + seconds;
-        time_t timeLeft = seconds;
-        fd_set rfds, wfds, efds;
-        FD_ZERO(&rfds);
-        FD_ZERO(&wfds);
-        FD_ZERO(&efds);
-
-        while(timeLeft >= 0) {
-            zookeeper_interest(zh, &fd, &interest, &tv);
-            if (fd != -1) {
-                if (interest&ZOOKEEPER_READ) {
-                    FD_SET(fd, &rfds);
-                } else {
-                    FD_CLR(fd, &rfds);
-                }
-                if (interest&ZOOKEEPER_WRITE) {
-                    FD_SET(fd, &wfds);
-                } else {
-                    FD_CLR(fd, &wfds);
-                }
-            } else {
-                fd = 0;
-            }
-            FD_SET(0, &rfds);
-            if (tv.tv_sec > timeLeft) {
-                tv.tv_sec = timeLeft;
-            }
-            rc = select(fd+1, &rfds, &wfds, &efds, &tv);
-            timeLeft = expires - time(0);
-            events = 0;
-            if (FD_ISSET(fd, &rfds)) {
-                events |= ZOOKEEPER_READ;
-            }
-            if (FD_ISSET(fd, &wfds)) {
-                events |= ZOOKEEPER_WRITE;
-            }
-            zookeeper_process(zh, events);
-        }
-    }
-#endif
-
-typedef struct evt {
-    string path;
-    int type;
-} evt_t;
-
-typedef struct watchCtx {
-private:
-    list<evt_t> events;
-    watchCtx(const watchCtx&);
-    watchCtx& operator=(const watchCtx&);
-public:
-    bool connected;
-    zhandle_t *zh;
-    Mutex mutex;
-
-    watchCtx() {
-        connected = false;
-        zh = 0;
-    }
-    ~watchCtx() {
-        if (zh) {
-            zookeeper_close(zh);
-            zh = 0;
-        }
-    }
-
-    evt_t getEvent() {
-        evt_t evt;
-        mutex.acquire();
-        CPPUNIT_ASSERT( events.size() > 0);
-        evt = events.front();
-        events.pop_front();
-        mutex.release();
-        return evt;
-    }
-
-    int countEvents() {
-        int count;
-        mutex.acquire();
-        count = events.size();
-        mutex.release();
-        return count;
-    }
-
-    void putEvent(evt_t evt) {
-        mutex.acquire();
-        events.push_back(evt);
-        mutex.release();
-    }
-
-    bool waitForConnected(zhandle_t *zh) {
-        time_t expires = time(0) + 10;
-        while(!connected && time(0) < expires) {
-            yield(zh, 1);
-        }
-        return connected;
-    }
-    bool waitForDisconnected(zhandle_t *zh) {
-        time_t expires = time(0) + 15;
-        while(connected && time(0) < expires) {
-            yield(zh, 1);
-        }
-        return !connected;
-    }
-} watchctx_t;
-
-class Zookeeper_multi : public CPPUNIT_NS::TestFixture
-{
-    CPPUNIT_TEST_SUITE(Zookeeper_multi);
-//FIXME: None of these tests pass in single-threaded mode. It seems to be a
-//flaw in the test suite setup.
-#ifdef THREADED
-    CPPUNIT_TEST(testCreate);
-    CPPUNIT_TEST(testCreateDelete);
-    CPPUNIT_TEST(testInvalidVersion);
-    CPPUNIT_TEST(testNestedCreate);
-    CPPUNIT_TEST(testSetData);
-    CPPUNIT_TEST(testUpdateConflict);
-    CPPUNIT_TEST(testDeleteUpdateConflict);
-    CPPUNIT_TEST(testAsyncMulti);
-    CPPUNIT_TEST(testMultiFail);
-    CPPUNIT_TEST(testCheck);
-    CPPUNIT_TEST(testWatch);
-    CPPUNIT_TEST(testSequentialNodeCreateInAsyncMulti);
-#endif
-    CPPUNIT_TEST_SUITE_END();
-
-    static void watcher(zhandle_t *, int type, int state, const char *path,void*v){
-        watchctx_t *ctx = (watchctx_t*)v;
-
-        if (state == ZOO_CONNECTED_STATE) {
-            ctx->connected = true;
-        } else {
-            ctx->connected = false;
-        }
-        if (type != ZOO_SESSION_EVENT) {
-            evt_t evt;
-            evt.path = path;
-            evt.type = type;
-            ctx->putEvent(evt);
-        }
-    }
-
-    static const char hostPorts[];
-
-    const char *getHostPorts() {
-        return hostPorts;
-    }
-    
-    zhandle_t *createClient(watchctx_t *ctx) {
-        return createClient(hostPorts, ctx);
-    }
-
-    zhandle_t *createClient(const char *hp, watchctx_t *ctx) {
-        zhandle_t *zk = zookeeper_init(hp, watcher, 10000, 0, ctx, 0);
-        ctx->zh = zk;
-        CPPUNIT_ASSERT_EQUAL(true, ctx->waitForConnected(zk));
-        return zk;
-    }
-        
-    FILE *logfile;
-public:
-
-    Zookeeper_multi() {
-      logfile = openlogfile("Zookeeper_multi");
-    }
-
-    ~Zookeeper_multi() {
-      if (logfile) {
-        fflush(logfile);
-        fclose(logfile);
-        logfile = 0;
-      }
-    }
-
-    void setUp()
-    {
-        zoo_set_log_stream(logfile);
-    }
-
-    void tearDown()
-    {
-    }
-    
-    static volatile int count;
-
-    static void multi_completion_fn(int rc, const void *data) {
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-        count++;
-    }
-
-    static void multi_completion_fn_no_assert(int rc, const void *data) {
-        count++;
-    }
-
-    static void waitForMultiCompletion(int seconds) {
-        time_t expires = time(0) + seconds;
-        while(count == 0 && time(0) < expires) {
-            sleep(1);
-        }
-        count--;
-    }
-
-    static void resetCounter() {
-        count = 0;
-    }
-
-    /**
-     * Test basic multi-op create functionality 
-     */
-    void testCreate() {
-        int rc;
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-       
-        int sz = 512;
-        char p1[sz];
-        char p2[sz];
-        char p3[sz];
-        p1[0] = p2[0] = p3[0] = '\0';
-
-        int nops = 3 ;
-        zoo_op_t ops[nops];
-        zoo_op_result_t results[nops];
-
-        zoo_create_op_init(&ops[0], "/multi1", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
-        zoo_create_op_init(&ops[1], "/multi1/a", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p2, sz);
-        zoo_create_op_init(&ops[2], "/multi1/b", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p3, sz);
-        
-        rc = zoo_multi(zk, nops, ops, results);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        CPPUNIT_ASSERT(strcmp(p1, "/multi1") == 0);
-        CPPUNIT_ASSERT(strcmp(p2, "/multi1/a") == 0);
-        CPPUNIT_ASSERT(strcmp(p3, "/multi1/b") == 0);
-
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[0].err);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[1].err);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[2].err);
-    }
-
-    /**
-     * Test create followed by delete 
-     */
-    void testCreateDelete() {
-        int rc;
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-        int sz = 512;
-        char p1[sz];
-        p1[0] = '\0';
-        int nops = 2 ;
-        zoo_op_t ops[nops];
-        zoo_op_result_t results[nops];
-
-        zoo_create_op_init(&ops[0], "/multi2", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
-        zoo_delete_op_init(&ops[1], "/multi2", 0);
-        
-        rc = zoo_multi(zk, nops, ops, results);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        // '/multi2' should have been deleted
-        rc = zoo_exists(zk, "/multi2", 0, NULL);
-        CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
-    }
-
-    /** 
-     * Test invalid versions
-     */
-    void testInvalidVersion() {
-        int rc;
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-        int nops = 4;
-        zoo_op_t ops[nops];
-        zoo_op_result_t results[nops];
-
-        zoo_create_op_init(&ops[0], "/multi3", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, NULL, 0);
-        zoo_delete_op_init(&ops[1], "/multi3", 1);
-        zoo_create_op_init(&ops[2], "/multi3", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, NULL, 0);
-        zoo_create_op_init(&ops[3], "/multi3/a", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, NULL, 0);
-        
-        rc = zoo_multi(zk, nops, ops, results);
-        CPPUNIT_ASSERT_EQUAL((int)ZBADVERSION, rc);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[0].err);
-        CPPUNIT_ASSERT_EQUAL((int)ZBADVERSION, results[1].err);
-        CPPUNIT_ASSERT_EQUAL((int)ZRUNTIMEINCONSISTENCY, results[2].err);
-        CPPUNIT_ASSERT_EQUAL((int)ZRUNTIMEINCONSISTENCY, results[3].err);
-    }
-
-    /**
-     * Test nested creates that rely on state in earlier op in multi
-     */
-    void testNestedCreate() {
-        int rc;
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-        int sz = 512;
-        char p1[sz];
-        p1[0] = '\0';
-        int nops = 6;
-        zoo_op_t ops[nops];
-        zoo_op_result_t results[nops];
-
-        /* Create */
-        zoo_create_op_init(&ops[0], "/multi4", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
-        zoo_create_op_init(&ops[1], "/multi4/a", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
-        zoo_create_op_init(&ops[2], "/multi4/a/1", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
-
-        /* Delete */
-        zoo_delete_op_init(&ops[3], "/multi4/a/1", 0);
-        zoo_delete_op_init(&ops[4], "/multi4/a", 0);
-        zoo_delete_op_init(&ops[5], "/multi4", 0);
-        
-        rc = zoo_multi(zk, nops, ops, results);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        // Verify tree deleted
-        rc = zoo_exists(zk, "/multi4/a/1", 0, NULL);
-        CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
-        
-        rc = zoo_exists(zk, "/multi4/a", 0, NULL);
-        CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
-  
-        rc = zoo_exists(zk, "/multi4", 0, NULL);
-        CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
-    }
-
-    /**
-     * Test setdata functionality
-     */
-    void testSetData() {
-        int rc;
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-        int sz = 512;
-        struct Stat s1;
-
-        char buf[sz];
-        int blen = sz ;
-
-        char p1[sz], p2[sz];
-        
-        int nops = 2;
-        zoo_op_t ops[nops];
-        zoo_op_result_t results[nops];
-
-        zoo_create_op_init(&ops[0], "/multi5",   "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
-        zoo_create_op_init(&ops[1], "/multi5/a", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p2, sz);
-       
-        rc = zoo_multi(zk, nops, ops, results);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        
-        yield(zk, 5);
-
-        zoo_op_t setdata_ops[nops];
-        zoo_op_result_t setdata_results[nops];
-
-        zoo_set_op_init(&setdata_ops[0], "/multi5",   "1", 1, 0, &s1);
-        zoo_set_op_init(&setdata_ops[1], "/multi5/a", "2", 1, 0, &s1);
-
-        rc = zoo_multi(zk, nops, setdata_ops, setdata_results);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[0].err);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[1].err);
-        
-        memset(buf, '\0', blen);
-        rc = zoo_get(zk, "/multi5", 0, buf, &blen, &s1);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        CPPUNIT_ASSERT_EQUAL(1, blen);
-        CPPUNIT_ASSERT(strcmp("1", buf) == 0);
-        
-        memset(buf, '\0', blen);
-        rc = zoo_get(zk, "/multi5/a", 0, buf, &blen, &s1);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        CPPUNIT_ASSERT_EQUAL(1, blen);
-        CPPUNIT_ASSERT(strcmp("2", buf) == 0);
-    }
-
-    /**
-     * Test update conflicts
-     */
-    void testUpdateConflict() {
-        int rc;
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-        int sz = 512;
-        char buf[sz];
-        int blen = sz;
-        char p1[sz];
-        p1[0] = '\0';
-        struct Stat s1;
-        int nops = 3;
-        zoo_op_t ops[nops];
-        zoo_op_result_t results[nops];
-
-        zoo_create_op_init(&ops[0], "/multi6", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
-        zoo_set_op_init(&ops[1], "/multi6", "X", 1, 0, &s1);
-        zoo_set_op_init(&ops[2], "/multi6", "Y", 1, 0, &s1);
-        
-        rc = zoo_multi(zk, nops, ops, results);
-        CPPUNIT_ASSERT_EQUAL((int)ZBADVERSION, rc);
-
-        //Updating version solves conflict -- order matters
-        ops[2].set_op.version = 1;
-        rc = zoo_multi(zk, nops, ops, results);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-       
-        memset(buf, 0, sz);
-        rc = zoo_get(zk, "/multi6", 0, buf, &blen, &s1);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        CPPUNIT_ASSERT_EQUAL(blen, 1);
-        CPPUNIT_ASSERT(strncmp(buf, "Y", 1) == 0);
-    }
-
-    /**
-     * Test delete-update conflicts
-     */
-    void testDeleteUpdateConflict() {
-        int rc;
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-        int sz = 512;
-        char buf[sz];
-        int blen;
-        char p1[sz];
-        p1[0] = '\0';
-        struct Stat stat;
-        int nops = 3;
-        zoo_op_t ops[nops];
-        zoo_op_result_t results[nops];
-
-        zoo_create_op_init(&ops[0], "/multi7", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
-        zoo_delete_op_init(&ops[1], "/multi7", 0);
-        zoo_set_op_init(&ops[2], "/multi7", "Y", 1, 0, &stat);
-        
-        rc = zoo_multi(zk, nops, ops, results);
-        CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
-
-        // '/multi' should never have been created as entire op should fail
-        rc = zoo_exists(zk, "/multi7", 0, NULL);
-        CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
-    }
-
-    void testAsyncMulti() {
-        int rc;
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-       
-        int sz = 512;
-        char p1[sz], p2[sz], p3[sz];
-        p1[0] = '\0';
-        p2[0] = '\0';
-        p3[0] = '\0';
-
-        int nops = 3;
-        zoo_op_t ops[nops];
-        zoo_op_result_t results[nops];
-
-        zoo_create_op_init(&ops[0], "/multi8",   "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
-        zoo_create_op_init(&ops[1], "/multi8/a", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p2, sz);
-        zoo_create_op_init(&ops[2], "/multi8/b", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p3, sz);
- 
-        rc = zoo_amulti(zk, nops, ops, results, multi_completion_fn, 0);
-        waitForMultiCompletion(10);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        CPPUNIT_ASSERT(strcmp(p1, "/multi8") == 0);
-        CPPUNIT_ASSERT(strcmp(p2, "/multi8/a") == 0);
-        CPPUNIT_ASSERT(strcmp(p3, "/multi8/b") == 0);
-
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[0].err);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[1].err);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[2].err);
-    }
-
-    void testMultiFail() {
-        int rc;
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-       
-        int sz = 512;
-        char p1[sz], p2[sz], p3[sz];
-
-        p1[0] = '\0';
-        p2[0] = '\0';
-        p3[0] = '\0';
-
-        int nops = 3;
-        zoo_op_t ops[nops];
-        zoo_op_result_t results[nops];
-
-        zoo_create_op_init(&ops[0], "/multi9",   "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
-        zoo_create_op_init(&ops[1], "/multi9",   "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p2, sz);
-        zoo_create_op_init(&ops[2], "/multi9/b", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p3, sz);
-        
-        rc = zoo_multi(zk, nops, ops, results);
-        CPPUNIT_ASSERT_EQUAL((int)ZNODEEXISTS, rc);
-    }
-    
-    /**
-     * Test basic multi-op check functionality 
-     */
-    void testCheck() {
-        int rc;
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-        int sz = 512;
-        char p1[sz];
-        p1[0] = '\0';
-        struct Stat s1;
-
-        rc = zoo_create(zk, "/multi0", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        // Conditionally create /multi0/a' only if '/multi0' at version 0
-        int nops = 2;
-        zoo_op_t ops[nops];
-        zoo_op_result_t results[nops];
-
-        zoo_check_op_init(&ops[0], "/multi0", 0);
-        zoo_create_op_init(&ops[1], "/multi0/a", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
-        
-        rc = zoo_multi(zk, nops, ops, results);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[0].err);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[1].err);
-
-        // '/multi0/a' should have been created as it passed version check
-        rc = zoo_exists(zk, "/multi0/a", 0, NULL);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
- 
-        // Only create '/multi0/b' if '/multi0' at version 10 (which it's not)
-        zoo_op_t ops2[nops];
-        zoo_check_op_init(&ops2[0], "/multi0", 10);
-        zoo_create_op_init(&ops2[1], "/multi0/b", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, p1, sz);
-        
-        rc = zoo_multi(zk, nops, ops2, results);
-        CPPUNIT_ASSERT_EQUAL((int)ZBADVERSION, rc);
-
-        CPPUNIT_ASSERT_EQUAL((int)ZBADVERSION, results[0].err);
-        CPPUNIT_ASSERT_EQUAL((int)ZRUNTIMEINCONSISTENCY, results[1].err);
-
-        // '/multi0/b' should NOT have been created
-        rc = zoo_exists(zk, "/multi0/b", 0, NULL);
-        CPPUNIT_ASSERT_EQUAL((int)ZNONODE, rc);
-    }
-
-    /**
-     * Do a multi op inside a watch callback context.
-     */
-    static void doMultiInWatch(zhandle_t *zk, int type, int state, const char *path, void *ctx) {
-        int rc;
-        int sz = 512;
-        char p1[sz];
-        p1[0] = '\0';
-        struct Stat s1;
-
-        int nops = 1;
-        zoo_op_t ops[nops];
-        zoo_op_result_t results[nops];
-
-        zoo_set_op_init(&ops[0], "/multiwatch", "1", 1, -1, NULL);
-
-        rc = zoo_multi(zk, nops, ops, results);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, results[0].err);
-
-        memset(p1, '\0', sz);
-        rc = zoo_get(zk, "/multiwatch", 0, p1, &sz, &s1);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-        CPPUNIT_ASSERT_EQUAL(1, sz);
-        CPPUNIT_ASSERT(strcmp("1", p1) == 0);
-        count++;
-    }
-
-    /**
-     * Test multi-op called from a watch
-     */
-     void testWatch() {
-        int rc;
-        watchctx_t ctx;
-        zhandle_t *zk = createClient(&ctx);
-        int sz = 512;
-        char p1[sz];
-        p1[0] = '\0';
-
-        rc = zoo_create(zk, "/multiwatch", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, NULL, 0);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-
-        // create a watch on node '/multiwatch'
-        rc = zoo_wget(zk, "/multiwatch", doMultiInWatch, &ctx, p1, &sz, NULL);
-
-        // setdata on node '/multiwatch' this should trip the watch
-        rc = zoo_set(zk, "/multiwatch", NULL, -1, -1);
-        CPPUNIT_ASSERT_EQUAL((int) ZOK, rc);
-
-        // wait for multi completion in doMultiInWatch
-        waitForMultiCompletion(5);
-     }
-
-     /**
-      * ZOOKEEPER-1624: PendingChanges of create sequential node request didn't
-      * get rollbacked correctly when multi-op failed. This caused
-      * create sequential node request in subsequent multi-op to failed because
-      * sequential node name generation is incorrect.
-      *
-      * The check is to make sure that each request in multi-op failed with
-      * the correct reason.
-      */
-     void testSequentialNodeCreateInAsyncMulti() {
-         int rc;
-         watchctx_t ctx;
-         zhandle_t *zk = createClient(&ctx);
-
-         int iteration = 4;
-         int nops = 2;
-
-         zoo_op_result_t results[iteration][nops];
-         zoo_op_t ops[nops];
-         zoo_create_op_init(&ops[0], "/node-",   "", 0, &ZOO_OPEN_ACL_UNSAFE, ZOO_SEQUENCE, NULL, 0);
-         zoo_create_op_init(&ops[1], "/dup", "", 0, &ZOO_OPEN_ACL_UNSAFE, 0, NULL, 0);
-         for (int i = 0; i < iteration ; ++i) {
-           rc = zoo_amulti(zk, nops, ops, results[i], multi_completion_fn_no_assert, 0);
-           CPPUNIT_ASSERT_EQUAL((int)ZOK, rc);
-         }
-
-         waitForMultiCompletion(10);
-
-         CPPUNIT_ASSERT_EQUAL((int)ZOK, results[0][0].err);
-         CPPUNIT_ASSERT_EQUAL((int)ZOK, results[1][0].err);
-         CPPUNIT_ASSERT_EQUAL((int)ZOK, results[2][0].err);
-         CPPUNIT_ASSERT_EQUAL((int)ZOK, results[3][0].err);
-
-         CPPUNIT_ASSERT_EQUAL((int)ZOK, results[0][1].err);
-         CPPUNIT_ASSERT_EQUAL((int)ZNODEEXISTS, results[1][1].err);
-         CPPUNIT_ASSERT_EQUAL((int)ZNODEEXISTS, results[2][1].err);
-         CPPUNIT_ASSERT_EQUAL((int)ZNODEEXISTS, results[3][1].err);
-
-         resetCounter();
-     }
-};
-
-volatile int Zookeeper_multi::count;
-const char Zookeeper_multi::hostPorts[] = "127.0.0.1:22181";
-CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_multi);


[06/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/recordio.c
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/recordio.c b/zookeeper-client/zookeeper-client-c/src/recordio.c
new file mode 100644
index 0000000..0fcf48e
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/recordio.c
@@ -0,0 +1,366 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <recordio.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#ifndef WIN32
+#include <netinet/in.h>
+#else
+#include <winsock2.h> /* for _htonl and _ntohl */
+#endif
+
+void deallocate_String(char **s)
+{
+    if (*s)
+        free(*s);
+    *s = 0;
+}
+
+void deallocate_Buffer(struct buffer *b)
+{
+    if (b->buff)
+        free(b->buff);
+    b->buff = 0;
+}
+
+struct buff_struct {
+    int32_t len;
+    int32_t off;
+    char *buffer;
+};
+
+static int resize_buffer(struct buff_struct *s, int newlen)
+{
+    char *buffer= NULL;
+    while (s->len < newlen) {
+        s->len *= 2;
+    }
+    buffer = (char*)realloc(s->buffer, s->len);
+    if (!buffer) {
+        s->buffer = 0;
+        return -ENOMEM;
+    }
+    s->buffer = buffer;
+    return 0;
+}
+
+int oa_start_record(struct oarchive *oa, const char *tag)
+{
+    return 0;
+}
+int oa_end_record(struct oarchive *oa, const char *tag)
+{
+    return 0;
+}
+int oa_serialize_int(struct oarchive *oa, const char *tag, const int32_t *d)
+{
+    struct buff_struct *priv = oa->priv;
+    int32_t i = htonl(*d);
+    if ((priv->len - priv->off) < sizeof(i)) {
+        int rc = resize_buffer(priv, priv->len + sizeof(i));
+        if (rc < 0) return rc;
+    }
+    memcpy(priv->buffer+priv->off, &i, sizeof(i));
+    priv->off+=sizeof(i);
+    return 0;
+}
+int64_t zoo_htonll(int64_t v)
+{
+    int i = 0;
+    char *s = (char *)&v;
+    if (htonl(1) == 1) {
+        return v;
+    }
+    for (i = 0; i < 4; i++) {
+        int tmp = s[i];
+        s[i] = s[8-i-1];
+        s[8-i-1] = tmp;
+    }
+
+    return v;
+}
+
+int oa_serialize_long(struct oarchive *oa, const char *tag, const int64_t *d)
+{
+    const int64_t i = zoo_htonll(*d);
+    struct buff_struct *priv = oa->priv;
+    if ((priv->len - priv->off) < sizeof(i)) {
+        int rc = resize_buffer(priv, priv->len + sizeof(i));
+        if (rc < 0) return rc;
+    }
+    memcpy(priv->buffer+priv->off, &i, sizeof(i));
+    priv->off+=sizeof(i);
+    return 0;
+}
+int oa_start_vector(struct oarchive *oa, const char *tag, const int32_t *count)
+{
+    return oa_serialize_int(oa, tag, count);
+}
+int oa_end_vector(struct oarchive *oa, const char *tag)
+{
+    return 0;
+}
+int oa_serialize_bool(struct oarchive *oa, const char *name, const int32_t *i)
+{
+    //return oa_serialize_int(oa, name, i);
+    struct buff_struct *priv = oa->priv;
+    if ((priv->len - priv->off) < 1) {
+        int rc = resize_buffer(priv, priv->len + 1);
+        if (rc < 0)
+            return rc;
+    }
+    priv->buffer[priv->off] = (*i == 0 ? '\0' : '\1');
+    priv->off++;
+    return 0;
+}
+static const int32_t negone = -1;
+int oa_serialize_buffer(struct oarchive *oa, const char *name,
+        const struct buffer *b)
+{
+    struct buff_struct *priv = oa->priv;
+    int rc;
+    if (!b) {
+        return oa_serialize_int(oa, "len", &negone);
+    }
+    rc = oa_serialize_int(oa, "len", &b->len);
+    if (rc < 0)
+        return rc;
+    // this means a buffer of NUll 
+    // with size of -1. This is 
+    // waht we use in java serialization for NULL
+    if (b->len == -1) {
+      return rc;
+    }
+    if ((priv->len - priv->off) < b->len) {
+        rc = resize_buffer(priv, priv->len + b->len);
+        if (rc < 0)
+            return rc;
+    }
+    memcpy(priv->buffer+priv->off, b->buff, b->len);
+    priv->off += b->len;
+    return 0;
+}
+int oa_serialize_string(struct oarchive *oa, const char *name, char **s)
+{
+    struct buff_struct *priv = oa->priv;
+    int32_t len;
+    int rc;
+    if (!*s) {
+        oa_serialize_int(oa, "len", &negone);
+        return 0;
+    }
+    len = strlen(*s);
+    rc = oa_serialize_int(oa, "len", &len);
+    if (rc < 0)
+        return rc;
+    if ((priv->len - priv->off) < len) {
+        rc = resize_buffer(priv, priv->len + len);
+        if (rc < 0)
+            return rc;
+    }
+    memcpy(priv->buffer+priv->off, *s, len);
+    priv->off += len;
+    return 0;
+}
+int ia_start_record(struct iarchive *ia, const char *tag)
+{
+    return 0;
+}
+int ia_end_record(struct iarchive *ia, const char *tag)
+{
+    return 0;
+}
+int ia_deserialize_int(struct iarchive *ia, const char *tag, int32_t *count)
+{
+    struct buff_struct *priv = ia->priv;
+    if ((priv->len - priv->off) < sizeof(*count)) {
+        return -E2BIG;
+    }
+    memcpy(count, priv->buffer+priv->off, sizeof(*count));
+    priv->off+=sizeof(*count);
+    *count = ntohl(*count);
+    return 0;
+}
+
+int ia_deserialize_long(struct iarchive *ia, const char *tag, int64_t *count)
+{
+    struct buff_struct *priv = ia->priv;
+    int64_t v = 0;
+    if ((priv->len - priv->off) < sizeof(*count)) {
+        return -E2BIG;
+    }
+    memcpy(count, priv->buffer+priv->off, sizeof(*count));
+    priv->off+=sizeof(*count);
+    v = zoo_htonll(*count); // htonll and  ntohll do the same
+    *count = v;
+    return 0;
+}
+int ia_start_vector(struct iarchive *ia, const char *tag, int32_t *count)
+{
+    return ia_deserialize_int(ia, tag, count);
+}
+int ia_end_vector(struct iarchive *ia, const char *tag)
+{
+    return 0;
+}
+int ia_deserialize_bool(struct iarchive *ia, const char *name, int32_t *v)
+{
+    struct buff_struct *priv = ia->priv;
+    //fprintf(stderr, "Deserializing bool %d\n", priv->off);
+    //return ia_deserialize_int(ia, name, v);
+    if ((priv->len - priv->off) < 1) {
+        return -E2BIG;
+    }
+    *v = priv->buffer[priv->off];
+    priv->off+=1;
+    //fprintf(stderr, "Deserializing bool end %d\n", priv->off);
+    return 0;
+}
+int ia_deserialize_buffer(struct iarchive *ia, const char *name,
+        struct buffer *b)
+{
+    struct buff_struct *priv = ia->priv;
+    int rc = ia_deserialize_int(ia, "len", &b->len);
+    if (rc < 0)
+        return rc;
+    if ((priv->len - priv->off) < b->len) {
+        return -E2BIG;
+    }
+    // set the buffer to null
+    if (b->len == -1) {
+       b->buff = NULL;
+       return rc;
+    }
+    b->buff = malloc(b->len);
+    if (!b->buff) {
+        return -ENOMEM;
+    }
+    memcpy(b->buff, priv->buffer+priv->off, b->len);
+    priv->off += b->len;
+    return 0;
+}
+int ia_deserialize_string(struct iarchive *ia, const char *name, char **s)
+{
+    struct buff_struct *priv = ia->priv;
+    int32_t len;
+    int rc = ia_deserialize_int(ia, "len", &len);
+    if (rc < 0)
+        return rc;
+    if ((priv->len - priv->off) < len) {
+        return -E2BIG;
+    }
+    if (len < 0) {
+        return -EINVAL;
+    }
+    *s = malloc(len+1);
+    if (!*s) {
+        return -ENOMEM;
+    }
+    memcpy(*s, priv->buffer+priv->off, len);
+    (*s)[len] = '\0';
+    priv->off += len;
+    return 0;
+}
+
+static struct iarchive ia_default = { STRUCT_INITIALIZER (start_record ,ia_start_record),
+        STRUCT_INITIALIZER (end_record ,ia_end_record), STRUCT_INITIALIZER (start_vector , ia_start_vector),
+        STRUCT_INITIALIZER (end_vector ,ia_end_vector), STRUCT_INITIALIZER (deserialize_Bool , ia_deserialize_bool),
+        STRUCT_INITIALIZER (deserialize_Int ,ia_deserialize_int),
+        STRUCT_INITIALIZER (deserialize_Long , ia_deserialize_long) ,
+        STRUCT_INITIALIZER (deserialize_Buffer, ia_deserialize_buffer),
+        STRUCT_INITIALIZER (deserialize_String, ia_deserialize_string)   };
+
+static struct oarchive oa_default = { STRUCT_INITIALIZER (start_record , oa_start_record),
+        STRUCT_INITIALIZER (end_record , oa_end_record), STRUCT_INITIALIZER (start_vector , oa_start_vector),
+        STRUCT_INITIALIZER (end_vector , oa_end_vector), STRUCT_INITIALIZER (serialize_Bool , oa_serialize_bool),
+        STRUCT_INITIALIZER (serialize_Int , oa_serialize_int),
+        STRUCT_INITIALIZER (serialize_Long , oa_serialize_long) ,
+        STRUCT_INITIALIZER (serialize_Buffer , oa_serialize_buffer),
+        STRUCT_INITIALIZER (serialize_String , oa_serialize_string) };
+
+struct iarchive *create_buffer_iarchive(char *buffer, int len)
+{
+    struct iarchive *ia;
+    struct buff_struct *buff;
+    ia = malloc(sizeof(*ia));
+    if (!ia) return 0;
+    buff = malloc(sizeof(struct buff_struct));
+    if (!buff) {
+        free(ia);
+        return 0;
+    }
+    *ia = ia_default;
+    buff->off = 0;
+    buff->buffer = buffer;
+    buff->len = len;
+    ia->priv = buff;
+    return ia;
+}
+
+struct oarchive *create_buffer_oarchive()
+{
+    struct oarchive *oa;
+    struct buff_struct *buff;
+    oa = malloc(sizeof(*oa));
+    if (!oa) return 0;
+    buff = malloc(sizeof(struct buff_struct));
+    if (!buff) {
+        free(oa);
+        return 0;
+    }
+    *oa = oa_default;
+    buff->off = 0;
+    buff->buffer = malloc(128);
+    buff->len = 128;
+    oa->priv = buff;
+    return oa;
+}
+
+void close_buffer_iarchive(struct iarchive **ia)
+{
+    free((*ia)->priv);
+    free(*ia);
+    *ia = 0;
+}
+
+void close_buffer_oarchive(struct oarchive **oa, int free_buffer)
+{
+    if (free_buffer) {
+        struct buff_struct *buff = (struct buff_struct *)(*oa)->priv;
+        if (buff->buffer) {
+            free(buff->buffer);
+        }
+    }
+    free((*oa)->priv);
+    free(*oa);
+    *oa = 0;
+}
+
+char *get_buffer(struct oarchive *oa)
+{
+    struct buff_struct *buff = oa->priv;
+    return buff->buffer;
+}
+int get_buffer_len(struct oarchive *oa)
+{
+    struct buff_struct *buff = oa->priv;
+    return buff->off;
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/st_adaptor.c
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/st_adaptor.c b/zookeeper-client/zookeeper-client-c/src/st_adaptor.c
new file mode 100644
index 0000000..23573b3
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/st_adaptor.c
@@ -0,0 +1,113 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DLL_EXPORT
+#  define USE_STATIC_LIB
+#endif
+
+#include "zk_adaptor.h"
+#include <stdlib.h>
+#include <time.h>
+
+int zoo_lock_auth(zhandle_t *zh)
+{
+	return 0;
+}
+int zoo_unlock_auth(zhandle_t *zh)
+{
+	return 0;
+}
+int lock_buffer_list(buffer_head_t *l)
+{
+	return 0;
+}
+int unlock_buffer_list(buffer_head_t *l)
+{
+	return 0;
+}
+int lock_completion_list(completion_head_t *l)
+{
+	return 0;
+}
+int unlock_completion_list(completion_head_t *l)
+{
+	return 0;
+}
+struct sync_completion *alloc_sync_completion(void)
+{
+    return (struct sync_completion*)calloc(1, sizeof(struct sync_completion));
+}
+int wait_sync_completion(struct sync_completion *sc)
+{
+    return 0;
+}
+
+void free_sync_completion(struct sync_completion *sc)
+{
+    free(sc);
+}
+
+void notify_sync_completion(struct sync_completion *sc)
+{
+}
+
+int process_async(int outstanding_sync)
+{
+    return outstanding_sync == 0;
+}
+
+int adaptor_init(zhandle_t *zh)
+{
+    return 0;
+}
+
+void adaptor_finish(zhandle_t *zh){}
+
+void adaptor_destroy(zhandle_t *zh){}
+
+int flush_send_queue(zhandle_t *, int);
+
+int adaptor_send_queue(zhandle_t *zh, int timeout)
+{
+    return flush_send_queue(zh, timeout);
+}
+
+int32_t inc_ref_counter(zhandle_t* zh,int i)
+{
+    zh->ref_counter+=(i<0?-1:(i>0?1:0));
+    return zh->ref_counter;
+}
+
+int32_t get_xid()
+{
+    static int32_t xid = -1;
+    if (xid == -1) {
+        xid = time(0);
+    }
+    return xid++;
+}
+
+int enter_critical(zhandle_t* zh)
+{
+	return 0;
+}
+
+int leave_critical(zhandle_t* zh)
+{
+	return 0;
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/winport.c
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/winport.c b/zookeeper-client/zookeeper-client-c/src/winport.c
new file mode 100644
index 0000000..3592ea1
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/winport.c
@@ -0,0 +1,302 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef WIN32
+#include "winport.h"
+#include <stdlib.h>
+#include <stdint.h> /* for int64_t */
+#include <winsock2.h> /* must always be included before ws2tcpip.h */
+#include <ws2tcpip.h> /* for SOCKET */
+
+int pthread_mutex_lock(pthread_mutex_t* _mutex ){      
+       int rc = WaitForSingleObject( *_mutex,    // handle to mutex
+            INFINITE);  // no time-out interval
+       return ((rc == WAIT_OBJECT_0) ? 0: rc); 
+}
+
+int pthread_mutex_unlock( pthread_mutex_t* _mutex ){   
+       int rc = ReleaseMutex(*_mutex);
+       return ((rc != 0)? 0: GetLastError());  
+}
+
+int pthread_mutex_init(pthread_mutex_t* _mutex, void* ignoredAttr){
+       //use CreateMutex as we are using the HANDLES in pthread_cond
+       *_mutex = CreateMutex( 
+        NULL,              // default security attributes
+        FALSE,             // initially not owned
+        NULL);             // unnamed mutex    
+       return ((*_mutex == NULL) ? GetLastError() : 0);
+}
+
+int pthread_mutex_destroy(pthread_mutex_t* _mutex)
+{
+       int rc = CloseHandle(*_mutex);
+       return ((rc != 0)? 0: GetLastError());  
+}
+
+int pthread_create(pthread_t *thread, const pthread_attr_t *attr, unsigned  (__stdcall* start_routine)(void* a), void *arg)
+{
+   int _intThreadId; 
+   (*thread).thread_handle = (HANDLE)_beginthreadex( NULL, 0, start_routine , arg, 0, (unsigned int*)&_intThreadId );
+   (*thread).thread_id = _intThreadId;
+   return (((*thread).thread_handle == 0 ) ? errno : 0 );         
+}
+
+
+int pthread_equal(pthread_t t1, pthread_t t2){
+//Is there a better way to do this? GetThreadId(handle) is only supported Windows 2003 n above.
+       return ((t1.thread_id == t2.thread_id) ? 1:0);              
+}
+
+pthread_t pthread_self(){
+    pthread_t thread_self;
+    thread_self.thread_handle = GetCurrentThread();
+    thread_self.thread_id     = GetCurrentThreadId();
+    return thread_self;
+}
+
+int pthread_join(pthread_t _thread, void** ignore)
+{
+       int rc = WaitForSingleObject( _thread.thread_handle, INFINITE );
+       return ((rc == WAIT_OBJECT_0) ? 0: rc); 
+}
+
+int pthread_detach(pthread_t _thread)
+{
+       int rc = CloseHandle(_thread.thread_handle) ;
+       return  (rc != 0) ? 0: GetLastError();
+}
+
+void pthread_mutexattr_init(pthread_mutexattr_t* ignore){}
+void pthread_mutexattr_settype(pthread_mutexattr_t* ingore_attr, int ignore){}
+void pthread_mutexattr_destroy(pthread_mutexattr_t* ignore_attr){}
+       
+int 
+pthread_cond_init (pthread_cond_t *cv,
+                   const pthread_condattr_t * ignore)
+{
+  cv->waiters_count_ = 0;
+  cv->was_broadcast_ = 0;
+  cv->sema_ = CreateSemaphore (NULL,       // no security
+                                0,          // initially 0
+                                0x7fffffff, // max count
+                                NULL);      // unnamed 
+  if (cv->sema_ == NULL ) 
+               return GetLastError();
+  InitializeCriticalSection (&cv->waiters_count_lock_);
+  cv->waiters_done_ = CreateEvent (NULL,  // no security
+                                   FALSE, // auto-reset
+                                   FALSE, // non-signaled initially
+                                   NULL); // unnamed
+  return (cv->waiters_done_ == NULL) ? GetLastError() : 0;
+       
+}
+
+
+int pthread_cond_destroy(pthread_cond_t *cond)
+{
+       CloseHandle( cond->sema_);
+       DeleteCriticalSection(&cond->waiters_count_lock_);
+       return (CloseHandle( cond->waiters_done_ ) == 0)? GetLastError(): 0 ;
+}
+
+
+int
+pthread_cond_signal (pthread_cond_t *cv)
+{
+  int have_waiters;
+  EnterCriticalSection (& (cv->waiters_count_lock_));
+  have_waiters = cv->waiters_count_ > 0;
+  LeaveCriticalSection (&cv->waiters_count_lock_);
+
+  // If there aren't any waiters, then this is a no-op.  
+  if (have_waiters){
+         return (ReleaseSemaphore (cv->sema_, 1, 0) == 0 )  ? GetLastError() : 0 ;
+  }else
+         return 0;
+}
+
+
+int
+pthread_cond_broadcast (pthread_cond_t *cv)
+{
+  // This is needed to ensure that <waiters_count_> and <was_broadcast_> are
+  // consistent relative to each other.
+  int have_waiters = 0;
+  EnterCriticalSection (&cv->waiters_count_lock_);
+  
+  if (cv->waiters_count_ > 0) {
+    // We are broadcasting, even if there is just one waiter...
+    // Record that we are broadcasting, which helps optimize
+    // <pthread_cond_wait> for the non-broadcast case.
+    cv->was_broadcast_ = 1;
+    have_waiters = 1;
+  }
+
+  if (have_waiters) {
+    // Wake up all the waiters atomically.
+    ReleaseSemaphore (cv->sema_, cv->waiters_count_, 0);
+
+    LeaveCriticalSection (&cv->waiters_count_lock_);
+
+    // Wait for all the awakened threads to acquire the counting
+    // semaphore. 
+    WaitForSingleObject (cv->waiters_done_, INFINITE);
+    // This assignment is okay, even without the <waiters_count_lock_> held 
+    // because no other waiter threads can wake up to access it.
+    cv->was_broadcast_ = 0;
+  }
+  else
+    LeaveCriticalSection (&cv->waiters_count_lock_);
+}
+
+
+int
+pthread_cond_wait (pthread_cond_t *cv, 
+                   pthread_mutex_t *external_mutex)
+{
+  int last_waiter;
+  // Avoid race conditions.
+  EnterCriticalSection (&cv->waiters_count_lock_);
+  cv->waiters_count_++;
+  LeaveCriticalSection (&cv->waiters_count_lock_);
+
+  // This call atomically releases the mutex and waits on the
+  // semaphore until <pthread_cond_signal> or <pthread_cond_broadcast>
+  // are called by another thread.
+  SignalObjectAndWait (*external_mutex, cv->sema_, INFINITE, FALSE);
+
+  // Reacquire lock to avoid race conditions.
+  EnterCriticalSection (&cv->waiters_count_lock_);
+
+  // We're no longer waiting...
+  cv->waiters_count_--;
+
+  // Check to see if we're the last waiter after <pthread_cond_broadcast>.
+  last_waiter = cv->was_broadcast_ && cv->waiters_count_ == 0;
+
+  LeaveCriticalSection (&cv->waiters_count_lock_);
+
+  // If we're the last waiter thread during this particular broadcast
+  // then let all the other threads proceed.
+  if (last_waiter)
+    // This call atomically signals the <waiters_done_> event and waits until
+    // it can acquire the <external_mutex>.  This is required to ensure fairness. 
+    SignalObjectAndWait (cv->waiters_done_, *external_mutex, INFINITE, FALSE);
+  else
+    // Always regain the external mutex since that's the guarantee we
+    // give to our callers. 
+    WaitForSingleObject (*external_mutex, INFINITE);
+}
+
+int pthread_key_create(pthread_key_t *key, void (*destructor)(void *) )
+{
+  int result = 0;
+  pthread_key_t* newkey;
+
+  if ((newkey = (pthread_key_t*) calloc (1, sizeof (pthread_key_t))) == NULL)
+    {
+      result = ENOMEM;
+    }
+  else if ((newkey->key = TlsAlloc ()) == TLS_OUT_OF_INDEXES)
+    {
+      result = EAGAIN;
+      free (newkey);
+      newkey = NULL;
+    }
+  else if (destructor != NULL)
+    {
+      //--we have to store the function pointer for destructor, so that we can call it 
+         //--to free up the user allocated storage--       
+      newkey->destructor = destructor;
+    }
+  key = newkey;  
+  return (result);     
+}
+
+int pthread_key_delete(pthread_key_t key)
+{
+  int rc = 0;
+  LPVOID lpvData =  TlsGetValue(key.key);
+  rc = TlsFree (key.key);
+  rc = (rc != 0 ) ? 0 : GetLastError();
+  if (key.destructor != NULL && lpvData != 0){
+       key.destructor(lpvData);         //we take control of calling destructor, instead of calling it on thread exit.
+  }
+  free (&key);
+  return (rc);
+}
+
+void *pthread_getspecific(pthread_key_t key)
+{
+       LPVOID lpvData =  TlsGetValue(key.key);
+       if ((lpvData == 0) && (GetLastError() != ERROR_SUCCESS)) 
+               return NULL;
+       else 
+               return lpvData;
+}
+
+int pthread_setspecific(pthread_key_t key, const void *value)
+{
+       int rc = TlsSetValue (key.key, value);
+       return ((rc != 0 ) ? 0 : GetLastError());
+}
+
+int gettimeofday(struct timeval *tp, void *tzp) {
+        int64_t now = 0;
+        if (tzp != 0) { errno = EINVAL; return -1; }
+        GetSystemTimeAsFileTime( (LPFILETIME)&now );
+        tp->tv_sec = (long)(now / 10000000 - 11644473600LL);
+        tp->tv_usec = (now / 10) % 1000000;
+        return 0;
+}
+
+int close(SOCKET fd) {
+        return closesocket(fd);
+}
+
+int Win32WSAStartup()
+{
+       WORD    wVersionRq;
+       WSADATA wsaData;
+       int             err;
+
+       wVersionRq = MAKEWORD(2,0);
+       err = WSAStartup(wVersionRq, &wsaData);
+       if (err != 0)
+               return 1;
+       
+       // confirm the version information
+       if ((LOBYTE(wsaData.wVersion) != 2) ||
+           (HIBYTE(wsaData.wVersion) != 0))
+       {
+               Win32WSACleanup();              
+               return 1;
+       }
+       return 0;
+}
+
+void Win32WSACleanup()
+{
+       WSACleanup();
+}
+
+#endif //WIN32
+
+
+

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/winport.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/winport.h b/zookeeper-client/zookeeper-client-c/src/winport.h
new file mode 100644
index 0000000..da6028c
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/winport.h
@@ -0,0 +1,138 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * This header file is to port pthread lib , sockets and other utility methods on windows.
+ * Specifically the threads function, mutexes, keys, and socket initialization.
+ */
+
+#ifndef WINPORT_H_
+#define WINPORT_H_
+
+#ifdef WIN32
+#include "winconfig.h"
+
+#define _WINSOCK_DEPRECATED_NO_WARNINGS
+#include <winsock2.h> /* must always be included before ws2tcpip.h */
+#include <ws2tcpip.h> /* for struct sock_addr used in zookeeper.h */
+
+/* POSIX names are deprecated, use ISO conformant names instead. */
+#define strdup _strdup
+#define getcwd _getcwd
+#define getpid _getpid
+
+/* Windows "secure" versions of POSIX reentrant functions */
+#define strtok_r strtok_s
+#define localtime_r(a,b) localtime_s(b,a)
+
+/* After this version of MSVC, snprintf became a defined function,
+   and so cannot be redefined, nor can #ifndef be used to guard it. */
+#if ((defined(_MSC_VER) && _MSC_VER < 1900) || !defined(_MSC_VER))
+#define snprintf _snprintf
+#endif
+
+
+#include <errno.h>
+#include <process.h>
+#include <stdint.h> /* for int64_t */
+#include <stdlib.h>
+#include <malloc.h>
+
+
+typedef int ssize_t;
+typedef HANDLE pthread_mutex_t;
+
+struct pthread_t_
+{
+  HANDLE thread_handle;
+  DWORD  thread_id;
+};
+
+typedef struct pthread_t_ pthread_t;
+typedef int pthread_mutexattr_t;       
+typedef int pthread_condattr_t;        
+typedef int pthread_attr_t; 
+#define PTHREAD_MUTEX_RECURSIVE 0
+
+int pthread_mutex_lock(pthread_mutex_t* _mutex );
+int pthread_mutex_unlock( pthread_mutex_t* _mutex );
+int pthread_mutex_init(pthread_mutex_t* _mutex, void* ignoredAttr);
+int pthread_mutex_destroy(pthread_mutex_t* _mutex);
+int pthread_create(pthread_t *thread, const pthread_attr_t *attr, unsigned  (__stdcall* start_routine)(void* a), void *arg);
+int pthread_equal(pthread_t t1, pthread_t t2);
+pthread_t pthread_self();
+int pthread_join(pthread_t _thread, void** ignore);
+int pthread_detach(pthread_t _thread);
+
+void pthread_mutexattr_init(pthread_mutexattr_t* ignore);
+void pthread_mutexattr_settype(pthread_mutexattr_t* ingore_attr, int ignore);
+void pthread_mutexattr_destroy(pthread_mutexattr_t* ignore_attr);
+
+
+// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
+ 
+typedef struct 
+{
+       int waiters_count_;
+    // Number of waiting threads.
+
+    CRITICAL_SECTION waiters_count_lock_;
+    // Serialize access to <waiters_count_>.
+
+    HANDLE sema_;
+       // Semaphore used to queue up threads waiting for the condition to
+    // become signaled. 
+
+    HANDLE waiters_done_;
+    // An auto-reset event used by the broadcast/signal thread to wait
+    // for all the waiting thread(s) to wake up and be released from the
+    // semaphore. 
+
+    size_t was_broadcast_;
+    // Keeps track of whether we were broadcasting or signaling.  This
+    // allows us to optimize the code if we're just signaling.
+}pthread_cond_t;
+       
+int pthread_cond_init (pthread_cond_t *cv,const pthread_condattr_t * ignore);
+int pthread_cond_destroy(pthread_cond_t *cond);
+int pthread_cond_signal (pthread_cond_t *cv);
+int pthread_cond_broadcast (pthread_cond_t *cv);
+int pthread_cond_wait (pthread_cond_t *cv, pthread_mutex_t *external_mutex);
+
+
+struct pthread_key_t_
+{
+  DWORD key;
+  void (*destructor) (void *);  
+};
+
+typedef struct pthread_key_t_ pthread_key_t;
+int pthread_key_create(pthread_key_t *key, void (*destructor)(void *) );
+int pthread_key_delete(pthread_key_t key);
+void *pthread_getspecific(pthread_key_t key);
+int pthread_setspecific(pthread_key_t key, const void *value);
+
+int gettimeofday(struct timeval *tp, void *tzp);
+int close(SOCKET fd);
+int Win32WSAStartup();
+void Win32WSACleanup();
+#endif //WIN32
+
+
+
+#endif //WINPORT_H_

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/zk_adaptor.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/zk_adaptor.h b/zookeeper-client/zookeeper-client-c/src/zk_adaptor.h
new file mode 100644
index 0000000..b990779
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/zk_adaptor.h
@@ -0,0 +1,276 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ZK_ADAPTOR_H_
+#define ZK_ADAPTOR_H_
+#include <zookeeper.jute.h>
+#ifdef THREADED
+#ifndef WIN32
+#include <pthread.h>
+#else
+#include "winport.h"
+#endif
+#endif
+#include "zookeeper.h"
+#include "zk_hashtable.h"
+
+/* predefined xid's values recognized as special by the server */
+#define WATCHER_EVENT_XID -1 
+#define PING_XID -2
+#define AUTH_XID -4
+#define SET_WATCHES_XID -8
+
+/* zookeeper state constants */
+#define EXPIRED_SESSION_STATE_DEF -112
+#define AUTH_FAILED_STATE_DEF -113
+#define CONNECTING_STATE_DEF 1
+#define ASSOCIATING_STATE_DEF 2
+#define CONNECTED_STATE_DEF 3
+#define NOTCONNECTED_STATE_DEF 999
+
+/* zookeeper event type constants */
+#define CREATED_EVENT_DEF 1
+#define DELETED_EVENT_DEF 2
+#define CHANGED_EVENT_DEF 3
+#define CHILD_EVENT_DEF 4
+#define SESSION_EVENT_DEF -1
+#define NOTWATCHING_EVENT_DEF -2
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _buffer_list;
+struct _completion_list;
+
+typedef struct _buffer_head {
+    struct _buffer_list *volatile head;
+    struct _buffer_list *last;
+#ifdef THREADED
+    pthread_mutex_t lock;
+#endif
+} buffer_head_t;
+
+typedef struct _completion_head {
+    struct _completion_list *volatile head;
+    struct _completion_list *last;
+#ifdef THREADED
+    pthread_cond_t cond;
+    pthread_mutex_t lock;
+#endif
+} completion_head_t;
+
+int lock_buffer_list(buffer_head_t *l);
+int unlock_buffer_list(buffer_head_t *l);
+int lock_completion_list(completion_head_t *l);
+int unlock_completion_list(completion_head_t *l);
+
+struct sync_completion {
+    int rc;
+    union {
+        struct {
+            char *str;
+            int str_len;
+        } str;
+        struct Stat stat;
+        struct {
+            char *buffer;
+            int buff_len;
+            struct Stat stat;
+        } data;
+        struct {
+            struct ACL_vector acl;
+            struct Stat stat;
+        } acl;
+        struct String_vector strs2;
+        struct {
+            struct String_vector strs2;
+            struct Stat stat2;
+        } strs_stat;
+    } u;
+    int complete;
+#ifdef THREADED
+    pthread_cond_t cond;
+    pthread_mutex_t lock;
+#endif
+};
+
+typedef struct _auth_info {
+    int state; /* 0=>inactive, >0 => active */
+    char* scheme;
+    struct buffer auth;
+    void_completion_t completion;
+    const char* data;
+    struct _auth_info *next;
+} auth_info;
+
+/**
+ * This structure represents a packet being read or written.
+ */
+typedef struct _buffer_list {
+    char *buffer;
+    int len; /* This represents the length of sizeof(header) + length of buffer */
+    int curr_offset; /* This is the offset into the header followed by offset into the buffer */
+    struct _buffer_list *next;
+} buffer_list_t;
+
+/* the size of connect request */
+#define HANDSHAKE_REQ_SIZE 44
+/* connect request */
+struct connect_req {
+    int32_t protocolVersion;
+    int64_t lastZxidSeen;
+    int32_t timeOut;
+    int64_t sessionId;
+    int32_t passwd_len;
+    char passwd[16];
+};
+
+/* the connect response */
+struct prime_struct {
+    int32_t len;
+    int32_t protocolVersion;
+    int32_t timeOut;
+    int64_t sessionId;
+    int32_t passwd_len;
+    char passwd[16];
+}; 
+
+#ifdef THREADED
+/* this is used by mt_adaptor internally for thread management */
+struct adaptor_threads {
+     pthread_t io;
+     pthread_t completion;
+     int threadsToWait;         // barrier
+     pthread_cond_t cond;       // barrier's conditional
+     pthread_mutex_t lock;      // ... and a lock
+     pthread_mutex_t zh_lock;   // critical section lock
+#ifdef WIN32
+     SOCKET self_pipe[2];
+#else
+     int self_pipe[2];
+#endif
+};
+#endif
+
+/** the auth list for adding auth */
+typedef struct _auth_list_head {
+     auth_info *auth;
+#ifdef THREADED
+     pthread_mutex_t lock;
+#endif
+} auth_list_head_t;
+
+/**
+ * This structure represents the connection to zookeeper.
+ */
+
+struct _zhandle {
+#ifdef WIN32
+    SOCKET fd; /* the descriptor used to talk to zookeeper */
+#else
+    int fd; /* the descriptor used to talk to zookeeper */
+#endif
+    char *hostname; /* the hostname of zookeeper */
+    struct sockaddr_storage *addrs; /* the addresses that correspond to the hostname */
+    int addrs_count; /* The number of addresses in the addrs array */
+    watcher_fn watcher; /* the registered watcher */
+    struct timeval last_recv; /* The time that the last message was received */
+    struct timeval last_send; /* The time that the last message was sent */
+    struct timeval last_ping; /* The time that the last PING was sent */
+    struct timeval next_deadline; /* The time of the next deadline */
+    int recv_timeout; /* The maximum amount of time that can go by without 
+     receiving anything from the zookeeper server */
+    buffer_list_t *input_buffer; /* the current buffer being read in */
+    buffer_head_t to_process; /* The buffers that have been read and are ready to be processed. */
+    buffer_head_t to_send; /* The packets queued to send */
+    completion_head_t sent_requests; /* The outstanding requests */
+    completion_head_t completions_to_process; /* completions that are ready to run */
+    int connect_index; /* The index of the address to connect to */
+    clientid_t client_id;
+    long long last_zxid;
+    int outstanding_sync; /* Number of outstanding synchronous requests */
+    struct _buffer_list primer_buffer; /* The buffer used for the handshake at the start of a connection */
+    struct prime_struct primer_storage; /* the connect response */
+    char primer_storage_buffer[40]; /* the true size of primer_storage */
+    volatile int state;
+    void *context;
+    auth_list_head_t auth_h; /* authentication data list */
+    /* zookeeper_close is not reentrant because it de-allocates the zhandler. 
+     * This guard variable is used to defer the destruction of zhandle till 
+     * right before top-level API call returns to the caller */
+    int32_t ref_counter;
+    volatile int close_requested;
+    void *adaptor_priv;
+    /* Used for debugging only: non-zero value indicates the time when the zookeeper_process
+     * call returned while there was at least one unprocessed server response 
+     * available in the socket recv buffer */
+    struct timeval socket_readable;
+    
+    zk_hashtable* active_node_watchers;   
+    zk_hashtable* active_exist_watchers;
+    zk_hashtable* active_child_watchers;
+    /** used for chroot path at the client side **/
+    char *chroot;
+};
+
+
+int adaptor_init(zhandle_t *zh);
+void adaptor_finish(zhandle_t *zh);
+void adaptor_destroy(zhandle_t *zh);
+struct sync_completion *alloc_sync_completion(void);
+int wait_sync_completion(struct sync_completion *sc);
+void free_sync_completion(struct sync_completion *sc);
+void notify_sync_completion(struct sync_completion *sc);
+int adaptor_send_queue(zhandle_t *zh, int timeout);
+int process_async(int outstanding_sync);
+void process_completions(zhandle_t *zh);
+int flush_send_queue(zhandle_t*zh, int timeout);
+char* sub_string(zhandle_t *zh, const char* server_path);
+void free_duplicate_path(const char* free_path, const char* path);
+int zoo_lock_auth(zhandle_t *zh);
+int zoo_unlock_auth(zhandle_t *zh);
+
+// critical section guards
+int enter_critical(zhandle_t* zh);
+int leave_critical(zhandle_t* zh);
+// zhandle object reference counting
+void api_prolog(zhandle_t* zh);
+int api_epilog(zhandle_t *zh, int rc);
+int32_t get_xid();
+// returns the new value of the ref counter
+int32_t inc_ref_counter(zhandle_t* zh,int i);
+
+#ifdef THREADED
+// atomic post-increment
+int32_t fetch_and_add(volatile int32_t* operand, int incr);
+// in mt mode process session event asynchronously by the completion thread
+#define PROCESS_SESSION_EVENT(zh,newstate) queue_session_event(zh,newstate)
+#else
+// in single-threaded mode process session event immediately
+//#define PROCESS_SESSION_EVENT(zh,newstate) deliverWatchers(zh,ZOO_SESSION_EVENT,newstate,0)
+#define PROCESS_SESSION_EVENT(zh,newstate) queue_session_event(zh,newstate)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*ZK_ADAPTOR_H_*/
+
+

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/zk_hashtable.c
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/zk_hashtable.c b/zookeeper-client/zookeeper-client-c/src/zk_hashtable.c
new file mode 100644
index 0000000..0efc5aa
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/zk_hashtable.c
@@ -0,0 +1,337 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "zk_hashtable.h"
+#include "zk_adaptor.h"
+#include "hashtable/hashtable.h"
+#include "hashtable/hashtable_itr.h"
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+typedef struct _watcher_object {
+    watcher_fn watcher;
+    void* context;
+    struct _watcher_object* next;
+} watcher_object_t;
+
+
+struct _zk_hashtable {
+    struct hashtable* ht;
+};
+
+struct watcher_object_list {
+    watcher_object_t* head;
+};
+
+/* the following functions are for testing only */
+typedef struct hashtable hashtable_impl;
+
+hashtable_impl* getImpl(zk_hashtable* ht){
+    return ht->ht;
+}
+
+watcher_object_t* getFirstWatcher(zk_hashtable* ht,const char* path)
+{
+    watcher_object_list_t* wl=hashtable_search(ht->ht,(void*)path);
+    if(wl!=0)
+        return wl->head;
+    return 0;
+}
+/* end of testing functions */
+
+watcher_object_t* clone_watcher_object(watcher_object_t* wo)
+{
+    watcher_object_t* res=calloc(1,sizeof(watcher_object_t));
+    assert(res);
+    res->watcher=wo->watcher;
+    res->context=wo->context;
+    return res;
+}
+
+static unsigned int string_hash_djb2(void *str) 
+{
+    unsigned int hash = 5381;
+    int c;
+    const char* cstr = (const char*)str;
+    while ((c = *cstr++))
+        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+
+    return hash;
+}
+
+static int string_equal(void *key1,void *key2)
+{
+    return strcmp((const char*)key1,(const char*)key2)==0;
+}
+
+static watcher_object_t* create_watcher_object(watcher_fn watcher,void* ctx)
+{
+    watcher_object_t* wo=calloc(1,sizeof(watcher_object_t));
+    assert(wo);
+    wo->watcher=watcher;
+    wo->context=ctx;
+    return wo;
+}
+
+static watcher_object_list_t* create_watcher_object_list(watcher_object_t* head) 
+{
+    watcher_object_list_t* wl=calloc(1,sizeof(watcher_object_list_t));
+    assert(wl);
+    wl->head=head;
+    return wl;
+}
+
+static void destroy_watcher_object_list(watcher_object_list_t* list)
+{
+    watcher_object_t* e = NULL;
+
+    if(list==0)
+        return;
+    e=list->head;
+    while(e!=0){
+        watcher_object_t* this=e;
+        e=e->next;
+        free(this);
+    }
+    free(list);
+}
+
+zk_hashtable* create_zk_hashtable()
+{
+    struct _zk_hashtable *ht=calloc(1,sizeof(struct _zk_hashtable));
+    assert(ht);
+    ht->ht=create_hashtable(32,string_hash_djb2,string_equal);
+    return ht;
+}
+
+static void do_clean_hashtable(zk_hashtable* ht)
+{
+    struct hashtable_itr *it;
+    int hasMore;
+    if(hashtable_count(ht->ht)==0)
+        return;
+    it=hashtable_iterator(ht->ht);
+    do {
+        watcher_object_list_t* w=hashtable_iterator_value(it);
+        destroy_watcher_object_list(w);
+        hasMore=hashtable_iterator_remove(it);
+    } while(hasMore);
+    free(it);
+}
+
+void destroy_zk_hashtable(zk_hashtable* ht)
+{
+    if(ht!=0){
+        do_clean_hashtable(ht);
+        hashtable_destroy(ht->ht,0);
+        free(ht);
+    }
+}
+
+// searches for a watcher object instance in a watcher object list;
+// two watcher objects are equal if their watcher function and context pointers
+// are equal
+static watcher_object_t* search_watcher(watcher_object_list_t** wl,watcher_object_t* wo)
+{
+    watcher_object_t* wobj=(*wl)->head;
+    while(wobj!=0){
+        if(wobj->watcher==wo->watcher && wobj->context==wo->context)
+            return wobj;
+        wobj=wobj->next;
+    }
+    return 0;
+}
+
+static int add_to_list(watcher_object_list_t **wl, watcher_object_t *wo,
+                       int clone)
+{
+    if (search_watcher(wl, wo)==0) {
+        watcher_object_t* cloned=wo;
+        if (clone) {
+            cloned = clone_watcher_object(wo);
+            assert(cloned);
+        }
+        cloned->next = (*wl)->head;
+        (*wl)->head = cloned;
+        return 1;
+    } else if (!clone) {
+        // If it's here and we aren't supposed to clone, we must destroy
+        free(wo);
+    }
+    return 0;
+}
+
+static int do_insert_watcher_object(zk_hashtable *ht, const char *path, watcher_object_t* wo)
+{
+    int res=1;
+    watcher_object_list_t* wl;
+
+    wl=hashtable_search(ht->ht,(void*)path);
+    if(wl==0){
+        int res;
+        /* inserting a new path element */
+        res=hashtable_insert(ht->ht,strdup(path),create_watcher_object_list(wo));
+        assert(res);
+    }else{
+        /*
+         * Path already exists; check if the watcher already exists.
+         * Don't clone the watcher since it's allocated on the heap --- avoids
+         * a memory leak and saves a clone operation (calloc + copy).
+         */
+        res = add_to_list(&wl, wo, 0);
+    }
+    return res;    
+}
+
+
+char **collect_keys(zk_hashtable *ht, int *count)
+{
+    char **list;
+    struct hashtable_itr *it;
+    int i;
+
+    *count = hashtable_count(ht->ht);
+    list = calloc(*count, sizeof(char*));
+    it=hashtable_iterator(ht->ht);
+    for(i = 0; i < *count; i++) {
+        list[i] = strdup(hashtable_iterator_key(it));
+        hashtable_iterator_advance(it);
+    }
+    free(it);
+    return list;
+}
+
+static int insert_watcher_object(zk_hashtable *ht, const char *path,
+                                 watcher_object_t* wo)
+{
+    int res;
+    res=do_insert_watcher_object(ht,path,wo);
+    return res;
+}
+
+static void copy_watchers(watcher_object_list_t *from, watcher_object_list_t *to, int clone)
+{
+    watcher_object_t* wo=from->head;
+    while(wo){
+        watcher_object_t *next = wo->next;
+        add_to_list(&to, wo, clone);
+        wo=next;
+    }
+}
+
+static void copy_table(zk_hashtable *from, watcher_object_list_t *to) {
+    struct hashtable_itr *it;
+    int hasMore;
+    if(hashtable_count(from->ht)==0)
+        return;
+    it=hashtable_iterator(from->ht);
+    do {
+        watcher_object_list_t *w = hashtable_iterator_value(it);
+        copy_watchers(w, to, 1);
+        hasMore=hashtable_iterator_advance(it);
+    } while(hasMore);
+    free(it);
+}
+
+static void collect_session_watchers(zhandle_t *zh,
+                                     watcher_object_list_t **list)
+{
+    copy_table(zh->active_node_watchers, *list);
+    copy_table(zh->active_exist_watchers, *list);
+    copy_table(zh->active_child_watchers, *list);
+}
+
+static void add_for_event(zk_hashtable *ht, char *path, watcher_object_list_t **list)
+{
+    watcher_object_list_t* wl;
+    wl = (watcher_object_list_t*)hashtable_remove(ht->ht, path);
+    if (wl) {
+        copy_watchers(wl, *list, 0);
+        // Since we move, not clone the watch_objects, we just need to free the
+        // head pointer
+        free(wl);
+    }
+}
+
+static void do_foreach_watcher(watcher_object_t* wo,zhandle_t* zh,
+        const char* path,int type,int state)
+{
+    // session event's don't have paths
+    const char *client_path =
+        (type != ZOO_SESSION_EVENT ? sub_string(zh, path) : path);
+    while(wo!=0){
+        wo->watcher(zh,type,state,client_path,wo->context);
+        wo=wo->next;
+    }    
+    free_duplicate_path(client_path, path);
+}
+
+watcher_object_list_t *collectWatchers(zhandle_t *zh,int type, char *path)
+{
+    struct watcher_object_list *list = create_watcher_object_list(0); 
+
+    if(type==ZOO_SESSION_EVENT){
+        watcher_object_t defWatcher;
+        defWatcher.watcher=zh->watcher;
+        defWatcher.context=zh->context;
+        add_to_list(&list, &defWatcher, 1);
+        collect_session_watchers(zh, &list);
+        return list;
+    }
+    switch(type){
+    case CREATED_EVENT_DEF:
+    case CHANGED_EVENT_DEF:
+        // look up the watchers for the path and move them to a delivery list
+        add_for_event(zh->active_node_watchers,path,&list);
+        add_for_event(zh->active_exist_watchers,path,&list);
+        break;
+    case CHILD_EVENT_DEF:
+        // look up the watchers for the path and move them to a delivery list
+        add_for_event(zh->active_child_watchers,path,&list);
+        break;
+    case DELETED_EVENT_DEF:
+        // look up the watchers for the path and move them to a delivery list
+        add_for_event(zh->active_node_watchers,path,&list);
+        add_for_event(zh->active_exist_watchers,path,&list);
+        add_for_event(zh->active_child_watchers,path,&list);
+        break;
+    }
+    return list;
+}
+
+void deliverWatchers(zhandle_t *zh, int type,int state, char *path, watcher_object_list_t **list)
+{
+    if (!list || !(*list)) return;
+    do_foreach_watcher((*list)->head, zh, path, type, state);
+    destroy_watcher_object_list(*list);
+    *list = 0;
+}
+
+void activateWatcher(zhandle_t *zh, watcher_registration_t* reg, int rc)
+{
+    if(reg){
+        /* in multithreaded lib, this code is executed 
+         * by the IO thread */
+        zk_hashtable *ht = reg->checker(zh, rc);
+        if(ht){
+            insert_watcher_object(ht,reg->path,
+                    create_watcher_object(reg->watcher, reg->context));
+        }
+    }    
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/zk_hashtable.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/zk_hashtable.h b/zookeeper-client/zookeeper-client-c/src/zk_hashtable.h
new file mode 100644
index 0000000..31109c1
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/zk_hashtable.h
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ZK_HASHTABLE_H_
+#define ZK_HASHTABLE_H_
+
+#include <zookeeper.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    typedef struct watcher_object_list watcher_object_list_t;
+typedef struct _zk_hashtable zk_hashtable;
+
+/**
+ * The function must return a non-zero value if the watcher object can be activated
+ * as a result of the server response. Normally, a watch can only be activated
+ * if the server returns a success code (ZOK). However in the case when zoo_exists() 
+ * returns a ZNONODE code the watcher should be activated nevertheless.
+ */
+typedef zk_hashtable *(*result_checker_fn)(zhandle_t *, int rc);
+
+/**
+ * A watcher object gets temporarily stored with the completion entry until 
+ * the server response comes back at which moment the watcher object is moved
+ * to the active watchers map.
+ */
+typedef struct _watcher_registration {
+    watcher_fn watcher;
+    void* context;
+    result_checker_fn checker;
+    const char* path;
+} watcher_registration_t;
+
+zk_hashtable* create_zk_hashtable();
+void destroy_zk_hashtable(zk_hashtable* ht);
+
+char **collect_keys(zk_hashtable *ht, int *count);
+
+/**
+ * check if the completion has a watcher object associated
+ * with it. If it does, move the watcher object to the map of
+ * active watchers (only if the checker allows to do so)
+ */
+    void activateWatcher(zhandle_t *zh, watcher_registration_t* reg, int rc);
+    watcher_object_list_t *collectWatchers(zhandle_t *zh,int type, char *path);
+    void deliverWatchers(zhandle_t *zh, int type, int state, char *path, struct watcher_object_list **list);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*ZK_HASHTABLE_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/zk_log.c
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/zk_log.c b/zookeeper-client/zookeeper-client-c/src/zk_log.c
new file mode 100644
index 0000000..6b4fdfa
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/zk_log.c
@@ -0,0 +1,180 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if !defined(DLL_EXPORT) && !defined(USE_STATIC_LIB)
+#  define USE_STATIC_LIB
+#endif
+
+#include "zookeeper_log.h"
+#ifndef WIN32
+#include <unistd.h>
+#else
+typedef DWORD pid_t;
+#include <process.h> /* for getpid */
+#endif
+
+#include <stdarg.h>
+#include <time.h>
+
+#define TIME_NOW_BUF_SIZE 1024
+#define FORMAT_LOG_BUF_SIZE 4096
+
+#ifdef THREADED
+#ifndef WIN32
+#include <pthread.h>
+#else 
+#include "winport.h"
+#endif
+
+static pthread_key_t time_now_buffer;
+static pthread_key_t format_log_msg_buffer;
+
+void freeBuffer(void* p){
+    if(p) free(p);
+}
+
+__attribute__((constructor)) void prepareTSDKeys() {
+    pthread_key_create (&time_now_buffer, freeBuffer);
+    pthread_key_create (&format_log_msg_buffer, freeBuffer);
+}
+
+char* getTSData(pthread_key_t key,int size){
+    char* p=pthread_getspecific(key);
+    if(p==0){
+        int res;
+        p=calloc(1,size);
+        res=pthread_setspecific(key,p);
+        if(res!=0){
+            fprintf(stderr,"Failed to set TSD key: %d",res);
+        }
+    }
+    return p;
+}
+
+char* get_time_buffer(){
+    return getTSData(time_now_buffer,TIME_NOW_BUF_SIZE);
+}
+
+char* get_format_log_buffer(){  
+    return getTSData(format_log_msg_buffer,FORMAT_LOG_BUF_SIZE);
+}
+#else
+char* get_time_buffer(){
+    static char buf[TIME_NOW_BUF_SIZE];
+    return buf;    
+}
+
+char* get_format_log_buffer(){
+    static char buf[FORMAT_LOG_BUF_SIZE];
+    return buf;
+}
+
+#endif
+
+ZooLogLevel logLevel=ZOO_LOG_LEVEL_INFO;
+
+static FILE* logStream=0;
+FILE* getLogStream(){
+    if(logStream==0)
+        logStream=stderr;
+    return logStream;
+}
+
+void zoo_set_log_stream(FILE* stream){
+    logStream=stream;
+}
+
+static const char* time_now(char* now_str){
+    struct timeval tv;
+    struct tm lt;
+    time_t now = 0;
+    size_t len = 0;
+    
+    gettimeofday(&tv,0);
+
+    now = tv.tv_sec;
+    localtime_r(&now, &lt);
+
+    // clone the format used by log4j ISO8601DateFormat
+    // specifically: "yyyy-MM-dd HH:mm:ss,SSS"
+
+    len = strftime(now_str, TIME_NOW_BUF_SIZE,
+                          "%Y-%m-%d %H:%M:%S",
+                          &lt);
+
+    len += snprintf(now_str + len,
+                    TIME_NOW_BUF_SIZE - len,
+                    ",%03d",
+                    (int)(tv.tv_usec/1000));
+
+    return now_str;
+}
+
+void log_message(ZooLogLevel curLevel,int line,const char* funcName,
+    const char* message)
+{
+    static const char* dbgLevelStr[]={"ZOO_INVALID","ZOO_ERROR","ZOO_WARN",
+            "ZOO_INFO","ZOO_DEBUG"};
+    static pid_t pid=0;
+#ifdef WIN32
+    char timebuf [TIME_NOW_BUF_SIZE];
+#endif
+    if(pid==0)pid=getpid();
+#ifndef THREADED
+    // pid_t is long on Solaris
+    fprintf(LOGSTREAM, "%s:%ld:%s@%s@%d: %s\n", time_now(get_time_buffer()),(long)pid,
+            dbgLevelStr[curLevel],funcName,line,message);
+#else
+#ifdef WIN32
+    fprintf(LOGSTREAM, "%s:%d(0x%lx):%s@%s@%d: %s\n", time_now(timebuf),pid,
+            (unsigned long int)(pthread_self().thread_id),
+            dbgLevelStr[curLevel],funcName,line,message);      
+#else
+    fprintf(LOGSTREAM, "%s:%ld(0x%lx):%s@%s@%d: %s\n", time_now(get_time_buffer()),(long)pid,
+            (unsigned long int)pthread_self(),
+            dbgLevelStr[curLevel],funcName,line,message);      
+#endif
+#endif
+    fflush(LOGSTREAM);
+}
+
+const char* format_log_message(const char* format,...)
+{
+    va_list va;
+    char* buf=get_format_log_buffer();
+    if(!buf)
+        return "format_log_message: Unable to allocate memory buffer";
+    
+    va_start(va,format);
+    vsnprintf(buf, FORMAT_LOG_BUF_SIZE-1,format,va);
+    va_end(va); 
+    return buf;
+}
+
+void zoo_set_debug_level(ZooLogLevel level)
+{
+    if(level==0){
+        // disable logging (unit tests do this)
+        logLevel=(ZooLogLevel)0;
+        return;
+    }
+    if(level<ZOO_LOG_LEVEL_ERROR)level=ZOO_LOG_LEVEL_ERROR;
+    if(level>ZOO_LOG_LEVEL_DEBUG)level=ZOO_LOG_LEVEL_DEBUG;
+    logLevel=level;
+}
+


[20/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Separate PR for branch 3.5, code change based on 176bd68222f3a3bddac9deb412eee7f538cb01ca

Author: Norbert Kalmar <nk...@yahoo.com>

Reviewers: andor@apache.org

Closes #603 from nkalmar/ZOOKEEPER-3031_3.4


Project: http://git-wip-us.apache.org/repos/asf/zookeeper/repo
Commit: http://git-wip-us.apache.org/repos/asf/zookeeper/commit/5694559d
Tree: http://git-wip-us.apache.org/repos/asf/zookeeper/tree/5694559d
Diff: http://git-wip-us.apache.org/repos/asf/zookeeper/diff/5694559d

Branch: refs/heads/branch-3.4
Commit: 5694559d797b60f3d8428bf44cc3c29354fb3b4f
Parents: f90e4a4
Author: Norbert Kalmar <nk...@yahoo.com>
Authored: Thu Aug 23 16:11:36 2018 +0200
Committer: Andor Molnar <an...@apache.org>
Committed: Thu Aug 23 16:11:36 2018 +0200

----------------------------------------------------------------------
 .gitignore                                      |   36 +-
 build.xml                                       |   17 +-
 src/c/CMakeLists.txt                            |  237 --
 src/c/ChangeLog                                 |  116 -
 src/c/INSTALL                                   |  234 --
 src/c/LICENSE                                   |  202 -
 src/c/Makefile.am                               |  128 -
 src/c/NOTICE.txt                                |   41 -
 src/c/README                                    |  156 -
 src/c/acinclude.m4                              |  312 --
 src/c/aminclude.am                              |  186 -
 src/c/c-doc.Doxyfile                            | 1252 ------
 src/c/cmake_config.h.in                         |  154 -
 src/c/configure.ac                              |  165 -
 src/c/include/proto.h                           |   47 -
 src/c/include/recordio.h                        |   83 -
 src/c/include/winconfig.h                       |   15 -
 src/c/include/zookeeper.h                       | 1589 --------
 src/c/include/zookeeper_log.h                   |   51 -
 src/c/include/zookeeper_version.h               |   33 -
 src/c/src/cli.c                                 |  697 ----
 src/c/src/hashtable/LICENSE.txt                 |   30 -
 src/c/src/hashtable/hashtable.c                 |  274 --
 src/c/src/hashtable/hashtable.h                 |  209 -
 src/c/src/hashtable/hashtable_itr.c             |  176 -
 src/c/src/hashtable/hashtable_itr.h             |  119 -
 src/c/src/hashtable/hashtable_private.h         |   85 -
 src/c/src/load_gen.c                            |  282 --
 src/c/src/mt_adaptor.c                          |  519 ---
 src/c/src/recordio.c                            |  366 --
 src/c/src/st_adaptor.c                          |  113 -
 src/c/src/winport.c                             |  302 --
 src/c/src/winport.h                             |  138 -
 src/c/src/zk_adaptor.h                          |  276 --
 src/c/src/zk_hashtable.c                        |  337 --
 src/c/src/zk_hashtable.h                        |   69 -
 src/c/src/zk_log.c                              |  180 -
 src/c/src/zookeeper.c                           | 3767 ------------------
 src/c/tests/CollectionUtil.h                    |  195 -
 src/c/tests/CppAssertHelper.h                   |   37 -
 src/c/tests/LibCMocks.cc                        |  333 --
 src/c/tests/LibCMocks.h                         |  408 --
 src/c/tests/LibCSymTable.cc                     |   83 -
 src/c/tests/LibCSymTable.h                      |  107 -
 src/c/tests/MocksBase.cc                        |   36 -
 src/c/tests/MocksBase.h                         |   36 -
 src/c/tests/PthreadMocks.cc                     |  106 -
 src/c/tests/PthreadMocks.h                      |  449 ---
 src/c/tests/TestClient.cc                       | 1135 ------
 src/c/tests/TestClientRetry.cc                  |  273 --
 src/c/tests/TestDriver.cc                       |  173 -
 src/c/tests/TestMulti.cc                        |  703 ----
 src/c/tests/TestOperations.cc                   |  710 ----
 src/c/tests/TestWatchers.cc                     |  773 ----
 src/c/tests/TestZookeeperClose.cc               |  472 ---
 src/c/tests/TestZookeeperInit.cc                |  301 --
 src/c/tests/ThreadingUtil.cc                    |   87 -
 src/c/tests/ThreadingUtil.h                     |  261 --
 src/c/tests/Util.cc                             |   51 -
 src/c/tests/Util.h                              |  137 -
 src/c/tests/Vector.h                            |   37 -
 src/c/tests/ZKMocks.cc                          |  519 ---
 src/c/tests/ZKMocks.h                           |  509 ---
 src/c/tests/wrappers-mt.opt                     |    3 -
 src/c/tests/wrappers.opt                        |    7 -
 src/c/tests/zkServer.sh                         |  161 -
 .../zookeeper-client-c/CMakeLists.txt           |  237 ++
 zookeeper-client/zookeeper-client-c/ChangeLog   |  116 +
 zookeeper-client/zookeeper-client-c/INSTALL     |  234 ++
 zookeeper-client/zookeeper-client-c/LICENSE     |  202 +
 zookeeper-client/zookeeper-client-c/Makefile.am |  128 +
 zookeeper-client/zookeeper-client-c/NOTICE.txt  |   41 +
 zookeeper-client/zookeeper-client-c/README      |  157 +
 .../zookeeper-client-c/acinclude.m4             |  312 ++
 .../zookeeper-client-c/aminclude.am             |  186 +
 .../zookeeper-client-c/c-doc.Doxyfile           | 1252 ++++++
 .../zookeeper-client-c/cmake_config.h.in        |  154 +
 .../zookeeper-client-c/configure.ac             |  165 +
 .../zookeeper-client-c/include/proto.h          |   47 +
 .../zookeeper-client-c/include/recordio.h       |   83 +
 .../zookeeper-client-c/include/winconfig.h      |   15 +
 .../zookeeper-client-c/include/zookeeper.h      | 1589 ++++++++
 .../zookeeper-client-c/include/zookeeper_log.h  |   51 +
 .../include/zookeeper_version.h                 |   33 +
 zookeeper-client/zookeeper-client-c/src/cli.c   |  697 ++++
 .../src/hashtable/LICENSE.txt                   |   30 +
 .../src/hashtable/hashtable.c                   |  274 ++
 .../src/hashtable/hashtable.h                   |  209 +
 .../src/hashtable/hashtable_itr.c               |  176 +
 .../src/hashtable/hashtable_itr.h               |  119 +
 .../src/hashtable/hashtable_private.h           |   85 +
 .../zookeeper-client-c/src/load_gen.c           |  282 ++
 .../zookeeper-client-c/src/mt_adaptor.c         |  519 +++
 .../zookeeper-client-c/src/recordio.c           |  366 ++
 .../zookeeper-client-c/src/st_adaptor.c         |  113 +
 .../zookeeper-client-c/src/winport.c            |  302 ++
 .../zookeeper-client-c/src/winport.h            |  138 +
 .../zookeeper-client-c/src/zk_adaptor.h         |  276 ++
 .../zookeeper-client-c/src/zk_hashtable.c       |  337 ++
 .../zookeeper-client-c/src/zk_hashtable.h       |   69 +
 .../zookeeper-client-c/src/zk_log.c             |  180 +
 .../zookeeper-client-c/src/zookeeper.c          | 3767 ++++++++++++++++++
 .../zookeeper-client-c/tests/CollectionUtil.h   |  195 +
 .../zookeeper-client-c/tests/CppAssertHelper.h  |   37 +
 .../zookeeper-client-c/tests/LibCMocks.cc       |  333 ++
 .../zookeeper-client-c/tests/LibCMocks.h        |  408 ++
 .../zookeeper-client-c/tests/LibCSymTable.cc    |   83 +
 .../zookeeper-client-c/tests/LibCSymTable.h     |  107 +
 .../zookeeper-client-c/tests/MocksBase.cc       |   36 +
 .../zookeeper-client-c/tests/MocksBase.h        |   36 +
 .../zookeeper-client-c/tests/PthreadMocks.cc    |  106 +
 .../zookeeper-client-c/tests/PthreadMocks.h     |  449 +++
 .../zookeeper-client-c/tests/TestClient.cc      | 1135 ++++++
 .../zookeeper-client-c/tests/TestClientRetry.cc |  273 ++
 .../zookeeper-client-c/tests/TestDriver.cc      |  173 +
 .../zookeeper-client-c/tests/TestMulti.cc       |  703 ++++
 .../zookeeper-client-c/tests/TestOperations.cc  |  710 ++++
 .../zookeeper-client-c/tests/TestWatchers.cc    |  773 ++++
 .../tests/TestZookeeperClose.cc                 |  472 +++
 .../tests/TestZookeeperInit.cc                  |  301 ++
 .../zookeeper-client-c/tests/ThreadingUtil.cc   |   87 +
 .../zookeeper-client-c/tests/ThreadingUtil.h    |  261 ++
 .../zookeeper-client-c/tests/Util.cc            |   51 +
 .../zookeeper-client-c/tests/Util.h             |  137 +
 .../zookeeper-client-c/tests/Vector.h           |   37 +
 .../zookeeper-client-c/tests/ZKMocks.cc         |  519 +++
 .../zookeeper-client-c/tests/ZKMocks.h          |  509 +++
 .../zookeeper-client-c/tests/wrappers-mt.opt    |    3 +
 .../zookeeper-client-c/tests/wrappers.opt       |    7 +
 .../zookeeper-client-c/tests/zkServer.sh        |  161 +
 .../src/python/setup.py                         |    8 +-
 .../content/xdocs/zookeeperProgrammers.xml      |   10 +-
 .../src/main/c/configure.ac                     |    4 +-
 .../src/main/c/configure.ac                     |    4 +-
 134 files changed, 21083 insertions(+), 21081 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index c5bd7f5..78c9ed4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,24 +59,24 @@ tags
 .cproject
 .project
 obj
-src/c/core.*
-src/c/TEST-*.txt
-src/c/*.la
-src/c/*.lo
-src/c/*.o
-src/c/generated/
+zookeeper-client/zookeeper-client-c/core.*
+zookeeper-client/zookeeper-client-c/TEST-*.txt
+zookeeper-client/zookeeper-client-c/*.la
+zookeeper-client/zookeeper-client-c/*.lo
+zookeeper-client/zookeeper-client-c/*.o
+zookeeper-client/zookeeper-client-c/generated/
 src/java/generated/
 src/java/lib/ant-eclipse-*
 src/java/lib/ivy-*
-src/c/Makefile.in
-src/c/aclocal.m4
-src/c/autom4te.cache/
-src/c/compile
-src/c/config.guess
-src/c/config.h.in
-src/c/config.sub
-src/c/configure
-src/c/depcomp
-src/c/install-sh
-src/c/ltmain.sh
-src/c/missing
+zookeeper-client/zookeeper-client-c/Makefile.in
+zookeeper-client/zookeeper-client-c/aclocal.m4
+zookeeper-client/zookeeper-client-c/autom4te.cache/
+zookeeper-client/zookeeper-client-c/compile
+szookeeper-client/zookeeper-client-c/config.guess
+zookeeper-client/zookeeper-client-c/config.h.in
+zookeeper-client/zookeeper-client-c/config.sub
+zookeeper-client/zookeeper-client-c/configure
+zookeeper-client/zookeeper-client-c/depcomp
+zookeeper-client/zookeeper-client-c/install-sh
+zookeeper-client/zookeeper-client-c/ltmain.sh
+zookeeper-client/zookeeper-client-c/missing

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/build.xml
----------------------------------------------------------------------
diff --git a/build.xml b/build.xml
index 0131468..021c9b6 100644
--- a/build.xml
+++ b/build.xml
@@ -99,7 +99,7 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
     <property name="build.dir" value="${basedir}/build" />
     <property name="distribution" value="${basedir}/distribution" />
     <property name="src_generated.dir" value="${src.dir}/java/generated" />
-    <property name="c.src.dir" value="${src.dir}/c" />    
+    <property name="c.src.dir" value="${basedir}/zookeeper-client/zookeeper-client-c" />
     <property name="csrc_generated.dir" value="${c.src.dir}/generated" />
 
     <property name="jute.file" value="${src.dir}/zookeeper.jute" />
@@ -328,7 +328,7 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
         <java classname="org.apache.jute.compiler.generated.Rcc" fork="true" dir="${src_generated.dir}">
             <arg value="-l" />
             <arg value="java" />
-            <arg value="../../zookeeper.jute" /> 
+            <arg value="../../zookeeper.jute" />
             <classpath>
                 <pathelement path="${build.classes}" />
             </classpath>
@@ -337,7 +337,7 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
         <java classname="org.apache.jute.compiler.generated.Rcc" fork="true" dir="${csrc_generated.dir}">
             <arg value="-l" />
             <arg value="c" />
-            <arg value="../../zookeeper.jute" />
+            <arg value="../../../src/zookeeper.jute" />
             <classpath>
                 <pathelement path="${build.classes}" />
             </classpath>
@@ -833,6 +833,7 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
           <include name="zookeeper-recipes/**"/>
           <include name="zookeeper-docs/**"/>
           <include name="zookeeper-contrib/**"/>
+          <include name="zookeeper-client/**"/>
         </fileset>
         <fileset file="src/pom.template"/>
       </copy>
@@ -1027,8 +1028,8 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
       <macro_tar param.destfile="${build.dir}/${final.name}-bin.tar.gz">
         <param.listofitems>
           <tarfileset dir="${build.dir}" mode="664">
-            <include name="${final.name}/src/c/**" />
-            <exclude name="${final.name}/src/c/generated/**" />
+            <include name="${final.name}/zookeeper-client/zookeeper-client-c/**" />
+            <exclude name="${final.name}/zookeeper-client/zookeeper-client-c/generated/**" />
           </tarfileset>
           <tarfileset dir="${build.dir}" mode="664">
             <exclude name="${final.name}/bin/*" />
@@ -1811,9 +1812,9 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
           <exclude name="**/docs/"/>
           <exclude name="**/zookeeper-docs/"/>
           <exclude name="**/lib/jdiff/"/>
-          <exclude name="src/c/autom4te.cache/**"/>
-          <exclude name="src/c/config**"/>
-          <exclude name="src/c/src/hashtable/"/>
+          <exclude name="src/zookeeper-client/zookeeper-client-c/autom4te.cache/**"/>
+          <exclude name="src/zookeeper-client/zookeeper-client-c/config**"/>
+          <exclude name="src/zookeeper-client/zookeeper-client-c/src/hashtable/"/>
           <exclude name="src/java/generated/.generated/"/>
           <exclude name="src/java/test/checkstyle*.xml"/>
           <exclude name="src/java/test/checkstyle*.xsl"/>

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/c/CMakeLists.txt b/src/c/CMakeLists.txt
deleted file mode 100644
index e7dfbeb..0000000
--- a/src/c/CMakeLists.txt
+++ /dev/null
@@ -1,237 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-cmake_minimum_required(VERSION 3.6)
-
-project(zookeeper VERSION 3.4.13)
-set(email user@zookeeper.apache.org)
-set(description "zookeeper C client")
-
-# general options
-include_directories(include tests generated ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})
-if(UNIX)
-  add_compile_options(-Wall -fPIC)
-elseif(WIN32)
-  add_compile_options(/W3)
-endif()
-add_definitions(-DUSE_STATIC_LIB)
-
-# TODO: Enable /WX and /W4 on Windows. Currently there are ~1000 warnings.
-# TODO: Add Solaris support.
-# TODO: Add a shared library option.
-# TODO: Specify symbols to export.
-# TODO: Generate doxygen documentation.
-
-# Sync API option
-option(WANT_SYNCAPI "Enables Sync API support" ON)
-if(WANT_SYNCAPI)
-  add_definitions(-DTHREADED)
-  if(WIN32)
-    # Note that the generator expression ensures that `/MTd` is used when Debug
-    # configurations are built.
-    add_compile_options(/MT$<$<CONFIG:Debug>:d>)
-  endif()
-endif()
-
-# CppUnit option
-if(WIN32 OR APPLE)
-  # The tests do not yet compile on Windows or macOS,
-  # so we set this to off by default.
-  #
-  # Note that CMake does not have expressions except in conditionals,
-  # so we're left with this if/else/endif pattern.
-  set(DEFAULT_WANT_CPPUNIT OFF)
-else()
-  set(DEFAULT_WANT_CPPUNIT ON)
-endif()
-option(WANT_CPPUNIT "Enables CppUnit and tests" ${DEFAULT_WANT_CPPUNIT})
-
-# The function `to_have(in out)` converts a header name like `arpa/inet.h`
-# into an Autotools style preprocessor definition `HAVE_ARPA_INET_H`.
-# This is then set or unset in `configure_file()` step.
-#
-# Note that CMake functions do not have return values; instead an "out"
-# variable must be passed, and explicitly set with parent scope.
-function(to_have in out)
-  string(TOUPPER ${in} str)
-  string(REGEX REPLACE "/|\\." "_" str ${str})
-  set(${out} "HAVE_${str}" PARENT_SCOPE)
-endfunction()
-
-# include file checks
-foreach(f generated/zookeeper.jute.h generated/zookeeper.jute.c)
-  if(EXISTS "${CMAKE_SOURCE_DIR}/${f}")
-    to_have(${f} name)
-    set(${name} 1)
-  else()
-    message(FATAL_ERROR
-      "jute files are missing!\n"
-      "Please run 'ant compile_jute' while in the ZooKeeper top level directory.")
-  endif()
-endforeach()
-
-# header checks
-include(CheckIncludeFile)
-set(check_headers
-  arpa/inet.h
-  dlfcn.h
-  fcntl.h
-  inttypes.h
-  memory.h
-  netdb.h
-  netinet/in.h
-  stdint.h
-  stdlib.h
-  string.h
-  strings.h
-  sys/socket.h
-  sys/stat.h
-  sys/time.h
-  sys/types.h
-  unistd.h
-  sys/utsname.h)
-
-foreach(f ${check_headers})
-  to_have(${f} name)
-  check_include_file(${f} ${name})
-endforeach()
-
-# function checks
-include(CheckFunctionExists)
-set(check_functions
-  getcwd
-  gethostbyname
-  gethostname
-  getlogin
-  getpwuid_r
-  gettimeofday
-  getuid
-  memmove
-  memset
-  poll
-  socket
-  strchr
-  strdup
-  strerror
-  strtol)
-
-foreach(fn ${check_functions})
-  to_have(${fn} name)
-  check_function_exists(${fn} ${name})
-endforeach()
-
-# library checks
-set(check_libraries rt m pthread)
-foreach(lib ${check_libraries})
-  to_have("lib${lib}" name)
-  find_library(${name} ${lib})
-endforeach()
-
-# IPv6 check
-include(CheckStructHasMember)
-check_struct_has_member("struct sockaddr_in6" sin6_addr "netinet/in.h" ZOO_IPV6_ENABLED)
-
-# configure
-configure_file(cmake_config.h.in ${CMAKE_SOURCE_DIR}/include/config.h)
-
-# hashtable library
-set(hashtable_sources src/hashtable/hashtable_itr.c src/hashtable/hashtable.c)
-add_library(hashtable STATIC ${hashtable_sources})
-target_link_libraries(hashtable PUBLIC $<$<PLATFORM_ID:Linux>:m>)
-
-# zookeeper library
-set(zookeeper_sources
-  src/zookeeper.c
-  src/recordio.c
-  generated/zookeeper.jute.c
-  src/zk_log.c
-  src/zk_hashtable.c)
-
-if(WANT_SYNCAPI)
-  list(APPEND zookeeper_sources src/mt_adaptor.c)
-else()
-  list(APPEND zookeeper_sources src/st_adaptor.c)
-endif()
-
-if(WIN32)
-  list(APPEND zookeeper_sources src/winport.c)
-endif()
-
-add_library(zookeeper STATIC ${zookeeper_sources})
-target_link_libraries(zookeeper PUBLIC
-  hashtable
-  $<$<PLATFORM_ID:Linux>:rt> # clock_gettime
-  $<$<PLATFORM_ID:Windows>:ws2_32>) # Winsock 2.0
-
-if(WANT_SYNCAPI AND NOT WIN32)
-  find_package(Threads REQUIRED)
-  target_link_libraries(zookeeper PUBLIC Threads::Threads)
-endif()
-
-# cli executable
-add_executable(cli src/cli.c)
-target_link_libraries(cli zookeeper)
-
-# load_gen executable
-if(WANT_SYNCAPI AND NOT WIN32)
-  add_executable(load_gen src/load_gen.c)
-  target_link_libraries(load_gen zookeeper)
-endif()
-
-# tests
-set(test_sources
-  tests/TestDriver.cc
-  tests/LibCMocks.cc
-  tests/LibCSymTable.cc
-  tests/MocksBase.cc
-  tests/ZKMocks.cc
-  tests/Util.cc
-  tests/ThreadingUtil.cc
-  tests/TestZookeeperInit.cc
-  tests/TestZookeeperClose.cc
-  tests/TestClientRetry.cc
-  tests/TestOperations.cc
-  tests/TestMulti.cc
-  tests/TestWatchers.cc
-  tests/TestClient.cc)
-
-if(WANT_SYNCAPI)
-  list(APPEND test_sources tests/PthreadMocks.cc)
-endif()
-
-if(WANT_CPPUNIT)
-  add_executable(zktest ${test_sources})
-  target_compile_definitions(zktest
-    PRIVATE -DZKSERVER_CMD="${CMAKE_SOURCE_DIR}/tests/zkServer.sh")
-  # TODO: Use `find_library()` for `cppunit`.
-  target_link_libraries(zktest zookeeper cppunit dl)
-
-  # This reads the link flags from the file `tests/wrappers.opt` into
-  # the variable `symbol_wrappers` for use in `target_link_libraries`.
-  # It is a holdover from the original build system.
-  file(STRINGS tests/wrappers.opt symbol_wrappers)
-  if(WANT_SYNCAPI)
-    file(STRINGS tests/wrappers-mt.opt symbol_wrappers_mt)
-  endif()
-
-  target_link_libraries(zktest ${symbol_wrappers} ${symbol_wrappers_mt})
-
-  enable_testing()
-  add_test(NAME zktest_runner COMMAND zktest)
-  set_property(TEST zktest_runner PROPERTY ENVIRONMENT
-    "ZKROOT=${CMAKE_SOURCE_DIR}/../.."
-    "CLASSPATH=$CLASSPATH:$CLOVER_HOME/lib/clover.jar")
-endif()

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/ChangeLog
----------------------------------------------------------------------
diff --git a/src/c/ChangeLog b/src/c/ChangeLog
deleted file mode 100644
index c85a6c0..0000000
--- a/src/c/ChangeLog
+++ /dev/null
@@ -1,116 +0,0 @@
-Release 2.1.1
-2008-04-30 Andrew Kornev <ak...@users.sourceforge.net>
-
-    * changed the distributino package name to "c-client-src"
-    
-Release 2.1.0
-2008-04-30 Andrew Kornev <ak...@users.sourceforge.net>
-
-    * added the client latency diagnostics; the client prints a warning when the
-      reponse latency exceeds 20ms
-
-    * modified logging format to report the znode path for which the zookeeper 
-      operation is called
-
-    * fixed a minor bug where error messages were missing for some of the newer 
-      zookeeper error codes (ZCLOSING and ZNOTHING).
-
-    * improved logging by adding the XID to the message to make it easy to match
-      requests to responses
-
-    * fixed the bug causing sporadic session termination and timeouts
-
-    * added a new return code to zookeeper_process() -- ZNOTHING -- 
-      that indicates that the socket has no more data to read
-
-    * more unit tests added    
-
-Release 1.1.3
-2008-02-07 Andrew Kornev <ak...@users.sourceforge.net>
-
-    * get_xid() is not thread-safe (xid initialization race condition 
-      in the multi-threaded mode).
-    
-    * the I/O thread doesn�t automatically terminate on AUTH_FAILURE and 
-      SESSION_EXPIRED events.
-      
-    * all session events should be processed on the completion thread. 
-    
-    * PING operation doesn�t atomically enqueue the completion and 
-      send buffers like other operations do.
-      
-    * corrected zookeeper_init() doxygen docs.
-    
-    * new unit tests added.
-      
-
-Release 1.1.2
-2008-01-24 Andrew Kornev <ak...@users.sourceforge.net>
-
-    * fixed a race condition caused by the code in zookeeper_process()
-      and free_completions() setting sc->complete to 1 without proper
-      synchronization;
-
-    * fixed zoo_get() not updating buffer_len value with the actual
-      buffer length on return; added missing enter_critical/leave_critical
-      calls to the async ZK operations.
-
-    * Replaced select() with poll() to fix the problem with the FD_SET
-      macro causing stack corruption for FDs higher than 1024
-
-    * Added zoo_set_log_stream() to the public API. The function allows
-      applications to specify a different log file.
-
-    * Removed unused declarations from zookeeper.h (ACL related)
-
-    * changed zoo_get() signature to take a pointer to buffer length.
-      The function sets the parameter to the actual data length upon return.
-
-    * the watcher callback now takes the zhandle as its first parameter. This
-      is to avoid a race condition in the multi-threaded client when a watcher
-      is called before zookeeper_init() has returned.
-
-    * fixed zookeeper_close() resource leaks and race conditions,
-      fixed the race condition causing xid mismatch.
-
-    * added support for cppunit, added new targets: "check" and "run-check"
-      to build and run unit tests.
-
-    * Changed the signature of zookeeper_init(): it now takes a context pointer
-      as a parameter. This is to avoid a race condition in the multi-threaded client.
-
-    * Using a self-pipe rather than SIGUSR1 to wake up select() in the I/O thread
-
-    * Added the doxygen target to the autoconf scripts
-
-    * Pulled out the logging functionality from zookeeper.c to zk_log.c/.h.
-      Fixed a minor issue with PING responses being unnecessarily put on
-      the completion queue rather than simply dropped. Make use of DLL_EXPORT
-      symbol for building shared lib on cygwin.
-
-    * Implemented new Zookeeper operation sync() to flush the leader channel
-      to ensure that all updates have reached the followers.
-
-    * Synchronous methods not being handled properly on disconnect
-
-    * breed: fixed an incorrect parameter passed to zookeeper API by
-      the Sync API wrapper functions
-
-    * breed: the set and delete commands now support both Sync and Async API.
-      Prefix the command name with an 'a' to call the Async API: aset, adelete
-
-    * Make sure mutexes and condition variables are properly initialized
-      and destroyed
-
-    * Fixed zookeeper_close() causing core dumps with mt_adaptor
-
-
-Release 1.0.0
-2007-11-27 Andrew Kornev <ak...@users.sourceforge.net>
-
-    * configure.ac and Makefile.am added support for GNU autotools
-
-    * recordio.c/.h updated jute IO routines to use bit-explicit integer types
-      (int32_t vs. int, and int64_t vs. long long)
-
-    * README rough draft
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/INSTALL
----------------------------------------------------------------------
diff --git a/src/c/INSTALL b/src/c/INSTALL
deleted file mode 100644
index 5458714..0000000
--- a/src/c/INSTALL
+++ /dev/null
@@ -1,234 +0,0 @@
-Installation Instructions
-*************************
-
-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
-2006 Free Software Foundation, Inc.
-
-This file is free documentation; the Free Software Foundation gives
-unlimited permission to copy, distribute and modify it.
-
-Basic Installation
-==================
-
-Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package.  The following
-more-detailed instructions are generic; see the `README' file for
-instructions specific to this package.
-
-   The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation.  It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions.  Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
-   It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring.  Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.
-
-   If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release.  If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
-   The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'.  You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
-
-The simplest way to compile this package is:
-
-  1. `cd' to the directory containing the package's source code and type
-     `./configure' to configure the package for your system.
-
-     Running `configure' might take a while.  While running, it prints
-     some messages telling which features it is checking for.
-
-  2. Type `make' to compile the package.
-
-  3. Optionally, type `make check' to run any self-tests that come with
-     the package.
-
-  4. Type `make install' to install the programs and any data files and
-     documentation.
-
-  5. You can remove the program binaries and object files from the
-     source code directory by typing `make clean'.  To also remove the
-     files that `configure' created (so you can compile the package for
-     a different kind of computer), type `make distclean'.  There is
-     also a `make maintainer-clean' target, but that is intended mainly
-     for the package's developers.  If you use it, you may have to get
-     all sorts of other programs in order to regenerate files that came
-     with the distribution.
-
-Compilers and Options
-=====================
-
-Some systems require unusual options for compilation or linking that the
-`configure' script does not know about.  Run `./configure --help' for
-details on some of the pertinent environment variables.
-
-   You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment.  Here
-is an example:
-
-     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-
-   *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
-You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory.  To do this, you can use GNU `make'.  `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script.  `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.
-
-   With a non-GNU `make', it is safer to compile the package for one
-architecture at a time in the source code directory.  After you have
-installed the package for one architecture, use `make distclean' before
-reconfiguring for another architecture.
-
-Installation Names
-==================
-
-By default, `make install' installs the package's commands under
-`/usr/local/bin', include files under `/usr/local/include', etc.  You
-can specify an installation prefix other than `/usr/local' by giving
-`configure' the option `--prefix=PREFIX'.
-
-   You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files.  If you
-pass the option `--exec-prefix=PREFIX' to `configure', the package uses
-PREFIX as the prefix for installing programs and libraries.
-Documentation and other data files still use the regular prefix.
-
-   In addition, if you use an unusual directory layout you can give
-options like `--bindir=DIR' to specify different values for particular
-kinds of files.  Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.
-
-   If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
-Optional Features
-=================
-
-Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System).  The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
-   For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
-Specifying the System Type
-==========================
-
-There may be some features `configure' cannot figure out automatically,
-but needs to determine by the type of machine the package will run on.
-Usually, assuming the package is built to be run on the _same_
-architectures, `configure' can figure that out, but if it prints a
-message saying it cannot guess the machine type, give it the
-`--build=TYPE' option.  TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
-     CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
-     OS KERNEL-OS
-
-   See the file `config.sub' for the possible values of each field.  If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
-   If you are _building_ compiler tools for cross-compiling, you should
-use the option `--target=TYPE' to select the type of system they will
-produce code for.
-
-   If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
-
-Sharing Defaults
-================
-
-If you want to set default values for `configure' scripts to share, you
-can create a site shell script called `config.site' that gives default
-values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists.  Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Defining Variables
-==================
-
-Variables not defined in a site shell script can be set in the
-environment passed to `configure'.  However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost.  In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'.  For example:
-
-     ./configure CC=/usr/local2/bin/gcc
-
-causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf bug.  Until the bug is fixed you can use this workaround:
-
-     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
-
-`configure' Invocation
-======================
-
-`configure' recognizes the following options to control how it operates.
-
-`--help'
-`-h'
-     Print a summary of the options to `configure', and exit.
-
-`--version'
-`-V'
-     Print the version of Autoconf used to generate the `configure'
-     script, and exit.
-
-`--cache-file=FILE'
-     Enable the cache: use and save the results of the tests in FILE,
-     traditionally `config.cache'.  FILE defaults to `/dev/null' to
-     disable caching.
-
-`--config-cache'
-`-C'
-     Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
-     Do not print messages saying which checks are being made.  To
-     suppress all normal output, redirect it to `/dev/null' (any error
-     messages will still be shown).
-
-`--srcdir=DIR'
-     Look for the package's source code in directory DIR.  Usually
-     `configure' can determine that directory automatically.
-
-`configure' also accepts some other, not widely useful, options.  Run
-`configure --help' for more details.
-

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/LICENSE
----------------------------------------------------------------------
diff --git a/src/c/LICENSE b/src/c/LICENSE
deleted file mode 100644
index d645695..0000000
--- a/src/c/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/Makefile.am
----------------------------------------------------------------------
diff --git a/src/c/Makefile.am b/src/c/Makefile.am
deleted file mode 100644
index 5993098..0000000
--- a/src/c/Makefile.am
+++ /dev/null
@@ -1,128 +0,0 @@
-# need this for Doxygen integration
-include $(top_srcdir)/aminclude.am
-
-if SOLARIS
-  SOLARIS_CPPFLAGS = -D_POSIX_PTHREAD_SEMANTICS
-  SOLARIS_LIB_LDFLAGS = -lnsl -lsocket
-endif
-AM_CPPFLAGS = -I${srcdir}/include -I${srcdir}/tests -I${srcdir}/generated $(SOLARIS_CPPFLAGS)
-AM_CFLAGS = -Wall -Werror 
-AM_CXXFLAGS = -Wall $(USEIPV6)
-
-# Additional flags for coverage testing (if enabled)
-if ENABLEGCOV
-  AM_CFLAGS += -fprofile-arcs -ftest-coverage
-  AM_LDFLAGS = -lgcov
-endif
-
-LIB_LDFLAGS = -no-undefined -version-info 2 $(SOLARIS_LIB_LDFLAGS)
-
-pkginclude_HEADERS = include/zookeeper.h include/zookeeper_version.h include/zookeeper_log.h include/proto.h include/recordio.h generated/zookeeper.jute.h
-EXTRA_DIST=LICENSE
-
-HASHTABLE_SRC = src/hashtable/hashtable_itr.h src/hashtable/hashtable_itr.c \
-    src/hashtable/hashtable_private.h src/hashtable/hashtable.h src/hashtable/hashtable.c
-
-noinst_LTLIBRARIES = libhashtable.la
-libhashtable_la_SOURCES = $(HASHTABLE_SRC)
-
-COMMON_SRC = src/zookeeper.c include/zookeeper.h include/zookeeper_version.h include/zookeeper_log.h\
-    src/recordio.c include/recordio.h include/proto.h \
-    src/zk_adaptor.h generated/zookeeper.jute.c \
-    src/zookeeper_log.h src/zk_log.c src/zk_hashtable.h src/zk_hashtable.c
-
-# These are the symbols (classes, mostly) we want to export from our library.
-EXPORT_SYMBOLS = '(zoo_|zookeeper_|zhandle|Z|format_log_message|log_message|logLevel|deallocate_|allocate_|zerror|is_unrecoverable)'
-noinst_LTLIBRARIES += libzkst.la
-libzkst_la_SOURCES =$(COMMON_SRC) src/st_adaptor.c
-libzkst_la_LIBADD = -lm
-
-lib_LTLIBRARIES = libzookeeper_st.la
-libzookeeper_st_la_SOURCES =
-libzookeeper_st_la_LIBADD=libzkst.la libhashtable.la
-libzookeeper_st_la_DEPENDENCIES=libzkst.la libhashtable.la
-libzookeeper_st_la_LDFLAGS = $(LIB_LDFLAGS) -export-symbols-regex $(EXPORT_SYMBOLS)
-
-if WANT_SYNCAPI
-noinst_LTLIBRARIES += libzkmt.la
-libzkmt_la_SOURCES =$(COMMON_SRC) src/mt_adaptor.c
-libzkmt_la_CFLAGS = -DTHREADED
-libzkmt_la_LIBADD = -lm
-
-lib_LTLIBRARIES += libzookeeper_mt.la
-libzookeeper_mt_la_SOURCES =
-libzookeeper_mt_la_LIBADD=libzkmt.la libhashtable.la -lpthread
-libzookeeper_mt_la_DEPENDENCIES=libzkmt.la libhashtable.la
-libzookeeper_mt_la_LDFLAGS = $(LIB_LDFLAGS) -export-symbols-regex $(EXPORT_SYMBOLS)
-endif
-
-bin_PROGRAMS = cli_st
-
-cli_st_SOURCES = src/cli.c
-cli_st_LDADD = libzookeeper_st.la
-
-if WANT_SYNCAPI
-bin_PROGRAMS += cli_mt load_gen
-
-cli_mt_SOURCES = src/cli.c
-cli_mt_LDADD = libzookeeper_mt.la
-cli_mt_CFLAGS = -DTHREADED
-
-load_gen_SOURCES = src/load_gen.c
-load_gen_LDADD = libzookeeper_mt.la
-load_gen_CFLAGS = -DTHREADED
-
-endif
-
-#########################################################################
-# build and run unit tests
-
-EXTRA_DIST+=$(wildcard ${srcdir}/tests/*.cc) $(wildcard ${srcdir}/tests/*.h) \
-    ${srcdir}/tests/wrappers.opt ${srcdir}/tests/wrappers-mt.opt
-
-TEST_SOURCES = tests/TestDriver.cc tests/LibCMocks.cc tests/LibCSymTable.cc \
-    tests/MocksBase.cc  tests/ZKMocks.cc tests/Util.cc tests/ThreadingUtil.cc \
-    tests/TestClientRetry.cc \
-    tests/TestOperations.cc tests/TestZookeeperInit.cc \
-    tests/TestZookeeperClose.cc tests/TestClient.cc \
-    tests/TestMulti.cc tests/TestWatchers.cc
-
-
-if SOLARIS
-  SHELL_SYMBOL_WRAPPERS = cat ${srcdir}/tests/wrappers.opt
-  SYMBOL_WRAPPERS=$(SHELL_SYMBOL_WRAPPERS:sh)
-else
-  SYMBOL_WRAPPERS=$(shell cat ${srcdir}/tests/wrappers.opt)
-endif
-
-check_PROGRAMS = zktest-st
-nodist_zktest_st_SOURCES = $(TEST_SOURCES)
-zktest_st_LDADD = libzkst.la libhashtable.la $(CPPUNIT_LIBS)
-zktest_st_CXXFLAGS = -DUSE_STATIC_LIB $(CPPUNIT_CFLAGS) $(USEIPV6) $(SOLARIS_CPPFLAGS)
-zktest_st_LDFLAGS = -static-libtool-libs $(SYMBOL_WRAPPERS) $(SOLARIS_LIB_LDFLAGS)
-
-if WANT_SYNCAPI
-  check_PROGRAMS += zktest-mt
-  nodist_zktest_mt_SOURCES = $(TEST_SOURCES) tests/PthreadMocks.cc
-  zktest_mt_LDADD = libzkmt.la libhashtable.la -lpthread $(CPPUNIT_LIBS)
-  zktest_mt_CXXFLAGS = -DUSE_STATIC_LIB -DTHREADED $(CPPUNIT_CFLAGS) $(USEIPV6)
-if SOLARIS
-  SHELL_SYMBOL_WRAPPERS_MT = cat ${srcdir}/tests/wrappers-mt.opt
-  SYMBOL_WRAPPERS_MT=$(SYMBOL_WRAPPERS) $(SHELL_SYMBOL_WRAPPERS_MT:sh)
-else
-  SYMBOL_WRAPPERS_MT=$(SYMBOL_WRAPPERS) $(shell cat ${srcdir}/tests/wrappers-mt.opt)
-endif
-  zktest_mt_LDFLAGS = -static-libtool-libs $(SYMBOL_WRAPPERS_MT) $(SOLARIS_LIB_LDFLAGS)
-endif
-
-run-check: check
-	./zktest-st $(TEST_OPTIONS)
-if WANT_SYNCAPI
-	./zktest-mt $(TEST_OPTIONS)
-endif
-
-clean-local: clean-check
-	$(RM) $(DX_CLEANFILES)
-
-clean-check:
-	$(RM) $(nodist_zktest_st_OBJECTS) $(nodist_zktest_mt_OBJECTS)

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/NOTICE.txt
----------------------------------------------------------------------
diff --git a/src/c/NOTICE.txt b/src/c/NOTICE.txt
deleted file mode 100644
index dcd9d53..0000000
--- a/src/c/NOTICE.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-Apache ZooKeeper
-Copyright 2009-2018 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
-----------
-include/winstdint.h is included only for Windows Client support, as follows:
-
-// ISO C9x  compliant stdint.h for Microsoft Visual Studio
-// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
-// 
-//  Copyright (c) 2006-2008 Alexander Chemeris
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 
-//   1. Redistributions of source code must retain the above copyright notice,
-//      this list of conditions and the following disclaimer.
-// 
-//   2. Redistributions in binary form must reproduce the above copyright
-//      notice, this list of conditions and the following disclaimer in the
-//      documentation and/or other materials provided with the distribution.
-// 
-//   3. The name of the author may be used to endorse or promote products
-//      derived from this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// 
-///////////////////////////////////////////////////////////////////////////////
-
-----------

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/README
----------------------------------------------------------------------
diff --git a/src/c/README b/src/c/README
deleted file mode 100644
index 5115845..0000000
--- a/src/c/README
+++ /dev/null
@@ -1,156 +0,0 @@
-                     Zookeeper C client library 
-
-
-This package provides a C client interface to Zookeeper server.
-
-For the latest information about ZooKeeper, please visit our website at:
-   http://zookeeper.apache.org/
-and our wiki, at:
-   https://cwiki.apache.org/confluence/display/ZOOKEEPER
-
-Full documentation for this release can also be found in ../../docs/index.html
-
-
-OVERVIEW
-
-The client supports two types of APIs -- synchronous and asynchronous.
-
-Asynchronous API provides non-blocking operations with completion callbacks and 
-relies on the application to implement event multiplexing on its behalf.
-
-On the other hand, Synchronous API provides a blocking flavor of
-zookeeper operations and runs its own event loop in a separate thread.
-
-Sync and Async APIs can be mixed and matched within the same application.
-
-The package includes two shared libraries: zookeeper_st and
-zookeeper_mt. The former only provides the Async API and is not
-thread-safe. The only reason this library exists is to support the
-platforms were pthread library is not available or unstable
-(i.e. FreeBSD 4.x). In all other cases the application developers are
-advised to link against zookeeper_mt as it includes support for both
-Sync and Async API.
-
-
-INSTALLATION
-
-If you're building the client from a source checkout you need to
-follow the steps outlined below. If you're building from a release
-tar downloaded from Apache please skip to step 2.
-
-1) do a "ant compile_jute" from the zookeeper top level directory (.../trunk).
-   This will create a directory named "generated" under src/c.  Skip to step 3.
-2) unzip/untar the source tarball and cd to the zookeeper-x.x.x/src/c directory
-3) change directory to src/c and do a "autoreconf -if" to bootstrap
-   autoconf, automake and libtool. Please make sure you have autoconf
-   version 2.59 or greater installed. If cppunit is installed in a non-standard
-   directory, you need to specify where to find cppunit.m4. For example, if
-   cppunit is installed under /usr/local, run:
-   
-       ACLOCAL="aclocal -I /usr/local/share/aclocal" autoreconf -if
-
-4) do a "./configure [OPTIONS]" to generate the makefile. See INSTALL
-   for general information about running configure. Additionally, the
-   configure supports the following options:
-   --enable-debug     enables optimization and enables debug info compiler
-                      options, disabled by default
-   --without-syncapi  disables Sync API support; zookeeper_mt library won't
-                      be built, enabled by default
-   --disable-static   do not build static libraries, enabled by default
-   --disable-shared   do not build shared libraries, enabled by default
-   --without-cppunit  do not build the test library, enabled by default.
-
-5) do a "make" or "make install" to build the libraries and install them. 
-   Alternatively, you can also build and run a unit test suite (and
-   you probably should).  Please make sure you have cppunit-1.10.x or
-   higher installed before you execute step 4.  Once ./configure has
-   finished, do a "make run-check". It will build the libraries, build
-   the tests and run them.
-6) to generate doxygen documentation do a "make doxygen-doc". All
-   documentations will be placed to a new subfolder named docs. By
-   default only HTML documentation is generated.  For information on
-   other document formats please use "./configure --help"
-
-Alternatively you can use the CMake build system. On Windows, this is required.
-Follow steps 1 and 2 above, and then continue here.
-
-1) do a "cmake [OPTIONS]" to generate the makefile or msbuild files (the correct
-   build system will be generated based on your platform). Some options from above
-   are supported:
-   -DCMAKE_BUILD_TYPE  Debug by default, Release enables optimzation etc.
-   -DWANT_SYNCAPI      ON by default, OFF disables the Sync API support
-   -DWANT_CPPUNIT      ON except on Windows, OFF disables the tests
-   -DBUILD_SHARED_LIBS not yet supported, only static libraries are built
-   other CMake options see "cmake --help" for generic options, such as generator
-
-2) do a "cmake --build ." to build the default targets. Alternatively you can
-   invoke "make" or "msbuild" manually. If the tests were enabled, use "ctest -V"
-   to run them.
-
-Current limitations of the CMake build system include lack of Solaris support,
-no shared library option, no explicitly exported symbols (all are exported by
-default), no versions on the libraries, and no documentation generation.
-Features of CMake include a single, easily consumed cross-platform build system
-to generate the ZooKeeper C Client libraries for any project, with little to no
-configuration.
-
-EXAMPLE/SAMPLE C CLIENT SHELL
-
-NOTE: the ZooKeeper C client shell (cli_st and cli_mt) is meant as a
-example/sample of ZooKeeper C client API usage. It is not a full
-fledged client and not meant for production usage - see the Java
-client shell for a fully featured shell.
-
-You can test your client by running a zookeeper server (see
-instructions on the project wiki page on how to run it) and connecting
-to it using the zookeeper shell application cli that is built as part
-of the installation procedure.
-
-cli_mt (multithreaded, built against zookeeper_mt library) is shown in
-this example, but you could also use cli_st (singlethreaded, built
-against zookeeper_st library):
-
-$ cli_mt zookeeper_host:9876
-
-This is a client application that gives you a shell for executing
-simple zookeeper commands. Once successfully started and connected to
-the server it displays a shell prompt.
-
-You can now enter zookeeper commands. For example, to create a node:
-
-> create /my_new_node
-
-To verify that the node's been created:
-
-> ls /
-
-You should see a list of nodes who are the children of the root node "/".
-
-Here's a list of command supported by the cli shell:
-
-ls <path>             -- list children of a znode identified by <path>. The
-                         command set a children watch on the znode.
-get <path>            -- get the value of a znode at <path>
-set <path> <value>    -- set the value of a znode at <path> to <value>
-create [+e|+s] <path> -- create a znode as a child of znode <path>; 
-                         use +e option to create an ephemeral znode,
-                         use +s option to create a znode with a sequence number 
-                         appended to the name. The operation will fail if 
-                         the parent znode (the one identified by <path>) doesn't
-                         exist.
-delete <path>         -- delete the znode at <path>. The command will fail if the znode
-                         has children.
-sync <path>           -- make sure all pending updates have been applied to znode at <path>
-exists <path>         -- returns a result code indicating whether the znode at <path>
-                         exists. The command also sets a znode watch.
-myid                  -- prints out the current zookeeper session id.
-quit                  -- exit the shell.
-
-In order to be able to use the zookeeper API in your application you have to
-1) remember to include the zookeeper header 
-   #include <zookeeper/zookeeper.h>
-2) use -DTHREADED compiler option to enable Sync API; in this case you should
-   be linking your code against zookeeper_mt library
-
-Please take a look at cli.c to understand how to use the two API types. 
-(TODO: some kind of short tutorial would be helpful, I guess)

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/acinclude.m4
----------------------------------------------------------------------
diff --git a/src/c/acinclude.m4 b/src/c/acinclude.m4
deleted file mode 100644
index d0041d8..0000000
--- a/src/c/acinclude.m4
+++ /dev/null
@@ -1,312 +0,0 @@
-# This file is part of Autoconf.                       -*- Autoconf -*-
-
-# Copyright (C) 2004 Oren Ben-Kiki
-# This file is distributed under the same terms as the Autoconf macro files.
-
-# Generate automatic documentation using Doxygen. Works in concert with the
-# aminclude.m4 file and a compatible doxygen configuration file. Defines the
-# following public macros:
-#
-# DX_???_FEATURE(ON|OFF) - control the default setting fo a Doxygen feature.
-# Supported features are 'DOXYGEN' itself, 'DOT' for generating graphics,
-# 'HTML' for plain HTML, 'CHM' for compressed HTML help (for MS users), 'CHI'
-# for generating a seperate .chi file by the .chm file, and 'MAN', 'RTF',
-# 'XML', 'PDF' and 'PS' for the appropriate output formats. The environment
-# variable DOXYGEN_PAPER_SIZE may be specified to override the default 'a4wide'
-# paper size.
-#
-# By default, HTML, PDF and PS documentation is generated as this seems to be
-# the most popular and portable combination. MAN pages created by Doxygen are
-# usually problematic, though by picking an appropriate subset and doing some
-# massaging they might be better than nothing. CHM and RTF are specific for MS
-# (note that you can't generate both HTML and CHM at the same time). The XML is
-# rather useless unless you apply specialized post-processing to it.
-#
-# The macro mainly controls the default state of the feature. The use can
-# override the default by specifying --enable or --disable. The macros ensure
-# that contradictory flags are not given (e.g., --enable-doxygen-html and
-# --enable-doxygen-chm, --enable-doxygen-anything with --disable-doxygen, etc.)
-# Finally, each feature will be automatically disabled (with a warning) if the
-# required programs are missing.
-#
-# Once all the feature defaults have been specified, call DX_INIT_DOXYGEN with
-# the following parameters: a one-word name for the project for use as a
-# filename base etc., an optional configuration file name (the default is
-# 'Doxyfile', the same as Doxygen's default), and an optional output directory
-# name (the default is 'doxygen-doc').
-
-## ----------##
-## Defaults. ##
-## ----------##
-
-DX_ENV=""
-AC_DEFUN([DX_FEATURE_doc],  ON)
-AC_DEFUN([DX_FEATURE_dot],  ON)
-AC_DEFUN([DX_FEATURE_man],  OFF)
-AC_DEFUN([DX_FEATURE_html], ON)
-AC_DEFUN([DX_FEATURE_chm],  OFF)
-AC_DEFUN([DX_FEATURE_chi],  OFF)
-AC_DEFUN([DX_FEATURE_rtf],  OFF)
-AC_DEFUN([DX_FEATURE_xml],  OFF)
-AC_DEFUN([DX_FEATURE_pdf],  ON)
-AC_DEFUN([DX_FEATURE_ps],   ON)
-
-## --------------- ##
-## Private macros. ##
-## --------------- ##
-
-# DX_ENV_APPEND(VARIABLE, VALUE)
-# ------------------------------
-# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen.
-AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])])
-
-# DX_DIRNAME_EXPR
-# ---------------
-# Expand into a shell expression prints the directory part of a path.
-AC_DEFUN([DX_DIRNAME_EXPR],
-         [[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']])
-
-# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)
-# -------------------------------------
-# Expands according to the M4 (static) status of the feature.
-AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])
-
-# DX_REQUIRE_PROG(VARIABLE, PROGRAM)
-# ----------------------------------
-# Require the specified program to be found for the DX_CURRENT_FEATURE to work.
-AC_DEFUN([DX_REQUIRE_PROG], [
-AC_PATH_TOOL([$1], [$2])
-if test "$DX_FLAG_$[DX_CURRENT_FEATURE$$1]" = 1; then
-    AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
-    AC_SUBST([DX_FLAG_]DX_CURRENT_FEATURE, 0)
-fi
-])
-
-# DX_TEST_FEATURE(FEATURE)
-# ------------------------
-# Expand to a shell expression testing whether the feature is active.
-AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1])
-
-# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)
-# -------------------------------------------------
-# Verify that a required features has the right state before trying to turn on
-# the DX_CURRENT_FEATURE.
-AC_DEFUN([DX_CHECK_DEPEND], [
-test "$DX_FLAG_$1" = "$2" \
-|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,
-                            requires, contradicts) doxygen-DX_CURRENT_FEATURE])
-])
-
-# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)
-# ----------------------------------------------------------
-# Turn off the DX_CURRENT_FEATURE if the required feature is off.
-AC_DEFUN([DX_CLEAR_DEPEND], [
-test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_]DX_CURRENT_FEATURE, 0)
-])
-
-# DX_FEATURE_ARG(FEATURE, DESCRIPTION,
-#                CHECK_DEPEND, CLEAR_DEPEND,
-#                REQUIRE, DO-IF-ON, DO-IF-OFF)
-# --------------------------------------------
-# Parse the command-line option controlling a feature. CHECK_DEPEND is called
-# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),
-# otherwise CLEAR_DEPEND is called to turn off the default state if a required
-# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional
-# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and
-# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.
-AC_DEFUN([DX_ARG_ABLE], [
-    AC_DEFUN([DX_CURRENT_FEATURE], [$1])
-    AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])
-    AC_ARG_ENABLE(doxygen-$1,
-                  [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],
-                                                      [--enable-doxygen-$1]),
-                                  DX_IF_FEATURE([$1], [don't $2], [$2]))],
-                  [
-case "$enableval" in
-#(
-y|Y|yes|Yes|YES)
-    AC_SUBST([DX_FLAG_$1], 1)
-    $3
-;; #(
-n|N|no|No|NO)
-    AC_SUBST([DX_FLAG_$1], 0)
-;; #(
-*)
-    AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])
-;;
-esac
-], [
-AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])
-$4
-])
-if DX_TEST_FEATURE([$1]); then
-    $5
-    :
-fi
-if DX_TEST_FEATURE([$1]); then
-    AM_CONDITIONAL(DX_COND_$1, :)
-    $6
-    :
-else
-    AM_CONDITIONAL(DX_COND_$1, false)
-    $7
-    :
-fi
-])
-
-## -------------- ##
-## Public macros. ##
-## -------------- ##
-
-# DX_XXX_FEATURE(DEFAULT_STATE)
-# -----------------------------
-AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc],  [$1])])
-AC_DEFUN([DX_MAN_FEATURE],     [AC_DEFUN([DX_FEATURE_man],  [$1])])
-AC_DEFUN([DX_HTML_FEATURE],    [AC_DEFUN([DX_FEATURE_html], [$1])])
-AC_DEFUN([DX_CHM_FEATURE],     [AC_DEFUN([DX_FEATURE_chm],  [$1])])
-AC_DEFUN([DX_CHI_FEATURE],     [AC_DEFUN([DX_FEATURE_chi],  [$1])])
-AC_DEFUN([DX_RTF_FEATURE],     [AC_DEFUN([DX_FEATURE_rtf],  [$1])])
-AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
-AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
-AC_DEFUN([DX_PDF_FEATURE],     [AC_DEFUN([DX_FEATURE_pdf],  [$1])])
-AC_DEFUN([DX_PS_FEATURE],      [AC_DEFUN([DX_FEATURE_ps],   [$1])])
-
-# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR])
-# ---------------------------------------------------------
-# PROJECT also serves as the base name for the documentation files.
-# The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc".
-AC_DEFUN([DX_INIT_DOXYGEN], [
-
-# Files:
-AC_SUBST([DX_PROJECT], [$1])
-AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])])
-AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])])
-
-# Environment variables used inside doxygen.cfg:
-DX_ENV_APPEND(SRCDIR, $srcdir)
-DX_ENV_APPEND(PROJECT, $DX_PROJECT)
-DX_ENV_APPEND(DOCDIR, $DX_DOCDIR)
-DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
-
-# Doxygen itself:
-DX_ARG_ABLE(doc, [generate any doxygen documentation],
-            [],
-            [],
-            [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)
-             DX_REQUIRE_PROG([DX_PERL], perl)],
-            [DX_ENV_APPEND(PERL_PATH, $DX_PERL)])
-
-# Dot for graphics:
-DX_ARG_ABLE(dot, [generate graphics for doxygen documentation],
-            [DX_CHECK_DEPEND(doc, 1)],
-            [DX_CLEAR_DEPEND(doc, 1)],
-            [DX_REQUIRE_PROG([DX_DOT], dot)],
-            [DX_ENV_APPEND(HAVE_DOT, YES)
-             DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],
-            [DX_ENV_APPEND(HAVE_DOT, NO)])
-
-# Man pages generation:
-DX_ARG_ABLE(man, [generate doxygen manual pages],
-            [DX_CHECK_DEPEND(doc, 1)],
-            [DX_CLEAR_DEPEND(doc, 1)],
-            [],
-            [DX_ENV_APPEND(GENERATE_MAN, YES)],
-            [DX_ENV_APPEND(GENERATE_MAN, NO)])
-
-# RTF file generation:
-DX_ARG_ABLE(rtf, [generate doxygen RTF documentation],
-            [DX_CHECK_DEPEND(doc, 1)],
-            [DX_CLEAR_DEPEND(doc, 1)],
-            [],
-            [DX_ENV_APPEND(GENERATE_RTF, YES)],
-            [DX_ENV_APPEND(GENERATE_RTF, NO)])
-
-# XML file generation:
-DX_ARG_ABLE(xml, [generate doxygen XML documentation],
-            [DX_CHECK_DEPEND(doc, 1)],
-            [DX_CLEAR_DEPEND(doc, 1)],
-            [],
-            [DX_ENV_APPEND(GENERATE_XML, YES)],
-            [DX_ENV_APPEND(GENERATE_XML, NO)])
-
-# (Compressed) HTML help generation:
-DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],
-            [DX_CHECK_DEPEND(doc, 1)],
-            [DX_CLEAR_DEPEND(doc, 1)],
-            [DX_REQUIRE_PROG([DX_HHC], hhc)],
-            [DX_ENV_APPEND(HHC_PATH, $DX_HHC)
-             DX_ENV_APPEND(GENERATE_HTML, YES)
-             DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],
-            [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])
-
-# Seperate CHI file generation.
-DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file],
-            [DX_CHECK_DEPEND(chm, 1)],
-            [DX_CLEAR_DEPEND(chm, 1)],
-            [],
-            [DX_ENV_APPEND(GENERATE_CHI, YES)],
-            [DX_ENV_APPEND(GENERATE_CHI, NO)])
-
-# Plain HTML pages generation:
-DX_ARG_ABLE(html, [generate doxygen plain HTML documentation],
-            [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],
-            [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],
-            [],
-            [DX_ENV_APPEND(GENERATE_HTML, YES)],
-            [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])
-
-# PostScript file generation:
-DX_ARG_ABLE(ps, [generate doxygen PostScript documentation],
-            [DX_CHECK_DEPEND(doc, 1)],
-            [DX_CLEAR_DEPEND(doc, 1)],
-            [DX_REQUIRE_PROG([DX_LATEX], latex)
-             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
-             DX_REQUIRE_PROG([DX_DVIPS], dvips)
-             DX_REQUIRE_PROG([DX_EGREP], egrep)])
-
-# PDF file generation:
-DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],
-            [DX_CHECK_DEPEND(doc, 1)],
-            [DX_CLEAR_DEPEND(doc, 1)],
-            [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)
-             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
-             DX_REQUIRE_PROG([DX_EGREP], egrep)])
-
-# LaTeX generation for PS and/or PDF:
-if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
-    AM_CONDITIONAL(DX_COND_latex, :)
-    DX_ENV_APPEND(GENERATE_LATEX, YES)
-else
-    AM_CONDITIONAL(DX_COND_latex, false)
-    DX_ENV_APPEND(GENERATE_LATEX, NO)
-fi
-
-# Paper size for PS and/or PDF:
-AC_ARG_VAR(DOXYGEN_PAPER_SIZE,
-           [a4wide (default), a4, letter, legal or executive])
-case "$DOXYGEN_PAPER_SIZE" in
-#(
-"")
-    AC_SUBST(DOXYGEN_PAPER_SIZE, "")
-;; #(
-a4wide|a4|letter|legal|executive)
-    DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)
-;; #(
-*)
-    AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])
-;;
-esac
-
-#For debugging:
-#echo DX_FLAG_doc=$DX_FLAG_doc
-#echo DX_FLAG_dot=$DX_FLAG_dot
-#echo DX_FLAG_man=$DX_FLAG_man
-#echo DX_FLAG_html=$DX_FLAG_html
-#echo DX_FLAG_chm=$DX_FLAG_chm
-#echo DX_FLAG_chi=$DX_FLAG_chi
-#echo DX_FLAG_rtf=$DX_FLAG_rtf
-#echo DX_FLAG_xml=$DX_FLAG_xml
-#echo DX_FLAG_pdf=$DX_FLAG_pdf
-#echo DX_FLAG_ps=$DX_FLAG_ps
-#echo DX_ENV=$DX_ENV
-])

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/aminclude.am
----------------------------------------------------------------------
diff --git a/src/c/aminclude.am b/src/c/aminclude.am
deleted file mode 100644
index 420049e..0000000
--- a/src/c/aminclude.am
+++ /dev/null
@@ -1,186 +0,0 @@
-# Copyright (C) 2004 Oren Ben-Kiki
-# This file is distributed under the same terms as the Automake macro files.
-
-# Generate automatic documentation using Doxygen. Goals and variables values
-# are controlled by the various DX_COND_??? conditionals set by autoconf.
-#
-# The provided goals are:
-# doxygen-doc: Generate all doxygen documentation.
-# doxygen-run: Run doxygen, which will generate some of the documentation
-#              (HTML, CHM, CHI, MAN, RTF, XML) but will not do the post
-#              processing required for the rest of it (PS, PDF, and some MAN).
-# doxygen-man: Rename some doxygen generated man pages.
-# doxygen-ps: Generate doxygen PostScript documentation.
-# doxygen-pdf: Generate doxygen PDF documentation.
-#
-# Note that by default these are not integrated into the automake goals. If
-# doxygen is used to generate man pages, you can achieve this integration by
-# setting man3_MANS to the list of man pages generated and then adding the
-# dependency:
-#
-#   $(man3_MANS): doxygen-doc
-#
-# This will cause make to run doxygen and generate all the documentation.
-#
-# The following variable is intended for use in Makefile.am:
-#
-# DX_CLEANFILES = everything to clean.
-#
-# This is usually added to MOSTLYCLEANFILES.
-
-## --------------------------------- ##
-## Format-independent Doxygen rules. ##
-## --------------------------------- ##
-
-if DX_COND_doc
-
-## ------------------------------- ##
-## Rules specific for HTML output. ##
-## ------------------------------- ##
-
-if DX_COND_html
-
-DX_CLEAN_HTML = @DX_DOCDIR@/html
-
-endif DX_COND_html
-
-## ------------------------------ ##
-## Rules specific for CHM output. ##
-## ------------------------------ ##
-
-if DX_COND_chm
-
-DX_CLEAN_CHM = @DX_DOCDIR@/chm
-
-if DX_COND_chi
-
-DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi
-
-endif DX_COND_chi
-
-endif DX_COND_chm
-
-## ------------------------------ ##
-## Rules specific for MAN output. ##
-## ------------------------------ ##
-
-if DX_COND_man
-
-DX_CLEAN_MAN = @DX_DOCDIR@/man
-
-endif DX_COND_man
-
-## ------------------------------ ##
-## Rules specific for RTF output. ##
-## ------------------------------ ##
-
-if DX_COND_rtf
-
-DX_CLEAN_RTF = @DX_DOCDIR@/rtf
-
-endif DX_COND_rtf
-
-## ------------------------------ ##
-## Rules specific for XML output. ##
-## ------------------------------ ##
-
-if DX_COND_xml
-
-DX_CLEAN_XML = @DX_DOCDIR@/xml
-
-endif DX_COND_xml
-
-## ----------------------------- ##
-## Rules specific for PS output. ##
-## ----------------------------- ##
-
-if DX_COND_ps
-
-DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps
-
-DX_PS_GOAL = doxygen-ps
-
-doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps
-
-@DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag
-	cd @DX_DOCDIR@/latex; \
-	rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
-	$(DX_LATEX) refman.tex; \
-	$(MAKEINDEX_PATH) refman.idx; \
-	$(DX_LATEX) refman.tex; \
-	countdown=5; \
-	while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
-	                  refman.log > /dev/null 2>&1 \
-	   && test $$countdown -gt 0; do \
-	    $(DX_LATEX) refman.tex; \
-	    countdown=`expr $$countdown - 1`; \
-	done; \
-	$(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi
-
-endif DX_COND_ps
-
-## ------------------------------ ##
-## Rules specific for PDF output. ##
-## ------------------------------ ##
-
-if DX_COND_pdf
-
-DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf
-
-DX_PDF_GOAL = doxygen-pdf
-
-doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf
-
-@DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag
-	cd @DX_DOCDIR@/latex; \
-	rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
-	$(DX_PDFLATEX) refman.tex; \
-	$(DX_MAKEINDEX) refman.idx; \
-	$(DX_PDFLATEX) refman.tex; \
-	countdown=5; \
-	while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
-	                  refman.log > /dev/null 2>&1 \
-	   && test $$countdown -gt 0; do \
-	    $(DX_PDFLATEX) refman.tex; \
-	    countdown=`expr $$countdown - 1`; \
-	done; \
-	mv refman.pdf ../@PACKAGE@.pdf
-
-endif DX_COND_pdf
-
-## ------------------------------------------------- ##
-## Rules specific for LaTeX (shared for PS and PDF). ##
-## ------------------------------------------------- ##
-
-if DX_COND_latex
-
-DX_CLEAN_LATEX = @DX_DOCDIR@/latex
-
-endif DX_COND_latex
-
-.PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
-
-.INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
-
-doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag
-
-doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
-
-@DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS)
-	rm -rf @DX_DOCDIR@
-	$(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG)
-
-DX_CLEANFILES = \
-    @DX_DOCDIR@/@PACKAGE@.tag \
-    -r \
-    $(DX_CLEAN_HTML) \
-    $(DX_CLEAN_CHM) \
-    $(DX_CLEAN_CHI) \
-    $(DX_CLEAN_MAN) \
-    $(DX_CLEAN_RTF) \
-    $(DX_CLEAN_XML) \
-    $(DX_CLEAN_PS) \
-    $(DX_CLEAN_PDF) \
-    $(DX_CLEAN_LATEX)
-
-endif DX_COND_doc


[17/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/cli.c
----------------------------------------------------------------------
diff --git a/src/c/src/cli.c b/src/c/src/cli.c
deleted file mode 100644
index ef32a10..0000000
--- a/src/c/src/cli.c
+++ /dev/null
@@ -1,697 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * cli.c is a example/sample C client shell for ZooKeeper. It contains
- * basic shell functionality which exercises some of the features of
- * the ZooKeeper C client API. It is not a full fledged client and is
- * not meant for production usage - see the Java client shell for a
- * fully featured shell.
- */
-
-#include <zookeeper.h>
-#include <proto.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifndef WIN32
-#include <sys/time.h>
-#include <unistd.h>
-#include <sys/select.h>
-#else
-#include "winport.h"
-//#include <io.h> <-- can't include, conflicting definitions of close()
-int read(int _FileHandle, void * _DstBuf, unsigned int _MaxCharCount);
-int write(int _Filehandle, const void * _Buf, unsigned int _MaxCharCount);
-#define ctime_r(tctime, buffer) ctime_s (buffer, 40, tctime)
-#endif
-
-#include <time.h>
-#include <errno.h>
-#include <assert.h>
-
-#ifdef YCA
-#include <yca/yca.h>
-#endif
-
-#define _LL_CAST_ (long long)
-
-static zhandle_t *zh;
-static clientid_t myid;
-static const char *clientIdFile = 0;
-struct timeval startTime;
-static char cmd[1024];
-static int batchMode=0;
-
-static int to_send=0;
-static int sent=0;
-static int recvd=0;
-
-static int shutdownThisThing=0;
-
-static __attribute__ ((unused)) void 
-printProfileInfo(struct timeval start, struct timeval end, int thres,
-                 const char* msg)
-{
-  int delay=(end.tv_sec*1000+end.tv_usec/1000)-
-    (start.tv_sec*1000+start.tv_usec/1000);
-  if(delay>thres)
-    fprintf(stderr,"%s: execution time=%dms\n",msg,delay);
-}
-
-static const char* state2String(int state){
-  if (state == 0)
-    return "CLOSED_STATE";
-  if (state == ZOO_CONNECTING_STATE)
-    return "CONNECTING_STATE";
-  if (state == ZOO_ASSOCIATING_STATE)
-    return "ASSOCIATING_STATE";
-  if (state == ZOO_CONNECTED_STATE)
-    return "CONNECTED_STATE";
-  if (state == ZOO_EXPIRED_SESSION_STATE)
-    return "EXPIRED_SESSION_STATE";
-  if (state == ZOO_AUTH_FAILED_STATE)
-    return "AUTH_FAILED_STATE";
-
-  return "INVALID_STATE";
-}
-
-static const char* type2String(int state){
-  if (state == ZOO_CREATED_EVENT)
-    return "CREATED_EVENT";
-  if (state == ZOO_DELETED_EVENT)
-    return "DELETED_EVENT";
-  if (state == ZOO_CHANGED_EVENT)
-    return "CHANGED_EVENT";
-  if (state == ZOO_CHILD_EVENT)
-    return "CHILD_EVENT";
-  if (state == ZOO_SESSION_EVENT)
-    return "SESSION_EVENT";
-  if (state == ZOO_NOTWATCHING_EVENT)
-    return "NOTWATCHING_EVENT";
-
-  return "UNKNOWN_EVENT_TYPE";
-}
-
-void watcher(zhandle_t *zzh, int type, int state, const char *path,
-             void* context)
-{
-    /* Be careful using zh here rather than zzh - as this may be mt code
-     * the client lib may call the watcher before zookeeper_init returns */
-
-    fprintf(stderr, "Watcher %s state = %s", type2String(type), state2String(state));
-    if (path && strlen(path) > 0) {
-      fprintf(stderr, " for path %s", path);
-    }
-    fprintf(stderr, "\n");
-
-    if (type == ZOO_SESSION_EVENT) {
-        if (state == ZOO_CONNECTED_STATE) {
-            const clientid_t *id = zoo_client_id(zzh);
-            if (myid.client_id == 0 || myid.client_id != id->client_id) {
-                myid = *id;
-                fprintf(stderr, "Got a new session id: 0x%llx\n",
-                        _LL_CAST_ myid.client_id);
-                if (clientIdFile) {
-                    FILE *fh = fopen(clientIdFile, "w");
-                    if (!fh) {
-                        perror(clientIdFile);
-                    } else {
-                        int rc = fwrite(&myid, sizeof(myid), 1, fh);
-                        if (rc != sizeof(myid)) {
-                            perror("writing client id");
-                        }
-                        fclose(fh);
-                    }
-                }
-            }
-        } else if (state == ZOO_AUTH_FAILED_STATE) {
-            fprintf(stderr, "Authentication failure. Shutting down...\n");
-            zookeeper_close(zzh);
-            shutdownThisThing=1;
-            zh=0;
-        } else if (state == ZOO_EXPIRED_SESSION_STATE) {
-            fprintf(stderr, "Session expired. Shutting down...\n");
-            zookeeper_close(zzh);
-            shutdownThisThing=1;
-            zh=0;
-        }
-    }
-}
-
-void dumpStat(const struct Stat *stat) {
-    char tctimes[40];
-    char tmtimes[40];
-    time_t tctime;
-    time_t tmtime;
-
-    if (!stat) {
-        fprintf(stderr,"null\n");
-        return;
-    }
-    tctime = stat->ctime/1000;
-    tmtime = stat->mtime/1000;
-       
-    ctime_r(&tmtime, tmtimes);
-    ctime_r(&tctime, tctimes);
-       
-    fprintf(stderr, "\tctime = %s\tczxid=%llx\n"
-    "\tmtime=%s\tmzxid=%llx\n"
-    "\tversion=%x\taversion=%x\n"
-    "\tephemeralOwner = %llx\n",
-     tctimes, _LL_CAST_ stat->czxid, tmtimes,
-    _LL_CAST_ stat->mzxid,
-    (unsigned int)stat->version, (unsigned int)stat->aversion,
-    _LL_CAST_ stat->ephemeralOwner);
-}
-
-void my_string_completion(int rc, const char *name, const void *data) {
-    fprintf(stderr, "[%s]: rc = %d\n", (char*)(data==0?"null":data), rc);
-    if (!rc) {
-        fprintf(stderr, "\tname = %s\n", name);
-    }
-    if(batchMode)
-      shutdownThisThing=1;
-}
-
-void my_string_completion_free_data(int rc, const char *name, const void *data) {
-    my_string_completion(rc, name, data);
-    free((void*)data);
-}
-
-void my_data_completion(int rc, const char *value, int value_len,
-        const struct Stat *stat, const void *data) {
-    struct timeval tv;
-    int sec;
-    int usec;
-    gettimeofday(&tv, 0);
-    sec = tv.tv_sec - startTime.tv_sec;
-    usec = tv.tv_usec - startTime.tv_usec;
-    fprintf(stderr, "time = %d msec\n", sec*1000 + usec/1000);
-    fprintf(stderr, "%s: rc = %d\n", (char*)data, rc);
-    if (value) {
-        fprintf(stderr, " value_len = %d\n", value_len);
-        assert(write(2, value, value_len) == value_len);
-    }
-    fprintf(stderr, "\nStat:\n");
-    dumpStat(stat);
-    free((void*)data);
-    if(batchMode)
-      shutdownThisThing=1;
-}
-
-void my_silent_data_completion(int rc, const char *value, int value_len,
-        const struct Stat *stat, const void *data) {
-    recvd++;
-    fprintf(stderr, "Data completion %s rc = %d\n",(char*)data,rc);
-    free((void*)data);
-    if (recvd==to_send) {
-        fprintf(stderr,"Recvd %d responses for %d requests sent\n",recvd,to_send);
-        if(batchMode)
-          shutdownThisThing=1;
-    }
-}
-
-void my_strings_completion(int rc, const struct String_vector *strings,
-        const void *data) {
-    struct timeval tv;
-    int sec;
-    int usec;
-    int i;
-
-    gettimeofday(&tv, 0);
-    sec = tv.tv_sec - startTime.tv_sec;
-    usec = tv.tv_usec - startTime.tv_usec;
-    fprintf(stderr, "time = %d msec\n", sec*1000 + usec/1000);
-    fprintf(stderr, "%s: rc = %d\n", (char*)data, rc);
-    if (strings)
-        for (i=0; i < strings->count; i++) {
-            fprintf(stderr, "\t%s\n", strings->data[i]);
-        }
-    free((void*)data);
-    gettimeofday(&tv, 0);
-    sec = tv.tv_sec - startTime.tv_sec;
-    usec = tv.tv_usec - startTime.tv_usec;
-    fprintf(stderr, "time = %d msec\n", sec*1000 + usec/1000);
-    if(batchMode)
-      shutdownThisThing=1;
-}
-
-void my_strings_stat_completion(int rc, const struct String_vector *strings,
-        const struct Stat *stat, const void *data) {
-    my_strings_completion(rc, strings, data);
-    dumpStat(stat);
-    if(batchMode)
-      shutdownThisThing=1;
-}
-
-void my_void_completion(int rc, const void *data) {
-    fprintf(stderr, "%s: rc = %d\n", (char*)data, rc);
-    free((void*)data);
-    if(batchMode)
-      shutdownThisThing=1;
-}
-
-void my_stat_completion(int rc, const struct Stat *stat, const void *data) {
-    fprintf(stderr, "%s: rc = %d Stat:\n", (char*)data, rc);
-    dumpStat(stat);
-    free((void*)data);
-    if(batchMode)
-      shutdownThisThing=1;
-}
-
-void my_silent_stat_completion(int rc, const struct Stat *stat,
-        const void *data) {
-    //    fprintf(stderr, "State completion: [%s] rc = %d\n", (char*)data, rc);
-    sent++;
-    free((void*)data);
-}
-
-static void sendRequest(const char* data) {
-    zoo_aset(zh, "/od", data, strlen(data), -1, my_silent_stat_completion,
-            strdup("/od"));
-    zoo_aget(zh, "/od", 1, my_silent_data_completion, strdup("/od"));
-}
-
-void od_completion(int rc, const struct Stat *stat, const void *data) {
-    int i;
-    fprintf(stderr, "od command response: rc = %d Stat:\n", rc);
-    dumpStat(stat);
-    // send a whole bunch of requests
-    recvd=0;
-    sent=0;
-    to_send=200;
-    for (i=0; i<to_send; i++) {
-        char buf[4096*16];
-        memset(buf, -1, sizeof(buf)-1);
-        buf[sizeof(buf)-1]=0;
-        sendRequest(buf);
-    }
-}
-
-int startsWith(const char *line, const char *prefix) {
-    int len = strlen(prefix);
-    return strncmp(line, prefix, len) == 0;
-}
-
-static const char *hostPort;
-static int verbose = 0;
-
-void processline(char *line) {
-    int rc;
-    int async = ((line[0] == 'a') && !(startsWith(line, "addauth ")));
-    if (async) {
-        line++;
-    }
-    if (startsWith(line, "help")) {
-      fprintf(stderr, "    create [+[e|s]] <path>\n");
-      fprintf(stderr, "    delete <path>\n");
-      fprintf(stderr, "    set <path> <data>\n");
-      fprintf(stderr, "    get <path>\n");
-      fprintf(stderr, "    ls <path>\n");
-      fprintf(stderr, "    ls2 <path>\n");
-      fprintf(stderr, "    sync <path>\n");
-      fprintf(stderr, "    exists <path>\n");
-      fprintf(stderr, "    wexists <path>\n");
-      fprintf(stderr, "    myid\n");
-      fprintf(stderr, "    verbose\n");
-      fprintf(stderr, "    addauth <id> <scheme>\n");
-      fprintf(stderr, "    quit\n");
-      fprintf(stderr, "\n");
-      fprintf(stderr, "    prefix the command with the character 'a' to run the command asynchronously.\n");
-      fprintf(stderr, "    run the 'verbose' command to toggle verbose logging.\n");
-      fprintf(stderr, "    i.e. 'aget /foo' to get /foo asynchronously\n");
-    } else if (startsWith(line, "verbose")) {
-      if (verbose) {
-        verbose = 0;
-        zoo_set_debug_level(ZOO_LOG_LEVEL_WARN);
-        fprintf(stderr, "logging level set to WARN\n");
-      } else {
-        verbose = 1;
-        zoo_set_debug_level(ZOO_LOG_LEVEL_DEBUG);
-        fprintf(stderr, "logging level set to DEBUG\n");
-      }
-    } else if (startsWith(line, "get ")) {
-        line += 4;
-        if (line[0] != '/') {
-            fprintf(stderr, "Path must start with /, found: %s\n", line);
-            return;
-        }
-               
-        rc = zoo_aget(zh, line, 1, my_data_completion, strdup(line));
-        if (rc) {
-            fprintf(stderr, "Error %d for %s\n", rc, line);
-        }
-    } else if (startsWith(line, "set ")) {
-        char *ptr;
-        line += 4;
-        if (line[0] != '/') {
-            fprintf(stderr, "Path must start with /, found: %s\n", line);
-            return;
-        }
-        ptr = strchr(line, ' ');
-        if (!ptr) {
-            fprintf(stderr, "No data found after path\n");
-            return;
-        }
-        *ptr = '\0';
-        ptr++;
-        if (async) {
-            rc = zoo_aset(zh, line, ptr, strlen(ptr), -1, my_stat_completion,
-                    strdup(line));
-        } else {
-            struct Stat stat;
-            rc = zoo_set2(zh, line, ptr, strlen(ptr), -1, &stat);
-        }
-        if (rc) {
-            fprintf(stderr, "Error %d for %s\n", rc, line);
-        }
-    } else if (startsWith(line, "ls ")) {
-        line += 3;
-        if (line[0] != '/') {
-            fprintf(stderr, "Path must start with /, found: %s\n", line);
-            return;
-        }
-        gettimeofday(&startTime, 0);
-        rc= zoo_aget_children(zh, line, 1, my_strings_completion, strdup(line));
-        if (rc) {
-            fprintf(stderr, "Error %d for %s\n", rc, line);
-        }
-    } else if (startsWith(line, "ls2 ")) {
-        line += 4;
-        if (line[0] != '/') {
-            fprintf(stderr, "Path must start with /, found: %s\n", line);
-            return;
-        }
-        gettimeofday(&startTime, 0);
-        rc= zoo_aget_children2(zh, line, 1, my_strings_stat_completion, strdup(line));
-        if (rc) {
-            fprintf(stderr, "Error %d for %s\n", rc, line);
-        }
-    } else if (startsWith(line, "create ")) {
-        int flags = 0;
-        line += 7;
-        if (line[0] == '+') {
-            line++;
-            if (line[0] == 'e') {
-                flags |= ZOO_EPHEMERAL;
-                line++;
-            }
-            if (line[0] == 's') {
-                flags |= ZOO_SEQUENCE;
-                line++;
-            }
-            line++;
-        }
-        if (line[0] != '/') {
-            fprintf(stderr, "Path must start with /, found: %s\n", line);
-            return;
-        }
-        fprintf(stderr, "Creating [%s] node\n", line);
-//        {
-//            struct ACL _CREATE_ONLY_ACL_ACL[] = {{ZOO_PERM_CREATE, ZOO_ANYONE_ID_UNSAFE}};
-//            struct ACL_vector CREATE_ONLY_ACL = {1,_CREATE_ONLY_ACL_ACL};
-//            rc = zoo_acreate(zh, line, "new", 3, &CREATE_ONLY_ACL, flags,
-//                    my_string_completion, strdup(line));
-//        }
-        rc = zoo_acreate(zh, line, "new", 3, &ZOO_OPEN_ACL_UNSAFE, flags,
-                my_string_completion_free_data, strdup(line));
-        if (rc) {
-            fprintf(stderr, "Error %d for %s\n", rc, line);
-        }
-    } else if (startsWith(line, "delete ")) {
-        line += 7;
-        if (line[0] != '/') {
-            fprintf(stderr, "Path must start with /, found: %s\n", line);
-            return;
-        }
-        if (async) {
-            rc = zoo_adelete(zh, line, -1, my_void_completion, strdup(line));
-        } else {
-            rc = zoo_delete(zh, line, -1);
-        }
-        if (rc) {
-            fprintf(stderr, "Error %d for %s\n", rc, line);
-        }
-    } else if (startsWith(line, "sync ")) {
-        line += 5;
-        if (line[0] != '/') {
-            fprintf(stderr, "Path must start with /, found: %s\n", line);
-            return;
-        }
-        rc = zoo_async(zh, line, my_string_completion_free_data, strdup(line));
-        if (rc) {
-            fprintf(stderr, "Error %d for %s\n", rc, line);
-        }
-    } else if (startsWith(line, "wexists ")) {
-#ifdef THREADED
-        struct Stat stat;
-#endif
-        line += 8;
-        if (line[0] != '/') {
-            fprintf(stderr, "Path must start with /, found: %s\n", line);
-            return;
-        }
-#ifndef THREADED
-        rc = zoo_awexists(zh, line, watcher, (void*) 0, my_stat_completion, strdup(line));
-#else
-        rc = zoo_wexists(zh, line, watcher, (void*) 0, &stat);
-#endif
-        if (rc) {
-            fprintf(stderr, "Error %d for %s\n", rc, line);
-        }
-    } else if (startsWith(line, "exists ")) {
-#ifdef THREADED
-        struct Stat stat;
-#endif
-        line += 7;
-        if (line[0] != '/') {
-            fprintf(stderr, "Path must start with /, found: %s\n", line);
-            return;
-        }
-#ifndef THREADED
-        rc = zoo_aexists(zh, line, 1, my_stat_completion, strdup(line));
-#else
-        rc = zoo_exists(zh, line, 1, &stat);
-#endif
-        if (rc) {
-            fprintf(stderr, "Error %d for %s\n", rc, line);
-        }
-    } else if (strcmp(line, "myid") == 0) {
-        printf("session Id = %llx\n", _LL_CAST_ zoo_client_id(zh)->client_id);
-    } else if (strcmp(line, "reinit") == 0) {
-        zookeeper_close(zh);
-        // we can't send myid to the server here -- zookeeper_close() removes 
-        // the session on the server. We must start anew.
-        zh = zookeeper_init(hostPort, watcher, 30000, 0, 0, 0);
-    } else if (startsWith(line, "quit")) {
-        fprintf(stderr, "Quitting...\n");
-        shutdownThisThing=1;
-    } else if (startsWith(line, "od")) {
-        const char val[]="fire off";
-        fprintf(stderr, "Overdosing...\n");
-        rc = zoo_aset(zh, "/od", val, sizeof(val)-1, -1, od_completion, 0);
-        if (rc)
-            fprintf(stderr, "od command failed: %d\n", rc);
-    } else if (startsWith(line, "addauth ")) {
-      char *ptr;
-      line += 8;
-      ptr = strchr(line, ' ');
-      if (ptr) {
-        *ptr = '\0';
-        ptr++;
-      }
-      zoo_add_auth(zh, line, ptr, ptr ? strlen(ptr) : 0, NULL, NULL);
-    }
-}
-
-int main(int argc, char **argv) {
-#ifndef THREADED
-    fd_set rfds, wfds, efds;
-    int processed=0;
-#endif
-    char buffer[4096];
-    char p[2048];
-#ifdef YCA  
-    char *cert=0;
-    char appId[64];
-#endif
-    int bufoff = 0;
-    FILE *fh;
-
-    if (argc < 2) {
-        fprintf(stderr,
-                "USAGE %s zookeeper_host_list [clientid_file|cmd:(ls|ls2|create|od|...)]\n", 
-                argv[0]);
-        fprintf(stderr,
-                "Version: ZooKeeper cli (c client) version %d.%d.%d\n", 
-                ZOO_MAJOR_VERSION,
-                ZOO_MINOR_VERSION,
-                ZOO_PATCH_VERSION);
-        return 2;
-    }
-    if (argc > 2) {
-      if(strncmp("cmd:",argv[2],4)==0){
-        size_t cmdlen = strlen(argv[2]);
-        if (cmdlen > sizeof(cmd)) {
-          fprintf(stderr,
-                  "Command length %zu exceeds max length of %zu\n",
-                  cmdlen,
-                  sizeof(cmd));
-          return 2;
-        }
-        strncpy(cmd, argv[2]+4, sizeof(cmd));
-        batchMode=1;
-        fprintf(stderr,"Batch mode: %s\n",cmd);
-      }else{
-        clientIdFile = argv[2];
-        fh = fopen(clientIdFile, "r");
-        if (fh) {
-            if (fread(&myid, sizeof(myid), 1, fh) != sizeof(myid)) {
-                memset(&myid, 0, sizeof(myid));
-            }
-            fclose(fh);
-        }
-      }
-    }
-#ifdef YCA
-    strcpy(appId,"yahoo.example.yca_test");
-    cert = yca_get_cert_once(appId);
-    if(cert!=0) {
-        fprintf(stderr,"Certificate for appid [%s] is [%s]\n",appId,cert);
-        strncpy(p,cert,sizeof(p)-1);
-        free(cert);
-    } else {
-      fprintf(stderr,"Certificate for appid [%s] not found\n",appId);
-      strcpy(p,"dummy");
-    }
-#else
-    strcpy(p, "dummy");
-#endif
-    verbose = 0;
-    zoo_set_debug_level(ZOO_LOG_LEVEL_WARN);
-    zoo_deterministic_conn_order(1); // enable deterministic order
-    hostPort = argv[1];
-    zh = zookeeper_init(hostPort, watcher, 30000, &myid, 0, 0);
-    if (!zh) {
-        return errno;
-    }
-
-#ifdef YCA
-    if(zoo_add_auth(zh,"yca",p,strlen(p),0,0)!=ZOK)
-    return 2;
-#endif
-
-#ifdef THREADED
-    while(!shutdownThisThing) {
-        int rc;
-        int len = sizeof(buffer) - bufoff -1;
-        if (len <= 0) {
-            fprintf(stderr, "Can't handle lines that long!\n");
-            exit(2);
-        }
-        rc = read(0, buffer+bufoff, len);
-        if (rc <= 0) {
-            fprintf(stderr, "bye\n");
-            shutdownThisThing=1;
-            break;
-        }
-        bufoff += rc;
-        buffer[bufoff] = '\0';
-        while (strchr(buffer, '\n')) {
-            char *ptr = strchr(buffer, '\n');
-            *ptr = '\0';
-            processline(buffer);
-            ptr++;
-            memmove(buffer, ptr, strlen(ptr)+1);
-            bufoff = 0;
-        }
-    }
-#else
-    FD_ZERO(&rfds);
-    FD_ZERO(&wfds);
-    FD_ZERO(&efds);
-    while (!shutdownThisThing) {
-        int fd;
-        int interest;
-        int events;
-        struct timeval tv;
-        int rc;
-        zookeeper_interest(zh, &fd, &interest, &tv);
-        if (fd != -1) {
-            if (interest&ZOOKEEPER_READ) {
-                FD_SET(fd, &rfds);
-            } else {
-                FD_CLR(fd, &rfds);
-            }
-            if (interest&ZOOKEEPER_WRITE) {
-                FD_SET(fd, &wfds);
-            } else {
-                FD_CLR(fd, &wfds);
-            }
-        } else {
-            fd = 0;
-        }
-        FD_SET(0, &rfds);
-        rc = select(fd+1, &rfds, &wfds, &efds, &tv);
-        events = 0;
-        if (rc > 0) {
-            if (FD_ISSET(fd, &rfds)) {
-                events |= ZOOKEEPER_READ;
-            }
-            if (FD_ISSET(fd, &wfds)) {
-                events |= ZOOKEEPER_WRITE;
-            }
-        }
-        if(batchMode && processed==0){
-          //batch mode
-          processline(cmd);
-          processed=1;
-        }
-        if (FD_ISSET(0, &rfds)) {
-            int rc;
-            int len = sizeof(buffer) - bufoff -1;
-            if (len <= 0) {
-                fprintf(stderr, "Can't handle lines that long!\n");
-                exit(2);
-            }
-            rc = read(0, buffer+bufoff, len);
-            if (rc <= 0) {
-                fprintf(stderr, "bye\n");
-                break;
-            }
-            bufoff += rc;
-            buffer[bufoff] = '\0';
-            while (strchr(buffer, '\n')) {
-                char *ptr = strchr(buffer, '\n');
-                *ptr = '\0';
-                processline(buffer);
-                ptr++;
-                memmove(buffer, ptr, strlen(ptr)+1);
-                bufoff = 0;
-            }
-        }
-        zookeeper_process(zh, events);
-    }
-#endif
-    if (to_send!=0)
-        fprintf(stderr,"Recvd %d responses for %d requests sent\n",recvd,sent);
-    zookeeper_close(zh);
-    return 0;
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/hashtable/LICENSE.txt
----------------------------------------------------------------------
diff --git a/src/c/src/hashtable/LICENSE.txt b/src/c/src/hashtable/LICENSE.txt
deleted file mode 100644
index 674a624..0000000
--- a/src/c/src/hashtable/LICENSE.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Copyright (c) 2002, 2004, Christopher Clark
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-	* Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-
-	* Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-
-	* Neither the name of the original author; nor the names of any contributors
-may be used to endorse or promote products derived from this software
-without specific prior written permission.
-
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/hashtable/hashtable.c
----------------------------------------------------------------------
diff --git a/src/c/src/hashtable/hashtable.c b/src/c/src/hashtable/hashtable.c
deleted file mode 100644
index 763357e..0000000
--- a/src/c/src/hashtable/hashtable.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/* Copyright (C) 2004 Christopher Clark <fi...@cl.cam.ac.uk> */
-
-#include "hashtable.h"
-#include "hashtable_private.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-
-/*
-Credit for primes table: Aaron Krowne
- http://br.endernet.org/~akrowne/
- http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
-*/
-static const unsigned int primes[] = {
-53, 97, 193, 389,
-769, 1543, 3079, 6151,
-12289, 24593, 49157, 98317,
-196613, 393241, 786433, 1572869,
-3145739, 6291469, 12582917, 25165843,
-50331653, 100663319, 201326611, 402653189,
-805306457, 1610612741
-};
-const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]);
-const float max_load_factor = 0.65;
-
-/*****************************************************************************/
-struct hashtable *
-create_hashtable(unsigned int minsize,
-                 unsigned int (*hashf) (void*),
-                 int (*eqf) (void*,void*))
-{
-    struct hashtable *h;
-    unsigned int pindex, size = primes[0];
-    /* Check requested hashtable isn't too large */
-    if (minsize > (1u << 30)) return NULL;
-    /* Enforce size as prime */
-    for (pindex=0; pindex < prime_table_length; pindex++) {
-        if (primes[pindex] > minsize) { size = primes[pindex]; break; }
-    }
-    h = (struct hashtable *)malloc(sizeof(struct hashtable));
-    if (NULL == h) return NULL; /*oom*/
-    h->table = (struct entry **)malloc(sizeof(struct entry*) * size);
-    if (NULL == h->table) { free(h); return NULL; } /*oom*/
-    memset(h->table, 0, size * sizeof(struct entry *));
-    h->tablelength  = size;
-    h->primeindex   = pindex;
-    h->entrycount   = 0;
-    h->hashfn       = hashf;
-    h->eqfn         = eqf;
-    h->loadlimit    = (unsigned int) ceil(size * max_load_factor);
-    return h;
-}
-
-/*****************************************************************************/
-unsigned int
-hash(struct hashtable *h, void *k)
-{
-    /* Aim to protect against poor hash functions by adding logic here
-     * - logic taken from java 1.4 hashtable source */
-    unsigned int i = h->hashfn(k);
-    i += ~(i << 9);
-    i ^=  ((i >> 14) | (i << 18)); /* >>> */
-    i +=  (i << 4);
-    i ^=  ((i >> 10) | (i << 22)); /* >>> */
-    return i;
-}
-
-/*****************************************************************************/
-static int
-hashtable_expand(struct hashtable *h)
-{
-    /* Double the size of the table to accomodate more entries */
-    struct entry **newtable;
-    struct entry *e;
-    struct entry **pE;
-    unsigned int newsize, i, index;
-    /* Check we're not hitting max capacity */
-    if (h->primeindex == (prime_table_length - 1)) return 0;
-    newsize = primes[++(h->primeindex)];
-
-    newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize);
-    if (NULL != newtable)
-    {
-        memset(newtable, 0, newsize * sizeof(struct entry *));
-        /* This algorithm is not 'stable'. ie. it reverses the list
-         * when it transfers entries between the tables */
-        for (i = 0; i < h->tablelength; i++) {
-            while (NULL != (e = h->table[i])) {
-                h->table[i] = e->next;
-                index = indexFor(newsize,e->h);
-                e->next = newtable[index];
-                newtable[index] = e;
-            }
-        }
-        free(h->table);
-        h->table = newtable;
-    }
-    /* Plan B: realloc instead */
-    else 
-    {
-        newtable = (struct entry **)
-                   realloc(h->table, newsize * sizeof(struct entry *));
-        if (NULL == newtable) { (h->primeindex)--; return 0; }
-        h->table = newtable;
-        memset(newtable[h->tablelength], 0, newsize - h->tablelength);
-        for (i = 0; i < h->tablelength; i++) {
-            for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
-                index = indexFor(newsize,e->h);
-                if (index == i)
-                {
-                    pE = &(e->next);
-                }
-                else
-                {
-                    *pE = e->next;
-                    e->next = newtable[index];
-                    newtable[index] = e;
-                }
-            }
-        }
-    }
-    h->tablelength = newsize;
-    h->loadlimit   = (unsigned int) ceil(newsize * max_load_factor);
-    return -1;
-}
-
-/*****************************************************************************/
-unsigned int
-hashtable_count(struct hashtable *h)
-{
-    return h->entrycount;
-}
-
-/*****************************************************************************/
-int
-hashtable_insert(struct hashtable *h, void *k, void *v)
-{
-    /* This method allows duplicate keys - but they shouldn't be used */
-    unsigned int index;
-    struct entry *e;
-    if (++(h->entrycount) > h->loadlimit)
-    {
-        /* Ignore the return value. If expand fails, we should
-         * still try cramming just this value into the existing table
-         * -- we may not have memory for a larger table, but one more
-         * element may be ok. Next time we insert, we'll try expanding again.*/
-        hashtable_expand(h);
-    }
-    e = (struct entry *)malloc(sizeof(struct entry));
-    if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
-    e->h = hash(h,k);
-    index = indexFor(h->tablelength,e->h);
-    e->k = k;
-    e->v = v;
-    e->next = h->table[index];
-    h->table[index] = e;
-    return -1;
-}
-
-/*****************************************************************************/
-void * /* returns value associated with key */
-hashtable_search(struct hashtable *h, void *k)
-{
-    struct entry *e;
-    unsigned int hashvalue, index;
-    hashvalue = hash(h,k);
-    index = indexFor(h->tablelength,hashvalue);
-    e = h->table[index];
-    while (NULL != e)
-    {
-        /* Check hash value to short circuit heavier comparison */
-        if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;
-        e = e->next;
-    }
-    return NULL;
-}
-
-/*****************************************************************************/
-void * /* returns value associated with key */
-hashtable_remove(struct hashtable *h, void *k)
-{
-    /* TODO: consider compacting the table when the load factor drops enough,
-     *       or provide a 'compact' method. */
-
-    struct entry *e;
-    struct entry **pE;
-    void *v;
-    unsigned int hashvalue, index;
-
-    hashvalue = hash(h,k);
-    index = indexFor(h->tablelength,hash(h,k));
-    pE = &(h->table[index]);
-    e = *pE;
-    while (NULL != e)
-    {
-        /* Check hash value to short circuit heavier comparison */
-        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
-        {
-            *pE = e->next;
-            h->entrycount--;
-            v = e->v;
-            freekey(e->k);
-            free(e);
-            return v;
-        }
-        pE = &(e->next);
-        e = e->next;
-    }
-    return NULL;
-}
-
-/*****************************************************************************/
-/* destroy */
-void
-hashtable_destroy(struct hashtable *h, int free_values)
-{
-    unsigned int i;
-    struct entry *e, *f;
-    struct entry **table = h->table;
-    if (free_values)
-    {
-        for (i = 0; i < h->tablelength; i++)
-        {
-            e = table[i];
-            while (NULL != e)
-            { f = e; e = e->next; freekey(f->k); free(f->v); free(f); }
-        }
-    }
-    else
-    {
-        for (i = 0; i < h->tablelength; i++)
-        {
-            e = table[i];
-            while (NULL != e)
-            { f = e; e = e->next; freekey(f->k); free(f); }
-        }
-    }
-    free(h->table);
-    free(h);
-}
-
-/*
- * Copyright (c) 2002, Christopher Clark
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- * 
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/hashtable/hashtable.h
----------------------------------------------------------------------
diff --git a/src/c/src/hashtable/hashtable.h b/src/c/src/hashtable/hashtable.h
deleted file mode 100644
index cbead18..0000000
--- a/src/c/src/hashtable/hashtable.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/* Copyright (C) 2002 Christopher Clark <fi...@cl.cam.ac.uk> */
-
-#ifndef __HASHTABLE_CWC22_H__
-#define __HASHTABLE_CWC22_H__
-#ifdef WIN32
-#include "winconfig.h"
-#endif
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct hashtable;
-
-/* Example of use:
- *
- *      struct hashtable  *h;
- *      struct some_key   *k;
- *      struct some_value *v;
- *
- *      static unsigned int         hash_from_key_fn( void *k );
- *      static int                  keys_equal_fn ( void *key1, void *key2 );
- *
- *      h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
- *      k = (struct some_key *)     malloc(sizeof(struct some_key));
- *      v = (struct some_value *)   malloc(sizeof(struct some_value));
- *
- *      (initialise k and v to suitable values)
- * 
- *      if (! hashtable_insert(h,k,v) )
- *      {     exit(-1);               }
- *
- *      if (NULL == (found = hashtable_search(h,k) ))
- *      {    printf("not found!");                  }
- *
- *      if (NULL == (found = hashtable_remove(h,k) ))
- *      {    printf("Not found\n");                 }
- *
- */
-
-/* Macros may be used to define type-safe(r) hashtable access functions, with
- * methods specialized to take known key and value types as parameters.
- * 
- * Example:
- *
- * Insert this at the start of your file:
- *
- * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
- * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
- * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
- *
- * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
- * These operate just like hashtable_insert etc., with the same parameters,
- * but their function signatures have 'struct some_key *' rather than
- * 'void *', and hence can generate compile time errors if your program is
- * supplying incorrect data as a key (and similarly for value).
- *
- * Note that the hash and key equality functions passed to create_hashtable
- * still take 'void *' parameters instead of 'some key *'. This shouldn't be
- * a difficult issue as they're only defined and passed once, and the other
- * functions will ensure that only valid keys are supplied to them.
- *
- * The cost for this checking is increased code size and runtime overhead
- * - if performance is important, it may be worth switching back to the
- * unsafe methods once your program has been debugged with the safe methods.
- * This just requires switching to some simple alternative defines - eg:
- * #define insert_some hashtable_insert
- *
- */
-
-/*****************************************************************************
- * create_hashtable
-   
- * @name                    create_hashtable
- * @param   minsize         minimum initial size of hashtable
- * @param   hashfunction    function for hashing keys
- * @param   key_eq_fn       function for determining key equality
- * @return                  newly created hashtable or NULL on failure
- */
-
-struct hashtable *
-create_hashtable(unsigned int minsize,
-                 unsigned int (*hashfunction) (void*),
-                 int (*key_eq_fn) (void*,void*));
-
-/*****************************************************************************
- * hashtable_insert
-   
- * @name        hashtable_insert
- * @param   h   the hashtable to insert into
- * @param   k   the key - hashtable claims ownership and will free on removal
- * @param   v   the value - does not claim ownership
- * @return      non-zero for successful insertion
- *
- * This function will cause the table to expand if the insertion would take
- * the ratio of entries to table size over the maximum load factor.
- *
- * This function does not check for repeated insertions with a duplicate key.
- * The value returned when using a duplicate key is undefined -- when
- * the hashtable changes size, the order of retrieval of duplicate key
- * entries is reversed.
- * If in doubt, remove before insert.
- */
-
-int 
-hashtable_insert(struct hashtable *h, void *k, void *v);
-
-#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
-int fnname (struct hashtable *h, keytype *k, valuetype *v) \
-{ \
-    return hashtable_insert(h,k,v); \
-}
-
-/*****************************************************************************
- * hashtable_search
-   
- * @name        hashtable_search
- * @param   h   the hashtable to search
- * @param   k   the key to search for  - does not claim ownership
- * @return      the value associated with the key, or NULL if none found
- */
-
-void *
-hashtable_search(struct hashtable *h, void *k);
-
-#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
-valuetype * fnname (struct hashtable *h, keytype *k) \
-{ \
-    return (valuetype *) (hashtable_search(h,k)); \
-}
-
-/*****************************************************************************
- * hashtable_remove
-   
- * @name        hashtable_remove
- * @param   h   the hashtable to remove the item from
- * @param   k   the key to search for  - does not claim ownership
- * @return      the value associated with the key, or NULL if none found
- */
-
-void * /* returns value */
-hashtable_remove(struct hashtable *h, void *k);
-
-#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
-valuetype * fnname (struct hashtable *h, keytype *k) \
-{ \
-    return (valuetype *) (hashtable_remove(h,k)); \
-}
-
-
-/*****************************************************************************
- * hashtable_count
-   
- * @name        hashtable_count
- * @param   h   the hashtable
- * @return      the number of items stored in the hashtable
- */
-unsigned int
-hashtable_count(struct hashtable *h);
-
-
-/*****************************************************************************
- * hashtable_destroy
-   
- * @name        hashtable_destroy
- * @param   h   the hashtable
- * @param       free_values     whether to call 'free' on the remaining values
- */
-
-void
-hashtable_destroy(struct hashtable *h, int free_values);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __HASHTABLE_CWC22_H__ */
-
-/*
- * Copyright (c) 2002, Christopher Clark
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- * 
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/hashtable/hashtable_itr.c
----------------------------------------------------------------------
diff --git a/src/c/src/hashtable/hashtable_itr.c b/src/c/src/hashtable/hashtable_itr.c
deleted file mode 100644
index defac69..0000000
--- a/src/c/src/hashtable/hashtable_itr.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/* Copyright (C) 2002, 2004 Christopher Clark  <fi...@cl.cam.ac.uk> */
-
-#include "hashtable.h"
-#include "hashtable_private.h"
-#include "hashtable_itr.h"
-#include <stdlib.h> /* defines NULL */
-
-/*****************************************************************************/
-/* hashtable_iterator    - iterator constructor */
-
-struct hashtable_itr *
-hashtable_iterator(struct hashtable *h)
-{
-    unsigned int i, tablelength;
-    struct hashtable_itr *itr = (struct hashtable_itr *)
-        malloc(sizeof(struct hashtable_itr));
-    if (NULL == itr) return NULL;
-    itr->h = h;
-    itr->e = NULL;
-    itr->parent = NULL;
-    tablelength = h->tablelength;
-    itr->index = tablelength;
-    if (0 == h->entrycount) return itr;
-
-    for (i = 0; i < tablelength; i++)
-    {
-        if (NULL != h->table[i])
-        {
-            itr->e = h->table[i];
-            itr->index = i;
-            break;
-        }
-    }
-    return itr;
-}
-
-/*****************************************************************************/
-/* advance - advance the iterator to the next element
- *           returns zero if advanced to end of table */
-
-int
-hashtable_iterator_advance(struct hashtable_itr *itr)
-{
-    unsigned int j,tablelength;
-    struct entry **table;
-    struct entry *next;
-    if (NULL == itr->e) return 0; /* stupidity check */
-
-    next = itr->e->next;
-    if (NULL != next)
-    {
-        itr->parent = itr->e;
-        itr->e = next;
-        return -1;
-    }
-    tablelength = itr->h->tablelength;
-    itr->parent = NULL;
-    if (tablelength <= (j = ++(itr->index)))
-    {
-        itr->e = NULL;
-        return 0;
-    }
-    table = itr->h->table;
-    while (NULL == (next = table[j]))
-    {
-        if (++j >= tablelength)
-        {
-            itr->index = tablelength;
-            itr->e = NULL;
-            return 0;
-        }
-    }
-    itr->index = j;
-    itr->e = next;
-    return -1;
-}
-
-/*****************************************************************************/
-/* remove - remove the entry at the current iterator position
- *          and advance the iterator, if there is a successive
- *          element.
- *          If you want the value, read it before you remove:
- *          beware memory leaks if you don't.
- *          Returns zero if end of iteration. */
-
-int
-hashtable_iterator_remove(struct hashtable_itr *itr)
-{
-    struct entry *remember_e, *remember_parent;
-    int ret;
-
-    /* Do the removal */
-    if (NULL == (itr->parent))
-    {
-        /* element is head of a chain */
-        itr->h->table[itr->index] = itr->e->next;
-    } else {
-        /* element is mid-chain */
-        itr->parent->next = itr->e->next;
-    }
-    /* itr->e is now outside the hashtable */
-    remember_e = itr->e;
-    itr->h->entrycount--;
-    freekey(remember_e->k);
-
-    /* Advance the iterator, correcting the parent */
-    remember_parent = itr->parent;
-    ret = hashtable_iterator_advance(itr);
-    if (itr->parent == remember_e) { itr->parent = remember_parent; }
-    free(remember_e);
-    return ret;
-}
-
-/*****************************************************************************/
-int /* returns zero if not found */
-hashtable_iterator_search(struct hashtable_itr *itr,
-                          struct hashtable *h, void *k)
-{
-    struct entry *e, *parent;
-    unsigned int hashvalue, index;
-
-    hashvalue = hash(h,k);
-    index = indexFor(h->tablelength,hashvalue);
-
-    e = h->table[index];
-    parent = NULL;
-    while (NULL != e)
-    {
-        /* Check hash value to short circuit heavier comparison */
-        if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
-        {
-            itr->index = index;
-            itr->e = e;
-            itr->parent = parent;
-            itr->h = h;
-            return -1;
-        }
-        parent = e;
-        e = e->next;
-    }
-    return 0;
-}
-
-
-/*
- * Copyright (c) 2002, 2004, Christopher Clark
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- * 
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/hashtable/hashtable_itr.h
----------------------------------------------------------------------
diff --git a/src/c/src/hashtable/hashtable_itr.h b/src/c/src/hashtable/hashtable_itr.h
deleted file mode 100644
index 30379c7..0000000
--- a/src/c/src/hashtable/hashtable_itr.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Copyright (C) 2002, 2004 Christopher Clark <fi...@cl.cam.ac.uk> */
-
-#ifndef __HASHTABLE_ITR_CWC22__
-#define __HASHTABLE_ITR_CWC22__
-#include "hashtable.h"
-#include "hashtable_private.h" /* needed to enable inlining */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*****************************************************************************/
-/* This struct is only concrete here to allow the inlining of two of the
- * accessor functions. */
-struct hashtable_itr
-{
-    struct hashtable *h;
-    struct entry *e;
-    struct entry *parent;
-    unsigned int index;
-};
-
-
-/*****************************************************************************/
-/* hashtable_iterator
- */
-
-struct hashtable_itr *
-hashtable_iterator(struct hashtable *h);
-
-/*****************************************************************************/
-/* hashtable_iterator_key
- * - return the value of the (key,value) pair at the current position */
-
-static inline void *
-hashtable_iterator_key(struct hashtable_itr *i)
-{
-    return i->e->k;
-}
-
-/*****************************************************************************/
-/* value - return the value of the (key,value) pair at the current position */
-
-static inline void *
-hashtable_iterator_value(struct hashtable_itr *i)
-{
-    return i->e->v;
-}
-
-/*****************************************************************************/
-/* advance - advance the iterator to the next element
- *           returns zero if advanced to end of table */
-
-int
-hashtable_iterator_advance(struct hashtable_itr *itr);
-
-/*****************************************************************************/
-/* remove - remove current element and advance the iterator to the next element
- *          NB: if you need the value to free it, read it before
- *          removing. ie: beware memory leaks!
- *          returns zero if advanced to end of table */
-
-int
-hashtable_iterator_remove(struct hashtable_itr *itr);
-
-/*****************************************************************************/
-/* search - overwrite the supplied iterator, to point to the entry
- *          matching the supplied key.
-            h points to the hashtable to be searched.
- *          returns zero if not found. */
-int
-hashtable_iterator_search(struct hashtable_itr *itr,
-                          struct hashtable *h, void *k);
-
-#define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
-int fnname (struct hashtable_itr *i, struct hashtable *h, keytype *k) \
-{ \
-    return (hashtable_iterator_search(i,h,k)); \
-}
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __HASHTABLE_ITR_CWC22__*/
-
-/*
- * Copyright (c) 2002, 2004, Christopher Clark
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- * 
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/hashtable/hashtable_private.h
----------------------------------------------------------------------
diff --git a/src/c/src/hashtable/hashtable_private.h b/src/c/src/hashtable/hashtable_private.h
deleted file mode 100644
index 3e95f60..0000000
--- a/src/c/src/hashtable/hashtable_private.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Copyright (C) 2002, 2004 Christopher Clark <fi...@cl.cam.ac.uk> */
-
-#ifndef __HASHTABLE_PRIVATE_CWC22_H__
-#define __HASHTABLE_PRIVATE_CWC22_H__
-
-#include "hashtable.h"
-
-/*****************************************************************************/
-struct entry
-{
-    void *k, *v;
-    unsigned int h;
-    struct entry *next;
-};
-
-struct hashtable {
-    unsigned int tablelength;
-    struct entry **table;
-    unsigned int entrycount;
-    unsigned int loadlimit;
-    unsigned int primeindex;
-    unsigned int (*hashfn) (void *k);
-    int (*eqfn) (void *k1, void *k2);
-};
-
-/*****************************************************************************/
-unsigned int
-hash(struct hashtable *h, void *k);
-
-/*****************************************************************************/
-/* indexFor */
-static inline unsigned int
-indexFor(unsigned int tablelength, unsigned int hashvalue) {
-    return (hashvalue % tablelength);
-};
-
-/* Only works if tablelength == 2^N */
-/*static inline unsigned int
-indexFor(unsigned int tablelength, unsigned int hashvalue)
-{
-    return (hashvalue & (tablelength - 1u));
-}
-*/
-
-/*****************************************************************************/
-#define freekey(X) free(X)
-/*define freekey(X) ; */
-
-
-/*****************************************************************************/
-
-#endif /* __HASHTABLE_PRIVATE_CWC22_H__*/
-
-/*
- * Copyright (c) 2002, Christopher Clark
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- * 
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/load_gen.c
----------------------------------------------------------------------
diff --git a/src/c/src/load_gen.c b/src/c/src/load_gen.c
deleted file mode 100644
index 546d5d1..0000000
--- a/src/c/src/load_gen.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <zookeeper.h>
-#include "zookeeper_log.h"
-#include <errno.h>
-#ifdef THREADED 
-#include <pthread.h>
-#endif
-#include <string.h>
-#include <stdlib.h>
-
-static zhandle_t *zh;
-
-static int shutdownThisThing=0;
-
-// *****************************************************************************
-//
-static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
-static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
-
-static pthread_cond_t counterCond=PTHREAD_COND_INITIALIZER;
-static pthread_mutex_t counterLock=PTHREAD_MUTEX_INITIALIZER;
-static int counter; 
-
-
-
-void ensureConnected(){
-    pthread_mutex_lock(&lock);
-    while (zoo_state(zh)!=ZOO_CONNECTED_STATE) {
-        pthread_cond_wait(&cond,&lock);
-    }
-    pthread_mutex_unlock(&lock);
-}
-
-void incCounter(int delta){
-    pthread_mutex_lock(&counterLock);
-    counter+=delta;
-    pthread_cond_broadcast(&counterCond);
-    pthread_mutex_unlock(&counterLock);        
-    
-}
-void setCounter(int cnt){
-    pthread_mutex_lock(&counterLock);
-    counter=cnt;
-    pthread_cond_broadcast(&counterCond);
-    pthread_mutex_unlock(&counterLock);        
-    
-}
-void waitCounter(){
-    pthread_mutex_lock(&counterLock);
-    while (counter>0) {
-        pthread_cond_wait(&counterCond,&counterLock);
-    }
-    pthread_mutex_unlock(&counterLock);    
-}
-
-void listener(zhandle_t *zzh, int type, int state, const char *path,void* ctx) {
-    if(type == ZOO_SESSION_EVENT){
-        if(state == ZOO_CONNECTED_STATE){
-            pthread_mutex_lock(&lock);
-            pthread_cond_broadcast(&cond);
-            pthread_mutex_unlock(&lock);
-        }
-        setCounter(0);
-    }
-}
-
-void create_completion(int rc, const char *name, const void *data) {
-    incCounter(-1);
-    if(rc!=ZOK){
-        LOG_ERROR(("Failed to create a node rc=%d",rc));
-    }
-}
-
-int doCreateNodes(const char* root, int count){
-    char nodeName[1024];
-    int i;
-    for(i=0; i<count;i++){
-        int rc = 0;
-        snprintf(nodeName, sizeof(nodeName),"%s/%d",root,i);
-        incCounter(1);
-        rc=zoo_acreate(zh, nodeName, "first", 5, &ZOO_OPEN_ACL_UNSAFE, 0,
-                            create_completion, 0);
-        if(i%1000==0){
-            LOG_INFO(("Created %s",nodeName));
-        }
-        if(rc!=ZOK) return rc;        
-    }
-    return ZOK;
-}
-
-int createRoot(const char* root){
-    char realpath[1024];
-    return zoo_create(zh,root,"root",4,&ZOO_OPEN_ACL_UNSAFE,0,realpath,sizeof(realpath)-1);
-}
-
-void write_completion(int rc, const struct Stat *stat, const void *data) {
-    incCounter(-1);
-    if(rc!=ZOK){
-        LOG_ERROR(("Failed to write a node rc=%d",rc));
-    }
-}
-
-int doWrites(const char* root, int count){
-    char nodeName[1024];
-    int i;
-    counter=0;
-    for(i=0; i<count;i++){
-        int rc = 0;
-        snprintf(nodeName, sizeof(nodeName),"%s/%d",root,i);
-        incCounter(1);
-        rc=zoo_aset(zh, nodeName, "second", 6,-1,write_completion, 0);
-        if(rc!=ZOK) return rc;        
-    }
-    return ZOK;
-}
-
-void read_completion(int rc, const char *value, int value_len,
-        const struct Stat *stat, const void *data) {
-    incCounter(-1);    
-    if(rc!=ZOK){
-        LOG_ERROR(("Failed to read a node rc=%d",rc));
-        return;
-    }
-    if(memcmp(value,"second",6)!=0){
-        char buf[value_len+1];
-        memcpy(buf,value,value_len);buf[value_len]=0;
-        LOG_ERROR(("Invalid read, expected [second], received [%s]\n",buf));
-        exit(1);
-    }
-}
-
-int doReads(const char* root, int count){
-    char nodeName[1024];
-    int i;
-    counter=0;
-    for(i=0; i<count;i++){
-        int rc = 0;
-        snprintf(nodeName, sizeof(nodeName),"%s/%d",root,i);
-        incCounter(1);
-        rc=zoo_aget(zh, nodeName,0,read_completion, 0);
-        if(rc!=ZOK) return rc;        
-    }
-    return ZOK;
-}
-
-void delete_completion(int rc, const void *data) {
-    incCounter(-1);    
-}
-
-int doDeletes(const char* root, int count){
-    char nodeName[1024];
-    int i;
-    counter=0;
-    for(i=0; i<count;i++){
-        int rc = 0;
-        snprintf(nodeName, sizeof(nodeName),"%s/%d",root,i);
-        incCounter(1);
-        rc=zoo_adelete(zh, nodeName,-1,delete_completion, 0);
-        if(rc!=ZOK) return rc;        
-    }
-    return ZOK;
-}
-
-static int free_String_vector(struct String_vector *v) {
-    if (v->data) {
-        int32_t i;
-        for(i=0;i<v->count; i++) {
-            free(v->data[i]);
-        }
-        free(v->data);
-        v->data = 0;
-    }
-    return 0;
-}
-
-static int deletedCounter;
-
-int recursiveDelete(const char* root){
-    struct String_vector children;
-    int i;
-    int rc=zoo_get_children(zh,root,0,&children);
-    if(rc!=ZNONODE){
-        if(rc!=ZOK){
-            LOG_ERROR(("Failed to get children of %s, rc=%d",root,rc));
-            return rc;
-        }
-        for(i=0;i<children.count; i++){
-            int rc = 0;
-            char nodeName[2048];
-            snprintf(nodeName, sizeof(nodeName),"%s/%s",root,children.data[i]);
-            rc=recursiveDelete(nodeName);
-            if(rc!=ZOK){
-                free_String_vector(&children);
-                return rc;
-            }
-        }
-        free_String_vector(&children);
-    }
-    if(deletedCounter%1000==0)
-        LOG_INFO(("Deleting %s",root));
-    rc=zoo_delete(zh,root,-1);
-    if(rc!=ZOK){
-        LOG_ERROR(("Failed to delete znode %s, rc=%d",root,rc));
-    }else
-        deletedCounter++;
-    return rc;
-}
-
-void usage(char *argv[]){
-    fprintf(stderr, "USAGE:\t%s zookeeper_host_list path #children\nor", argv[0]);
-    fprintf(stderr, "\t%s zookeeper_host_list path clean\n", argv[0]);
-    exit(0);
-}
-
-int main(int argc, char **argv) {
-    int nodeCount;
-    int cleaning=0;
-    if (argc < 4) {
-        usage(argv);
-    }
-    if(strcmp("clean",argv[3])==0){
-        cleaning=1;
-    }
-    zoo_set_debug_level(ZOO_LOG_LEVEL_INFO);
-    zoo_deterministic_conn_order(1); // enable deterministic order
-
-    zh = zookeeper_init(argv[1], listener, 10000, 0, 0, 0);
-    if (!zh)
-        return errno;
-
-    LOG_INFO(("Checking server connection..."));
-    ensureConnected();
-    if(cleaning==1){
-        int rc = 0;
-        deletedCounter=0;
-        rc=recursiveDelete(argv[2]);
-        if(rc==ZOK){
-            LOG_INFO(("Successfully deleted a subtree starting at %s (%d nodes)",
-                    argv[2],deletedCounter));
-            exit(0);
-        }
-        exit(1);
-    }
-    nodeCount=atoi(argv[3]);
-    createRoot(argv[2]);
-    while(1) {
-        ensureConnected();
-        LOG_INFO(("Creating children for path %s",argv[2]));
-        doCreateNodes(argv[2],nodeCount);
-        waitCounter();
-        
-        LOG_INFO(("Starting the write cycle for path %s",argv[2]));
-        doWrites(argv[2],nodeCount);
-        waitCounter();
-        LOG_INFO(("Starting the read cycle for path %s",argv[2]));
-        doReads(argv[2],nodeCount);
-        waitCounter();
-
-        LOG_INFO(("Starting the delete cycle for path %s",argv[2]));
-        doDeletes(argv[2],nodeCount);
-        waitCounter();
-    }
-    zookeeper_close(zh);
-    return 0;
-}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/src/mt_adaptor.c
----------------------------------------------------------------------
diff --git a/src/c/src/mt_adaptor.c b/src/c/src/mt_adaptor.c
deleted file mode 100644
index 52d86d5..0000000
--- a/src/c/src/mt_adaptor.c
+++ /dev/null
@@ -1,519 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef THREADED
-#define THREADED
-#endif
-
-#if !defined(DLL_EXPORT) && !defined(USE_STATIC_LIB)
-#  define USE_STATIC_LIB
-#endif
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include "zk_adaptor.h"
-#include "zookeeper_log.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <errno.h>
-
-#ifndef WIN32
-#include <signal.h>
-#include <poll.h>
-#include <unistd.h>
-#include <sys/time.h>
-#endif
-
-int zoo_lock_auth(zhandle_t *zh)
-{
-    return pthread_mutex_lock(&zh->auth_h.lock);
-}
-int zoo_unlock_auth(zhandle_t *zh)
-{
-    return pthread_mutex_unlock(&zh->auth_h.lock);
-}
-int lock_buffer_list(buffer_head_t *l)
-{
-    return pthread_mutex_lock(&l->lock);
-}
-int  unlock_buffer_list(buffer_head_t *l)
-{
-    return pthread_mutex_unlock(&l->lock);
-}
-int lock_completion_list(completion_head_t *l)
-{
-    return pthread_mutex_lock(&l->lock);
-}
-int unlock_completion_list(completion_head_t *l)
-{
-    pthread_cond_broadcast(&l->cond);
-    return pthread_mutex_unlock(&l->lock);
-}
-struct sync_completion *alloc_sync_completion(void)
-{
-    struct sync_completion *sc = (struct sync_completion*)calloc(1, sizeof(struct sync_completion));
-    if (sc) {
-       pthread_cond_init(&sc->cond, 0);
-       pthread_mutex_init(&sc->lock, 0);
-    }
-    return sc;
-}
-int wait_sync_completion(struct sync_completion *sc)
-{
-    pthread_mutex_lock(&sc->lock);
-    while (!sc->complete) {
-        pthread_cond_wait(&sc->cond, &sc->lock);
-    }
-    pthread_mutex_unlock(&sc->lock);
-    return 0;
-}
-
-void free_sync_completion(struct sync_completion *sc)
-{
-    if (sc) {
-        pthread_mutex_destroy(&sc->lock);
-        pthread_cond_destroy(&sc->cond);
-        free(sc);
-    }
-}
-
-void notify_sync_completion(struct sync_completion *sc)
-{
-    pthread_mutex_lock(&sc->lock);
-    sc->complete = 1;
-    pthread_cond_broadcast(&sc->cond);
-    pthread_mutex_unlock(&sc->lock);
-}
-
-int process_async(int outstanding_sync)
-{
-    return 0;
-}
-
-#ifdef WIN32
-unsigned __stdcall do_io( void * );
-unsigned __stdcall do_completion( void * );
-
-int handle_error(SOCKET sock, char* message)
-{
-       LOG_ERROR(("%s. %d",message, WSAGetLastError()));
-       closesocket (sock);
-       return -1;
-}
-
-//--create socket pair for interupting selects.
-int create_socket_pair(SOCKET fds[2]) 
-{ 
-    struct sockaddr_in inaddr; 
-    struct sockaddr addr; 
-    int yes=1; 
-    int len=0;
-       
-    SOCKET lst=socket(AF_INET, SOCK_STREAM,IPPROTO_TCP); 
-    if (lst ==  INVALID_SOCKET ){
-       LOG_ERROR(("Error creating socket. %d",WSAGetLastError()));
-       return -1;
-    }
-    memset(&inaddr, 0, sizeof(inaddr)); 
-    memset(&addr, 0, sizeof(addr)); 
-    inaddr.sin_family = AF_INET; 
-    inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 
-    inaddr.sin_port = 0; //--system assigns the port
-
-    if ( setsockopt(lst,SOL_SOCKET,SO_REUSEADDR,(char*)&yes,sizeof(yes)) == SOCKET_ERROR  ) {
-       return handle_error(lst,"Error trying to set socket option.");          
-    }  
-    if (bind(lst,(struct sockaddr *)&inaddr,sizeof(inaddr)) == SOCKET_ERROR){
-       return handle_error(lst,"Error trying to bind socket.");                
-    }
-    if (listen(lst,1) == SOCKET_ERROR){
-       return handle_error(lst,"Error trying to listen on socket.");
-    }
-    len=sizeof(inaddr); 
-    getsockname(lst, &addr,&len); 
-    fds[0]=socket(AF_INET, SOCK_STREAM,0); 
-    if (connect(fds[0],&addr,len) == SOCKET_ERROR){
-       return handle_error(lst, "Error while connecting to socket.");
-    }
-    if ((fds[1]=accept(lst,0,0)) == INVALID_SOCKET){
-       closesocket(fds[0]);
-       return handle_error(lst, "Error while accepting socket connection.");
-    }
-    closesocket(lst);  
-    return 0;
-} 
-#else
-void *do_io(void *);
-void *do_completion(void *);
-#endif
-
-
-int wakeup_io_thread(zhandle_t *zh);
-
-#ifdef WIN32
-static int set_nonblock(SOCKET fd){
-    ULONG nonblocking_flag = 1;
-    if (ioctlsocket(fd, FIONBIO, &nonblocking_flag) == 0)
-        return 1;
-    else 
-        return -1;
-}
-#else
-static int set_nonblock(int fd){
-    long l = fcntl(fd, F_GETFL);
-    if(l & O_NONBLOCK) return 0;
-    return fcntl(fd, F_SETFL, l | O_NONBLOCK);
-}
-#endif
-
-void wait_for_others(zhandle_t* zh)
-{
-    struct adaptor_threads* adaptor=zh->adaptor_priv;
-    pthread_mutex_lock(&adaptor->lock);
-    while(adaptor->threadsToWait>0) 
-        pthread_cond_wait(&adaptor->cond,&adaptor->lock);
-    pthread_mutex_unlock(&adaptor->lock);    
-}
-
-void notify_thread_ready(zhandle_t* zh)
-{
-    struct adaptor_threads* adaptor=zh->adaptor_priv;
-    pthread_mutex_lock(&adaptor->lock);
-    adaptor->threadsToWait--;
-    pthread_cond_broadcast(&adaptor->cond);
-    while(adaptor->threadsToWait>0) 
-        pthread_cond_wait(&adaptor->cond,&adaptor->lock);
-    pthread_mutex_unlock(&adaptor->lock);
-}
-
-
-void start_threads(zhandle_t* zh)
-{
-    int rc = 0;
-    struct adaptor_threads* adaptor=zh->adaptor_priv;
-    pthread_cond_init(&adaptor->cond,0);
-    pthread_mutex_init(&adaptor->lock,0);
-    adaptor->threadsToWait=2;  // wait for 2 threads before opening the barrier
-    
-    // use api_prolog() to make sure zhandle doesn't get destroyed
-    // while initialization is in progress
-    api_prolog(zh);
-    LOG_DEBUG(("starting threads..."));
-    rc=pthread_create(&adaptor->io, 0, do_io, zh);
-    assert("pthread_create() failed for the IO thread"&&!rc);
-    rc=pthread_create(&adaptor->completion, 0, do_completion, zh);
-    assert("pthread_create() failed for the completion thread"&&!rc);
-    wait_for_others(zh);
-    api_epilog(zh, 0);    
-}
-
-int adaptor_init(zhandle_t *zh)
-{
-    pthread_mutexattr_t recursive_mx_attr;
-    struct adaptor_threads *adaptor_threads = calloc(1, sizeof(*adaptor_threads));
-    if (!adaptor_threads) {
-        LOG_ERROR(("Out of memory"));
-        return -1;
-    }
-
-    /* We use a pipe for interrupting select() in unix/sol and socketpair in windows. */
-#ifdef WIN32   
-    if (create_socket_pair(adaptor_threads->self_pipe) == -1){
-       LOG_ERROR(("Can't make a socket."));
-#else
-    if(pipe(adaptor_threads->self_pipe)==-1) {
-        LOG_ERROR(("Can't make a pipe %d",errno));
-#endif
-        free(adaptor_threads);
-        return -1;
-    }
-    set_nonblock(adaptor_threads->self_pipe[1]);
-    set_nonblock(adaptor_threads->self_pipe[0]);
-
-    pthread_mutex_init(&zh->auth_h.lock,0);
-
-    zh->adaptor_priv = adaptor_threads;
-    pthread_mutex_init(&zh->to_process.lock,0);
-    pthread_mutex_init(&adaptor_threads->zh_lock,0);
-    // to_send must be recursive mutex    
-    pthread_mutexattr_init(&recursive_mx_attr);
-    pthread_mutexattr_settype(&recursive_mx_attr, PTHREAD_MUTEX_RECURSIVE);
-    pthread_mutex_init(&zh->to_send.lock,&recursive_mx_attr);
-    pthread_mutexattr_destroy(&recursive_mx_attr);
-    
-    pthread_mutex_init(&zh->sent_requests.lock,0);
-    pthread_cond_init(&zh->sent_requests.cond,0);
-    pthread_mutex_init(&zh->completions_to_process.lock,0);
-    pthread_cond_init(&zh->completions_to_process.cond,0);
-    start_threads(zh);
-    return 0;
-}
-
-void adaptor_finish(zhandle_t *zh)
-{
-    struct adaptor_threads *adaptor_threads;
-    // make sure zh doesn't get destroyed until after we're done here
-    api_prolog(zh); 
-    adaptor_threads = zh->adaptor_priv;
-    if(adaptor_threads==0) {
-        api_epilog(zh,0);
-        return;
-    }
-
-    if(!pthread_equal(adaptor_threads->io,pthread_self())){
-        wakeup_io_thread(zh);
-        pthread_join(adaptor_threads->io, 0);
-    }else
-        pthread_detach(adaptor_threads->io);
-    
-    if(!pthread_equal(adaptor_threads->completion,pthread_self())){
-        pthread_mutex_lock(&zh->completions_to_process.lock);
-        pthread_cond_broadcast(&zh->completions_to_process.cond);
-        pthread_mutex_unlock(&zh->completions_to_process.lock);
-        pthread_join(adaptor_threads->completion, 0);
-    }else
-        pthread_detach(adaptor_threads->completion);
-    
-    api_epilog(zh,0);
-}
-
-void adaptor_destroy(zhandle_t *zh)
-{
-    struct adaptor_threads *adaptor = zh->adaptor_priv;
-    if(adaptor==0) return;
-    
-    pthread_cond_destroy(&adaptor->cond);
-    pthread_mutex_destroy(&adaptor->lock);
-    pthread_mutex_destroy(&zh->to_process.lock);
-    pthread_mutex_destroy(&zh->to_send.lock);
-    pthread_mutex_destroy(&zh->sent_requests.lock);
-    pthread_cond_destroy(&zh->sent_requests.cond);
-    pthread_mutex_destroy(&zh->completions_to_process.lock);
-    pthread_cond_destroy(&zh->completions_to_process.cond);
-    pthread_mutex_destroy(&adaptor->zh_lock);
-
-    pthread_mutex_destroy(&zh->auth_h.lock);
-
-    close(adaptor->self_pipe[0]);
-    close(adaptor->self_pipe[1]);
-    free(adaptor);
-    zh->adaptor_priv=0;
-}
-
-int wakeup_io_thread(zhandle_t *zh)
-{
-    struct adaptor_threads *adaptor_threads = zh->adaptor_priv;
-    char c=0;
-#ifndef WIN32
-    return write(adaptor_threads->self_pipe[1],&c,1)==1? ZOK: ZSYSTEMERROR;    
-#else
-    return send(adaptor_threads->self_pipe[1], &c, 1, 0)==1? ZOK: ZSYSTEMERROR;    
-#endif         
-}
-
-int adaptor_send_queue(zhandle_t *zh, int timeout)
-{
-    if(!zh->close_requested)
-        return wakeup_io_thread(zh);
-    // don't rely on the IO thread to send the messages if the app has
-    // requested to close 
-    return flush_send_queue(zh, timeout);
-}
-
-/* These two are declared here because we will run the event loop
- * and not the client */
-#ifdef WIN32
-int zookeeper_interest(zhandle_t *zh, SOCKET *fd, int *interest,
-        struct timeval *tv);
-#else
-int zookeeper_interest(zhandle_t *zh, int *fd, int *interest,
-        struct timeval *tv);
-#endif
-int zookeeper_process(zhandle_t *zh, int events);
-
-#ifdef WIN32
-unsigned __stdcall do_io( void * v)
-#else
-void *do_io(void *v)
-#endif
-{
-    zhandle_t *zh = (zhandle_t*)v;
-#ifndef WIN32
-    struct pollfd fds[2];
-    struct adaptor_threads *adaptor_threads = zh->adaptor_priv;
-
-    api_prolog(zh);
-    notify_thread_ready(zh);
-    LOG_DEBUG(("started IO thread"));
-    fds[0].fd=adaptor_threads->self_pipe[0];
-    fds[0].events=POLLIN;
-    while(!zh->close_requested) {
-        struct timeval tv;
-        int fd;
-        int interest;
-        int timeout;
-        int maxfd=1;
-
-        zookeeper_interest(zh, &fd, &interest, &tv);
-        if (fd != -1) {
-            fds[1].fd=fd;
-            fds[1].events=(interest&ZOOKEEPER_READ)?POLLIN:0;
-            fds[1].events|=(interest&ZOOKEEPER_WRITE)?POLLOUT:0;
-            maxfd=2;
-        }
-        timeout=tv.tv_sec * 1000 + (tv.tv_usec/1000);
-        
-        poll(fds,maxfd,timeout);
-        if (fd != -1) {
-            interest=(fds[1].revents&POLLIN)?ZOOKEEPER_READ:0;
-            interest|=((fds[1].revents&POLLOUT)||(fds[1].revents&POLLHUP))?ZOOKEEPER_WRITE:0;
-        }
-        if(fds[0].revents&POLLIN){
-            // flush the pipe
-            char b[128];
-            while(read(adaptor_threads->self_pipe[0],b,sizeof(b))==sizeof(b)){}
-        }        
-#else
-    fd_set rfds, wfds, efds;
-    struct adaptor_threads *adaptor_threads = zh->adaptor_priv;
-    api_prolog(zh);
-    notify_thread_ready(zh);
-    LOG_DEBUG(("started IO thread"));
-    FD_ZERO(&rfds);   FD_ZERO(&wfds);    FD_ZERO(&efds);
-    while(!zh->close_requested) {      
-        struct timeval tv;
-        SOCKET fd;
-        SOCKET maxfd=adaptor_threads->self_pipe[0];
-        int interest;        
-        int rc;
-               
-       zookeeper_interest(zh, &fd, &interest, &tv);
-       if (fd != -1) {
-           if (interest&ZOOKEEPER_READ) {
-                FD_SET(fd, &rfds);
-            } else {
-                FD_CLR(fd, &rfds);
-            }
-           if (interest&ZOOKEEPER_WRITE) {
-                FD_SET(fd, &wfds);
-            } else {
-                FD_CLR(fd, &wfds);
-            }                  
-        }
-       FD_SET( adaptor_threads->self_pipe[0] ,&rfds );        
-       rc = select((int)maxfd, &rfds, &wfds, &efds, &tv);
-       if (fd != -1) 
-       {
-           interest = (FD_ISSET(fd, &rfds))? ZOOKEEPER_READ:0;
-           interest|= (FD_ISSET(fd, &wfds))? ZOOKEEPER_WRITE:0;
-        }
-               
-       if (FD_ISSET(adaptor_threads->self_pipe[0], &rfds)){
-            // flush the pipe/socket
-            char b[128];
-           while(recv(adaptor_threads->self_pipe[0],b,sizeof(b), 0)==sizeof(b)){}
-       }
-#endif
-        // dispatch zookeeper events
-        zookeeper_process(zh, interest);
-        // check the current state of the zhandle and terminate 
-        // if it is_unrecoverable()
-        if(is_unrecoverable(zh))
-            break;
-    }
-    api_epilog(zh, 0);    
-    LOG_DEBUG(("IO thread terminated"));
-    return 0;
-}
-
-#ifdef WIN32
-unsigned __stdcall do_completion( void * v)
-#else
-void *do_completion(void *v)
-#endif
-{
-    zhandle_t *zh = v;
-    api_prolog(zh);
-    notify_thread_ready(zh);
-    LOG_DEBUG(("started completion thread"));
-    while(!zh->close_requested) {
-        pthread_mutex_lock(&zh->completions_to_process.lock);
-        while(!zh->completions_to_process.head && !zh->close_requested) {
-            pthread_cond_wait(&zh->completions_to_process.cond, &zh->completions_to_process.lock);
-        }
-        pthread_mutex_unlock(&zh->completions_to_process.lock);
-        process_completions(zh);
-    }
-    api_epilog(zh, 0);    
-    LOG_DEBUG(("completion thread terminated"));
-    return 0;
-}
-
-int32_t inc_ref_counter(zhandle_t* zh,int i)
-{
-    int incr=(i<0?-1:(i>0?1:0));
-    // fetch_and_add implements atomic post-increment
-    int v=fetch_and_add(&zh->ref_counter,incr);
-    // inc_ref_counter wants pre-increment
-    v+=incr;   // simulate pre-increment
-    return v;
-}
-
-int32_t fetch_and_add(volatile int32_t* operand, int incr)
-{
-#ifndef WIN32
-    return __sync_fetch_and_add(operand, incr);
-#else
-    return InterlockedExchangeAdd(operand, incr);
-#endif
-}
-
-// make sure the static xid is initialized before any threads started
-__attribute__((constructor)) int32_t get_xid()
-{
-    static int32_t xid = -1;
-    if (xid == -1) {
-        xid = time(0);
-    }
-    return fetch_and_add(&xid,1);
-}
-
-int enter_critical(zhandle_t* zh)
-{
-    struct adaptor_threads *adaptor = zh->adaptor_priv;
-    if (adaptor) {
-        return pthread_mutex_lock(&adaptor->zh_lock);
-    } else {
-        return 0;
-    }
-}
-
-int leave_critical(zhandle_t* zh)
-{
-    struct adaptor_threads *adaptor = zh->adaptor_priv;
-    if (adaptor) {
-        return pthread_mutex_unlock(&adaptor->zh_lock);
-    } else {
-        return 0;
-    }
-}


[04/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/CollectionUtil.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/CollectionUtil.h b/zookeeper-client/zookeeper-client-c/tests/CollectionUtil.h
new file mode 100644
index 0000000..dd34811
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/CollectionUtil.h
@@ -0,0 +1,195 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef _COLLECTION_UTIL_H_
+#define _COLLECTION_UTIL_H_
+
+/**
+ * \file
+ * CollectionBuilder and DictionaryBuilder classes and collection utility functions
+ */
+
+namespace Util 
+{
+
+// *********************************************************
+/** A shortcut to use for building collections.
+ * This class is a wrapper around standard STL collection containers such as vector.
+ * It allows one to conveniently build collections at the variable initialization time:
+ * \code
+ * #include "CollectionUtil.h"
+ * #include "Vector.h"  // for ostream << operator overload for STL vector
+ * using Util;
+ * 
+ * int main()
+ * {
+ *   typedef vector<string> MyVector;
+ *   MyVector myVector=CollectionBuilder<MyVector>()("str1")("str2")("str3");
+ *   cout<<myVector;
+ *   // the following output will be produced:
+ *   // [str1,str2,str3]
+ * }
+ * \endcode
+ */
+template <class CONT>
+class CollectionBuilder
+{
+public:
+  /// Type of the collection container. 
+  typedef CONT CollectionType;
+  /// Container's value type.
+  typedef typename CollectionType::value_type value_type;
+  /// Container's constant iterator type.
+  typedef typename CollectionType::const_iterator const_iterator;
+  /// Container's size type.
+  typedef typename CollectionType::size_type size_type;
+
+  /** Operator function call overload to allow call chaining.
+   * \param value the value to be inserted into the container
+   */
+  CollectionBuilder<CONT>& operator()(const value_type& value){
+    return push_back(value);
+  }
+  /** Same as regular STL push_back() but allows call chaining.
+   * \param value the value to be inserted into the container
+   */
+  CollectionBuilder<CONT>& push_back(const value_type& value){
+    collection_.push_back(value);
+    return *this;
+  }
+  /// \name Standard STL container interface
+  /// @{
+  const_iterator begin() const{return collection_.begin();}
+  const_iterator end() const{return collection_.end();}
+  size_type size() const{return collection_.size();}
+  void clear() {collection_.clear();}
+  ///@}
+  /// Explicit typecast operator.
+  operator const CollectionType&() const {return collection_;}
+private:
+  /// \cond PRIVATE
+  CollectionType collection_;
+  /// \endcond
+};
+
+
+// *********************************************************
+/** A shortcut to use for building dictionaries.
+ * This class is a wrapper around standard STL associative containers such as map.
+ * It allows one to conveniently build dictionaries at the variable initialization time:
+ * \code
+ * #include "CollectionUtil.h"
+ * #include "Map.h"  // for ostream << operator overload for STL map
+ * using Util;
+ * 
+ * int main()
+ * {
+ *   typedef map<string,int> MyMap;
+ *   MyMap myMap=DictionaryBuilder<MyMap>()("str1",1)("str2",2)("str3",3);
+ *   cout<<myMap;
+ *   // the following output will be produced:
+ *   // [str1=1,str2=2,str3=3]
+ * }
+ * \endcode
+ */
+template <class CONT>
+class DictionaryBuilder
+{
+public:
+  /// The type of the associative container
+  typedef CONT DictionaryType;
+  /// Container's element type (usually a pair<key_type,mapped_type>)
+  typedef typename DictionaryType::value_type value_type;
+  /// Container's key type
+  typedef typename DictionaryType::key_type key_type;
+  /// Container's value type 
+  typedef typename DictionaryType::mapped_type mapped_type;
+  /// Container's constant iterator type 
+  typedef typename DictionaryType::const_iterator const_iterator;
+  /// Container's writable iterator type   
+  typedef typename DictionaryType::iterator iterator;
+  /// Container's size type
+  typedef typename DictionaryType::size_type size_type;
+ 
+  /** Operator function call overload to allow call chaining.
+   * \param key the value key to be inserted
+   * \param value the value to be inserted into the container
+   * \return a non-const reference to self
+   */
+  DictionaryBuilder<CONT>& operator()(const key_type& key,const mapped_type& value){
+    dict_.insert(value_type(key,value));
+    return *this;
+  }
+  /** Lookup value by key.
+   * \param key the key associated with the value.
+   * \return a non-const iterator pointing to the element whose key matched the \a key parameter
+   */
+  iterator find(const key_type& key){
+    return dict_.find(key);
+  }
+  /** Lookup value by key.
+   * \param key the key associated with the value.
+   * \return a const iterator pointing to the element whose key matched the \a key parameter
+   */
+  const_iterator find(const key_type& key) const{
+    return dict_.find(key);
+  }
+
+  /// \name Standard STL container interface
+  /// @{
+  const_iterator begin() const{return dict_.begin();}
+  const_iterator end() const{return dict_.end();}
+  size_type size() const{return dict_.size();}
+  void clear() {dict_.clear();}
+  ///@}
+  /// Explicit typecast operator.
+  operator const DictionaryType&() const {return dict_;}
+private:
+  DictionaryType dict_;
+};
+
+
+// ***********************************************************
+/** Deletes all dynamically allocated elements of a collection.
+ * C::value_type is expected to be a pointer to a dynamically allocated object, or it won't compile.
+ * The function will iterate over all container elements and call delete for each of them.
+ * \param c a collection (vector,set) whose elements are being deleted.
+ */
+template <class C>
+void clearCollection(C& c){
+  for(typename C::const_iterator it=c.begin();it!=c.end();++it)
+    delete *it;
+  c.clear();
+}
+
+/** Deletes all dynamically allocated values of the assotiative container.
+ * The function expects the M::value_type to be a pair<..., ptr_to_type>, or it won't compile.
+ * It first deletes the objects pointed to by ptr_to_type
+ * and then clears (calls m.clear()) the container.
+ * \param m an associative container (map,hash_map) whose elements are being deleted.
+ */
+template <class M>
+void clearMap(M& m){
+  for(typename M::const_iterator it=m.begin();it!=m.end();++it)
+    delete it->second;
+  m.clear();
+}
+
+} // namespace Util
+
+
+#endif // _COLLECTION_UTIL_H_

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/CppAssertHelper.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/CppAssertHelper.h b/zookeeper-client/zookeeper-client-c/tests/CppAssertHelper.h
new file mode 100644
index 0000000..3926f51
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/CppAssertHelper.h
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CPPASSERTHELPER_H_
+#define CPPASSERTHELPER_H_
+
+#include <cppunit/TestAssert.h>
+
+// make it possible to specify location of the ASSERT call
+#define CPPUNIT_ASSERT_EQUAL_LOC(expected,actual,file,line) \
+  ( CPPUNIT_NS::assertEquals( (expected),              \
+                              (actual),                \
+                              CPPUNIT_NS::SourceLine(file,line),    \
+                              "" ) )
+
+#define CPPUNIT_ASSERT_EQUAL_MESSAGE_LOC(message,expected,actual,file,line) \
+  ( CPPUNIT_NS::assertEquals( (expected),              \
+                              (actual),                \
+                              CPPUNIT_NS::SourceLine(file,line), \
+                              (message) ) )
+
+#endif /*CPPASSERTHELPER_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/LibCMocks.cc
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/LibCMocks.cc b/zookeeper-client/zookeeper-client-c/tests/LibCMocks.cc
new file mode 100644
index 0000000..5db4553
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/LibCMocks.cc
@@ -0,0 +1,333 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstdlib>
+#include <cstdarg>
+#include <iostream>
+#include <stdarg.h>
+
+#include "Util.h"
+#include "LibCMocks.h"
+
+#undef USING_DUMA
+
+using namespace std;
+
+// *****************************************************************************
+// gethostbyname
+
+struct hostent* gethostbyname(const char *name) {
+    if(!Mock_gethostbyname::mock_)
+        return LIBC_SYMBOLS.gethostbyname(name);
+    return Mock_gethostbyname::mock_->call(name);
+}
+
+Mock_gethostbyname* Mock_gethostbyname::mock_=0;
+
+Mock_gethostbyname::~Mock_gethostbyname(){
+    mock_=0;
+    for(unsigned int i=0;i<gethostbynameReturns.size();i++)
+        delete gethostbynameReturns[i];
+}
+
+Mock_gethostbyname::HostEntry& Mock_gethostbyname::addHostEntry(
+        const char* hostName, short addrtype) {
+    gethostbynameReturns.push_back(new HostEntry(hostName, addrtype));
+    return *gethostbynameReturns.back();
+}
+
+hostent* Mock_gethostbyname::call(const char* name) {
+    assert("Must add one or more mock hostent entries first"&&
+            (gethostbynameReturns.size()!=0));
+    return gethostbynameReturns[current++ % gethostbynameReturns.size()];
+}
+
+static char** appendString(char **list,const char* str,int len=0){
+    const int SIZE_INCREMENT=16;
+    if(list==0)
+        list=(char**)LIBC_SYMBOLS.calloc(SIZE_INCREMENT,sizeof(char*));
+    // find the first available slot
+    int count=0;
+    for(char** ptr=list; *ptr!=0; ptr++,count++);
+    if(((count+1)%SIZE_INCREMENT)==0){
+        list=(char**)LIBC_SYMBOLS.realloc(list,(count+1+SIZE_INCREMENT)*sizeof(char*));
+        memset(list+count+1,0,SIZE_INCREMENT*sizeof(char*));
+    }
+    if(len==0){
+        len=strlen(str)+1;
+    }
+    char* ptr=(char*)malloc(len);
+    memcpy(ptr,str,len);
+    list[count]=ptr;
+    return list;
+}
+
+static void freeList(char **list){
+    if(list==0) return;
+    for(char** ptr=list; *ptr!=0; ptr++)
+        LIBC_SYMBOLS.free((void*)*ptr);
+    LIBC_SYMBOLS.free((void*)list);
+}
+
+Mock_gethostbyname::HostEntry::HostEntry(const char* hostName, short addrtype) {
+    h_name=strdup(hostName);
+    h_addrtype=addrtype;
+    if(addrtype==AF_INET)
+        h_length=4;
+    else{
+#ifdef AF_INET6
+        h_length=6; // TODO: not really sure, verify!
+#else
+        assert("AF_INET6 not supported yet"&&false);
+#endif
+    }
+    h_aliases=h_addr_list=0;
+}
+
+Mock_gethostbyname::HostEntry::~HostEntry(){
+    if(h_name) LIBC_SYMBOLS.free((void*)h_name);
+    freeList(h_aliases); h_aliases=0;
+    freeList(h_addr_list); h_addr_list=0;
+}
+
+Mock_gethostbyname::HostEntry& Mock_gethostbyname::HostEntry::addAlias(
+        const char* alias) {
+    h_aliases=appendString(h_aliases,alias);
+    return *this;
+}
+
+Mock_gethostbyname::HostEntry& Mock_gethostbyname::HostEntry::addAddress(
+        const char* addr4) {
+    h_addr_list=appendString(h_addr_list,addr4,4);
+    return *this;
+}
+
+
+// *****************************************************************************
+// calloc
+#ifndef USING_DUMA
+DECLARE_WRAPPER(void*,calloc,(size_t p1, size_t p2)){
+    if(!Mock_calloc::mock_)
+        return CALL_REAL(calloc,(p1,p2));
+    return Mock_calloc::mock_->call(p1,p2);
+}
+#endif
+
+void* Mock_calloc::call(size_t p1, size_t p2){
+#ifndef USING_DUMA
+    if(counter++ ==callsBeforeFailure){
+        counter=0;
+        errno=errnoOnFailure;
+        return 0;
+    }
+    return CALL_REAL(calloc,(p1,p2));
+#else
+    return 0;
+#endif
+}
+
+Mock_calloc* Mock_calloc::mock_=0;
+
+// *****************************************************************************
+// realloc
+
+#ifndef USING_DUMA
+DECLARE_WRAPPER(void*,realloc,(void* p, size_t s)){
+    if(!Mock_realloc::mock_)
+        return LIBC_SYMBOLS.realloc(p,s);
+    return Mock_realloc::mock_->call(p,s);
+}
+#endif
+
+Mock_realloc* Mock_realloc::mock_=0;
+
+void* Mock_realloc::call(void* p, size_t s){
+    if(counter++ ==callsBeforeFailure){
+        counter=0;
+        errno=errnoOnFailure;
+        return 0;
+    }
+    return LIBC_SYMBOLS.realloc(p,s);
+}
+
+// *****************************************************************************
+// random
+RANDOM_RET_TYPE random(){
+    if(!Mock_random::mock_)
+        return LIBC_SYMBOLS.random();
+    return Mock_random::mock_->call();    
+}
+
+void srandom(unsigned long seed){
+    if (!Mock_random::mock_)
+        LIBC_SYMBOLS.srandom(seed);
+    else
+        Mock_random::mock_->setSeed(seed);
+}
+
+Mock_random* Mock_random::mock_=0;
+
+int Mock_random::call(){
+    assert("Must specify one or more random integers"&&(randomReturns.size()!=0));
+    return randomReturns[currentIdx++ % randomReturns.size()];
+}
+
+// *****************************************************************************
+// free
+#ifndef USING_DUMA
+DECLARE_WRAPPER(void,free,(void* p)){
+    if(Mock_free_noop::mock_ && !Mock_free_noop::mock_->nested)
+        Mock_free_noop::mock_->call(p);
+    else
+        CALL_REAL(free,(p));
+}
+#endif
+
+void Mock_free_noop::call(void* p){
+    // on cygwin libc++ is linked statically
+    // push_back() may call free(), hence the nesting guards
+    synchronized(mx);
+    nested++;
+    callCounter++;
+    requested.push_back(p);
+    nested--;
+}
+void Mock_free_noop::freeRequested(){
+#ifndef USING_DUMA
+    synchronized(mx);
+    for(unsigned i=0; i<requested.size();i++)
+        CALL_REAL(free,(requested[i]));
+#endif
+}
+
+int Mock_free_noop::getFreeCount(void* p){
+    int cnt=0;
+    synchronized(mx);
+    for(unsigned i=0;i<requested.size();i++)
+        if(requested[i]==p)cnt++;
+    return cnt;
+}
+
+bool Mock_free_noop::isFreed(void* p){
+    synchronized(mx);
+    for(unsigned i=0;i<requested.size();i++)
+        if(requested[i]==p)return true;
+    return false;
+}
+
+Mock_free_noop* Mock_free_noop::mock_=0;
+
+// *****************************************************************************
+// socket
+int socket(int domain, int type, int protocol){
+    if (!Mock_socket::mock_)
+        return LIBC_SYMBOLS.socket(domain,type,protocol);
+    return Mock_socket::mock_->callSocket(domain,type,protocol);
+}
+
+int close(int fd){
+    if (!Mock_socket::mock_)
+        return LIBC_SYMBOLS.close(fd);
+    return Mock_socket::mock_->callClose(fd);
+}
+
+int getsockopt(int s,int level,int optname,void *optval,socklen_t *optlen){
+    if (!Mock_socket::mock_)
+        return LIBC_SYMBOLS.getsockopt(s,level,optname,optval,optlen);
+    return Mock_socket::mock_->callGet(s,level,optname,optval,optlen);    
+}
+
+int setsockopt(int s,int level,int optname,const void *optval,socklen_t optlen){
+    if (!Mock_socket::mock_)
+        return LIBC_SYMBOLS.setsockopt(s,level,optname,optval,optlen);
+    return Mock_socket::mock_->callSet(s,level,optname,optval,optlen);      
+}
+int connect(int s,const struct sockaddr *addr,socklen_t len){
+    if (!Mock_socket::mock_)
+        return LIBC_SYMBOLS.connect(s,addr,len);
+    return Mock_socket::mock_->callConnect(s,addr,len);
+}
+ssize_t send(int s,const void *buf,size_t len,int flags){
+    if (!Mock_socket::mock_)
+        return LIBC_SYMBOLS.send(s,buf,len,flags);
+    return Mock_socket::mock_->callSend(s,buf,len,flags);    
+}
+
+ssize_t recv(int s,void *buf,size_t len,int flags){
+    if (!Mock_socket::mock_)
+        return LIBC_SYMBOLS.recv(s,buf,len,flags);
+    return Mock_socket::mock_->callRecv(s,buf,len,flags);        
+}
+
+Mock_socket* Mock_socket::mock_=0;
+
+// *****************************************************************************
+// fcntl
+extern "C" int fcntl(int fd,int cmd,...){
+    va_list va;
+    va_start(va,cmd);
+    void* arg = va_arg(va, void *);
+    va_end (va);
+    if (!Mock_fcntl::mock_)
+        return LIBC_SYMBOLS.fcntl(fd,cmd,arg);
+    return Mock_fcntl::mock_->call(fd,cmd,arg);    
+}
+
+Mock_fcntl* Mock_fcntl::mock_=0;
+
+// *****************************************************************************
+// select
+int select(int nfds,fd_set *rfds,fd_set *wfds,fd_set *efds,struct timeval *timeout){
+    if (!Mock_select::mock_)
+        return LIBC_SYMBOLS.select(nfds,rfds,wfds,efds,timeout);
+    return Mock_select::mock_->call(nfds,rfds,wfds,efds,timeout);        
+}
+
+Mock_select* Mock_select::mock_=0;
+
+// *****************************************************************************
+// poll
+Mock_poll* Mock_poll::mock_=0;
+int poll(struct pollfd *fds, POLL_NFDS_TYPE nfds, int timeout){
+    if (!Mock_poll::mock_)
+        return LIBC_SYMBOLS.poll(fds,nfds,timeout);
+    return Mock_poll::mock_->call(fds,nfds,timeout);        
+    
+}
+
+/*
+ * Recent gcc with -O2 and glibc FORTIFY feature may cause our poll
+ * mock to be ignored.
+ */
+#if __USE_FORTIFY_LEVEL > 0
+int __poll_chk (struct pollfd *__fds, nfds_t __nfds, int __timeout,
+                __SIZE_TYPE__ __fdslen) {
+    return poll(__fds, __nfds, __timeout);
+}
+#endif
+
+// *****************************************************************************
+// gettimeofday
+int gettimeofday(struct timeval *tp, GETTIMEOFDAY_ARG2_TYPE tzp){
+    if (!Mock_gettimeofday::mock_)
+        return LIBC_SYMBOLS.gettimeofday(tp,tzp);
+    return Mock_gettimeofday::mock_->call(tp,tzp);            
+}
+
+Mock_gettimeofday* Mock_gettimeofday::mock_=0;
+

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/LibCMocks.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/LibCMocks.h b/zookeeper-client/zookeeper-client-c/tests/LibCMocks.h
new file mode 100644
index 0000000..5b07cda
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/LibCMocks.h
@@ -0,0 +1,408 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIBCMOCKS_H_
+#define LIBCMOCKS_H_
+
+#include <string>
+#include <vector>
+#include <deque>
+
+#include <errno.h>
+#include <string.h>
+
+#include "MocksBase.h"
+#include "LibCSymTable.h"
+#include "ThreadingUtil.h"
+
+// *****************************************************************************
+// gethostbyname
+
+class Mock_gethostbyname: public Mock
+{
+public:
+    struct HostEntry: public hostent {
+        HostEntry(const char* hostName,short addrtype);
+        ~HostEntry();
+        HostEntry& addAlias(const char* alias);
+        HostEntry& addAddress(const char* addr4);
+    };
+
+    Mock_gethostbyname():current(0){mock_=this;}
+    virtual ~Mock_gethostbyname();
+    HostEntry& addHostEntry(const char* hostName,short addrtype=AF_INET);
+    virtual hostent* call(const char* name);
+
+    typedef std::vector<HostEntry*> HostEntryCollection;
+    HostEntryCollection gethostbynameReturns;
+    int current;
+    static Mock_gethostbyname* mock_;
+};
+
+class MockFailed_gethostbyname: public Mock_gethostbyname
+{
+public:
+    MockFailed_gethostbyname():h_errnoReturn(HOST_NOT_FOUND) {}
+
+    int h_errnoReturn;
+    virtual hostent* call(const char* name) {
+        h_errno=h_errnoReturn;
+        return 0;
+    }
+};
+
+// *****************************************************************************
+// calloc
+
+class Mock_calloc: public Mock
+{
+public:
+    Mock_calloc():errnoOnFailure(ENOMEM),callsBeforeFailure(-1),counter(0) {
+        mock_=this;
+    }
+    virtual ~Mock_calloc() {mock_=0;}
+
+    int errnoOnFailure;
+    int callsBeforeFailure;
+    int counter;
+    virtual void* call(size_t p1, size_t p2);
+
+    static Mock_calloc* mock_;
+};
+
+// *****************************************************************************
+// realloc
+
+class Mock_realloc: public Mock
+{
+public:
+    Mock_realloc():errnoOnFailure(ENOMEM),callsBeforeFailure(-1),counter(0) {
+        mock_=this;
+    }
+    virtual ~Mock_realloc() {mock_=0;}
+
+    int errnoOnFailure;
+    int callsBeforeFailure;
+    int counter;
+    virtual void* call(void* p, size_t s);
+
+    static Mock_realloc* mock_;
+};
+
+// *****************************************************************************
+// random
+
+class Mock_random: public Mock
+{
+public:
+    Mock_random():currentIdx(0) {mock_=this;}
+    virtual ~Mock_random() {mock_=0;}
+
+    int currentIdx;
+    std::vector<int> randomReturns;
+    virtual int call();
+    void setSeed(unsigned long){currentIdx=0;}
+
+    static Mock_random* mock_;
+};
+
+// *****************************************************************************
+// no-op free; keeps track of all deallocation requests
+class Mock_free_noop: public Mock
+{
+    Mutex mx;
+    std::vector<void*> requested;
+public:
+    Mock_free_noop():nested(0),callCounter(0){mock_=this;}
+    virtual ~Mock_free_noop(){
+        mock_=0;
+        freeRequested();
+    }
+    
+    int nested;
+    int callCounter;
+    virtual void call(void* p);
+    void freeRequested();
+    void disable(){mock_=0;}
+    // returns number of times the pointer was freed
+    int getFreeCount(void*);
+    bool isFreed(void*);
+    
+    static Mock_free_noop* mock_;
+};
+
+// *****************************************************************************
+// socket and related system calls
+
+class Mock_socket: public Mock
+{
+public:
+    static const int FD=63;
+    Mock_socket():socketReturns(FD),closeReturns(0),getsocketoptReturns(0),
+        optvalSO_ERROR(0),
+        setsockoptReturns(0),connectReturns(0),connectErrno(0),
+        sendErrno(0),recvErrno(0)
+    {
+        mock_=this;
+    }
+    virtual ~Mock_socket(){mock_=0;}
+
+    int socketReturns;
+    virtual int callSocket(int domain, int type, int protocol){
+        return socketReturns;
+    }
+    int closeReturns;
+    virtual int callClose(int fd){
+        return closeReturns;
+    }
+    int getsocketoptReturns;
+    int optvalSO_ERROR;
+    virtual int callGet(int s,int level,int optname,void *optval,socklen_t *len){
+        if(level==SOL_SOCKET && optname==SO_ERROR){
+            setSO_ERROR(optval,*len);
+        }
+        return getsocketoptReturns;
+    }
+    virtual void setSO_ERROR(void *optval,socklen_t len){
+        memcpy(optval,&optvalSO_ERROR,len);
+    }
+    
+    int setsockoptReturns;
+    virtual int callSet(int s,int level,int optname,const void *optval,socklen_t len){
+        return setsockoptReturns;
+    }
+    int connectReturns;
+    int connectErrno;
+    virtual int callConnect(int s,const struct sockaddr *addr,socklen_t len){
+        errno=connectErrno;
+        return connectReturns;
+    }
+    
+    virtual void notifyBufferSent(const std::string& buffer){}
+    
+    int sendErrno;
+    std::string sendBuffer;
+    virtual ssize_t callSend(int s,const void *buf,size_t len,int flags){
+        if(sendErrno!=0){
+            errno=sendErrno;
+            return -1;
+        }
+        // first call to send() is always the length of the buffer to follow
+        bool sendingLength=sendBuffer.size()==0;
+        // overwrite the length bytes
+        sendBuffer.assign((const char*)buf,len);
+        if(!sendingLength){
+            notifyBufferSent(sendBuffer);
+            sendBuffer.erase();
+        }
+        return len;
+    }
+
+    int recvErrno;
+    std::string recvReturnBuffer;
+    virtual ssize_t callRecv(int s,void *buf,size_t len,int flags){
+        if(recvErrno!=0){
+            errno=recvErrno;
+            return -1;
+        }
+        int k=std::min(len,recvReturnBuffer.length());
+        if(k==0)
+            return 0;
+        memcpy(buf,recvReturnBuffer.data(),k);
+        recvReturnBuffer.erase(0,k);
+        return k;
+    }
+    virtual bool hasMoreRecv() const{
+        return recvReturnBuffer.size()!=0;
+    }
+    static Mock_socket* mock_;
+};
+
+// *****************************************************************************
+// fcntl
+class Mock_fcntl: public Mock
+{
+public:
+    Mock_fcntl():callReturns(0),trapFD(-1){mock_=this;}
+    ~Mock_fcntl(){mock_=0;}
+    
+    int callReturns;
+    int trapFD;
+    virtual int call(int fd, int cmd, void* arg){
+        if(trapFD==-1)
+            return LIBC_SYMBOLS.fcntl(fd,cmd,arg);
+        return callReturns;
+    }
+
+    static Mock_fcntl* mock_;
+};
+
+// *****************************************************************************
+// select
+class Mock_select: public Mock
+{
+public:
+    Mock_select(Mock_socket* s,int fd):sock(s),
+        callReturns(0),myFD(fd),timeout(50)
+    {
+        mock_=this;
+    }
+    ~Mock_select(){mock_=0;}
+    
+    Mock_socket* sock;
+    int callReturns;
+    int myFD;
+    int timeout; //in millis
+    virtual int call(int nfds,fd_set *rfds,fd_set *wfds,fd_set *efds,struct timeval *tv){
+        bool isWritableRequested=(wfds && FD_ISSET(myFD,wfds));
+        if(rfds) FD_CLR(myFD,rfds);
+        if(wfds) FD_CLR(myFD,wfds);
+        // this timeout is only to prevent a tight loop
+        timeval myTimeout={0,0};
+        if(!isWritableRequested && !isFDReadable()){
+            myTimeout.tv_sec=timeout/1000;
+            myTimeout.tv_usec=(timeout%1000)*1000;
+        }
+        LIBC_SYMBOLS.select(nfds,rfds,wfds,efds,&myTimeout);
+        // myFD is always writable
+        if(isWritableRequested) FD_SET(myFD,wfds);
+        // myFD is only readable if the socket has anything to read
+        if(isFDReadable() && rfds) FD_SET(myFD,rfds);
+        return callReturns;
+    }
+
+    virtual bool isFDReadable() const {
+        return sock->hasMoreRecv();
+    }
+    
+    static Mock_select* mock_;
+};
+
+// *****************************************************************************
+// poll
+// the last element of the pollfd array is expected to be test FD
+class Mock_poll: public Mock
+{
+public:
+    Mock_poll(Mock_socket* s,int fd):sock(s),
+        callReturns(1),myFD(fd),timeout(50)
+    {
+        mock_=this;
+    }
+    ~Mock_poll(){mock_=0;}
+    
+    Mock_socket* sock;
+    int callReturns;
+    int myFD;
+    int timeout; //in millis
+    virtual int call(struct pollfd *fds, POLL_NFDS_TYPE nfds, int to) {
+        pollfd* myPoll=0;
+        if(fds[nfds-1].fd==myFD)
+            myPoll=&fds[nfds-1];
+        bool isWritableRequested=false;
+        if(myPoll!=0){
+            isWritableRequested=myPoll->events&POLLOUT;
+            nfds--;
+        }
+        LIBC_SYMBOLS.poll(fds,nfds,(!isWritableRequested&&!isFDReadable())?timeout:0);
+        if(myPoll!=0){
+            // myFD is always writable if requested
+            myPoll->revents=isWritableRequested?POLLOUT:0;
+            // myFD is only readable if the socket has anything to read
+            myPoll->revents|=isFDReadable()?POLLIN:0;
+        }
+        return callReturns;
+    }
+
+    virtual bool isFDReadable() const {
+        return sock->hasMoreRecv();
+    }
+    
+    static Mock_poll* mock_;
+};
+
+// *****************************************************************************
+// gettimeofday
+class Mock_gettimeofday: public Mock
+{
+public:
+    Mock_gettimeofday(){
+        LIBC_SYMBOLS.gettimeofday(&tv,0);
+        mock_=this;
+    }
+    Mock_gettimeofday(const Mock_gettimeofday& other):tv(other.tv){}
+    Mock_gettimeofday(int32_t sec,int32_t usec){
+        tv.tv_sec=sec;
+        tv.tv_usec=usec;
+    }
+    ~Mock_gettimeofday(){mock_=0;}
+    
+    timeval tv;
+    virtual int call(struct timeval *tp, GETTIMEOFDAY_ARG2_TYPE tzp){
+        *tp=tv;
+        return 0;
+    }
+    operator timeval() const{
+        return tv;
+    }
+    // advance secs
+    virtual void tick(int howmuch=1){tv.tv_sec+=howmuch;}
+    // advance milliseconds
+    // can move the clock forward as well as backward by providing a negative
+    // number
+    virtual void millitick(int howmuch=1){
+        int ms=tv.tv_usec/1000+howmuch;
+        tv.tv_sec+=ms/1000;
+        // going backward?
+        if(ms<0){
+            ms=1000-(-ms%1000); //wrap millis around
+        }
+        tv.tv_usec=(ms%1000)*1000;
+    }
+    virtual void tick(const timeval& howmuch){
+        // add milliseconds (discarding microsecond portion)
+        long ms=tv.tv_usec/1000+howmuch.tv_usec/1000;
+        tv.tv_sec+=howmuch.tv_sec+ms/1000;
+        tv.tv_usec=(ms%1000)*1000;
+    }
+    static Mock_gettimeofday* mock_;
+};
+
+// discard microseconds!
+inline bool operator==(const timeval& lhs, const timeval& rhs){
+    return rhs.tv_sec==lhs.tv_sec && rhs.tv_usec/1000==lhs.tv_usec/1000;
+}
+
+// simplistic implementation: no normalization, assume lhs >= rhs,
+// discarding microseconds
+inline timeval operator-(const timeval& lhs, const timeval& rhs){
+    timeval res;
+    res.tv_sec=lhs.tv_sec-rhs.tv_sec;
+    res.tv_usec=(lhs.tv_usec/1000-rhs.tv_usec/1000)*1000;
+    if(res.tv_usec<0){
+        res.tv_sec--;
+        res.tv_usec=1000000+res.tv_usec%1000000; // wrap the millis around
+    }
+    return res;
+}
+
+inline int32_t toMilliseconds(const timeval& tv){
+    return tv.tv_sec*1000+tv.tv_usec/1000;    
+}
+
+#endif /*LIBCMOCKS_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/LibCSymTable.cc
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/LibCSymTable.cc b/zookeeper-client/zookeeper-client-c/tests/LibCSymTable.cc
new file mode 100644
index 0000000..5378579
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/LibCSymTable.cc
@@ -0,0 +1,83 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "LibCSymTable.h" 
+
+#define LOAD_SYM(sym) \
+    sym=(sym##_sig)dlsym(handle,#sym); \
+    assert("Unable to load "#sym" from libc"&&sym)      
+    
+
+LibCSymTable& LibCSymTable::instance(){
+    static LibCSymTable tbl;
+    return tbl;
+}
+
+//******************************************************************************
+// preload original libc symbols
+LibCSymTable::LibCSymTable()
+{
+    void* handle=getHandle();
+    LOAD_SYM(gethostbyname);
+    LOAD_SYM(calloc);
+    LOAD_SYM(realloc);
+    LOAD_SYM(free);
+    LOAD_SYM(random);
+    LOAD_SYM(srandom);
+    LOAD_SYM(printf);
+    LOAD_SYM(socket);
+    LOAD_SYM(close);
+    LOAD_SYM(getsockopt);
+    LOAD_SYM(setsockopt);
+    LOAD_SYM(fcntl);
+    LOAD_SYM(connect);
+    LOAD_SYM(send);
+    LOAD_SYM(recv);
+    LOAD_SYM(select);
+    LOAD_SYM(poll);
+    LOAD_SYM(gettimeofday);
+#ifdef THREADED
+    LOAD_SYM(pthread_create);
+    LOAD_SYM(pthread_detach);
+    LOAD_SYM(pthread_cond_broadcast);
+    LOAD_SYM(pthread_cond_destroy);
+    LOAD_SYM(pthread_cond_init);
+    LOAD_SYM(pthread_cond_signal);
+    LOAD_SYM(pthread_cond_timedwait);
+    LOAD_SYM(pthread_cond_wait);
+    LOAD_SYM(pthread_join);
+    LOAD_SYM(pthread_mutex_destroy);
+    LOAD_SYM(pthread_mutex_init);
+    LOAD_SYM(pthread_mutex_lock);
+    LOAD_SYM(pthread_mutex_trylock);
+    LOAD_SYM(pthread_mutex_unlock);
+#endif
+}
+
+void* LibCSymTable::getHandle(){
+    static void* handle=0;
+    if(!handle){
+#ifdef __CYGWIN__
+        handle=dlopen("cygwin1.dll",RTLD_LAZY);
+        assert("Unable to dlopen global sym table"&&handle);
+#else
+        handle=RTLD_NEXT;
+#endif
+    }
+    return handle;
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/LibCSymTable.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/LibCSymTable.h b/zookeeper-client/zookeeper-client-c/tests/LibCSymTable.h
new file mode 100644
index 0000000..2f7e0c2
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/LibCSymTable.h
@@ -0,0 +1,107 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIBCSYMTABLE_H_
+#define LIBCSYMTABLE_H_
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stddef.h>
+#include <dlfcn.h>
+#include <cassert>
+#include <poll.h>
+
+#ifdef THREADED
+#include <pthread.h>
+#endif
+
+#include "config.h"
+
+// TODO: move all these macros to config.h (generated by autoconf) 
+#ifdef __CYGWIN__
+#if (CYGWIN_VERSION_DLL_MAJOR < 1007)
+#define RANDOM_RET_TYPE int
+#else
+#define RANDOM_RET_TYPE long int
+#endif
+#define GETTIMEOFDAY_ARG2_TYPE void*
+#else
+#define RANDOM_RET_TYPE long int
+#define GETTIMEOFDAY_ARG2_TYPE struct timezone*
+#endif
+
+#define DECLARE_SYM(ret,sym,sig) \
+    typedef ret (*sym##_sig)sig; \
+    static sym##_sig preload_##sym () { \
+        static sym##_sig ptr=0;\
+        if(!ptr){ void* h=getHandle(); ptr=(sym##_sig)dlsym(h,#sym); } \
+        assert("Unable to load "#sym" from libc"&&ptr); \
+        return ptr; \
+    } \
+    sym##_sig sym
+
+#define LIBC_SYMBOLS LibCSymTable::instance()
+
+//******************************************************************************
+// preload original libc symbols
+struct LibCSymTable
+{
+    DECLARE_SYM(hostent*,gethostbyname,(const char*));
+    DECLARE_SYM(void*,calloc,(size_t, size_t));
+    DECLARE_SYM(void*,realloc,(void*, size_t));
+    DECLARE_SYM(void,free,(void*));
+    DECLARE_SYM(RANDOM_RET_TYPE,random,(void));
+    DECLARE_SYM(void,srandom,(unsigned long));
+    DECLARE_SYM(int,printf,(const char*, ...));
+    DECLARE_SYM(int,socket,(int,int,int));
+    DECLARE_SYM(int,close,(int));
+    DECLARE_SYM(int,getsockopt,(int,int,int,void*,socklen_t*));
+    DECLARE_SYM(int,setsockopt,(int,int,int,const void*,socklen_t));
+    DECLARE_SYM(int,fcntl,(int,int,...));
+    DECLARE_SYM(int,connect,(int,const struct sockaddr*,socklen_t));
+    DECLARE_SYM(ssize_t,send,(int,const void*,size_t,int));
+    DECLARE_SYM(ssize_t,recv,(int,const void*,size_t,int));
+    DECLARE_SYM(int,select,(int,fd_set*,fd_set*,fd_set*,struct timeval*));
+    DECLARE_SYM(int,poll,(struct pollfd*,POLL_NFDS_TYPE,int));
+    DECLARE_SYM(int,gettimeofday,(struct timeval*,GETTIMEOFDAY_ARG2_TYPE));
+#ifdef THREADED
+    DECLARE_SYM(int,pthread_create,(pthread_t *, const pthread_attr_t *,
+                void *(*)(void *), void *));
+    DECLARE_SYM(int,pthread_detach,(pthread_t));
+    DECLARE_SYM(int,pthread_cond_broadcast,(pthread_cond_t *));
+    DECLARE_SYM(int,pthread_cond_destroy,(pthread_cond_t *));
+    DECLARE_SYM(int,pthread_cond_init,(pthread_cond_t *, const pthread_condattr_t *));
+    DECLARE_SYM(int,pthread_cond_signal,(pthread_cond_t *));
+    DECLARE_SYM(int,pthread_cond_timedwait,(pthread_cond_t *,
+                    pthread_mutex_t *, const struct timespec *));
+    DECLARE_SYM(int,pthread_cond_wait,(pthread_cond_t *, pthread_mutex_t *));
+    DECLARE_SYM(int,pthread_join,(pthread_t, void **));
+    DECLARE_SYM(int,pthread_mutex_destroy,(pthread_mutex_t *));
+    DECLARE_SYM(int,pthread_mutex_init,(pthread_mutex_t *, const pthread_mutexattr_t *));
+    DECLARE_SYM(int,pthread_mutex_lock,(pthread_mutex_t *));
+    DECLARE_SYM(int,pthread_mutex_trylock,(pthread_mutex_t *));
+    DECLARE_SYM(int,pthread_mutex_unlock,(pthread_mutex_t *));
+#endif
+    LibCSymTable();
+    
+    static void* getHandle();
+    static LibCSymTable& instance();
+};
+
+#endif /*LIBCSYMTABLE_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/MocksBase.cc
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/MocksBase.cc b/zookeeper-client/zookeeper-client-c/tests/MocksBase.cc
new file mode 100644
index 0000000..60b2c75
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/MocksBase.cc
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstdlib>
+#include <new>
+
+#include "MocksBase.h"
+#include "LibCSymTable.h"
+
+// *****************************************************************************
+// Mock base
+void* Mock::operator new(std::size_t s){
+    void* p=malloc(s);
+    if(!p)
+        throw std::bad_alloc();
+    return p;
+}
+
+void Mock::operator delete(void* p){
+    LIBC_SYMBOLS.free(p);
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/MocksBase.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/MocksBase.h b/zookeeper-client/zookeeper-client-c/tests/MocksBase.h
new file mode 100644
index 0000000..5b54251
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/MocksBase.h
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOCKSBASE_H_
+#define MOCKSBASE_H_
+
+#include <cstddef>
+
+// *****************************************************************************
+// Mock base
+
+class Mock
+{
+public:
+    virtual ~Mock(){}
+
+    static void* operator new(std::size_t s);
+    static void operator delete(void* p);
+};
+
+#endif /*MOCKSBASE_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/PthreadMocks.cc
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/PthreadMocks.cc b/zookeeper-client/zookeeper-client-c/tests/PthreadMocks.cc
new file mode 100644
index 0000000..490cebf
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/PthreadMocks.cc
@@ -0,0 +1,106 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "PthreadMocks.h"
+
+MockPthreadsBase* MockPthreadsBase::mock_=0;
+
+#undef USING_DUMA
+
+#ifndef USING_DUMA
+int pthread_cond_broadcast (pthread_cond_t *c){
+    if(!MockPthreadsBase::mock_)
+        return LIBC_SYMBOLS.pthread_cond_broadcast(c);
+    return MockPthreadsBase::mock_->pthread_cond_broadcast(c);
+}
+int pthread_cond_destroy (pthread_cond_t *c){
+    if(!MockPthreadsBase::mock_)
+        return LIBC_SYMBOLS.pthread_cond_destroy(c);
+    return MockPthreadsBase::mock_->pthread_cond_destroy(c);
+}
+int pthread_cond_init (pthread_cond_t *c, const pthread_condattr_t *a){
+    if(!MockPthreadsBase::mock_)
+        return LIBC_SYMBOLS.pthread_cond_init(c,a);
+    return MockPthreadsBase::mock_->pthread_cond_init(c,a);
+}
+int pthread_cond_signal (pthread_cond_t *c){
+    if(!MockPthreadsBase::mock_)
+        return LIBC_SYMBOLS.pthread_cond_signal(c);
+    return MockPthreadsBase::mock_->pthread_cond_signal(c);
+}
+int pthread_cond_timedwait (pthread_cond_t *c,
+                pthread_mutex_t *m, const struct timespec *t){
+    if(!MockPthreadsBase::mock_)
+        return LIBC_SYMBOLS.pthread_cond_timedwait(c,m,t);
+    return MockPthreadsBase::mock_->pthread_cond_timedwait(c,m,t);
+}
+int pthread_cond_wait (pthread_cond_t *c, pthread_mutex_t *m){
+    if(!MockPthreadsBase::mock_)
+        return LIBC_SYMBOLS.pthread_cond_wait(c,m);
+    return MockPthreadsBase::mock_->pthread_cond_wait(c,m);
+}
+int pthread_create (pthread_t *t, const pthread_attr_t *a,
+            void *(*f)(void *), void *d){
+    if(!MockPthreadsBase::mock_)
+        return LIBC_SYMBOLS.pthread_create(t,a,f,d);
+    return MockPthreadsBase::mock_->pthread_create(t,a,f,d);
+}
+int pthread_detach(pthread_t t){
+    if(!MockPthreadsBase::mock_)
+        return LIBC_SYMBOLS.pthread_detach(t);
+    return MockPthreadsBase::mock_->pthread_detach(t);    
+}
+int pthread_join (pthread_t t, void **r){
+    if(!MockPthreadsBase::mock_)
+        return LIBC_SYMBOLS.pthread_join(t,r);
+    return MockPthreadsBase::mock_->pthread_join(t,r);
+}
+int pthread_mutex_destroy (pthread_mutex_t *m){
+    if(!MockPthreadsBase::mock_)
+        return LIBC_SYMBOLS.pthread_mutex_destroy(m);
+    return MockPthreadsBase::mock_->pthread_mutex_destroy(m);
+}
+int pthread_mutex_init (pthread_mutex_t *m, const pthread_mutexattr_t *a){
+    if(!MockPthreadsBase::mock_)
+        return LIBC_SYMBOLS.pthread_mutex_init(m,a);
+    return MockPthreadsBase::mock_->pthread_mutex_init(m,a);
+}
+
+DECLARE_WRAPPER(int,pthread_mutex_lock,(pthread_mutex_t *m)){
+    if(!MockPthreadsBase::mock_)
+        return CALL_REAL(pthread_mutex_lock,(m));
+    return MockPthreadsBase::mock_->pthread_mutex_lock(m);
+}
+
+int pthread_mutex_trylock (pthread_mutex_t *m){
+    if(!MockPthreadsBase::mock_)
+        return LIBC_SYMBOLS.pthread_mutex_trylock(m);
+    return MockPthreadsBase::mock_->pthread_mutex_trylock(m);
+}
+
+DECLARE_WRAPPER(int,pthread_mutex_unlock,(pthread_mutex_t *m)){
+    if(!MockPthreadsBase::mock_)
+        return CALL_REAL(pthread_mutex_unlock,(m));
+    return MockPthreadsBase::mock_->pthread_mutex_unlock(m);
+}
+#endif
+
+CheckedPthread::ThreadMap CheckedPthread::tmap_;
+CheckedPthread::MutexMap CheckedPthread::mmap_;
+CheckedPthread::CVMap CheckedPthread::cvmap_;
+Mutex CheckedPthread::mx;

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/PthreadMocks.h
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/PthreadMocks.h b/zookeeper-client/zookeeper-client-c/tests/PthreadMocks.h
new file mode 100644
index 0000000..8db8815
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/PthreadMocks.h
@@ -0,0 +1,449 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PTHREADMOCKS_H_
+#define PTHREADMOCKS_H_
+
+#include <pthread.h>
+#include <string.h>
+#include <errno.h>
+
+#include "src/zk_adaptor.h"
+
+#include "Util.h"
+#include "MocksBase.h"
+#include "LibCSymTable.h"
+#include "ThreadingUtil.h"
+
+// an ABC for pthreads
+class MockPthreadsBase: public Mock
+{
+public:
+    MockPthreadsBase(){mock_=this;}
+    virtual ~MockPthreadsBase(){mock_=0;}
+    
+    virtual int pthread_create(pthread_t * t, const pthread_attr_t *a,
+            void *(*f)(void *), void *d) =0;
+    virtual int pthread_join(pthread_t t, void ** r) =0;
+    virtual int pthread_detach(pthread_t t) =0;
+    virtual int pthread_cond_broadcast(pthread_cond_t *c) =0;
+    virtual int pthread_cond_destroy(pthread_cond_t *c) =0;
+    virtual int pthread_cond_init(pthread_cond_t *c, const pthread_condattr_t *a) =0;
+    virtual int pthread_cond_signal(pthread_cond_t *c) =0;
+    virtual int pthread_cond_timedwait(pthread_cond_t *c,
+            pthread_mutex_t *m, const struct timespec *t) =0;
+    virtual int pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m) =0;
+    virtual int pthread_mutex_destroy(pthread_mutex_t *m) =0;
+    virtual int pthread_mutex_init(pthread_mutex_t *m, const pthread_mutexattr_t *a) =0;
+    virtual int pthread_mutex_lock(pthread_mutex_t *m) =0;
+    virtual int pthread_mutex_trylock(pthread_mutex_t *m) =0;
+    virtual int pthread_mutex_unlock(pthread_mutex_t *m) =0;
+    
+    static MockPthreadsBase* mock_;
+};
+
+// all pthread functions simply return an error code
+// and increment their invocation counter. No actual threads are spawned.
+class MockPthreadsNull: public MockPthreadsBase
+{
+public:
+    MockPthreadsNull():
+    pthread_createReturns(0),pthread_createCounter(0),
+    pthread_joinReturns(0),pthread_joinCounter(0),pthread_joinResultReturn(0),
+    pthread_detachReturns(0),pthread_detachCounter(0),
+    pthread_cond_broadcastReturns(0),pthread_cond_broadcastCounter(0),
+    pthread_cond_destroyReturns(0),pthread_cond_destroyCounter(0),
+    pthread_cond_initReturns(0),pthread_cond_initCounter(0),
+    pthread_cond_signalReturns(0),pthread_cond_signalCounter(0),
+    pthread_cond_timedwaitReturns(0),pthread_cond_timedwaitCounter(0),
+    pthread_cond_waitReturns(0),pthread_cond_waitCounter(0),
+    pthread_mutex_destroyReturns(0),pthread_mutex_destroyCounter(0),
+    pthread_mutex_initReturns(0),pthread_mutex_initCounter(0),
+    pthread_mutex_lockReturns(0),pthread_mutex_lockCounter(0),
+    pthread_mutex_trylockReturns(0),pthread_mutex_trylockCounter(0),
+    pthread_mutex_unlockReturns(0),pthread_mutex_unlockCounter(0)
+    {
+        memset(threads,0,sizeof(threads));
+    }
+    
+    short threads[512];
+    
+    int pthread_createReturns;
+    int pthread_createCounter;
+    virtual int pthread_create(pthread_t * t, const pthread_attr_t *a,
+            void *(*f)(void *), void *d){
+        char* p=(char*)&threads[pthread_createCounter++];
+        p[0]='i'; // mark as created
+        *t=(pthread_t)p;
+        return pthread_createReturns; 
+    }
+    int pthread_joinReturns;
+    int pthread_joinCounter;
+    void* pthread_joinResultReturn;
+    virtual int pthread_join(pthread_t t, void ** r){
+        pthread_joinCounter++;
+        if(r!=0)
+            *r=pthread_joinResultReturn;
+        char* p=(char*)t;
+        p[0]='x';p[1]+=1;
+        return pthread_joinReturns; 
+    }
+    int pthread_detachReturns;
+    int pthread_detachCounter;        
+    virtual int pthread_detach(pthread_t t){
+        pthread_detachCounter++;
+        char* p=(char*)t;
+        p[0]='x';p[1]+=1;        
+        return pthread_detachReturns;
+    }
+
+    template<class T>
+    static bool isInitialized(const T& t){
+        return ((char*)t)[0]=='i';
+    }
+    template<class T>
+    static bool isDestroyed(const T& t){
+        return ((char*)t)[0]=='x';
+    }
+    template<class T>
+    static int getDestroyCounter(const T& t){
+        return ((char*)t)[1];
+    }
+    template<class T>
+    static int getInvalidAccessCounter(const T& t){
+        return ((char*)t)[2];
+    }
+    int pthread_cond_broadcastReturns;
+    int pthread_cond_broadcastCounter;
+    virtual int pthread_cond_broadcast(pthread_cond_t *c){
+        pthread_cond_broadcastCounter++;
+        if(isDestroyed(c))((char*)c)[2]++;
+        return pthread_cond_broadcastReturns; 
+    }
+    int pthread_cond_destroyReturns;
+    int pthread_cond_destroyCounter;
+    virtual int pthread_cond_destroy(pthread_cond_t *c){
+        pthread_cond_destroyCounter++;
+        char* p=(char*)c;
+        p[0]='x';p[1]+=1;
+        return pthread_cond_destroyReturns; 
+    }
+    int pthread_cond_initReturns;
+    int pthread_cond_initCounter;
+    virtual int pthread_cond_init(pthread_cond_t *c, const pthread_condattr_t *a){
+        pthread_cond_initCounter++;
+        char* p=(char*)c;
+        p[0]='i'; // mark as created
+        p[1]=0;   // destruction counter
+        p[2]=0;   // access after destruction counter
+        return pthread_cond_initReturns; 
+    }
+    int pthread_cond_signalReturns;
+    int pthread_cond_signalCounter;
+    virtual int pthread_cond_signal(pthread_cond_t *c){
+        pthread_cond_signalCounter++;
+        if(isDestroyed(c))((char*)c)[2]++;
+        return pthread_cond_signalReturns; 
+    }
+    int pthread_cond_timedwaitReturns;
+    int pthread_cond_timedwaitCounter;
+    virtual int pthread_cond_timedwait(pthread_cond_t *c,
+            pthread_mutex_t *m, const struct timespec *t){
+        pthread_cond_timedwaitCounter++;
+        if(isDestroyed(c))((char*)c)[2]++;
+        return pthread_cond_timedwaitReturns; 
+    }
+    int pthread_cond_waitReturns;
+    int pthread_cond_waitCounter;
+    virtual int pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m){
+        pthread_cond_waitCounter++;
+        if(isDestroyed(c))((char*)c)[2]++;
+        return pthread_cond_waitReturns; 
+    }
+    int pthread_mutex_destroyReturns;
+    int pthread_mutex_destroyCounter;
+    virtual int pthread_mutex_destroy(pthread_mutex_t *m){
+        pthread_mutex_destroyCounter++;
+        char* p=(char*)m;
+        p[0]='x';p[1]+=1;
+        return pthread_mutex_destroyReturns; 
+    }
+    int pthread_mutex_initReturns;
+    int pthread_mutex_initCounter;
+    virtual int pthread_mutex_init(pthread_mutex_t *m, const pthread_mutexattr_t *a){
+        pthread_mutex_initCounter++;
+        char* p=(char*)m;
+        p[0]='i'; // mark as created
+        p[1]=0;   // destruction counter
+        p[2]=0;   // access after destruction counter
+        return pthread_mutex_initReturns; 
+    }
+    int pthread_mutex_lockReturns;
+    int pthread_mutex_lockCounter;
+    virtual int pthread_mutex_lock(pthread_mutex_t *m){
+        pthread_mutex_lockCounter++;
+        if(isDestroyed(m))((char*)m)[2]++;
+        return pthread_mutex_lockReturns; 
+    }
+    int pthread_mutex_trylockReturns;
+    int pthread_mutex_trylockCounter;
+    virtual int pthread_mutex_trylock(pthread_mutex_t *m){
+        pthread_mutex_trylockCounter++;
+        if(isDestroyed(m))((char*)m)[2]++;
+        return pthread_mutex_trylockReturns; 
+    }
+    int pthread_mutex_unlockReturns;
+    int pthread_mutex_unlockCounter;
+    virtual int pthread_mutex_unlock(pthread_mutex_t *m){
+        pthread_mutex_unlockCounter++;
+        if(isDestroyed(m))((char*)m)[2]++;
+        return pthread_mutex_unlockReturns; 
+    }
+};
+
+// simulates the way zookeeper threads make use of api_prolog/epilog and
+// 
+class MockPthreadZKNull: public MockPthreadsNull
+{
+    typedef std::map<pthread_t,zhandle_t*> Map;
+    Map map_;
+public:
+    virtual int pthread_create(pthread_t * t, const pthread_attr_t *a,
+            void *(*f)(void *), void *d){
+        int ret=MockPthreadsNull::pthread_create(t,a,f,d);
+        zhandle_t* zh=(zhandle_t*)d;
+        adaptor_threads* ad=(adaptor_threads*)zh->adaptor_priv;
+        api_prolog(zh);
+        ad->threadsToWait--;
+        putValue(map_,*t,zh);
+        return ret;
+    }
+    virtual int pthread_join(pthread_t t, void ** r){
+        zhandle_t* zh=0;
+        if(getValue(map_,t,zh))
+            api_epilog(zh,0);
+        return MockPthreadsNull::pthread_join(t,r);
+    }
+};
+
+struct ThreadInfo{
+    typedef enum {RUNNING,TERMINATED} ThreadState;
+    
+    ThreadInfo():
+        destructionCounter_(0),invalidAccessCounter_(0),state_(RUNNING)
+    {
+    }
+    
+    ThreadInfo& incDestroyed() {
+        destructionCounter_++;
+        return *this;
+    }
+    ThreadInfo& incInvalidAccess(){
+        invalidAccessCounter_++;
+        return *this;
+    }
+    ThreadInfo& setTerminated(){
+        state_=TERMINATED;
+        return *this;
+    }
+    int destructionCounter_;
+    int invalidAccessCounter_;
+    ThreadState state_;
+};
+
+class CheckedPthread: public MockPthreadsBase
+{
+    // first => destruction counter
+    // second => invalid access counter
+    //typedef std::pair<int,int> Entry;
+    typedef ThreadInfo Entry;
+    typedef std::map<pthread_t,Entry> ThreadMap;
+    static ThreadMap tmap_;
+    static ThreadMap& getMap(const TypeOp<pthread_t>::BareT&){return tmap_;}
+    typedef std::map<pthread_mutex_t*,Entry> MutexMap;
+    static MutexMap mmap_;
+    static MutexMap& getMap(const TypeOp<pthread_mutex_t>::BareT&){return mmap_;}
+    typedef std::map<pthread_cond_t*,Entry> CVMap;
+    static CVMap cvmap_;
+    static CVMap& getMap(const TypeOp<pthread_cond_t>::BareT&){return cvmap_;}
+    
+    static Mutex mx;
+    
+    template<class T>
+    static void markDestroyed(T& t){
+        typedef typename TypeOp<T>::BareT Type;
+        Entry e;
+        synchronized(mx);
+        if(getValue(getMap(Type()),t,e)){
+            putValue(getMap(Type()),t,Entry(e).incDestroyed());
+        }else{
+            putValue(getMap(Type()),t,Entry().incDestroyed());
+        }
+    }
+    template<class T>
+    static void markCreated(T& t){
+        typedef typename TypeOp<T>::BareT Type;
+        Entry e;
+        synchronized(mx);
+        if(!getValue(getMap(Type()),t,e))
+            putValue(getMap(Type()),t,Entry());
+    }
+    template<class T>
+    static void checkAccessed(T& t){
+        typedef typename TypeOp<T>::BareT Type;
+        Entry e;
+        synchronized(mx);
+        if(getValue(getMap(Type()),t,e) && e.destructionCounter_>0)
+            putValue(getMap(Type()),t,Entry(e).incInvalidAccess());
+    }
+    static void setTerminated(pthread_t t){
+        Entry e;
+        synchronized(mx);
+        if(getValue(tmap_,t,e))
+            putValue(tmap_,t,Entry(e).setTerminated());
+    }
+public:
+    bool verbose;
+    CheckedPthread():verbose(false){
+        tmap_.clear();
+        mmap_.clear();
+        cvmap_.clear();
+        mx.release();
+    }
+    template <class T>
+    static bool isInitialized(const T& t){
+        typedef typename TypeOp<T>::BareT Type;
+        Entry e;
+        synchronized(mx);
+        return getValue(getMap(Type()),t,e) && e.destructionCounter_==0;
+    }
+    template <class T>
+    static bool isDestroyed(const T& t){
+        typedef typename TypeOp<T>::BareT Type;
+        Entry e;
+        synchronized(mx);
+        return getValue(getMap(Type()),t,e) && e.destructionCounter_>0;
+    }
+    static bool isTerminated(pthread_t t){
+        Entry e;
+        synchronized(mx);
+        return getValue(tmap_,t,e) && e.state_==ThreadInfo::TERMINATED;        
+    }
+    template <class T>
+    static int getDestroyCounter(const T& t){
+        typedef typename TypeOp<T>::BareT Type;
+        Entry e;
+        synchronized(mx);
+        return getValue(getMap(Type()),t,e)?e.destructionCounter_:-1;
+    }
+    template<class T>
+    static int getInvalidAccessCounter(const T& t){
+        typedef typename TypeOp<T>::BareT Type;
+        Entry e;
+        synchronized(mx);
+        return getValue(getMap(Type()),t,e)?e.invalidAccessCounter_:-1;
+    }
+
+    struct ThreadContext{
+        typedef void *(*ThreadFunc)(void *);
+        
+        ThreadContext(ThreadFunc func,void* param):func_(func),param_(param){}
+        ThreadFunc func_;
+        void* param_;        
+    };
+    static void* threadFuncWrapper(void* v){
+        ThreadContext* ctx=(ThreadContext*)v;
+        pthread_t t=pthread_self();
+        markCreated(t);
+        void* res=ctx->func_(ctx->param_);
+        setTerminated(pthread_self());
+        delete ctx;
+        return res;
+    }
+    virtual int pthread_create(pthread_t * t, const pthread_attr_t *a,
+            void *(*f)(void *), void *d)
+    {
+        int ret=LIBC_SYMBOLS.pthread_create(t,a,threadFuncWrapper,
+                new ThreadContext(f,d));
+        if(verbose)
+            TEST_TRACE(("thread created %p",*t));
+        return ret;
+    }
+    virtual int pthread_join(pthread_t t, void ** r){
+        if(verbose) TEST_TRACE(("thread joined %p",t));
+        int ret=LIBC_SYMBOLS.pthread_join(t,r);
+        if(ret==0)
+            markDestroyed(t);
+        return ret;
+    }
+    virtual int pthread_detach(pthread_t t){
+        if(verbose) TEST_TRACE(("thread detached %p",t));
+        int ret=LIBC_SYMBOLS.pthread_detach(t);
+        if(ret==0)
+            markDestroyed(t);
+        return ret;
+    }
+    virtual int pthread_cond_broadcast(pthread_cond_t *c){
+        checkAccessed(c);
+        return LIBC_SYMBOLS.pthread_cond_broadcast(c);
+    }
+    virtual int pthread_cond_destroy(pthread_cond_t *c){
+        markDestroyed(c);
+        return LIBC_SYMBOLS.pthread_cond_destroy(c);
+    }
+    virtual int pthread_cond_init(pthread_cond_t *c, const pthread_condattr_t *a){
+        markCreated(c);
+        return LIBC_SYMBOLS.pthread_cond_init(c,a);
+    }
+    virtual int pthread_cond_signal(pthread_cond_t *c){
+        checkAccessed(c);
+        return LIBC_SYMBOLS.pthread_cond_signal(c);
+    }
+    virtual int pthread_cond_timedwait(pthread_cond_t *c,
+            pthread_mutex_t *m, const struct timespec *t){
+        checkAccessed(c);
+        return LIBC_SYMBOLS.pthread_cond_timedwait(c,m,t);
+    }
+    virtual int pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m){
+        checkAccessed(c);
+        return LIBC_SYMBOLS.pthread_cond_wait(c,m);
+    }
+    virtual int pthread_mutex_destroy(pthread_mutex_t *m){
+        markDestroyed(m);
+        return LIBC_SYMBOLS.pthread_mutex_destroy(m);
+    }
+    virtual int pthread_mutex_init(pthread_mutex_t *m, const pthread_mutexattr_t *a){
+        markCreated(m);
+        return LIBC_SYMBOLS.pthread_mutex_init(m,a);
+    }
+    virtual int pthread_mutex_lock(pthread_mutex_t *m){
+        checkAccessed(m);
+        return LIBC_SYMBOLS.pthread_mutex_lock(m);
+    }
+    virtual int pthread_mutex_trylock(pthread_mutex_t *m){
+        checkAccessed(m);
+        return LIBC_SYMBOLS.pthread_mutex_trylock(m);
+    }
+    virtual int pthread_mutex_unlock(pthread_mutex_t *m){
+        checkAccessed(m);
+        return LIBC_SYMBOLS.pthread_mutex_unlock(m);
+    }    
+};
+
+#endif /*PTHREADMOCKS_H_*/
+


[02/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/TestOperations.cc
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/TestOperations.cc b/zookeeper-client/zookeeper-client-c/tests/TestOperations.cc
new file mode 100644
index 0000000..27d9270
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/TestOperations.cc
@@ -0,0 +1,710 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "CppAssertHelper.h"
+
+#include "ZKMocks.h"
+#include <proto.h>
+
+using namespace std;
+
+class Zookeeper_operations : public CPPUNIT_NS::TestFixture
+{
+    CPPUNIT_TEST_SUITE(Zookeeper_operations);
+#ifndef THREADED
+    CPPUNIT_TEST(testPing);
+    CPPUNIT_TEST(testUnsolicitedPing);
+    CPPUNIT_TEST(testTimeoutCausedByWatches1);
+    CPPUNIT_TEST(testTimeoutCausedByWatches2);
+#else    
+    CPPUNIT_TEST(testAsyncWatcher1);
+    CPPUNIT_TEST(testAsyncGetOperation);
+#endif
+    CPPUNIT_TEST(testOperationsAndDisconnectConcurrently1);
+    CPPUNIT_TEST(testOperationsAndDisconnectConcurrently2);
+    CPPUNIT_TEST(testConcurrentOperations1);
+    CPPUNIT_TEST_SUITE_END();
+    zhandle_t *zh;
+    FILE *logfile;
+
+    static void watcher(zhandle_t *, int, int, const char *,void*){}
+public: 
+    Zookeeper_operations() {
+      logfile = openlogfile("Zookeeper_operations");
+    }
+
+    ~Zookeeper_operations() {
+      if (logfile) {
+        fflush(logfile);
+        fclose(logfile);
+        logfile = 0;
+      }
+    }
+
+    void setUp()
+    {
+        zoo_set_log_stream(logfile);
+
+        zoo_deterministic_conn_order(0);
+        zh=0;
+    }
+    
+    void tearDown()
+    {
+        zookeeper_close(zh);
+    }
+
+    class AsyncGetOperationCompletion: public AsyncCompletion{
+    public:
+        AsyncGetOperationCompletion():called_(false),rc_(ZAPIERROR){}
+        virtual void dataCompl(int rc, const char *value, int len, const Stat *stat){
+            synchronized(mx_);
+            called_=true;
+            rc_=rc;
+            value_.erase();
+            if(rc!=ZOK) return;
+            value_.assign(value,len);
+            if(stat)
+                stat_=*stat;
+        }
+        bool operator()()const{
+            synchronized(mx_);
+            return called_;
+        }
+        mutable Mutex mx_;
+        bool called_;
+        int rc_;
+        string value_;
+        NodeStat stat_;
+    };
+#ifndef THREADED
+    // send two get data requests; verify that the corresponding completions called
+    void testConcurrentOperations1()
+    {
+        Mock_gettimeofday timeMock;
+        ZookeeperServer zkServer;
+        // must call zookeeper_close() while all the mocks are in scope
+        CloseFinally guard(&zh);
+        
+        zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // simulate connected state
+        forceConnected(zh);
+        
+        int fd=0;
+        int interest=0;
+        timeval tv;
+        // first operation
+        AsyncGetOperationCompletion res1;
+        zkServer.addOperationResponse(new ZooGetResponse("1",1));
+        int rc=zoo_aget(zh,"/x/y/1",0,asyncCompletion,&res1);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // second operation
+        AsyncGetOperationCompletion res2;
+        zkServer.addOperationResponse(new ZooGetResponse("2",1));
+        rc=zoo_aget(zh,"/x/y/2",0,asyncCompletion,&res2);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // process the send queue
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        while((rc=zookeeper_process(zh,interest))==ZOK) {
+          millisleep(100);
+          //printf("%d\n", rc);
+        }
+        //printf("RC = %d", rc);
+        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
+
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,res1.rc_);
+        CPPUNIT_ASSERT_EQUAL(string("1"),res1.value_);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,res2.rc_);
+        CPPUNIT_ASSERT_EQUAL(string("2"),res2.value_);
+    }
+    // send two getData requests and disconnect while the second request is
+    // outstanding;
+    // verify the completions are called
+    void testOperationsAndDisconnectConcurrently1()
+    {
+        Mock_gettimeofday timeMock;
+        ZookeeperServer zkServer;
+        // must call zookeeper_close() while all the mocks are in scope
+        CloseFinally guard(&zh);
+        
+        zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // simulate connected state
+        forceConnected(zh);
+        
+        int fd=0;
+        int interest=0;
+        timeval tv;
+        // first operation
+        AsyncGetOperationCompletion res1;
+        zkServer.addOperationResponse(new ZooGetResponse("1",1));
+        int rc=zoo_aget(zh,"/x/y/1",0,asyncCompletion,&res1);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // second operation
+        AsyncGetOperationCompletion res2;
+        zkServer.addOperationResponse(new ZooGetResponse("2",1));
+        rc=zoo_aget(zh,"/x/y/2",0,asyncCompletion,&res2);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // process the send queue
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // simulate a disconnect
+        zkServer.setConnectionLost();
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZCONNECTIONLOSS,rc);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,res1.rc_);
+        CPPUNIT_ASSERT_EQUAL(string("1"),res1.value_);
+        CPPUNIT_ASSERT_EQUAL((int)ZCONNECTIONLOSS,res2.rc_);
+        CPPUNIT_ASSERT_EQUAL(string(""),res2.value_);
+    }
+    // send two getData requests and simulate timeout while the both request
+    // are pending;
+    // verify the completions are called
+    void testOperationsAndDisconnectConcurrently2()
+    {
+        Mock_gettimeofday timeMock;
+        ZookeeperServer zkServer;
+        // must call zookeeper_close() while all the mocks are in scope
+        CloseFinally guard(&zh);
+        
+        zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // simulate connected state
+        forceConnected(zh);
+        
+        int fd=0;
+        int interest=0;
+        timeval tv;
+        // first operation
+        AsyncGetOperationCompletion res1;
+        zkServer.addOperationResponse(new ZooGetResponse("1",1));
+        int rc=zoo_aget(zh,"/x/y/1",0,asyncCompletion,&res1);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // second operation
+        AsyncGetOperationCompletion res2;
+        zkServer.addOperationResponse(new ZooGetResponse("2",1));
+        rc=zoo_aget(zh,"/x/y/2",0,asyncCompletion,&res2);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // simulate timeout
+        timeMock.tick(+10); // advance system time by 10 secs
+        // the next call to zookeeper_interest should return ZOPERATIONTIMEOUT
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOPERATIONTIMEOUT,rc);
+        // make sure the completions have been called
+        CPPUNIT_ASSERT_EQUAL((int)ZOPERATIONTIMEOUT,res1.rc_);
+        CPPUNIT_ASSERT_EQUAL((int)ZOPERATIONTIMEOUT,res2.rc_);
+    }
+
+    class PingCountingServer: public ZookeeperServer{
+    public:
+        PingCountingServer():pingCount_(0){}
+        // called when a client request is received
+        virtual void onMessageReceived(const RequestHeader& rh, iarchive* ia){
+           if(rh.type==ZOO_PING_OP){
+               pingCount_++;
+           }
+        }
+        int pingCount_;
+    };
+
+    // establish a connection; idle for a while
+    // verify ping was sent at least once
+    void testPing()
+    {
+        const int TIMEOUT=9; // timeout in secs
+        Mock_gettimeofday timeMock;
+        PingCountingServer zkServer;
+        // must call zookeeper_close() while all the mocks are in scope
+        CloseFinally guard(&zh);
+        
+        // receive timeout is in milliseconds
+        zh=zookeeper_init("localhost:1234",watcher,TIMEOUT*1000,TEST_CLIENT_ID,0,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // simulate connected state
+        forceConnected(zh);
+        
+        int fd=0;
+        int interest=0;
+        timeval tv;
+        // Round 1.
+        int rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // simulate waiting for the select() call to timeout; 
+        // advance the system clock accordingly
+        timeMock.tick(tv);  
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
+        // verify no ping sent
+        CPPUNIT_ASSERT(zkServer.pingCount_==0);
+        
+        // Round 2.
+        // the client should have the idle threshold exceeded, by now
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // assume the socket is writable, so no idling here; move on to 
+        // zookeeper_process immediately
+        rc=zookeeper_process(zh,interest);
+        // ZNOTHING means the client hasn't received a ping response yet
+        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
+        // verify a ping is sent
+        CPPUNIT_ASSERT_EQUAL(1,zkServer.pingCount_);
+        
+        // Round 3.
+        // we're going to receive a server PING response and make sure
+        // that the client has updated its last_recv timestamp 
+        zkServer.addRecvResponse(new PingResponse);
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // pseudo-sleep for a short while (10 ms)
+        timeMock.millitick(10);
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // only one ping so far?
+        CPPUNIT_ASSERT_EQUAL(1,zkServer.pingCount_);
+        CPPUNIT_ASSERT(timeMock==zh->last_recv);
+
+        // Round 4
+        // make sure that a ping is not sent if something is outstanding
+        AsyncGetOperationCompletion res1;
+        rc=zoo_aget(zh,"/x/y/1",0,asyncCompletion,&res1);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        timeMock.tick(tv);  
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // pseudo-sleep for a short while (10 ms)
+        timeMock.millitick(10);
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
+        // only one ping so far?
+        CPPUNIT_ASSERT_EQUAL(1,zkServer.pingCount_);
+    }
+
+    // ZOOKEEPER-2253: Permit unsolicited pings
+    void testUnsolicitedPing()
+    {
+        const int TIMEOUT=9; // timeout in secs
+        Mock_gettimeofday timeMock;
+        PingCountingServer zkServer;
+        // must call zookeeper_close() while all the mocks are in scope
+        CloseFinally guard(&zh);
+
+        // receive timeout is in milliseconds
+        zh=zookeeper_init("localhost:1234",watcher,TIMEOUT*1000,TEST_CLIENT_ID,0,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // simulate connected state
+        forceConnected(zh);
+
+        int fd=0;
+        int interest=0;
+        timeval tv;
+
+        int rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+
+        // verify no ping sent
+        CPPUNIT_ASSERT(zkServer.pingCount_==0);
+
+        // we're going to receive a unsolicited PING response; ensure
+        // that the client has updated its last_recv timestamp
+        timeMock.tick(tv);
+        zkServer.addRecvResponse(new PingResponse);
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        CPPUNIT_ASSERT(timeMock==zh->last_recv);
+    }
+
+    // simulate a watch arriving right before a ping is due
+    // assert the ping is sent nevertheless
+    void testTimeoutCausedByWatches1()
+    {
+        const int TIMEOUT=9; // timeout in secs
+        Mock_gettimeofday timeMock;
+        PingCountingServer zkServer;
+        // must call zookeeper_close() while all the mocks are in scope
+        CloseFinally guard(&zh);
+        
+        // receive timeout is in milliseconds
+        zh=zookeeper_init("localhost:1234",watcher,TIMEOUT*1000,TEST_CLIENT_ID,0,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // simulate connected state
+        forceConnected(zh);
+        
+        int fd=0;
+        int interest=0;
+        timeval tv;
+        // Round 1.
+        int rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // simulate waiting for the select() call to timeout; 
+        // advance the system clock accordingly
+        timeMock.tick(tv);
+        timeMock.tick(-1); // set the clock to a millisecond before a ping is due
+        // trigger a watch now
+        zkServer.addRecvResponse(new ZNodeEvent(ZOO_CHANGED_EVENT,"/x/y/z"));
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // arrival of a watch sets the last_recv to the current time
+        CPPUNIT_ASSERT(timeMock==zh->last_recv);
+        // spend 1 millisecond by processing the watch
+        timeMock.tick(1);
+        
+        // Round 2.
+        // a ping is due; zookeeper_interest() must send it now
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // no delay here -- as if the socket is immediately writable
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
+        // verify a ping is sent
+        CPPUNIT_ASSERT_EQUAL(1,zkServer.pingCount_);        
+    }
+
+    // similar to testTimeoutCausedByWatches1, but this time the watch is 
+    // triggered while the client has an outstanding request
+    // assert the ping is sent on time
+    void testTimeoutCausedByWatches2()
+    {
+        const int TIMEOUT=9; // timeout in secs
+        Mock_gettimeofday now;
+        PingCountingServer zkServer;
+        // must call zookeeper_close() while all the mocks are in scope
+        CloseFinally guard(&zh);
+        
+        // receive timeout is in milliseconds
+        zh=zookeeper_init("localhost:1234",watcher,TIMEOUT*1000,TEST_CLIENT_ID,0,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // simulate connected state
+        forceConnected(zh);
+        
+        // queue up a request; keep it pending (as if the server is busy or has died)
+        AsyncGetOperationCompletion res1;
+        zkServer.addOperationResponse(new ZooGetResponse("2",1));
+        int rc=zoo_aget(zh,"/x/y/1",0,asyncCompletion,&res1);
+
+        int fd=0;
+        int interest=0;
+        timeval tv;
+        // Round 1.
+        // send the queued up zoo_aget() request
+        Mock_gettimeofday beginningOfTimes(now); // remember when we started
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // no delay -- the socket is writable
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc); 
+        
+        // Round 2.
+        // what's next?
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // no response from the server yet -- waiting in the select() call
+        now.tick(tv);
+        // a watch has arrived, thus preventing the connection from timing out 
+        zkServer.addRecvResponse(new ZNodeEvent(ZOO_CHANGED_EVENT,"/x/y/z"));        
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc); // read the watch message
+        CPPUNIT_ASSERT_EQUAL(0,zkServer.pingCount_); // not yet!
+        
+        //Round 3.
+        // now is the time to send a ping; make sure it's actually sent
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
+        // verify a ping is sent
+        CPPUNIT_ASSERT_EQUAL(1,zkServer.pingCount_);
+        // make sure only 1/3 of the timeout has passed
+        CPPUNIT_ASSERT_EQUAL((int32_t)TIMEOUT/3*1000,toMilliseconds(now-beginningOfTimes));
+    }
+
+#else   
+    class TestGetDataJob: public TestJob{
+    public:
+        TestGetDataJob(ZookeeperServer* svr,zhandle_t* zh, int reps=500)
+            :svr_(svr),zh_(zh),rc_(ZAPIERROR),reps_(reps){}
+        virtual void run(){
+            int i;
+            for(i=0;i<reps_;i++){
+                char buf;
+                int size=sizeof(buf);
+
+                if (i % 10 == 0) {
+                    // We need to pause every once in a while so we don't
+                    // get too far ahead and finish before the disconnect
+	            millisleep(1);
+                }
+                svr_->addOperationResponse(new ZooGetResponse("1",1));
+                rc_=zoo_get(zh_,"/x/y/z",0,&buf,&size,0);
+                if(rc_!=ZOK){
+                    break;
+                }
+            }
+        }
+        ZookeeperServer* svr_;
+        zhandle_t* zh_;
+        int rc_;
+        int reps_;
+    };
+    class TestConcurrentOpJob: public TestGetDataJob{
+    public:
+        static const int REPS=500;
+        TestConcurrentOpJob(ZookeeperServer* svr,zhandle_t* zh):
+            TestGetDataJob(svr,zh,REPS){}
+        virtual TestJob* clone() const {
+            return new TestConcurrentOpJob(svr_,zh_);
+        }
+        virtual void validate(const char* file, int line) const{
+            CPPUNIT_ASSERT_EQUAL_MESSAGE_LOC("ZOK != rc",(int)ZOK,rc_,file,line);
+        }
+    };
+    void testConcurrentOperations1()
+    {
+        for(int counter=0; counter<50; counter++){
+            // frozen time -- no timeouts and no pings
+            Mock_gettimeofday timeMock;
+            
+            ZookeeperServer zkServer;
+            Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
+            // must call zookeeper_close() while all the mocks are in the scope!
+            CloseFinally guard(&zh);
+            
+            zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0);
+            CPPUNIT_ASSERT(zh!=0);
+            // make sure the client has connected
+            CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
+            
+            TestJobManager jmgr(TestConcurrentOpJob(&zkServer,zh),10);
+            jmgr.startAllJobs();
+            jmgr.wait();
+            // validate test results
+            VALIDATE_JOBS(jmgr);
+        }
+    }
+    class ZKGetJob: public TestJob{
+    public:
+        static const int REPS=1000;
+        ZKGetJob(zhandle_t* zh)
+            :zh_(zh),rc_(ZAPIERROR){}
+        virtual TestJob* clone() const {
+            return new ZKGetJob(zh_);
+        }
+        virtual void run(){
+            int i;
+            for(i=0;i<REPS;i++){
+                char buf;
+                int size=sizeof(buf);                
+                rc_=zoo_get(zh_,"/xyz",0,&buf,&size,0);
+                if(rc_!=ZOK){
+                    break;
+                }
+            }
+            //TEST_TRACE(("Finished %d iterations",i));
+        }
+        virtual void validate(const char* file, int line) const{
+            CPPUNIT_ASSERT_EQUAL_MESSAGE_LOC("ZOK != rc",(int)ZOK,rc_,file,line);
+        }
+        zhandle_t* zh_;
+        int rc_;
+    };
+
+    // this test connects to a real ZK server and creates the /xyz node and sends
+    // lots of zoo_get requests.
+    // to run this test use the following command:
+    // zktest-mt Zookeeper_operations::testOperationsAndDisconnectConcurrently2 localhost:3181
+    // where the second parameter is the server host and port
+    void testOperationsAndDisconnectConcurrently2()
+    {
+        if(globalTestConfig.getTestName().find(__func__)==string::npos || 
+                globalTestConfig.getExtraOptCount()==0)
+        {
+            // only run this test when specifically asked so
+            return;
+        }
+        string host(*(globalTestConfig.getExtraOptBegin()));
+        zhandle_t* lzh=zookeeper_init(host.c_str(),watcher,10000,0,0,0);
+        CPPUNIT_ASSERT(lzh!=0);
+        // make sure the client has connected
+        CPPUNIT_ASSERT_MESSAGE("Unable to connect to the host",
+                ensureCondition(ClientConnected(zh),5000)<5000);
+        
+        char realpath[1024];
+        int rc=zoo_create(lzh,"/xyz","1",1,&ZOO_OPEN_ACL_UNSAFE,0,realpath,sizeof(realpath)-1);
+        CPPUNIT_ASSERT(rc==ZOK || rc==ZNODEEXISTS);
+        zookeeper_close(lzh); 
+  
+        for(int counter=0; counter<200; counter++){
+            TEST_TRACE(("Loop count %d",counter));
+            
+            CloseFinally guard(&zh);
+
+            zh=zookeeper_init(host.c_str(),watcher,10000,0,0,0);
+            CPPUNIT_ASSERT(zh!=0);
+            // make sure the client has connected
+            CPPUNIT_ASSERT_MESSAGE("Unable to connect to the host",
+                    ensureCondition(ClientConnected(zh),5000)<5000);
+            
+            TestJobManager jmgr(ZKGetJob(zh),10);
+            jmgr.startJobsImmediately();
+            jmgr.wait();
+            VALIDATE_JOBS(jmgr);
+            TEST_TRACE(("run %d finished",counter));
+        }
+
+    }
+
+    class TestConcurrentOpWithDisconnectJob: public TestGetDataJob{
+    public:
+        static const int REPS=1000;
+        TestConcurrentOpWithDisconnectJob(ZookeeperServer* svr,zhandle_t* zh):
+            TestGetDataJob(svr,zh,REPS){}
+        virtual TestJob* clone() const {
+            return new TestConcurrentOpWithDisconnectJob(svr_,zh_);
+        }
+        virtual void validate(const char* file, int line) const{
+            CPPUNIT_ASSERT_EQUAL_MESSAGE_LOC("ZCONNECTIONLOSS != rc",(int)ZCONNECTIONLOSS,rc_,file,line);
+        }
+    };
+
+    // this test is not 100% accurate in a sense it may not detect all error cases.
+    // TODO: I can't think of a test that is 100% accurate and doesn't interfere
+    //       with the code being tested (in terms of introducing additional 
+    //       implicit synchronization points)
+    void testOperationsAndDisconnectConcurrently1()
+    {
+        for(int counter=0; counter<50; counter++){
+            //TEST_TRACE(("Loop count %d",counter));
+            // frozen time -- no timeouts and no pings
+            Mock_gettimeofday timeMock;
+            
+            ZookeeperServer zkServer;
+            Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
+            // must call zookeeper_close() while all the mocks are in the scope!
+            CloseFinally guard(&zh);
+            
+            zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0);
+            CPPUNIT_ASSERT(zh!=0);
+            // make sure the client has connected
+            CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
+            
+            TestJobManager jmgr(TestConcurrentOpWithDisconnectJob(&zkServer,zh),10);
+            jmgr.startJobsImmediately();
+            // let everything startup before we shutdown the server
+            millisleep(4);
+            // reconnect attempts will start failing immediately 
+            zkServer.setServerDown(0);
+            // next recv call will return 0
+            zkServer.setConnectionLost();
+            jmgr.wait();
+            VALIDATE_JOBS(jmgr);
+        }
+        
+    }
+    // call zoo_aget() in the multithreaded mode
+    void testAsyncGetOperation()
+    {
+        Mock_gettimeofday timeMock;
+        
+        ZookeeperServer zkServer;
+        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
+        // must call zookeeper_close() while all the mocks are in the scope!
+        CloseFinally guard(&zh);
+        
+        zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // make sure the client has connected
+        CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
+
+        AsyncGetOperationCompletion res1;
+        zkServer.addOperationResponse(new ZooGetResponse("1",1));
+        int rc=zoo_aget(zh,"/x/y/1",0,asyncCompletion,&res1);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        
+        CPPUNIT_ASSERT(ensureCondition(res1,1000)<1000);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,res1.rc_);
+        CPPUNIT_ASSERT_EQUAL(string("1"),res1.value_);        
+    }
+    class ChangeNodeWatcher: public WatcherAction{
+    public:
+        ChangeNodeWatcher():changed_(false){}
+        virtual void onNodeValueChanged(zhandle_t*,const char* path){
+            synchronized(mx_);
+            changed_=true;
+            if(path!=0) path_=path;
+        }
+        // this predicate checks if CHANGE_EVENT event type was triggered, unlike
+        // the isWatcherTriggered() that returns true whenever a watcher is triggered
+        // regardless of the event type
+        SyncedBoolCondition isNodeChangedTriggered() const{
+            return SyncedBoolCondition(changed_,mx_);
+        }
+        bool changed_;
+        string path_;
+    };
+    
+    class AsyncWatcherCompletion: public AsyncCompletion{
+    public:
+        AsyncWatcherCompletion(ZookeeperServer& zkServer):zkServer_(zkServer){}
+        virtual void statCompl(int rc, const Stat *stat){
+            // we received a server response, now enqueue a watcher event
+            // to trigger the watcher
+            zkServer_.addRecvResponse(new ZNodeEvent(ZOO_CHANGED_EVENT,"/x/y/z"));
+        }
+        ZookeeperServer& zkServer_;
+    };
+    // verify that async watcher is called for znode events (CREATED, DELETED etc.)
+    void testAsyncWatcher1(){
+        Mock_gettimeofday timeMock;
+        
+        ZookeeperServer zkServer;
+        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
+        // must call zookeeper_close() while all the mocks are in the scope!
+        CloseFinally guard(&zh);
+        
+        ChangeNodeWatcher action;        
+        zh=zookeeper_init("localhost:2121",activeWatcher,10000,
+                TEST_CLIENT_ID,&action,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // make sure the client has connected
+        CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
+        
+        // set the watcher
+        AsyncWatcherCompletion completion(zkServer);
+        // prepare a response for the zoo_aexists() request
+        zkServer.addOperationResponse(new ZooStatResponse);
+        int rc=zoo_aexists(zh,"/x/y/z",1,asyncCompletion,&completion);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        
+        CPPUNIT_ASSERT(ensureCondition(action.isNodeChangedTriggered(),1000)<1000);
+        CPPUNIT_ASSERT_EQUAL(string("/x/y/z"),action.path_);                
+    }
+#endif
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_operations);

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/TestWatchers.cc
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/TestWatchers.cc b/zookeeper-client/zookeeper-client-c/tests/TestWatchers.cc
new file mode 100644
index 0000000..0a26934
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/TestWatchers.cc
@@ -0,0 +1,773 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "CppAssertHelper.h"
+
+#include "ZKMocks.h"
+#include "CollectionUtil.h"
+#include "Util.h"
+
+class Zookeeper_watchers : public CPPUNIT_NS::TestFixture
+{
+    CPPUNIT_TEST_SUITE(Zookeeper_watchers);
+    CPPUNIT_TEST(testDefaultSessionWatcher1);
+    CPPUNIT_TEST(testDefaultSessionWatcher2);
+    CPPUNIT_TEST(testObjectSessionWatcher1);
+    CPPUNIT_TEST(testObjectSessionWatcher2);
+    CPPUNIT_TEST(testNodeWatcher1);
+    CPPUNIT_TEST(testChildWatcher1);
+    CPPUNIT_TEST(testChildWatcher2);
+    CPPUNIT_TEST_SUITE_END();
+
+    static void watcher(zhandle_t *, int, int, const char *,void*){}
+    zhandle_t *zh;
+    FILE *logfile;
+    
+public:
+
+    Zookeeper_watchers() {
+      logfile = openlogfile("Zookeeper_watchers");
+    }
+
+    ~Zookeeper_watchers() {
+      if (logfile) {
+        fflush(logfile);
+        fclose(logfile);
+        logfile = 0;
+      }
+    }
+
+    void setUp()
+    {
+        zoo_set_log_stream(logfile);
+
+        zoo_deterministic_conn_order(0);
+        zh=0;
+    }
+    
+    void tearDown()
+    {
+        zookeeper_close(zh);
+    }
+    
+    class ConnectionWatcher: public WatcherAction{
+    public:
+        ConnectionWatcher():connected_(false),counter_(0){}
+        virtual void onConnectionEstablished(zhandle_t*){
+            synchronized(mx_);
+            counter_++;
+            connected_=true;
+        }
+        SyncedBoolCondition isConnectionEstablished() const{
+            return SyncedBoolCondition(connected_,mx_);
+        }
+        bool connected_;
+        int counter_;
+    };
+
+    class DisconnectWatcher: public WatcherAction{
+    public:
+        DisconnectWatcher():disconnected_(false),counter_(0){}
+        virtual void onConnectionLost(zhandle_t*){
+            synchronized(mx_);
+            counter_++;
+            disconnected_=true;
+        }
+        SyncedBoolCondition isDisconnected() const{
+            return SyncedBoolCondition(disconnected_,mx_);
+        }
+        bool disconnected_;
+        int counter_;
+    };
+
+    class CountingDataWatcher: public WatcherAction{
+    public:
+        CountingDataWatcher():disconnected_(false),counter_(0){}
+        virtual void onNodeValueChanged(zhandle_t*,const char* path){
+            synchronized(mx_);
+            counter_++;
+        }
+        virtual void onConnectionLost(zhandle_t*){
+            synchronized(mx_);
+            counter_++;
+            disconnected_=true;
+        }
+        bool disconnected_;
+        int counter_;
+    };
+
+    class DeletionCountingDataWatcher: public WatcherAction{
+    public:
+        DeletionCountingDataWatcher():counter_(0){}
+        virtual void onNodeDeleted(zhandle_t*,const char* path){
+            synchronized(mx_);
+            counter_++;
+        }
+        int counter_;
+    };
+
+    class ChildEventCountingWatcher: public WatcherAction{
+    public:
+        ChildEventCountingWatcher():counter_(0){}
+        virtual void onChildChanged(zhandle_t*,const char* path){
+            synchronized(mx_);
+            counter_++;
+        }
+        int counter_;
+    };
+
+#ifndef THREADED
+    
+    // verify: the default watcher is called once for a session event
+    void testDefaultSessionWatcher1(){
+        Mock_gettimeofday timeMock;
+        ZookeeperServer zkServer;
+        // must call zookeeper_close() while all the mocks are in scope
+        CloseFinally guard(&zh);
+
+        ConnectionWatcher watcher;
+        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
+                &watcher,0);
+        CPPUNIT_ASSERT(zh!=0);
+        
+        int fd=0;
+        int interest=0;
+        timeval tv;
+        // open the socket
+        int rc=zookeeper_interest(zh,&fd,&interest,&tv);        
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);        
+        CPPUNIT_ASSERT_EQUAL(ZOO_CONNECTING_STATE,zoo_state(zh));
+        // send the handshake packet to the server
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);        
+        CPPUNIT_ASSERT_EQUAL(ZOO_ASSOCIATING_STATE,zoo_state(zh));
+        // receive the server handshake response
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // verify connected
+        CPPUNIT_ASSERT_EQUAL(ZOO_CONNECTED_STATE,zoo_state(zh));
+        CPPUNIT_ASSERT(watcher.connected_);
+        CPPUNIT_ASSERT_EQUAL(1,watcher.counter_);
+    }
+    
+    // test case: connect to server, set a default watcher, disconnect from the server
+    // verify: the default watcher is called once
+    void testDefaultSessionWatcher2(){
+        Mock_gettimeofday timeMock;
+        ZookeeperServer zkServer;
+        // must call zookeeper_close() while all the mocks are in scope
+        CloseFinally guard(&zh);
+
+        DisconnectWatcher watcher;
+        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
+                &watcher,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // simulate connected state
+        forceConnected(zh);
+        
+        // first operation
+        AsyncCompletion ignored;
+        zkServer.addOperationResponse(new ZooGetResponse("1",1));
+        int rc=zoo_aget(zh,"/x/y/1",0,asyncCompletion,&ignored);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // this will process the response and activate the watcher
+        rc=zookeeper_process(zh,ZOOKEEPER_READ);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+
+        // now, disconnect
+        zkServer.setConnectionLost();
+        rc=zookeeper_process(zh,ZOOKEEPER_READ);
+        CPPUNIT_ASSERT_EQUAL((int)ZCONNECTIONLOSS,rc);
+        // verify disconnected
+        CPPUNIT_ASSERT(watcher.disconnected_);
+        CPPUNIT_ASSERT_EQUAL(1,watcher.counter_);
+    }
+    
+    // testcase: connect to the server, set a watcher object on a node, 
+    //           disconnect from the server
+    // verify: the watcher object as well as the default watcher are called
+    void testObjectSessionWatcher1(){
+        Mock_gettimeofday timeMock;
+        ZookeeperServer zkServer;
+        // must call zookeeper_close() while all the mocks are in scope
+        CloseFinally guard(&zh);
+
+        DisconnectWatcher defWatcher;
+        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
+                &defWatcher,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // simulate connected state
+        forceConnected(zh);
+        
+        AsyncCompletion ignored;
+        CountingDataWatcher wobject;
+        zkServer.addOperationResponse(new ZooStatResponse);
+        int rc=zoo_awexists(zh,"/x/y/1",activeWatcher,&wobject,
+                asyncCompletion,&ignored);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // this will process the response and activate the watcher
+        rc=zookeeper_process(zh,ZOOKEEPER_READ);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+
+        // now, disconnect
+        zkServer.setConnectionLost();
+        rc=zookeeper_process(zh,ZOOKEEPER_READ);
+        CPPUNIT_ASSERT_EQUAL((int)ZCONNECTIONLOSS,rc);
+
+        // verify the default watcher has been triggered
+        CPPUNIT_ASSERT(defWatcher.disconnected_);
+        // and triggered only once
+        CPPUNIT_ASSERT_EQUAL(1,defWatcher.counter_);
+        
+        // the path-specific watcher has been triggered as well
+        CPPUNIT_ASSERT(wobject.disconnected_);
+        // only once!
+        CPPUNIT_ASSERT_EQUAL(1,wobject.counter_);
+    }
+
+    // testcase: connect to the server, set a watcher object on a node, 
+    //           set a def watcher on another node,disconnect from the server
+    // verify: the watcher object as well as the default watcher are called
+    void testObjectSessionWatcher2(){
+        Mock_gettimeofday timeMock;
+        ZookeeperServer zkServer;
+        // must call zookeeper_close() while all the mocks are in scope
+        CloseFinally guard(&zh);
+
+        DisconnectWatcher defWatcher;
+        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
+                &defWatcher,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // simulate connected state
+        forceConnected(zh);
+        
+        // set the default watcher
+        AsyncCompletion ignored;
+        zkServer.addOperationResponse(new ZooStatResponse);
+        int rc=zoo_aexists(zh,"/a/b/c",1,asyncCompletion,&ignored);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+
+        CountingDataWatcher wobject;
+        zkServer.addOperationResponse(new ZooStatResponse);
+        rc=zoo_awexists(zh,"/x/y/z",activeWatcher,&wobject,
+                asyncCompletion,&ignored);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        
+        // this will process the response and activate the watcher
+        while((rc=zookeeper_process(zh,ZOOKEEPER_READ))==ZOK) {
+          millisleep(100);
+        }
+        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
+
+        // disconnect now
+        zkServer.setConnectionLost();
+        rc=zookeeper_process(zh,ZOOKEEPER_READ);
+        CPPUNIT_ASSERT_EQUAL((int)ZCONNECTIONLOSS,rc);
+
+        // verify the default watcher has been triggered
+        CPPUNIT_ASSERT(defWatcher.disconnected_);
+        // and triggered only once
+        CPPUNIT_ASSERT_EQUAL(1,defWatcher.counter_);
+        
+        // the path-specific watcher has been triggered as well
+        CPPUNIT_ASSERT(wobject.disconnected_);
+        // only once!
+        CPPUNIT_ASSERT_EQUAL(1,wobject.counter_);
+    }
+
+    // testcase: register 2 node watches for different paths, trigger the watches
+    // verify: the data watchers are processed, the default watcher is not called
+    void testNodeWatcher1(){
+        Mock_gettimeofday timeMock;
+        ZookeeperServer zkServer;
+        // must call zookeeper_close() while all the mocks are in scope
+        CloseFinally guard(&zh);
+
+        DisconnectWatcher defWatcher;
+        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
+                &defWatcher,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // simulate connected state
+        forceConnected(zh);
+        
+        AsyncCompletion ignored;
+        CountingDataWatcher wobject1;
+        zkServer.addOperationResponse(new ZooStatResponse);
+        int rc=zoo_awexists(zh,"/a/b/c",activeWatcher,&wobject1,
+                asyncCompletion,&ignored);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+
+        CountingDataWatcher wobject2;
+        zkServer.addOperationResponse(new ZooStatResponse);
+        rc=zoo_awexists(zh,"/x/y/z",activeWatcher,&wobject2,
+                asyncCompletion,&ignored);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        
+        // this will process the response and activate the watcher
+        while((rc=zookeeper_process(zh,ZOOKEEPER_READ))==ZOK) {
+          millisleep(100);
+        }
+        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
+
+        // we are all set now; let's trigger the watches
+        zkServer.addRecvResponse(new ZNodeEvent(ZOO_CHANGED_EVENT,"/a/b/c"));
+        zkServer.addRecvResponse(new ZNodeEvent(ZOO_CHANGED_EVENT,"/x/y/z"));
+        // make sure all watchers have been processed
+        while((rc=zookeeper_process(zh,ZOOKEEPER_READ))==ZOK) {
+          millisleep(100);
+        }
+        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
+        
+        CPPUNIT_ASSERT_EQUAL(1,wobject1.counter_);
+        CPPUNIT_ASSERT_EQUAL(1,wobject2.counter_);        
+        CPPUNIT_ASSERT_EQUAL(0,defWatcher.counter_);
+    }
+
+    // testcase: set up both a children and a data watchers on the node /a, then
+    //           delete the node by sending a DELETE_EVENT event
+    // verify: both watchers are triggered
+    void testChildWatcher1(){
+        Mock_gettimeofday timeMock;
+        ZookeeperServer zkServer;
+        // must call zookeeper_close() while all the mocks are in scope
+        CloseFinally guard(&zh);
+
+        DeletionCountingDataWatcher defWatcher;
+        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
+                &defWatcher,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // simulate connected state
+        forceConnected(zh);
+        
+        AsyncCompletion ignored;
+        DeletionCountingDataWatcher wobject1;
+        zkServer.addOperationResponse(new ZooStatResponse);
+        int rc=zoo_awexists(zh,"/a",activeWatcher,&wobject1,
+                asyncCompletion,&ignored);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+
+        typedef ZooGetChildrenResponse::StringVector ZooVector;
+        zkServer.addOperationResponse(new ZooGetChildrenResponse(
+                Util::CollectionBuilder<ZooVector>()("/a/1")("/a/2")
+                ));
+        DeletionCountingDataWatcher wobject2;
+        rc=zoo_awget_children(zh,"/a",activeWatcher,
+                &wobject2,asyncCompletion,&ignored);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        
+        // this will process the response and activate the watcher
+        while((rc=zookeeper_process(zh,ZOOKEEPER_READ))==ZOK) {
+          millisleep(100);
+        }
+        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
+
+        // we are all set now; let's trigger the watches
+        zkServer.addRecvResponse(new ZNodeEvent(ZOO_DELETED_EVENT,"/a"));
+        // make sure the watchers have been processed
+        while((rc=zookeeper_process(zh,ZOOKEEPER_READ))==ZOK) {
+          millisleep(100);
+        }
+        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
+
+        CPPUNIT_ASSERT_EQUAL(1,wobject1.counter_);
+        CPPUNIT_ASSERT_EQUAL(1,wobject2.counter_);        
+        CPPUNIT_ASSERT_EQUAL(0,defWatcher.counter_);
+    }
+
+    // testcase: create both a child and data watch on the node /a, send a ZOO_CHILD_EVENT
+    // verify: only the child watch triggered
+    void testChildWatcher2(){
+        Mock_gettimeofday timeMock;
+        ZookeeperServer zkServer;
+        // must call zookeeper_close() while all the mocks are in scope
+        CloseFinally guard(&zh);
+
+        ChildEventCountingWatcher defWatcher;
+        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
+                &defWatcher,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // simulate connected state
+        forceConnected(zh);
+        
+        AsyncCompletion ignored;
+        ChildEventCountingWatcher wobject1;
+        zkServer.addOperationResponse(new ZooStatResponse);
+        int rc=zoo_awexists(zh,"/a",activeWatcher,&wobject1,
+                asyncCompletion,&ignored);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+
+        typedef ZooGetChildrenResponse::StringVector ZooVector;
+        zkServer.addOperationResponse(new ZooGetChildrenResponse(
+                Util::CollectionBuilder<ZooVector>()("/a/1")("/a/2")
+                ));
+        ChildEventCountingWatcher wobject2;
+        rc=zoo_awget_children(zh,"/a",activeWatcher,
+                &wobject2,asyncCompletion,&ignored);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        
+        // this will process the response and activate the watcher
+        while((rc=zookeeper_process(zh,ZOOKEEPER_READ))==ZOK) {
+          millisleep(100);
+        }
+        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
+
+        // we are all set now; let's trigger the watches
+        zkServer.addRecvResponse(new ZNodeEvent(ZOO_CHILD_EVENT,"/a"));
+        // make sure the watchers have been processed
+        while((rc=zookeeper_process(zh,ZOOKEEPER_READ))==ZOK) {
+          millisleep(100);
+        }
+        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
+
+        CPPUNIT_ASSERT_EQUAL(0,wobject1.counter_);
+        CPPUNIT_ASSERT_EQUAL(1,wobject2.counter_);        
+        CPPUNIT_ASSERT_EQUAL(0,defWatcher.counter_);
+    }
+
+#else
+    // verify: the default watcher is called once for a session event
+    void testDefaultSessionWatcher1(){
+        Mock_gettimeofday timeMock;
+        // zookeeper simulator
+        ZookeeperServer zkServer;
+        // detects when all watchers have been delivered
+        WatcherDeliveryTracker deliveryTracker(ZOO_SESSION_EVENT,ZOO_CONNECTED_STATE);
+        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
+        // must call zookeeper_close() while all the mocks are in the scope!
+        CloseFinally guard(&zh);
+        
+        ConnectionWatcher watcher;
+        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
+                &watcher,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // wait till watcher proccessing has completed (the connection 
+        // established event)
+        CPPUNIT_ASSERT(ensureCondition(
+                deliveryTracker.isWatcherProcessingCompleted(),1000)<1000);
+        
+        // verify the watcher has been triggered
+        CPPUNIT_ASSERT(ensureCondition(watcher.isConnectionEstablished(),1000)<1000);
+        // triggered only once
+        CPPUNIT_ASSERT_EQUAL(1,watcher.counter_);
+    }
+
+    // test case: connect to server, set a default watcher, disconnect from the server
+    // verify: the default watcher is called once
+    void testDefaultSessionWatcher2(){
+        Mock_gettimeofday timeMock;
+        // zookeeper simulator
+        ZookeeperServer zkServer;
+        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
+        // must call zookeeper_close() while all the mocks are in the scope!
+        CloseFinally guard(&zh);
+        
+        // detects when all watchers have been delivered
+        WatcherDeliveryTracker deliveryTracker(ZOO_SESSION_EVENT,ZOO_CONNECTING_STATE);
+        DisconnectWatcher watcher;
+        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
+                &watcher,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // make sure the client has connected
+        CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
+        // set a default watch
+        AsyncCompletion ignored;
+        // a successful server response will activate the watcher 
+        zkServer.addOperationResponse(new ZooStatResponse);
+        int rc=zoo_aexists(zh,"/x/y/z",1,asyncCompletion,&ignored);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+
+        // now, initiate a disconnect
+        zkServer.setConnectionLost();
+        CPPUNIT_ASSERT(ensureCondition(
+                deliveryTracker.isWatcherProcessingCompleted(),1000)<1000);
+        
+        // verify the watcher has been triggered
+        CPPUNIT_ASSERT(watcher.disconnected_);
+        // triggered only once
+        CPPUNIT_ASSERT_EQUAL(1,watcher.counter_);
+    }
+
+    // testcase: connect to the server, set a watcher object on a node, 
+    //           disconnect from the server
+    // verify: the watcher object as well as the default watcher are called
+    void testObjectSessionWatcher1(){
+        Mock_gettimeofday timeMock;
+        // zookeeper simulator
+        ZookeeperServer zkServer;
+        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
+        // must call zookeeper_close() while all the mocks are in the scope!
+        CloseFinally guard(&zh);
+        
+        // detects when all watchers have been delivered
+        WatcherDeliveryTracker deliveryTracker(ZOO_SESSION_EVENT,ZOO_CONNECTING_STATE);
+        DisconnectWatcher defWatcher;
+        // use the tracker to find out when the watcher has been activated
+        WatcherActivationTracker activationTracker;
+        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
+                &defWatcher,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // make sure the client has connected
+        CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
+
+        AsyncCompletion ignored;
+        // this successful server response will activate the watcher 
+        zkServer.addOperationResponse(new ZooStatResponse);
+        CountingDataWatcher wobject;
+        activationTracker.track(&wobject);
+        // set a path-specific watcher
+        int rc=zoo_awexists(zh,"/x/y/z",activeWatcher,&wobject,
+                asyncCompletion,&ignored);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // make sure the watcher gets activated before we continue
+        CPPUNIT_ASSERT(ensureCondition(activationTracker.isWatcherActivated(),1000)<1000);
+        
+        // now, initiate a disconnect
+        zkServer.setConnectionLost();
+        // make sure all watchers have been processed
+        CPPUNIT_ASSERT(ensureCondition(
+                deliveryTracker.isWatcherProcessingCompleted(),1000)<1000);
+        
+        // verify the default watcher has been triggered
+        CPPUNIT_ASSERT(defWatcher.disconnected_);
+        // and triggered only once
+        CPPUNIT_ASSERT_EQUAL(1,defWatcher.counter_);
+        
+        // the path-specific watcher has been triggered as well
+        CPPUNIT_ASSERT(wobject.disconnected_);
+        // only once!
+        CPPUNIT_ASSERT_EQUAL(1,wobject.counter_);
+    }
+
+    // testcase: connect to the server, set a watcher object on a node, 
+    //           set a def watcher on another node,disconnect from the server
+    // verify: the watcher object as well as the default watcher are called
+    void testObjectSessionWatcher2(){
+        Mock_gettimeofday timeMock;
+        // zookeeper simulator
+        ZookeeperServer zkServer;
+        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
+        // must call zookeeper_close() while all the mocks are in the scope!
+        CloseFinally guard(&zh);
+        
+        // detects when all watchers have been delivered
+        WatcherDeliveryTracker deliveryTracker(ZOO_SESSION_EVENT,ZOO_CONNECTING_STATE);
+        DisconnectWatcher defWatcher;
+        // use the tracker to find out when the watcher has been activated
+        WatcherActivationTracker activationTracker;
+        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
+                &defWatcher,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // make sure the client has connected
+        CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
+
+        // set a default watch
+        AsyncCompletion ignored;
+        // a successful server response will activate the watcher 
+        zkServer.addOperationResponse(new ZooStatResponse);
+        activationTracker.track(&defWatcher);
+        int rc=zoo_aexists(zh,"/a/b/c",1,asyncCompletion,&ignored);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // make sure the watcher gets activated before we continue
+        CPPUNIT_ASSERT(ensureCondition(activationTracker.isWatcherActivated(),1000)<1000);
+
+        // this successful server response will activate the watcher 
+        zkServer.addOperationResponse(new ZooStatResponse);
+        CountingDataWatcher wobject;
+        activationTracker.track(&wobject);
+        // set a path-specific watcher
+        rc=zoo_awexists(zh,"/x/y/z",activeWatcher,&wobject,
+                asyncCompletion,&ignored);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // make sure the watcher gets activated before we continue
+        CPPUNIT_ASSERT(ensureCondition(activationTracker.isWatcherActivated(),1000)<1000);
+        
+        // now, initiate a disconnect
+        zkServer.setConnectionLost();
+        // make sure all watchers have been processed
+        CPPUNIT_ASSERT(ensureCondition(
+                deliveryTracker.isWatcherProcessingCompleted(),1000)<1000);
+        
+        // verify the default watcher has been triggered
+        CPPUNIT_ASSERT(defWatcher.disconnected_);
+        // and triggered only once
+        CPPUNIT_ASSERT_EQUAL(1,defWatcher.counter_);
+        
+        // the path-specific watcher has been triggered as well
+        CPPUNIT_ASSERT(wobject.disconnected_);
+        // only once!
+        CPPUNIT_ASSERT_EQUAL(1,wobject.counter_);
+    }
+
+    // testcase: register 2 node watches for different paths, trigger the watches
+    // verify: the data watchers are processed, the default watcher is not called
+    void testNodeWatcher1(){
+        Mock_gettimeofday timeMock;
+        // zookeeper simulator
+        ZookeeperServer zkServer;
+        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
+        // must call zookeeper_close() while all the mocks are in the scope!
+        CloseFinally guard(&zh);
+        
+        // detects when all watchers have been delivered
+        WatcherDeliveryTracker deliveryTracker(ZOO_CHANGED_EVENT,0,false);
+        CountingDataWatcher defWatcher;
+        // use the tracker to find out when the watcher has been activated
+        WatcherActivationTracker activationTracker;
+        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
+                &defWatcher,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // make sure the client has connected
+        CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
+
+        // don't care about completions
+        AsyncCompletion ignored;
+        // set a one-shot watch
+        // a successful server response will activate the watcher 
+        zkServer.addOperationResponse(new ZooStatResponse);
+        CountingDataWatcher wobject1;
+        activationTracker.track(&wobject1);
+        int rc=zoo_awexists(zh,"/a/b/c",activeWatcher,&wobject1,
+                asyncCompletion,&ignored);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // make sure the watcher gets activated before we continue
+        CPPUNIT_ASSERT(ensureCondition(activationTracker.isWatcherActivated(),1000)<1000);
+
+        // this successful server response will activate the watcher 
+        zkServer.addOperationResponse(new ZooStatResponse);
+        CountingDataWatcher wobject2;
+        activationTracker.track(&wobject2);
+        // set a path-specific watcher
+        rc=zoo_awexists(zh,"/x/y/z",activeWatcher,&wobject2,
+                asyncCompletion,&ignored);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // make sure the watcher gets activated before we continue
+        CPPUNIT_ASSERT(ensureCondition(activationTracker.isWatcherActivated(),1000)<1000);
+
+        // we are all set now; let's trigger the watches
+        zkServer.addRecvResponse(new ZNodeEvent(ZOO_CHANGED_EVENT,"/a/b/c"));
+        zkServer.addRecvResponse(new ZNodeEvent(ZOO_CHANGED_EVENT,"/x/y/z"));
+        // make sure all watchers have been processed
+        CPPUNIT_ASSERT(ensureCondition(
+                deliveryTracker.deliveryCounterEquals(2),1000)<1000);
+        
+        CPPUNIT_ASSERT_EQUAL(1,wobject1.counter_);
+        CPPUNIT_ASSERT_EQUAL(1,wobject2.counter_);        
+        CPPUNIT_ASSERT_EQUAL(0,defWatcher.counter_);
+    }
+
+    // testcase: set up both a children and a data watchers on the node /a, then
+    //           delete the node (that is, send a DELETE_EVENT)
+    // verify: both watchers are triggered
+    void testChildWatcher1(){
+        Mock_gettimeofday timeMock;
+        // zookeeper simulator
+        ZookeeperServer zkServer;
+        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
+        // must call zookeeper_close() while all the mocks are in the scope!
+        CloseFinally guard(&zh);
+        
+        // detects when all watchers have been delivered
+        WatcherDeliveryTracker deliveryTracker(ZOO_DELETED_EVENT,0);
+        DeletionCountingDataWatcher defWatcher;
+        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
+                &defWatcher,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // make sure the client has connected
+        CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
+        
+        // a successful server response will activate the watcher 
+        zkServer.addOperationResponse(new ZooStatResponse);
+        DeletionCountingDataWatcher wobject1;
+        Stat stat;
+        // add a node watch
+        int rc=zoo_wexists(zh,"/a",activeWatcher,&wobject1,&stat);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        
+        typedef ZooGetChildrenResponse::StringVector ZooVector;
+        zkServer.addOperationResponse(new ZooGetChildrenResponse(
+                Util::CollectionBuilder<ZooVector>()("/a/1")("/a/2")
+                ));
+        DeletionCountingDataWatcher wobject2;
+        String_vector children;
+        rc=zoo_wget_children(zh,"/a",activeWatcher,&wobject2,&children);
+        deallocate_String_vector(&children);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        
+        // we are all set now; let's trigger the watches
+        zkServer.addRecvResponse(new ZNodeEvent(ZOO_DELETED_EVENT,"/a"));
+        // make sure the watchers have been processed
+        CPPUNIT_ASSERT(ensureCondition(
+                deliveryTracker.isWatcherProcessingCompleted(),1000)<1000);
+
+        CPPUNIT_ASSERT_EQUAL(1,wobject1.counter_);
+        CPPUNIT_ASSERT_EQUAL(1,wobject2.counter_);        
+        CPPUNIT_ASSERT_EQUAL(0,defWatcher.counter_);
+    }
+    
+    // testcase: create both a child and data watch on the node /a, send a ZOO_CHILD_EVENT
+    // verify: only the child watch triggered
+    void testChildWatcher2(){
+        Mock_gettimeofday timeMock;
+        // zookeeper simulator
+        ZookeeperServer zkServer;
+        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
+        // must call zookeeper_close() while all the mocks are in the scope!
+        CloseFinally guard(&zh);
+        
+        // detects when all watchers have been delivered
+        WatcherDeliveryTracker deliveryTracker(ZOO_CHILD_EVENT,0);
+        ChildEventCountingWatcher defWatcher;
+        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
+                &defWatcher,0);
+        CPPUNIT_ASSERT(zh!=0);
+        // make sure the client has connected
+        CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
+        // a successful server response will activate the watcher 
+        zkServer.addOperationResponse(new ZooStatResponse);
+        ChildEventCountingWatcher wobject1;
+        Stat stat;
+        // add a node watch
+        int rc=zoo_wexists(zh,"/a",activeWatcher,&wobject1,&stat);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        
+        typedef ZooGetChildrenResponse::StringVector ZooVector;
+        zkServer.addOperationResponse(new ZooGetChildrenResponse(
+                Util::CollectionBuilder<ZooVector>()("/a/1")("/a/2")
+                ));
+        ChildEventCountingWatcher wobject2;
+        String_vector children;
+        rc=zoo_wget_children(zh,"/a",activeWatcher,&wobject2,&children);
+        deallocate_String_vector(&children);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+
+        // we are all set now; let's trigger the watches
+        zkServer.addRecvResponse(new ZNodeEvent(ZOO_CHILD_EVENT,"/a"));
+        // make sure the watchers have been processed
+        CPPUNIT_ASSERT(ensureCondition(
+                deliveryTracker.isWatcherProcessingCompleted(),1000)<1000);
+
+        CPPUNIT_ASSERT_EQUAL(0,wobject1.counter_);
+        CPPUNIT_ASSERT_EQUAL(1,wobject2.counter_);        
+        CPPUNIT_ASSERT_EQUAL(0,defWatcher.counter_);
+    }
+
+#endif //THREADED
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_watchers);

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/tests/TestZookeeperClose.cc
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/tests/TestZookeeperClose.cc b/zookeeper-client/zookeeper-client-c/tests/TestZookeeperClose.cc
new file mode 100644
index 0000000..edefa66
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/tests/TestZookeeperClose.cc
@@ -0,0 +1,472 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "ZKMocks.h"
+
+#ifdef THREADED
+#include "PthreadMocks.h"
+#endif
+
+using namespace std;
+
+class Zookeeper_close : public CPPUNIT_NS::TestFixture
+{
+    CPPUNIT_TEST_SUITE(Zookeeper_close);
+#ifdef THREADED
+    CPPUNIT_TEST(testIOThreadStoppedOnExpire);
+#endif
+    CPPUNIT_TEST(testCloseUnconnected);
+    CPPUNIT_TEST(testCloseUnconnected1);
+    CPPUNIT_TEST(testCloseConnected1);
+    CPPUNIT_TEST(testCloseFromWatcher1);
+    CPPUNIT_TEST_SUITE_END();
+    zhandle_t *zh;
+    static void watcher(zhandle_t *, int, int, const char *,void*){}
+    FILE *logfile;
+public: 
+
+    Zookeeper_close() {
+      logfile = openlogfile("Zookeeper_close");
+    }
+
+    ~Zookeeper_close() {
+      if (logfile) {
+        fflush(logfile);
+        fclose(logfile);
+        logfile = 0;
+      }
+    }
+
+    void setUp()
+    {
+        zoo_set_log_stream(logfile);
+
+        zoo_deterministic_conn_order(0);
+        zh=0;
+    }
+    
+    void tearDown()
+    {
+        zookeeper_close(zh);
+    }
+
+    class CloseOnSessionExpired: public WatcherAction{
+    public:
+        CloseOnSessionExpired(bool callClose=true):
+            callClose_(callClose),rc(ZOK){}
+        virtual void onSessionExpired(zhandle_t* zh){
+            memcpy(&lzh,zh,sizeof(lzh));
+            if(callClose_)
+                rc=zookeeper_close(zh);
+        }
+        zhandle_t lzh;
+        bool callClose_;
+        int rc;
+    };
+    
+#ifndef THREADED
+    void testCloseUnconnected()
+    {       
+        zh=zookeeper_init("localhost:2121",watcher,10000,0,0,0);       
+        CPPUNIT_ASSERT(zh!=0);
+        
+        // do not actually free the memory while in zookeeper_close()
+        Mock_free_noop freeMock;
+        // make a copy of zhandle before close() overwrites some of 
+        // it members with NULLs
+        zhandle_t lzh;
+        memcpy(&lzh,zh,sizeof(lzh));
+        int rc=zookeeper_close(zh);
+        zhandle_t* savezh=zh; zh=0;
+        freeMock.disable(); // disable mock's fake free()- use libc's free() instead
+        
+        // verify that zookeeper_close has done its job
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // memory
+        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
+        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.hostname));
+        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.addrs));
+        // This cannot be maintained properly CPPUNIT_ASSERT_EQUAL(9,freeMock.callCounter);
+    }
+    void testCloseUnconnected1()
+    {
+        zh=zookeeper_init("localhost:2121",watcher,10000,0,0,0);       
+        CPPUNIT_ASSERT(zh!=0);
+        // simulate connected state 
+        zh->fd=ZookeeperServer::FD;
+        zh->state=ZOO_CONNECTED_STATE;
+        Mock_flush_send_queue zkMock;
+        // do not actually free the memory while in zookeeper_close()
+        Mock_free_noop freeMock;
+        // make a copy of zhandle before close() overwrites some of 
+        // it members with NULLs
+        zhandle_t lzh;
+        memcpy(&lzh,zh,sizeof(lzh));
+        int rc=zookeeper_close(zh);
+        zhandle_t* savezh=zh; zh=0;
+        freeMock.disable(); // disable mock's fake free()- use libc's free() instead
+
+        // verify that zookeeper_close has done its job
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // memory
+        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
+        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.hostname));
+        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.addrs));
+        // the close request sent?
+        CPPUNIT_ASSERT_EQUAL(1,zkMock.counter);
+    }
+    void testCloseConnected1()
+    {
+        ZookeeperServer zkServer;
+        // poll() will called from zookeeper_close()
+        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
+
+        zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0);
+        CPPUNIT_ASSERT(zh!=0);
+
+        Mock_gettimeofday timeMock;
+        
+        int fd=0;
+        int interest=0;
+        timeval tv;
+        int rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);        
+        CPPUNIT_ASSERT_EQUAL(ZOO_CONNECTING_STATE,zoo_state(zh));
+        CPPUNIT_ASSERT_EQUAL(ZOOKEEPER_READ|ZOOKEEPER_WRITE,interest);
+        
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);        
+        CPPUNIT_ASSERT_EQUAL(ZOO_ASSOCIATING_STATE,zoo_state(zh));
+        
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);        
+        CPPUNIT_ASSERT_EQUAL(ZOO_CONNECTED_STATE,zoo_state(zh));
+        // do not actually free the memory while in zookeeper_close()
+        Mock_free_noop freeMock;
+        // make a copy of zhandle before close() overwrites some of 
+        // it members with NULLs
+        zhandle_t lzh;
+        memcpy(&lzh,zh,sizeof(lzh));
+        zookeeper_close(zh);
+        zhandle_t* savezh=zh; zh=0;
+        freeMock.disable(); // disable mock's fake free()- use libc's free() instead
+        // memory
+        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
+        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.hostname));
+        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.addrs));
+        // the close request sent?
+        CPPUNIT_ASSERT_EQUAL(1,(int)zkServer.closeSent);
+    }
+    void testCloseFromWatcher1()
+    {
+        Mock_gettimeofday timeMock;
+
+        ZookeeperServer zkServer;
+        // make the server return a non-matching session id
+        zkServer.returnSessionExpired();
+        // poll() will called from zookeeper_close()
+        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
+
+        CloseOnSessionExpired closeAction;
+        zh=zookeeper_init("localhost:2121",activeWatcher,10000,
+                TEST_CLIENT_ID,&closeAction,0);
+        CPPUNIT_ASSERT(zh!=0);
+        
+        int fd=0;
+        int interest=0;
+        timeval tv;
+        // initiate connection
+        int rc=zookeeper_interest(zh,&fd,&interest,&tv);        
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);        
+        CPPUNIT_ASSERT_EQUAL(ZOO_CONNECTING_STATE,zoo_state(zh));
+        CPPUNIT_ASSERT_EQUAL(ZOOKEEPER_READ|ZOOKEEPER_WRITE,interest);
+        rc=zookeeper_process(zh,interest);
+        // make sure the handshake in progress 
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);        
+        CPPUNIT_ASSERT_EQUAL(ZOO_ASSOCIATING_STATE,zoo_state(zh));
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        
+        // do not actually free the memory while in zookeeper_close()
+        Mock_free_noop freeMock;
+        // should call the watcher with ZOO_EXPIRED_SESSION_STATE state
+        rc=zookeeper_process(zh,interest);
+        zhandle_t* savezh=zh; zh=0;
+        freeMock.disable(); // disable mock's fake free()- use libc's free() instead
+        
+        CPPUNIT_ASSERT_EQUAL(ZOO_EXPIRED_SESSION_STATE,zoo_state(savezh));
+        // memory
+        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
+        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.hostname));
+        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.addrs));
+        // make sure the close request NOT sent
+        CPPUNIT_ASSERT_EQUAL(0,(int)zkServer.closeSent);
+    }
+#else
+    void testCloseUnconnected()
+    {
+        // disable threading
+        MockPthreadZKNull pthreadMock;
+        zh=zookeeper_init("localhost:2121",watcher,10000,0,0,0); 
+        
+        CPPUNIT_ASSERT(zh!=0);
+        adaptor_threads* adaptor=(adaptor_threads*)zh->adaptor_priv;
+        CPPUNIT_ASSERT(adaptor!=0);
+
+        // do not actually free the memory while in zookeeper_close()
+        Mock_free_noop freeMock;
+        // make a copy of zhandle before close() overwrites some of 
+        // it members with NULLs
+        zhandle_t lzh;
+        memcpy(&lzh,zh,sizeof(lzh));
+        int rc=zookeeper_close(zh);
+        zhandle_t* savezh=zh; zh=0;
+        // we're done, disable mock's fake free(), use libc's free() instead
+        freeMock.disable();
+        
+        // verify that zookeeper_close has done its job
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // memory
+        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
+        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.hostname));
+        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.addrs));
+        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(adaptor));
+        // Cannot be maintained accurately: CPPUNIT_ASSERT_EQUAL(10,freeMock.callCounter);
+        // threads
+        CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(adaptor->io));
+        CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(adaptor->completion));
+        // mutexes
+        CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->to_process.lock));
+        CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->to_process.lock));
+        CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->to_send.lock));
+        CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->to_send.lock));
+        CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->sent_requests.lock));
+        CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->sent_requests.lock));
+        CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->completions_to_process.lock));
+        CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->completions_to_process.lock));
+        // conditionals
+        CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->sent_requests.cond));
+        CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->sent_requests.cond));
+        CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->completions_to_process.cond));
+        CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->completions_to_process.cond));
+    }
+    void testCloseUnconnected1()
+    {
+        for(int i=0; i<100;i++){
+            zh=zookeeper_init("localhost:2121",watcher,10000,0,0,0); 
+            CPPUNIT_ASSERT(zh!=0);
+            adaptor_threads* adaptor=(adaptor_threads*)zh->adaptor_priv;
+            CPPUNIT_ASSERT(adaptor!=0);
+            int rc=zookeeper_close(zh);
+            zh=0;
+            CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        }
+    }
+    void testCloseConnected1()
+    {
+        // frozen time -- no timeouts and no pings
+        Mock_gettimeofday timeMock;
+
+        for(int i=0;i<100;i++){
+            ZookeeperServer zkServer;
+            Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
+            // use a checked version of pthread calls
+            CheckedPthread threadMock;
+            // do not actually free the memory while in zookeeper_close()
+            Mock_free_noop freeMock;
+            
+            zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0); 
+            CPPUNIT_ASSERT(zh!=0);
+            // make sure the client has connected
+            CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
+            // make a copy of zhandle before close() overwrites some of 
+            // its members with NULLs
+            zhandle_t lzh;
+            memcpy(&lzh,zh,sizeof(lzh));
+            int rc=zookeeper_close(zh);
+            zhandle_t* savezh=zh; zh=0;
+            // we're done, disable mock's fake free(), use libc's free() instead
+            freeMock.disable();
+            
+            CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);            
+            adaptor_threads* adaptor=(adaptor_threads*)lzh.adaptor_priv;
+            // memory
+            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
+            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.hostname));
+            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.addrs));
+            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(adaptor));
+            // threads
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->io));
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->completion));
+            // mutexes
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->to_process.lock));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->to_process.lock));
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->to_send.lock));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->to_send.lock));
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->sent_requests.lock));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->sent_requests.lock));
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->completions_to_process.lock));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->completions_to_process.lock));
+            // conditionals
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->sent_requests.cond));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->sent_requests.cond));
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->completions_to_process.cond));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->completions_to_process.cond));
+        }
+    }
+    
+    struct PointerFreed{
+        PointerFreed(Mock_free_noop& freeMock,void* ptr):
+            freeMock_(freeMock),ptr_(ptr){}
+        bool operator()() const{return freeMock_.isFreed(ptr_); }
+        Mock_free_noop& freeMock_;
+        void* ptr_;
+    };
+    // test if zookeeper_close may be called from a watcher callback on
+    // SESSION_EXPIRED event
+    void testCloseFromWatcher1()
+    {
+        // frozen time -- no timeouts and no pings
+        Mock_gettimeofday timeMock;
+        
+        for(int i=0;i<100;i++){
+            ZookeeperServer zkServer;
+            // make the server return a non-matching session id
+            zkServer.returnSessionExpired();
+            
+            Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
+            // use a checked version of pthread calls
+            CheckedPthread threadMock;
+            // do not actually free the memory while in zookeeper_close()
+            Mock_free_noop freeMock;
+
+            CloseOnSessionExpired closeAction;
+            zh=zookeeper_init("localhost:2121",activeWatcher,10000,
+                    TEST_CLIENT_ID,&closeAction,0);
+            
+            CPPUNIT_ASSERT(zh!=0);
+            // we rely on the fact that zh is freed the last right before
+            // zookeeper_close() returns...
+            CPPUNIT_ASSERT(ensureCondition(PointerFreed(freeMock,zh),1000)<1000);
+            zhandle_t* lzh=zh;
+            zh=0;
+            // we're done, disable mock's fake free(), use libc's free() instead
+            freeMock.disable();
+            
+            CPPUNIT_ASSERT_EQUAL((int)ZOK,closeAction.rc);          
+            adaptor_threads* adaptor=(adaptor_threads*)closeAction.lzh.adaptor_priv;
+            // memory
+            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh));
+            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.hostname));
+            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.addrs));
+            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(adaptor));
+            // threads
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->io));
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->completion));
+            // mutexes
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->to_process.lock));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->to_process.lock));
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->to_send.lock));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->to_send.lock));
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->sent_requests.lock));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->sent_requests.lock));
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->completions_to_process.lock));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->completions_to_process.lock));
+            // conditionals
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->sent_requests.cond));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->sent_requests.cond));
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->completions_to_process.cond));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->completions_to_process.cond));
+        }
+    }
+
+    void testIOThreadStoppedOnExpire()
+    {
+        // frozen time -- no timeouts and no pings
+        Mock_gettimeofday timeMock;
+        
+        for(int i=0;i<100;i++){
+            ZookeeperServer zkServer;
+            // make the server return a non-matching session id
+            zkServer.returnSessionExpired();
+            
+            Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
+            // use a checked version of pthread calls
+            CheckedPthread threadMock;
+            // do not call zookeeper_close() from the watcher
+            CloseOnSessionExpired closeAction(false);
+            zh=zookeeper_init("localhost:2121",activeWatcher,10000,
+                    &testClientId,&closeAction,0);
+            
+            // this is to ensure that if any assert fires, zookeeper_close() 
+            // will still be called while all the mocks are in the scope!
+            CloseFinally guard(&zh);
+
+            CPPUNIT_ASSERT(zh!=0);
+            CPPUNIT_ASSERT(ensureCondition(SessionExpired(zh),1000)<1000);
+            CPPUNIT_ASSERT(ensureCondition(IOThreadStopped(zh),1000)<1000);
+            // make sure the watcher has been processed
+            CPPUNIT_ASSERT(ensureCondition(closeAction.isWatcherTriggered(),1000)<1000);
+            // make sure the threads have not been destroyed yet
+            adaptor_threads* adaptor=(adaptor_threads*)zh->adaptor_priv;
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getDestroyCounter(adaptor->io));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getDestroyCounter(adaptor->completion));
+            // about to call zookeeper_close() -- no longer need the guard
+            guard.disarm();
+            
+            // do not actually free the memory while in zookeeper_close()
+            Mock_free_noop freeMock;
+            zookeeper_close(zh);
+            zhandle_t* lzh=zh; zh=0;
+            // we're done, disable mock's fake free(), use libc's free() instead
+            freeMock.disable();
+            
+            // memory
+            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh));
+            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.hostname));
+            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.addrs));
+            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(adaptor));
+            // threads
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->io));
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->completion));
+            // mutexes
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->to_process.lock));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->to_process.lock));
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->to_send.lock));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->to_send.lock));
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->sent_requests.lock));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->sent_requests.lock));
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->completions_to_process.lock));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->completions_to_process.lock));
+            // conditionals
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->sent_requests.cond));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->sent_requests.cond));
+            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->completions_to_process.cond));
+            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->completions_to_process.cond));
+        }
+    }
+
+#endif
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_close);


[10/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/INSTALL
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/INSTALL b/zookeeper-client/zookeeper-client-c/INSTALL
new file mode 100644
index 0000000..5458714
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/INSTALL
@@ -0,0 +1,234 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006 Free Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.
+
+     Running `configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about.  Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you can use GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory.  After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug.  Until the bug is fixed you can use this workaround:
+
+     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/LICENSE
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/LICENSE b/zookeeper-client/zookeeper-client-c/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/Makefile.am
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/Makefile.am b/zookeeper-client/zookeeper-client-c/Makefile.am
new file mode 100644
index 0000000..5993098
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/Makefile.am
@@ -0,0 +1,128 @@
+# need this for Doxygen integration
+include $(top_srcdir)/aminclude.am
+
+if SOLARIS
+  SOLARIS_CPPFLAGS = -D_POSIX_PTHREAD_SEMANTICS
+  SOLARIS_LIB_LDFLAGS = -lnsl -lsocket
+endif
+AM_CPPFLAGS = -I${srcdir}/include -I${srcdir}/tests -I${srcdir}/generated $(SOLARIS_CPPFLAGS)
+AM_CFLAGS = -Wall -Werror 
+AM_CXXFLAGS = -Wall $(USEIPV6)
+
+# Additional flags for coverage testing (if enabled)
+if ENABLEGCOV
+  AM_CFLAGS += -fprofile-arcs -ftest-coverage
+  AM_LDFLAGS = -lgcov
+endif
+
+LIB_LDFLAGS = -no-undefined -version-info 2 $(SOLARIS_LIB_LDFLAGS)
+
+pkginclude_HEADERS = include/zookeeper.h include/zookeeper_version.h include/zookeeper_log.h include/proto.h include/recordio.h generated/zookeeper.jute.h
+EXTRA_DIST=LICENSE
+
+HASHTABLE_SRC = src/hashtable/hashtable_itr.h src/hashtable/hashtable_itr.c \
+    src/hashtable/hashtable_private.h src/hashtable/hashtable.h src/hashtable/hashtable.c
+
+noinst_LTLIBRARIES = libhashtable.la
+libhashtable_la_SOURCES = $(HASHTABLE_SRC)
+
+COMMON_SRC = src/zookeeper.c include/zookeeper.h include/zookeeper_version.h include/zookeeper_log.h\
+    src/recordio.c include/recordio.h include/proto.h \
+    src/zk_adaptor.h generated/zookeeper.jute.c \
+    src/zookeeper_log.h src/zk_log.c src/zk_hashtable.h src/zk_hashtable.c
+
+# These are the symbols (classes, mostly) we want to export from our library.
+EXPORT_SYMBOLS = '(zoo_|zookeeper_|zhandle|Z|format_log_message|log_message|logLevel|deallocate_|allocate_|zerror|is_unrecoverable)'
+noinst_LTLIBRARIES += libzkst.la
+libzkst_la_SOURCES =$(COMMON_SRC) src/st_adaptor.c
+libzkst_la_LIBADD = -lm
+
+lib_LTLIBRARIES = libzookeeper_st.la
+libzookeeper_st_la_SOURCES =
+libzookeeper_st_la_LIBADD=libzkst.la libhashtable.la
+libzookeeper_st_la_DEPENDENCIES=libzkst.la libhashtable.la
+libzookeeper_st_la_LDFLAGS = $(LIB_LDFLAGS) -export-symbols-regex $(EXPORT_SYMBOLS)
+
+if WANT_SYNCAPI
+noinst_LTLIBRARIES += libzkmt.la
+libzkmt_la_SOURCES =$(COMMON_SRC) src/mt_adaptor.c
+libzkmt_la_CFLAGS = -DTHREADED
+libzkmt_la_LIBADD = -lm
+
+lib_LTLIBRARIES += libzookeeper_mt.la
+libzookeeper_mt_la_SOURCES =
+libzookeeper_mt_la_LIBADD=libzkmt.la libhashtable.la -lpthread
+libzookeeper_mt_la_DEPENDENCIES=libzkmt.la libhashtable.la
+libzookeeper_mt_la_LDFLAGS = $(LIB_LDFLAGS) -export-symbols-regex $(EXPORT_SYMBOLS)
+endif
+
+bin_PROGRAMS = cli_st
+
+cli_st_SOURCES = src/cli.c
+cli_st_LDADD = libzookeeper_st.la
+
+if WANT_SYNCAPI
+bin_PROGRAMS += cli_mt load_gen
+
+cli_mt_SOURCES = src/cli.c
+cli_mt_LDADD = libzookeeper_mt.la
+cli_mt_CFLAGS = -DTHREADED
+
+load_gen_SOURCES = src/load_gen.c
+load_gen_LDADD = libzookeeper_mt.la
+load_gen_CFLAGS = -DTHREADED
+
+endif
+
+#########################################################################
+# build and run unit tests
+
+EXTRA_DIST+=$(wildcard ${srcdir}/tests/*.cc) $(wildcard ${srcdir}/tests/*.h) \
+    ${srcdir}/tests/wrappers.opt ${srcdir}/tests/wrappers-mt.opt
+
+TEST_SOURCES = tests/TestDriver.cc tests/LibCMocks.cc tests/LibCSymTable.cc \
+    tests/MocksBase.cc  tests/ZKMocks.cc tests/Util.cc tests/ThreadingUtil.cc \
+    tests/TestClientRetry.cc \
+    tests/TestOperations.cc tests/TestZookeeperInit.cc \
+    tests/TestZookeeperClose.cc tests/TestClient.cc \
+    tests/TestMulti.cc tests/TestWatchers.cc
+
+
+if SOLARIS
+  SHELL_SYMBOL_WRAPPERS = cat ${srcdir}/tests/wrappers.opt
+  SYMBOL_WRAPPERS=$(SHELL_SYMBOL_WRAPPERS:sh)
+else
+  SYMBOL_WRAPPERS=$(shell cat ${srcdir}/tests/wrappers.opt)
+endif
+
+check_PROGRAMS = zktest-st
+nodist_zktest_st_SOURCES = $(TEST_SOURCES)
+zktest_st_LDADD = libzkst.la libhashtable.la $(CPPUNIT_LIBS)
+zktest_st_CXXFLAGS = -DUSE_STATIC_LIB $(CPPUNIT_CFLAGS) $(USEIPV6) $(SOLARIS_CPPFLAGS)
+zktest_st_LDFLAGS = -static-libtool-libs $(SYMBOL_WRAPPERS) $(SOLARIS_LIB_LDFLAGS)
+
+if WANT_SYNCAPI
+  check_PROGRAMS += zktest-mt
+  nodist_zktest_mt_SOURCES = $(TEST_SOURCES) tests/PthreadMocks.cc
+  zktest_mt_LDADD = libzkmt.la libhashtable.la -lpthread $(CPPUNIT_LIBS)
+  zktest_mt_CXXFLAGS = -DUSE_STATIC_LIB -DTHREADED $(CPPUNIT_CFLAGS) $(USEIPV6)
+if SOLARIS
+  SHELL_SYMBOL_WRAPPERS_MT = cat ${srcdir}/tests/wrappers-mt.opt
+  SYMBOL_WRAPPERS_MT=$(SYMBOL_WRAPPERS) $(SHELL_SYMBOL_WRAPPERS_MT:sh)
+else
+  SYMBOL_WRAPPERS_MT=$(SYMBOL_WRAPPERS) $(shell cat ${srcdir}/tests/wrappers-mt.opt)
+endif
+  zktest_mt_LDFLAGS = -static-libtool-libs $(SYMBOL_WRAPPERS_MT) $(SOLARIS_LIB_LDFLAGS)
+endif
+
+run-check: check
+	./zktest-st $(TEST_OPTIONS)
+if WANT_SYNCAPI
+	./zktest-mt $(TEST_OPTIONS)
+endif
+
+clean-local: clean-check
+	$(RM) $(DX_CLEANFILES)
+
+clean-check:
+	$(RM) $(nodist_zktest_st_OBJECTS) $(nodist_zktest_mt_OBJECTS)

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/NOTICE.txt
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/NOTICE.txt b/zookeeper-client/zookeeper-client-c/NOTICE.txt
new file mode 100644
index 0000000..dcd9d53
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/NOTICE.txt
@@ -0,0 +1,41 @@
+Apache ZooKeeper
+Copyright 2009-2018 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+----------
+include/winstdint.h is included only for Windows Client support, as follows:
+
+// ISO C9x  compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
+// 
+//  Copyright (c) 2006-2008 Alexander Chemeris
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+//   1. Redistributions of source code must retain the above copyright notice,
+//      this list of conditions and the following disclaimer.
+// 
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+// 
+//   3. The name of the author may be used to endorse or promote products
+//      derived from this software without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// 
+///////////////////////////////////////////////////////////////////////////////
+
+----------

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/README
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/README b/zookeeper-client/zookeeper-client-c/README
new file mode 100644
index 0000000..1ef2cfd
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/README
@@ -0,0 +1,157 @@
+                     Zookeeper C client library 
+
+
+This package provides a C client interface to Zookeeper server.
+
+For the latest information about ZooKeeper, please visit our website at:
+   http://zookeeper.apache.org/
+and our wiki, at:
+   https://cwiki.apache.org/confluence/display/ZOOKEEPER
+
+Full documentation for this release can also be found in ../../docs/index.html
+
+
+OVERVIEW
+
+The client supports two types of APIs -- synchronous and asynchronous.
+
+Asynchronous API provides non-blocking operations with completion callbacks and 
+relies on the application to implement event multiplexing on its behalf.
+
+On the other hand, Synchronous API provides a blocking flavor of
+zookeeper operations and runs its own event loop in a separate thread.
+
+Sync and Async APIs can be mixed and matched within the same application.
+
+The package includes two shared libraries: zookeeper_st and
+zookeeper_mt. The former only provides the Async API and is not
+thread-safe. The only reason this library exists is to support the
+platforms were pthread library is not available or unstable
+(i.e. FreeBSD 4.x). In all other cases the application developers are
+advised to link against zookeeper_mt as it includes support for both
+Sync and Async API.
+
+
+INSTALLATION
+
+If you're building the client from a source checkout you need to
+follow the steps outlined below. If you're building from a release
+tar downloaded from Apache please skip to step 2.
+
+1) do a "ant compile_jute" from the zookeeper top level directory (.../trunk).
+   This will create a directory named "generated" under zookeeper-client/zookeeper-client-c.
+   Skip to step 3.
+2) unzip/untar the source tarball and cd to the zookeeper-x.x.x/zookeeper-client/zookeeper-client-c directory
+3) change directory to zookeeper-client/zookeeper-client-c and do a "autoreconf -if" to bootstrap
+   autoconf, automake and libtool. Please make sure you have autoconf
+   version 2.59 or greater installed. If cppunit is installed in a non-standard
+   directory, you need to specify where to find cppunit.m4. For example, if
+   cppunit is installed under /usr/local, run:
+   
+       ACLOCAL="aclocal -I /usr/local/share/aclocal" autoreconf -if
+
+4) do a "./configure [OPTIONS]" to generate the makefile. See INSTALL
+   for general information about running configure. Additionally, the
+   configure supports the following options:
+   --enable-debug     enables optimization and enables debug info compiler
+                      options, disabled by default
+   --without-syncapi  disables Sync API support; zookeeper_mt library won't
+                      be built, enabled by default
+   --disable-static   do not build static libraries, enabled by default
+   --disable-shared   do not build shared libraries, enabled by default
+   --without-cppunit  do not build the test library, enabled by default.
+
+5) do a "make" or "make install" to build the libraries and install them. 
+   Alternatively, you can also build and run a unit test suite (and
+   you probably should).  Please make sure you have cppunit-1.10.x or
+   higher installed before you execute step 4.  Once ./configure has
+   finished, do a "make run-check". It will build the libraries, build
+   the tests and run them.
+6) to generate doxygen documentation do a "make doxygen-doc". All
+   documentations will be placed to a new subfolder named docs. By
+   default only HTML documentation is generated.  For information on
+   other document formats please use "./configure --help"
+
+Alternatively you can use the CMake build system. On Windows, this is required.
+Follow steps 1 and 2 above, and then continue here.
+
+1) do a "cmake [OPTIONS]" to generate the makefile or msbuild files (the correct
+   build system will be generated based on your platform). Some options from above
+   are supported:
+   -DCMAKE_BUILD_TYPE  Debug by default, Release enables optimzation etc.
+   -DWANT_SYNCAPI      ON by default, OFF disables the Sync API support
+   -DWANT_CPPUNIT      ON except on Windows, OFF disables the tests
+   -DBUILD_SHARED_LIBS not yet supported, only static libraries are built
+   other CMake options see "cmake --help" for generic options, such as generator
+
+2) do a "cmake --build ." to build the default targets. Alternatively you can
+   invoke "make" or "msbuild" manually. If the tests were enabled, use "ctest -V"
+   to run them.
+
+Current limitations of the CMake build system include lack of Solaris support,
+no shared library option, no explicitly exported symbols (all are exported by
+default), no versions on the libraries, and no documentation generation.
+Features of CMake include a single, easily consumed cross-platform build system
+to generate the ZooKeeper C Client libraries for any project, with little to no
+configuration.
+
+EXAMPLE/SAMPLE C CLIENT SHELL
+
+NOTE: the ZooKeeper C client shell (cli_st and cli_mt) is meant as a
+example/sample of ZooKeeper C client API usage. It is not a full
+fledged client and not meant for production usage - see the Java
+client shell for a fully featured shell.
+
+You can test your client by running a zookeeper server (see
+instructions on the project wiki page on how to run it) and connecting
+to it using the zookeeper shell application cli that is built as part
+of the installation procedure.
+
+cli_mt (multithreaded, built against zookeeper_mt library) is shown in
+this example, but you could also use cli_st (singlethreaded, built
+against zookeeper_st library):
+
+$ cli_mt zookeeper_host:9876
+
+This is a client application that gives you a shell for executing
+simple zookeeper commands. Once successfully started and connected to
+the server it displays a shell prompt.
+
+You can now enter zookeeper commands. For example, to create a node:
+
+> create /my_new_node
+
+To verify that the node's been created:
+
+> ls /
+
+You should see a list of nodes who are the children of the root node "/".
+
+Here's a list of command supported by the cli shell:
+
+ls <path>             -- list children of a znode identified by <path>. The
+                         command set a children watch on the znode.
+get <path>            -- get the value of a znode at <path>
+set <path> <value>    -- set the value of a znode at <path> to <value>
+create [+e|+s] <path> -- create a znode as a child of znode <path>; 
+                         use +e option to create an ephemeral znode,
+                         use +s option to create a znode with a sequence number 
+                         appended to the name. The operation will fail if 
+                         the parent znode (the one identified by <path>) doesn't
+                         exist.
+delete <path>         -- delete the znode at <path>. The command will fail if the znode
+                         has children.
+sync <path>           -- make sure all pending updates have been applied to znode at <path>
+exists <path>         -- returns a result code indicating whether the znode at <path>
+                         exists. The command also sets a znode watch.
+myid                  -- prints out the current zookeeper session id.
+quit                  -- exit the shell.
+
+In order to be able to use the zookeeper API in your application you have to
+1) remember to include the zookeeper header 
+   #include <zookeeper/zookeeper.h>
+2) use -DTHREADED compiler option to enable Sync API; in this case you should
+   be linking your code against zookeeper_mt library
+
+Please take a look at cli.c to understand how to use the two API types. 
+(TODO: some kind of short tutorial would be helpful, I guess)

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/acinclude.m4
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/acinclude.m4 b/zookeeper-client/zookeeper-client-c/acinclude.m4
new file mode 100644
index 0000000..d0041d8
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/acinclude.m4
@@ -0,0 +1,312 @@
+# This file is part of Autoconf.                       -*- Autoconf -*-
+
+# Copyright (C) 2004 Oren Ben-Kiki
+# This file is distributed under the same terms as the Autoconf macro files.
+
+# Generate automatic documentation using Doxygen. Works in concert with the
+# aminclude.m4 file and a compatible doxygen configuration file. Defines the
+# following public macros:
+#
+# DX_???_FEATURE(ON|OFF) - control the default setting fo a Doxygen feature.
+# Supported features are 'DOXYGEN' itself, 'DOT' for generating graphics,
+# 'HTML' for plain HTML, 'CHM' for compressed HTML help (for MS users), 'CHI'
+# for generating a seperate .chi file by the .chm file, and 'MAN', 'RTF',
+# 'XML', 'PDF' and 'PS' for the appropriate output formats. The environment
+# variable DOXYGEN_PAPER_SIZE may be specified to override the default 'a4wide'
+# paper size.
+#
+# By default, HTML, PDF and PS documentation is generated as this seems to be
+# the most popular and portable combination. MAN pages created by Doxygen are
+# usually problematic, though by picking an appropriate subset and doing some
+# massaging they might be better than nothing. CHM and RTF are specific for MS
+# (note that you can't generate both HTML and CHM at the same time). The XML is
+# rather useless unless you apply specialized post-processing to it.
+#
+# The macro mainly controls the default state of the feature. The use can
+# override the default by specifying --enable or --disable. The macros ensure
+# that contradictory flags are not given (e.g., --enable-doxygen-html and
+# --enable-doxygen-chm, --enable-doxygen-anything with --disable-doxygen, etc.)
+# Finally, each feature will be automatically disabled (with a warning) if the
+# required programs are missing.
+#
+# Once all the feature defaults have been specified, call DX_INIT_DOXYGEN with
+# the following parameters: a one-word name for the project for use as a
+# filename base etc., an optional configuration file name (the default is
+# 'Doxyfile', the same as Doxygen's default), and an optional output directory
+# name (the default is 'doxygen-doc').
+
+## ----------##
+## Defaults. ##
+## ----------##
+
+DX_ENV=""
+AC_DEFUN([DX_FEATURE_doc],  ON)
+AC_DEFUN([DX_FEATURE_dot],  ON)
+AC_DEFUN([DX_FEATURE_man],  OFF)
+AC_DEFUN([DX_FEATURE_html], ON)
+AC_DEFUN([DX_FEATURE_chm],  OFF)
+AC_DEFUN([DX_FEATURE_chi],  OFF)
+AC_DEFUN([DX_FEATURE_rtf],  OFF)
+AC_DEFUN([DX_FEATURE_xml],  OFF)
+AC_DEFUN([DX_FEATURE_pdf],  ON)
+AC_DEFUN([DX_FEATURE_ps],   ON)
+
+## --------------- ##
+## Private macros. ##
+## --------------- ##
+
+# DX_ENV_APPEND(VARIABLE, VALUE)
+# ------------------------------
+# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen.
+AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])])
+
+# DX_DIRNAME_EXPR
+# ---------------
+# Expand into a shell expression prints the directory part of a path.
+AC_DEFUN([DX_DIRNAME_EXPR],
+         [[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']])
+
+# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)
+# -------------------------------------
+# Expands according to the M4 (static) status of the feature.
+AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])
+
+# DX_REQUIRE_PROG(VARIABLE, PROGRAM)
+# ----------------------------------
+# Require the specified program to be found for the DX_CURRENT_FEATURE to work.
+AC_DEFUN([DX_REQUIRE_PROG], [
+AC_PATH_TOOL([$1], [$2])
+if test "$DX_FLAG_$[DX_CURRENT_FEATURE$$1]" = 1; then
+    AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
+    AC_SUBST([DX_FLAG_]DX_CURRENT_FEATURE, 0)
+fi
+])
+
+# DX_TEST_FEATURE(FEATURE)
+# ------------------------
+# Expand to a shell expression testing whether the feature is active.
+AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1])
+
+# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)
+# -------------------------------------------------
+# Verify that a required features has the right state before trying to turn on
+# the DX_CURRENT_FEATURE.
+AC_DEFUN([DX_CHECK_DEPEND], [
+test "$DX_FLAG_$1" = "$2" \
+|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,
+                            requires, contradicts) doxygen-DX_CURRENT_FEATURE])
+])
+
+# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)
+# ----------------------------------------------------------
+# Turn off the DX_CURRENT_FEATURE if the required feature is off.
+AC_DEFUN([DX_CLEAR_DEPEND], [
+test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_]DX_CURRENT_FEATURE, 0)
+])
+
+# DX_FEATURE_ARG(FEATURE, DESCRIPTION,
+#                CHECK_DEPEND, CLEAR_DEPEND,
+#                REQUIRE, DO-IF-ON, DO-IF-OFF)
+# --------------------------------------------
+# Parse the command-line option controlling a feature. CHECK_DEPEND is called
+# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),
+# otherwise CLEAR_DEPEND is called to turn off the default state if a required
+# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional
+# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and
+# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.
+AC_DEFUN([DX_ARG_ABLE], [
+    AC_DEFUN([DX_CURRENT_FEATURE], [$1])
+    AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])
+    AC_ARG_ENABLE(doxygen-$1,
+                  [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],
+                                                      [--enable-doxygen-$1]),
+                                  DX_IF_FEATURE([$1], [don't $2], [$2]))],
+                  [
+case "$enableval" in
+#(
+y|Y|yes|Yes|YES)
+    AC_SUBST([DX_FLAG_$1], 1)
+    $3
+;; #(
+n|N|no|No|NO)
+    AC_SUBST([DX_FLAG_$1], 0)
+;; #(
+*)
+    AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])
+;;
+esac
+], [
+AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])
+$4
+])
+if DX_TEST_FEATURE([$1]); then
+    $5
+    :
+fi
+if DX_TEST_FEATURE([$1]); then
+    AM_CONDITIONAL(DX_COND_$1, :)
+    $6
+    :
+else
+    AM_CONDITIONAL(DX_COND_$1, false)
+    $7
+    :
+fi
+])
+
+## -------------- ##
+## Public macros. ##
+## -------------- ##
+
+# DX_XXX_FEATURE(DEFAULT_STATE)
+# -----------------------------
+AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc],  [$1])])
+AC_DEFUN([DX_MAN_FEATURE],     [AC_DEFUN([DX_FEATURE_man],  [$1])])
+AC_DEFUN([DX_HTML_FEATURE],    [AC_DEFUN([DX_FEATURE_html], [$1])])
+AC_DEFUN([DX_CHM_FEATURE],     [AC_DEFUN([DX_FEATURE_chm],  [$1])])
+AC_DEFUN([DX_CHI_FEATURE],     [AC_DEFUN([DX_FEATURE_chi],  [$1])])
+AC_DEFUN([DX_RTF_FEATURE],     [AC_DEFUN([DX_FEATURE_rtf],  [$1])])
+AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
+AC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])
+AC_DEFUN([DX_PDF_FEATURE],     [AC_DEFUN([DX_FEATURE_pdf],  [$1])])
+AC_DEFUN([DX_PS_FEATURE],      [AC_DEFUN([DX_FEATURE_ps],   [$1])])
+
+# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR])
+# ---------------------------------------------------------
+# PROJECT also serves as the base name for the documentation files.
+# The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc".
+AC_DEFUN([DX_INIT_DOXYGEN], [
+
+# Files:
+AC_SUBST([DX_PROJECT], [$1])
+AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])])
+AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])])
+
+# Environment variables used inside doxygen.cfg:
+DX_ENV_APPEND(SRCDIR, $srcdir)
+DX_ENV_APPEND(PROJECT, $DX_PROJECT)
+DX_ENV_APPEND(DOCDIR, $DX_DOCDIR)
+DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
+
+# Doxygen itself:
+DX_ARG_ABLE(doc, [generate any doxygen documentation],
+            [],
+            [],
+            [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)
+             DX_REQUIRE_PROG([DX_PERL], perl)],
+            [DX_ENV_APPEND(PERL_PATH, $DX_PERL)])
+
+# Dot for graphics:
+DX_ARG_ABLE(dot, [generate graphics for doxygen documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_DOT], dot)],
+            [DX_ENV_APPEND(HAVE_DOT, YES)
+             DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],
+            [DX_ENV_APPEND(HAVE_DOT, NO)])
+
+# Man pages generation:
+DX_ARG_ABLE(man, [generate doxygen manual pages],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_MAN, YES)],
+            [DX_ENV_APPEND(GENERATE_MAN, NO)])
+
+# RTF file generation:
+DX_ARG_ABLE(rtf, [generate doxygen RTF documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_RTF, YES)],
+            [DX_ENV_APPEND(GENERATE_RTF, NO)])
+
+# XML file generation:
+DX_ARG_ABLE(xml, [generate doxygen XML documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_XML, YES)],
+            [DX_ENV_APPEND(GENERATE_XML, NO)])
+
+# (Compressed) HTML help generation:
+DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_HHC], hhc)],
+            [DX_ENV_APPEND(HHC_PATH, $DX_HHC)
+             DX_ENV_APPEND(GENERATE_HTML, YES)
+             DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],
+            [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])
+
+# Seperate CHI file generation.
+DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file],
+            [DX_CHECK_DEPEND(chm, 1)],
+            [DX_CLEAR_DEPEND(chm, 1)],
+            [],
+            [DX_ENV_APPEND(GENERATE_CHI, YES)],
+            [DX_ENV_APPEND(GENERATE_CHI, NO)])
+
+# Plain HTML pages generation:
+DX_ARG_ABLE(html, [generate doxygen plain HTML documentation],
+            [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],
+            [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],
+            [],
+            [DX_ENV_APPEND(GENERATE_HTML, YES)],
+            [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])
+
+# PostScript file generation:
+DX_ARG_ABLE(ps, [generate doxygen PostScript documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_LATEX], latex)
+             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
+             DX_REQUIRE_PROG([DX_DVIPS], dvips)
+             DX_REQUIRE_PROG([DX_EGREP], egrep)])
+
+# PDF file generation:
+DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],
+            [DX_CHECK_DEPEND(doc, 1)],
+            [DX_CLEAR_DEPEND(doc, 1)],
+            [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)
+             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
+             DX_REQUIRE_PROG([DX_EGREP], egrep)])
+
+# LaTeX generation for PS and/or PDF:
+if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
+    AM_CONDITIONAL(DX_COND_latex, :)
+    DX_ENV_APPEND(GENERATE_LATEX, YES)
+else
+    AM_CONDITIONAL(DX_COND_latex, false)
+    DX_ENV_APPEND(GENERATE_LATEX, NO)
+fi
+
+# Paper size for PS and/or PDF:
+AC_ARG_VAR(DOXYGEN_PAPER_SIZE,
+           [a4wide (default), a4, letter, legal or executive])
+case "$DOXYGEN_PAPER_SIZE" in
+#(
+"")
+    AC_SUBST(DOXYGEN_PAPER_SIZE, "")
+;; #(
+a4wide|a4|letter|legal|executive)
+    DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)
+;; #(
+*)
+    AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])
+;;
+esac
+
+#For debugging:
+#echo DX_FLAG_doc=$DX_FLAG_doc
+#echo DX_FLAG_dot=$DX_FLAG_dot
+#echo DX_FLAG_man=$DX_FLAG_man
+#echo DX_FLAG_html=$DX_FLAG_html
+#echo DX_FLAG_chm=$DX_FLAG_chm
+#echo DX_FLAG_chi=$DX_FLAG_chi
+#echo DX_FLAG_rtf=$DX_FLAG_rtf
+#echo DX_FLAG_xml=$DX_FLAG_xml
+#echo DX_FLAG_pdf=$DX_FLAG_pdf
+#echo DX_FLAG_ps=$DX_FLAG_ps
+#echo DX_ENV=$DX_ENV
+])

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/aminclude.am
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/aminclude.am b/zookeeper-client/zookeeper-client-c/aminclude.am
new file mode 100644
index 0000000..420049e
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/aminclude.am
@@ -0,0 +1,186 @@
+# Copyright (C) 2004 Oren Ben-Kiki
+# This file is distributed under the same terms as the Automake macro files.
+
+# Generate automatic documentation using Doxygen. Goals and variables values
+# are controlled by the various DX_COND_??? conditionals set by autoconf.
+#
+# The provided goals are:
+# doxygen-doc: Generate all doxygen documentation.
+# doxygen-run: Run doxygen, which will generate some of the documentation
+#              (HTML, CHM, CHI, MAN, RTF, XML) but will not do the post
+#              processing required for the rest of it (PS, PDF, and some MAN).
+# doxygen-man: Rename some doxygen generated man pages.
+# doxygen-ps: Generate doxygen PostScript documentation.
+# doxygen-pdf: Generate doxygen PDF documentation.
+#
+# Note that by default these are not integrated into the automake goals. If
+# doxygen is used to generate man pages, you can achieve this integration by
+# setting man3_MANS to the list of man pages generated and then adding the
+# dependency:
+#
+#   $(man3_MANS): doxygen-doc
+#
+# This will cause make to run doxygen and generate all the documentation.
+#
+# The following variable is intended for use in Makefile.am:
+#
+# DX_CLEANFILES = everything to clean.
+#
+# This is usually added to MOSTLYCLEANFILES.
+
+## --------------------------------- ##
+## Format-independent Doxygen rules. ##
+## --------------------------------- ##
+
+if DX_COND_doc
+
+## ------------------------------- ##
+## Rules specific for HTML output. ##
+## ------------------------------- ##
+
+if DX_COND_html
+
+DX_CLEAN_HTML = @DX_DOCDIR@/html
+
+endif DX_COND_html
+
+## ------------------------------ ##
+## Rules specific for CHM output. ##
+## ------------------------------ ##
+
+if DX_COND_chm
+
+DX_CLEAN_CHM = @DX_DOCDIR@/chm
+
+if DX_COND_chi
+
+DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi
+
+endif DX_COND_chi
+
+endif DX_COND_chm
+
+## ------------------------------ ##
+## Rules specific for MAN output. ##
+## ------------------------------ ##
+
+if DX_COND_man
+
+DX_CLEAN_MAN = @DX_DOCDIR@/man
+
+endif DX_COND_man
+
+## ------------------------------ ##
+## Rules specific for RTF output. ##
+## ------------------------------ ##
+
+if DX_COND_rtf
+
+DX_CLEAN_RTF = @DX_DOCDIR@/rtf
+
+endif DX_COND_rtf
+
+## ------------------------------ ##
+## Rules specific for XML output. ##
+## ------------------------------ ##
+
+if DX_COND_xml
+
+DX_CLEAN_XML = @DX_DOCDIR@/xml
+
+endif DX_COND_xml
+
+## ----------------------------- ##
+## Rules specific for PS output. ##
+## ----------------------------- ##
+
+if DX_COND_ps
+
+DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps
+
+DX_PS_GOAL = doxygen-ps
+
+doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps
+
+@DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag
+	cd @DX_DOCDIR@/latex; \
+	rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
+	$(DX_LATEX) refman.tex; \
+	$(MAKEINDEX_PATH) refman.idx; \
+	$(DX_LATEX) refman.tex; \
+	countdown=5; \
+	while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
+	                  refman.log > /dev/null 2>&1 \
+	   && test $$countdown -gt 0; do \
+	    $(DX_LATEX) refman.tex; \
+	    countdown=`expr $$countdown - 1`; \
+	done; \
+	$(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi
+
+endif DX_COND_ps
+
+## ------------------------------ ##
+## Rules specific for PDF output. ##
+## ------------------------------ ##
+
+if DX_COND_pdf
+
+DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf
+
+DX_PDF_GOAL = doxygen-pdf
+
+doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf
+
+@DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag
+	cd @DX_DOCDIR@/latex; \
+	rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
+	$(DX_PDFLATEX) refman.tex; \
+	$(DX_MAKEINDEX) refman.idx; \
+	$(DX_PDFLATEX) refman.tex; \
+	countdown=5; \
+	while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
+	                  refman.log > /dev/null 2>&1 \
+	   && test $$countdown -gt 0; do \
+	    $(DX_PDFLATEX) refman.tex; \
+	    countdown=`expr $$countdown - 1`; \
+	done; \
+	mv refman.pdf ../@PACKAGE@.pdf
+
+endif DX_COND_pdf
+
+## ------------------------------------------------- ##
+## Rules specific for LaTeX (shared for PS and PDF). ##
+## ------------------------------------------------- ##
+
+if DX_COND_latex
+
+DX_CLEAN_LATEX = @DX_DOCDIR@/latex
+
+endif DX_COND_latex
+
+.PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
+
+.INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
+
+doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag
+
+doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
+
+@DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS)
+	rm -rf @DX_DOCDIR@
+	$(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG)
+
+DX_CLEANFILES = \
+    @DX_DOCDIR@/@PACKAGE@.tag \
+    -r \
+    $(DX_CLEAN_HTML) \
+    $(DX_CLEAN_CHM) \
+    $(DX_CLEAN_CHI) \
+    $(DX_CLEAN_MAN) \
+    $(DX_CLEAN_RTF) \
+    $(DX_CLEAN_XML) \
+    $(DX_CLEAN_PS) \
+    $(DX_CLEAN_PDF) \
+    $(DX_CLEAN_LATEX)
+
+endif DX_COND_doc


[19/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/c-doc.Doxyfile
----------------------------------------------------------------------
diff --git a/src/c/c-doc.Doxyfile b/src/c/c-doc.Doxyfile
deleted file mode 100644
index e9029cb..0000000
--- a/src/c/c-doc.Doxyfile
+++ /dev/null
@@ -1,1252 +0,0 @@
-# Doxyfile 1.4.7
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-#       TAG = value [value, ...]
-# For lists items can also be appended using:
-#       TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
-# by quotes) that should identify the project.
-
-PROJECT_NAME = $(PROJECT)-$(VERSION)
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
-# This could be handy for archiving the generated documentation or 
-# if some version control system is used.
-
-PROJECT_NUMBER = 
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
-# base path where the generated documentation will be put. 
-# If a relative path is entered, it will be relative to the location 
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY = $(DOCDIR)
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
-# 4096 sub-directories (in 2 levels) under the output directory of each output 
-# format and will distribute the generated files over these directories. 
-# Enabling this option can be useful when feeding doxygen a huge amount of 
-# source files, where putting all generated files in the same directory would 
-# otherwise cause performance problems for the file system.
-
-CREATE_SUBDIRS = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
-# documentation generated by doxygen is written. Doxygen will use this 
-# information to generate all constant output in the proper language. 
-# The default language is English, other supported languages are: 
-# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, 
-# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, 
-# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, 
-# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, 
-# Swedish, and Ukrainian.
-
-OUTPUT_LANGUAGE = English
-
-# This tag can be used to specify the encoding used in the generated output. 
-# The encoding is not always determined by the language that is chosen, 
-# but also whether or not the output is meant for Windows or non-Windows users. 
-# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
-# forces the Windows encoding (this is the default for the Windows binary), 
-# whereas setting the tag to NO uses a Unix-style encoding (the default for 
-# all platforms other than Windows).
-
-USE_WINDOWS_ENCODING = NO
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
-# include brief member descriptions after the members that are listed in 
-# the file and class documentation (similar to JavaDoc). 
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
-# the brief description of a member or function before the detailed description. 
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator 
-# that is used to form the text in various listings. Each string 
-# in this list, if found as the leading text of the brief description, will be 
-# stripped from the text and the result after processing the whole list, is 
-# used as the annotated text. Otherwise, the brief description is used as-is. 
-# If left blank, the following values are used ("$name" is automatically 
-# replaced with the name of the entity): "The $name class" "The $name widget" 
-# "The $name file" "is" "provides" "specifies" "contains" 
-# "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF = 
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
-# Doxygen will generate a detailed section even if there is only a brief 
-# description.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
-# inherited members of a class in the documentation of that class as if those 
-# members were ordinary class members. Constructors, destructors and assignment 
-# operators of the base classes will not be shown.
-
-INLINE_INHERITED_MEMB = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
-# path before files name in the file list and in the header files. If set 
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES = YES
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
-# can be used to strip a user-defined part of the path. Stripping is 
-# only done if one of the specified strings matches the left-hand part of 
-# the path. The tag can be used to show relative paths in the file list. 
-# If left blank the directory from which doxygen is run is used as the 
-# path to strip.
-
-STRIP_FROM_PATH = 
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
-# the path mentioned in the documentation of a class, which tells 
-# the reader which header file to include in order to use a class. 
-# If left blank only the name of the header file containing the class 
-# definition is used. Otherwise one should specify the include paths that 
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH = 
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
-# (but less readable) file names. This can be useful is your file systems 
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
-# will interpret the first line (until the first dot) of a JavaDoc-style 
-# comment as the brief description. If set to NO, the JavaDoc 
-# comments will behave just like the Qt-style comments (thus requiring an 
-# explicit @brief command for a brief description.
-
-JAVADOC_AUTOBRIEF = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
-# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
-# comments) as a brief description. This used to be the default behaviour. 
-# The new default is to treat a multi-line C++ comment block as a detailed 
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
-# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member 
-# documentation.
-
-DETAILS_AT_TOP = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
-# member inherits the documentation from any documented member that it 
-# re-implements.
-
-INHERIT_DOCS = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
-# a new page for each member. If set to NO, the documentation of a member will 
-# be part of the file/class/namespace that contains it.
-
-SEPARATE_MEMBER_PAGES = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE = 8
-
-# This tag can be used to specify a number of aliases that acts 
-# as commands in the documentation. An alias has the form "name=value". 
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
-# put the command \sideeffect (or @sideeffect) in the documentation, which 
-# will result in a user-defined paragraph with heading "Side Effects:". 
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES = 
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
-# sources only. Doxygen will then generate output that is more tailored for C. 
-# For instance, some of the names that are used will be different. The list 
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C = YES
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
-# sources only. Doxygen will then generate output that is more tailored for Java. 
-# For instance, namespaces will be presented as packages, qualified scopes 
-# will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA = NO
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to 
-# include (a tag file for) the STL sources as input, then you should 
-# set this tag to YES in order to let doxygen match functions declarations and 
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
-# func(std::string) {}). This also make the inheritance and collaboration 
-# diagrams that involve STL classes more complete and accurate.
-
-BUILTIN_STL_SUPPORT = NO
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
-# tag is set to YES, then doxygen will reuse the documentation of the first 
-# member in the group (if any) for the other members of the group. By default 
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
-# the same type (for instance a group of public functions) to be put as a 
-# subgroup of that type (e.g. under the Public Functions section). Set it to 
-# NO to prevent subgrouping. Alternatively, this can be done per class using 
-# the \nosubgrouping command.
-
-SUBGROUPING = YES
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
-# documentation are documented, even if no documentation was available. 
-# Private class members and static file members will be hidden unless 
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL = NO
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
-# will be included in the documentation.
-
-EXTRACT_PRIVATE = NO
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file 
-# will be included in the documentation.
-
-EXTRACT_STATIC = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
-# defined locally in source files will be included in the documentation. 
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES = YES
-
-# This flag is only useful for Objective-C code. When set to YES local 
-# methods, which are defined in the implementation section but not in 
-# the interface are included in the documentation. 
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
-# undocumented members of documented classes, files or namespaces. 
-# If set to NO (the default) these members will be included in the 
-# various overviews, but no documentation section is generated. 
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
-# undocumented classes that are normally visible in the class hierarchy. 
-# If set to NO (the default) these classes will be included in the various 
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
-# friend (class|struct|union) declarations. 
-# If set to NO (the default) these declarations will be included in the 
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
-# documentation blocks found inside the body of a function. 
-# If set to NO (the default) these blocks will be appended to the 
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS = NO
-
-# The INTERNAL_DOCS tag determines if documentation 
-# that is typed after a \internal command is included. If the tag is set 
-# to NO (the default) then the documentation will be excluded. 
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
-# file names in lower-case letters. If set to YES upper-case letters are also 
-# allowed. This is useful if you have classes or files whose names only differ 
-# in case and if your file system supports case sensitive file names. Windows 
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
-# will show members with their full class and namespace scopes in the 
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
-# will put a list of the files that are included by a file in the documentation 
-# of that file.
-
-SHOW_INCLUDE_FILES = NO
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
-# is inserted in the documentation for inline members.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
-# will sort the (detailed) documentation of file and class members 
-# alphabetically by member name. If set to NO the members will appear in 
-# declaration order.
-
-SORT_MEMBER_DOCS = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
-# brief documentation of file, namespace and class members alphabetically 
-# by member name. If set to NO (the default) the members will appear in 
-# declaration order.
-
-SORT_BRIEF_DOCS = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
-# sorted by fully-qualified names, including namespaces. If set to 
-# NO (the default), the class list will be sorted only by class name, 
-# not including the namespace part. 
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the 
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or 
-# disable (NO) the todo list. This list is created by putting \todo 
-# commands in the documentation.
-
-GENERATE_TODOLIST = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or 
-# disable (NO) the test list. This list is created by putting \test 
-# commands in the documentation.
-
-GENERATE_TESTLIST = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or 
-# disable (NO) the bug list. This list is created by putting \bug 
-# commands in the documentation.
-
-GENERATE_BUGLIST = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
-# disable (NO) the deprecated list. This list is created by putting 
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST = YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional 
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS = 
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
-# the initial value of a variable or define consists of for it to appear in 
-# the documentation. If the initializer consists of more lines than specified 
-# here it will be hidden. Use a value of 0 to hide initializers completely. 
-# The appearance of the initializer of individual variables and defines in the 
-# documentation can be controlled using \showinitializer or \hideinitializer 
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
-# at the bottom of the documentation of classes and structs. If set to YES the 
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES = YES
-
-# If the sources in your project are distributed over multiple directories 
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
-# in the documentation. The default is NO.
-
-SHOW_DIRECTORIES = NO
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
-# doxygen should invoke to get the current version for each file (typically from the 
-# version control system). Doxygen will invoke the program by executing (via 
-# popen()) the command <command> <input-file>, where <command> is the value of 
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
-# provided by doxygen. Whatever the program writes to standard output 
-# is used as the file version. See the manual for examples.
-
-FILE_VERSION_FILTER = 
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated 
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are 
-# generated by doxygen. Possible values are YES and NO. If left blank 
-# NO is used.
-
-WARNINGS = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED = YES
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
-# potential errors in the documentation, such as not documenting some 
-# parameters in a documented function, or documenting parameters that 
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR = YES
-
-# This WARN_NO_PARAMDOC option can be abled to get warnings for 
-# functions that are documented, but have no documentation for their parameters 
-# or return value. If set to NO (the default) doxygen will only warn about 
-# wrong or incomplete parameter documentation, but not about the absence of 
-# documentation.
-
-WARN_NO_PARAMDOC = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that 
-# doxygen can produce. The string should contain the $file, $line, and $text 
-# tags, which will be replaced by the file and line number from which the 
-# warning originated and the warning text. Optionally the format may contain 
-# $version, which will be replaced by the version of the file (if it could 
-# be obtained via FILE_VERSION_FILTER)
-
-WARN_FORMAT = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning 
-# and error messages should be written. If left blank the output is written 
-# to stderr.
-
-WARN_LOGFILE = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain 
-# documented source files. You may enter file names like "myfile.cpp" or 
-# directories like "/usr/src/myproject". Separate the files or directories 
-# with spaces.
-
-INPUT = include/zookeeper.h
-
-# If the value of the INPUT tag contains directories, you can use the 
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank the following patterns are tested: 
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
-# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
-
-FILE_PATTERNS = 
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
-# should be searched for input files as well. Possible values are YES and NO. 
-# If left blank NO is used.
-
-RECURSIVE = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should 
-# excluded from the INPUT source files. This way you can easily exclude a 
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE = 
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
-# directories that are symbolic links (a Unix filesystem feature) are excluded 
-# from the input.
-
-EXCLUDE_SYMLINKS = NO
-
-# If the value of the INPUT tag contains directories, you can use the 
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
-# certain files from those directories. Note that the wildcards are matched 
-# against the file with absolute path, so to exclude all test directories 
-# for example use the pattern */test/*
-
-EXCLUDE_PATTERNS = 
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or 
-# directories that contain example code fragments that are included (see 
-# the \include command).
-
-EXAMPLE_PATH = 
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank all files are included.
-
-EXAMPLE_PATTERNS = 
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
-# searched for input files to be used with the \include or \dontinclude 
-# commands irrespective of the value of the RECURSIVE tag. 
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or 
-# directories that contain image that are included in the documentation (see 
-# the \image command).
-
-IMAGE_PATH = 
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should 
-# invoke to filter for each input file. Doxygen will invoke the filter program 
-# by executing (via popen()) the command <filter> <input-file>, where <filter> 
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
-# input file. Doxygen will then use the output that the filter program writes 
-# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
-# ignored.
-
-INPUT_FILTER = 
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
-# basis.  Doxygen will compare the file name with each pattern and apply the 
-# filter if there is a match.  The filters are a list of the form: 
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
-# is applied to all files.
-
-FILTER_PATTERNS = 
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
-# INPUT_FILTER) will be used to filter the input files when producing source 
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
-# be generated. Documented entities will be cross-referenced with these sources. 
-# Note: To get rid of all source code in the generated output, make sure also 
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER = NO
-
-# Setting the INLINE_SOURCES tag to YES will include the body 
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
-# doxygen to hide any special comment blocks from generated source code 
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
-# then for each documented function all documented 
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES (the default) 
-# then for each documented function all documented entities 
-# called/used by that function will be listed.
-
-REFERENCES_RELATION = YES
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
-# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
-# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
-# link to the source code.  Otherwise they will link to the documentstion.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code 
-# will point to the HTML generated by the htags(1) tool instead of doxygen 
-# built-in source browser. The htags tool is part of GNU's global source 
-# tagging system (see http://www.gnu.org/software/global/global.html). You 
-# will need version 4.8.6 or higher.
-
-USE_HTAGS = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
-# will generate a verbatim copy of the header file for each class for 
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
-# of all compounds will be generated. Enable this if the project 
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX = NO
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX = 5
-
-# In case all classes in a project start with a common prefix, all 
-# classes will be put under the same header in the alphabetical index. 
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
-# generate HTML output.
-
-GENERATE_HTML = $(GENERATE_HTML)
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard header.
-
-HTML_HEADER = 
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard footer.
-
-HTML_FOOTER = 
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
-# style sheet that is used by each HTML page. It can be used to 
-# fine-tune the look of the HTML output. If the tag is left blank doxygen 
-# will generate a default style sheet. Note that doxygen will try to copy 
-# the style sheet file to the HTML output directory, so don't put your own 
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET = 
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
-# files or namespaces will be aligned in HTML using tables. If set to 
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
-# will be generated that can be used as input for tools like the 
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP = $(GENERATE_HTMLHELP)
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
-# be used to specify the file name of the resulting .chm file. You 
-# can add a path in front of the file if the result should not be 
-# written to the html output directory.
-
-CHM_FILE = ../$(PROJECT).chm
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
-# be used to specify the location (absolute path including file name) of 
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION = $(HHC_PATH)
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
-# controls if a separate .chi index file is generated (YES) or that 
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI = $(GENERATE_CHI)
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
-# controls whether a binary table of contents is generated (YES) or a 
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members 
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
-# top of each HTML page. The value NO (the default) enables the index and 
-# the value YES disables it.
-
-DISABLE_INDEX = NO
-
-# This tag can be used to set the number of enum values (range [1..20]) 
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE = 4
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that 
-# is generated for HTML Help). For this to work a browser that supports 
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
-# probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
-# used to set the initial width (in pixels) of the frame in which the tree 
-# is shown.
-
-TREEVIEW_WIDTH = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
-# generate Latex output.
-
-GENERATE_LATEX = $(GENERATE_LATEX)
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
-# invoked. If left blank `latex' will be used as the default command name.
-
-LATEX_CMD_NAME = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
-# generate index for LaTeX. If left blank `makeindex' will be used as the 
-# default command name.
-
-MAKEINDEX_CMD_NAME = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
-# LaTeX documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used 
-# by the printer. Possible values are: a4, a4wide, letter, legal and 
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE = $(PAPER_SIZE)
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES = 
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
-# the generated latex document. The header should contain everything until 
-# the first chapter. If it is left blank doxygen will generate a 
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER = 
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
-# contain links (just like the HTML output) instead of page references 
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS = NO
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
-# plain latex in the generated Makefile. Set this option to YES to get a 
-# higher quality PDF documentation.
-
-USE_PDFLATEX = $(GENERATE_PDF)
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
-# command to the generated LaTeX files. This will instruct LaTeX to keep 
-# running if errors occur, instead of asking the user for help. 
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
-# include the index chapters (such as File Index, Compound Index, etc.) 
-# in the output.
-
-LATEX_HIDE_INDICES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
-# The RTF output is optimized for Word 97 and may not look very pretty with 
-# other RTF readers or editors.
-
-GENERATE_RTF = $(GENERATE_RTF)
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
-# RTF documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
-# will contain hyperlink fields. The RTF file will 
-# contain links (just like the HTML output) instead of page references. 
-# This makes the output suitable for online browsing using WORD or other 
-# programs which support those fields. 
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's 
-# config file, i.e. a series of assignments. You only have to provide 
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE = 
-
-# Set optional variables used in the generation of an rtf document. 
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
-# generate man pages
-
-GENERATE_MAN = $(GENERATE_MAN)
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT = man
-
-# The MAN_EXTENSION tag determines the extension that is added to 
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION = .3
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
-# then it will generate one additional man file for each entity 
-# documented in the real man page(s). These additional files 
-# only source the real man page, but without them the man command 
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will 
-# generate an XML file that captures the structure of 
-# the code including all documentation.
-
-GENERATE_XML = $(GENERATE_XML)
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_SCHEMA = 
-
-# The XML_DTD tag can be used to specify an XML DTD, 
-# which can be used by a validating XML parser to check the 
-# syntax of the XML files.
-
-XML_DTD = 
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
-# dump the program listings (including syntax highlighting 
-# and cross-referencing information) to the XML output. Note that 
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
-# generate an AutoGen Definitions (see autogen.sf.net) file 
-# that captures the structure of the code including all 
-# documentation. Note that this feature is still experimental 
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
-# generate a Perl module file that captures the structure of 
-# the code including all documentation. Note that this 
-# feature is still experimental and incomplete at the 
-# moment.
-
-GENERATE_PERLMOD = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
-# nicely formatted so it can be parsed by a human reader.  This is useful 
-# if you want to understand what is going on.  On the other hand, if this 
-# tag is set to NO the size of the Perl module output will be much smaller 
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY = YES
-
-# The names of the make variables in the generated doxyrules.make file 
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
-# This is useful so different doxyrules.make files included by the same 
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor   
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
-# evaluate all C-preprocessor directives found in the sources and include 
-# files.
-
-ENABLE_PREPROCESSING = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
-# names in the source code. If set to NO (the default) only conditional 
-# compilation will be performed. Macro expansion can be done in a controlled 
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
-# then the macro expansion is limited to the macros specified with the 
-# PREDEFINED and EXPAND_AS_DEFINED tags.
-
-EXPAND_ONLY_PREDEF = NO
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that 
-# contain include files that are not input files but should be processed by 
-# the preprocessor.
-
-INCLUDE_PATH = 
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
-# patterns (like *.h and *.hpp) to filter out the header-files in the 
-# directories. If left blank, the patterns specified with FILE_PATTERNS will 
-# be used.
-
-INCLUDE_FILE_PATTERNS = 
-
-# The PREDEFINED tag can be used to specify one or more macro names that 
-# are defined before the preprocessor is started (similar to the -D option of 
-# gcc). The argument of the tag is a list of macros of the form: name 
-# or name=definition (no spaces). If the definition and the = are 
-# omitted =1 is assumed. To prevent a macro definition from being 
-# undefined via #undef or recursively expanded use the := operator 
-# instead of the = operator.
-
-PREDEFINED = 
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
-# this tag can be used to specify a list of macro names that should be expanded. 
-# The macro definition that is found in the sources will be used. 
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED = 
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
-# doxygen's preprocessor will remove all function-like macros that are alone 
-# on a line, have an all uppercase name, and do not end with a semicolon. Such 
-# function macros are typically used for boiler-plate code, and will confuse 
-# the parser if not removed.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references   
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles. 
-# Optionally an initial location of the external documentation 
-# can be added for each tagfile. The format of a tag file without 
-# this location is as follows: 
-#   TAGFILES = file1 file2 ... 
-# Adding location for the tag files is done as follows: 
-#   TAGFILES = file1=loc1 "file2 = loc2" ... 
-# where "loc1" and "loc2" can be relative or absolute paths or 
-# URLs. If a location is present for each tag, the installdox tool 
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen 
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES = 
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE = $(DOCDIR)/$(PROJECT).tag
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
-# in the class index. If set to NO only the inherited external classes 
-# will be listed.
-
-ALLEXTERNALS = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
-# in the modules index. If set to NO, only the current project's groups will 
-# be listed.
-
-EXTERNAL_GROUPS = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script 
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool   
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
-# or super classes. Setting the tag to NO turns the diagrams off. Note that 
-# this option is superseded by the HAVE_DOT option below. This is only a 
-# fallback. It is recommended to install and use dot, since it yields more 
-# powerful graphs.
-
-CLASS_DIAGRAMS = YES
-
-# If set to YES, the inheritance and collaboration graphs will hide 
-# inheritance and usage relations if the target is undocumented 
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
-# available from the path. This tool is part of Graphviz, a graph visualization 
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT = $(HAVE_DOT)
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect inheritance relations. Setting this tag to YES will force the 
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect implementation dependencies (inheritance, containment, and 
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH = YES
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for groups, showing the direct groups dependencies
-
-GROUP_GRAPHS = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
-# collaboration diagrams in a style similar to the OMG's Unified Modeling 
-# Language.
-
-UML_LOOK = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the 
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS = NO
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
-# tags are set to YES then doxygen will generate a graph for each documented 
-# file showing the direct and indirect include dependencies of the file with 
-# other documented files.
-
-INCLUDE_GRAPH = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
-# documented header file showing the documented files that directly or 
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH = YES
-
-# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
-# generate a call dependency graph for every global function or class method. 
-# Note that enabling this option will significantly increase the time of a run. 
-# So in most cases it will be better to enable call graphs for selected 
-# functions only using the \callgraph command.
-
-CALL_GRAPH = NO
-
-# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
-# generate a caller dependency graph for every global function or class method. 
-# Note that enabling this option will significantly increase the time of a run. 
-# So in most cases it will be better to enable caller graphs for selected 
-# functions only using the \callergraph command.
-
-CALLER_GRAPH = NO
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY = YES
-
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
-# then doxygen will show the dependencies a directory has on other directories 
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
-
-DIRECTORY_GRAPH = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be 
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH = $(DOT_PATH)
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that 
-# contain dot files that are included in the documentation (see the 
-# \dotfile command).
-
-DOTFILE_DIRS = 
-
-# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
-# this value, doxygen will try to truncate the graph, so that it fits within 
-# the specified constraint. Beware that most browsers cannot cope with very 
-# large images.
-
-MAX_DOT_GRAPH_WIDTH = 1024
-
-# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
-# this value, doxygen will try to truncate the graph, so that it fits within 
-# the specified constraint. Beware that most browsers cannot cope with very 
-# large images.
-
-MAX_DOT_GRAPH_HEIGHT = 1024
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
-# graphs generated by dot. A depth value of 3 means that only nodes reachable 
-# from the root by following a path via at most 3 edges will be shown. Nodes 
-# that lay further from the root node will be omitted. Note that setting this 
-# option to 1 or 2 may greatly reduce the computation time needed for large 
-# code bases. Also note that a graph may be further truncated if the graph's 
-# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH 
-# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), 
-# the graph is not depth-constrained.
-
-MAX_DOT_GRAPH_DEPTH = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
-# background. This is disabled by default, which results in a white background. 
-# Warning: Depending on the platform used, enabling this option may lead to 
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
-# read).
-
-DOT_TRANSPARENT = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
-# files in one run (i.e. multiple -o and -T options on the command line). This 
-# makes dot run faster, but since only newer versions of dot (>1.8.10) 
-# support this, this feature is disabled by default.
-
-DOT_MULTI_TARGETS = NO
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
-# generate a legend page explaining the meaning of the various boxes and 
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
-# remove the intermediate dot files that are used to generate 
-# the various graphs.
-
-DOT_CLEANUP = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine   
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be 
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE = NO

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/cmake_config.h.in
----------------------------------------------------------------------
diff --git a/src/c/cmake_config.h.in b/src/c/cmake_config.h.in
deleted file mode 100644
index 55efd8a..0000000
--- a/src/c/cmake_config.h.in
+++ /dev/null
@@ -1,154 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef CONFIG_H_
-#define CONFIG_H_
-
-/* Define to 1 if you have the <arpa/inet.h> header file. */
-#cmakedefine HAVE_ARPA_INET_H 1
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#cmakedefine HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#cmakedefine HAVE_FCNTL_H 1
-
-/* Define to 1 if you have the file `generated/zookeeper.jute.c'. */
-#cmakedefine HAVE_GENERATED_ZOOKEEPER_JUTE_C 1
-
-/* Define to 1 if you have the file `generated/zookeeper.jute.h'. */
-#cmakedefine HAVE_GENERATED_ZOOKEEPER_JUTE_H 1
-
-/* Define to 1 if you have the `getcwd' function. */
-#cmakedefine HAVE_GETCWD 1
-
-/* Define to 1 if you have the `gethostbyname' function. */
-#cmakedefine HAVE_GETHOSTBYNAME 1
-
-/* Define to 1 if you have the `gethostname' function. */
-#cmakedefine HAVE_GETHOSTNAME 1
-
-/* Define to 1 if you have the `getlogin' function. */
-#cmakedefine HAVE_GETLOGIN 1
-
-/* Define to 1 if you have the `getpwuid_r' function. */
-#cmakedefine HAVE_GETPWUID_R 1
-
-/* Define to 1 if you have the `gettimeofday' function. */
-#cmakedefine HAVE_GETTIMEOFDAY 1
-
-/* Define to 1 if you have the `getuid' function. */
-#cmakedefine HAVE_GETUID 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#cmakedefine HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the `rt' library (-lrt). */
-#cmakedefine HAVE_LIBRT 1
-
-/* Define to 1 if you have the `memmove' function. */
-#cmakedefine HAVE_MEMMOVE 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#cmakedefine HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `memset' function. */
-#cmakedefine HAVE_MEMSET 1
-
-/* Define to 1 if you have the <netdb.h> header file. */
-#cmakedefine HAVE_NETDB_H 1
-
-/* Define to 1 if you have the <netinet/in.h> header file. */
-#cmakedefine HAVE_NETINET_IN_H 1
-
-/* Define to 1 if you have the `poll' function. */
-#cmakedefine HAVE_POLL 1
-
-/* Define to 1 if you have the `socket' function. */
-#cmakedefine HAVE_SOCKET 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#cmakedefine HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#cmakedefine HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the `strchr' function. */
-#cmakedefine HAVE_STRCHR 1
-
-/* Define to 1 if you have the `strdup' function. */
-#cmakedefine HAVE_STRDUP 1
-
-/* Define to 1 if you have the `strerror' function. */
-#cmakedefine HAVE_STRERROR 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#cmakedefine HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#cmakedefine HAVE_STRING_H 1
-
-/* Define to 1 if you have the `strtol' function. */
-#cmakedefine HAVE_STRTOL 1
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#cmakedefine HAVE_SYS_SOCKET_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#cmakedefine HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#cmakedefine HAVE_SYS_TIME_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#cmakedefine HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <sys/utsname.h> header file. */
-#cmakedefine HAVE_SYS_UTSNAME_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#cmakedefine HAVE_UNISTD_H 1
-
-/* Define to 1 if IPv6 support is available. */
-#cmakedefine ZOO_IPV6_ENABLED 1
-
-/* poll() second argument type */
-#define POLL_NFDS_TYPE nfds_t
-
-/* Name of package */
-#define PACKAGE "${PROJECT_NAME}"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "${email}"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "${description}"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "${description} ${PROJECT_VERSION}"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "${PROJECT_NAME}"
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "${PROJECT_VERSION}"
-
-/* Version number of package */
-#define VERSION "${PROJECT_VERSION}"
-
-#endif

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/configure.ac
----------------------------------------------------------------------
diff --git a/src/c/configure.ac b/src/c/configure.ac
deleted file mode 100644
index aa1c30b..0000000
--- a/src/c/configure.ac
+++ /dev/null
@@ -1,165 +0,0 @@
-#                                               -*- Autoconf -*-
-# Process this file with autoconf to produce a configure script.
-
-AC_PREREQ(2.59)
-
-AC_INIT([zookeeper C client],3.4.13,[user@zookeeper.apache.org],[zookeeper])
-AC_CONFIG_SRCDIR([src/zookeeper.c])
-
-# Save initial CFLAGS and CXXFLAGS values before AC_PROG_CC and AC_PROG_CXX
-init_cflags="$CFLAGS"
-init_cxxflags="$CXXFLAGS"
-
-# initialize Doxygen support
-DX_HTML_FEATURE(ON)
-DX_CHM_FEATURE(OFF)
-DX_CHI_FEATURE(OFF)
-DX_MAN_FEATURE(OFF)
-DX_RTF_FEATURE(OFF)
-DX_XML_FEATURE(OFF)
-DX_PDF_FEATURE(OFF)
-DX_PS_FEATURE(OFF)
-DX_INIT_DOXYGEN([zookeeper],[c-doc.Doxyfile],[docs])
-
-# initialize automake
-AM_INIT_AUTOMAKE([-Wall foreign])
-AC_CONFIG_HEADER([config.h])
-
-# Checks for programs.
-AC_ARG_WITH(cppunit,
-        [  --without-cppunit       do not use CPPUNIT])
-
-if test "$with_cppunit" = "no" ; then
-   CPPUNIT_PATH="No_CPPUNIT"
-   CPPUNIT_INCLUDE=
-   CPPUNIT_LIBS=
-else
-   AM_PATH_CPPUNIT(1.10.2)
-fi
-
-if test "$CALLER" = "ANT" ; then
-CPPUNIT_CFLAGS="$CPPUNIT_CFLAGS -DZKSERVER_CMD=\"\\\"${base_dir}/src/c/tests/zkServer.sh\\\"\""
-else
-CPPUNIT_CFLAGS="$CPPUNIT_CFLAGS -DZKSERVER_CMD=\"\\\"./tests/zkServer.sh\\\"\""
-AC_CHECK_FILES([$srcdir/generated/zookeeper.jute.c $srcdir/generated/zookeeper.jute.h],[],
-    [AC_MSG_ERROR([jute files are missing! Please run "ant compile_jute" while in the zookeeper top level directory.])
-])
-fi
-AC_SUBST(CPPUNIT_CFLAGS)
-
-AC_PROG_CC
-AM_PROG_CC_C_O
-AC_PROG_CXX
-AC_PROG_INSTALL
-AC_PROG_LN_S
-
-# AC_DISABLE_SHARED
-AC_PROG_LIBTOOL
-
-#enable -D_GNU_SOURCE since the return code value of getaddrinfo
-#ifdefed with __USE_GNU
-#features.h header undef's __USE_GNU and defines it only if _GNU_SOURCE is defined
-#hence this define for gcc
-AC_ARG_ENABLE([debug],
- [AS_HELP_STRING([--enable-debug],[enable debug build [default=no]])],
- [],[enable_debug=no])
-
-if test "x$enable_debug" = xyes; then
-    if test "x$init_cflags" = x; then
-        CFLAGS=""
-    fi
-    CFLAGS="$CFLAGS -g -O0 -D_GNU_SOURCE"
-else
-    if test "x$init_cflags" = x; then
-        CFLAGS="-g -O2 -D_GNU_SOURCE"
-    fi
-fi
-
-if test "x$enable_debug" = xyes; then
-    if test "x$init_cxxflags" = x; then
-        CXXFLAGS=""
-    fi
-    CXXFLAGS="$CXXFLAGS -g -O0"
-else
-    if test "x$init_cxxflags" = x; then
-        CXXFLAGS="-g -O2"
-    fi
-fi
-
-# Check whether to enable gcov (coverage test)
-AC_ARG_ENABLE(gcov, [AS_HELP_STRING([--enable-gcov],[enable coverage test])])
-AC_MSG_CHECKING([whether to enable gcov])
-AS_IF([test "x${enable_gcov}" = "xyes"],AC_MSG_RESULT([yes]),AC_MSG_RESULT([no]))
-AM_CONDITIONAL([ENABLEGCOV],[test "x${enable_gcov}" = "xyes"])
-
-AC_ARG_WITH([syncapi],
- [AS_HELP_STRING([--with-syncapi],[build with support for SyncAPI [default=yes]])],
- [],[with_syncapi=yes])
-
-# Checks for libraries.
-AC_CHECK_LIB([pthread], [pthread_mutex_lock],[have_pthread=yes],[have_pthread=no])
-
-if test "x$with_syncapi" != xno && test "x$have_pthread" = xno; then
-    AC_MSG_WARN([cannot build SyncAPI -- pthread not found])
-    with_syncapi=no
-fi
-if test "x$with_syncapi" != xno; then
-    AC_MSG_NOTICE([building with SyncAPI support])
-else
-    AC_MSG_NOTICE([building without SyncAPI support])
-fi
-
-AM_CONDITIONAL([WANT_SYNCAPI],[test "x$with_syncapi" != xno])
-
-# Checks for header files.
-AC_HEADER_STDC
-AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h sys/time.h unistd.h sys/utsname.h])
-
-# Checks for typedefs, structures, and compiler characteristics.
-AC_C_CONST
-AC_C_INLINE
-AC_HEADER_TIME
-AC_CHECK_TYPE([nfds_t],
-    [AC_DEFINE([POLL_NFDS_TYPE],[nfds_t],[poll() second argument type])],
-    [AC_DEFINE([POLL_NFDS_TYPE],[unsigned int],[poll() second argument type])],
-    [#include <poll.h>])
-
-AC_MSG_CHECKING([whether to enable ipv6])
-
-AC_TRY_RUN([ /* is AF_INET6 available? */
-#include <sys/types.h>
-#include <sys/socket.h>
-main()
-{
- if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
-   exit(1);
- else
-   exit(0);
-}
-], AC_MSG_RESULT(yes) 
-   ipv6=yes, 
-   AC_MSG_RESULT(no) 
-   ipv6=no, 
-   AC_MSG_RESULT(no) 
-   ipv6=no)
-
-if test x"$ipv6" = xyes; then
-  USEIPV6="-DZOO_IPV6_ENABLED"
-  AC_SUBST(USEIPV6)
-fi
-
-# Checks for library functions.
-AC_CHECK_FUNCS([getcwd gethostbyname gethostname getlogin getpwuid_r gettimeofday getuid memmove memset poll socket strchr strdup strerror strtol])
-
-AC_CONFIG_FILES([Makefile])
-AC_CANONICAL_HOST
-AM_CONDITIONAL([SOLARIS],[
-  case "$host_os" in
-  *solaris*)
-    true
-    ;;
-  *)
-    false
-    ;;
-  esac ])
-AC_OUTPUT

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/include/proto.h
----------------------------------------------------------------------
diff --git a/src/c/include/proto.h b/src/c/include/proto.h
deleted file mode 100644
index bce408e..0000000
--- a/src/c/include/proto.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef PROTO_H_
-#define PROTO_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ZOO_NOTIFY_OP 0
-#define ZOO_CREATE_OP 1
-#define ZOO_DELETE_OP 2
-#define ZOO_EXISTS_OP 3
-#define ZOO_GETDATA_OP 4
-#define ZOO_SETDATA_OP 5
-#define ZOO_GETACL_OP 6
-#define ZOO_SETACL_OP 7
-#define ZOO_GETCHILDREN_OP 8
-#define ZOO_SYNC_OP 9
-#define ZOO_PING_OP 11
-#define ZOO_GETCHILDREN2_OP 12
-#define ZOO_CHECK_OP 13
-#define ZOO_MULTI_OP 14
-#define ZOO_CLOSE_OP -11
-#define ZOO_SETAUTH_OP 100
-#define ZOO_SETWATCHES_OP 101
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*PROTO_H_*/

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/include/recordio.h
----------------------------------------------------------------------
diff --git a/src/c/include/recordio.h b/src/c/include/recordio.h
deleted file mode 100644
index eed5f99..0000000
--- a/src/c/include/recordio.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef __RECORDIO_H__
-#define __RECORDIO_H__
-
-#include <sys/types.h>
-#include <stdint.h> /* for int64_t */
-#ifdef WIN32
-#include "winconfig.h"
-#define STRUCT_INITIALIZER(l,r)  r
-#else
-#define STRUCT_INITIALIZER(l,r) .l = r
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct buffer {
-    int32_t len;
-    char *buff;
-};
-
-void deallocate_String(char **s);
-void deallocate_Buffer(struct buffer *b);
-void deallocate_vector(void *d);
-struct iarchive {
-    int (*start_record)(struct iarchive *ia, const char *tag);
-    int (*end_record)(struct iarchive *ia, const char *tag);
-    int (*start_vector)(struct iarchive *ia, const char *tag, int32_t *count);
-    int (*end_vector)(struct iarchive *ia, const char *tag);
-    int (*deserialize_Bool)(struct iarchive *ia, const char *name, int32_t *);
-    int (*deserialize_Int)(struct iarchive *ia, const char *name, int32_t *);
-    int (*deserialize_Long)(struct iarchive *ia, const char *name, int64_t *);
-    int (*deserialize_Buffer)(struct iarchive *ia, const char *name,
-            struct buffer *);
-    int (*deserialize_String)(struct iarchive *ia, const char *name, char **);
-    void *priv;
-};
-struct oarchive {
-    int (*start_record)(struct oarchive *oa, const char *tag);
-    int (*end_record)(struct oarchive *oa, const char *tag);
-    int (*start_vector)(struct oarchive *oa, const char *tag, const int32_t *count);
-    int (*end_vector)(struct oarchive *oa, const char *tag);
-    int (*serialize_Bool)(struct oarchive *oa, const char *name, const int32_t *);
-    int (*serialize_Int)(struct oarchive *oa, const char *name, const int32_t *);
-    int (*serialize_Long)(struct oarchive *oa, const char *name,
-            const int64_t *);
-    int (*serialize_Buffer)(struct oarchive *oa, const char *name,
-            const struct buffer *);
-    int (*serialize_String)(struct oarchive *oa, const char *name, char **);
-    void *priv;
-};
-
-struct oarchive *create_buffer_oarchive(void);
-void close_buffer_oarchive(struct oarchive **oa, int free_buffer);
-struct iarchive *create_buffer_iarchive(char *buffer, int len);
-void close_buffer_iarchive(struct iarchive **ia);
-char *get_buffer(struct oarchive *);
-int get_buffer_len(struct oarchive *);
-
-int64_t zoo_htonll(int64_t v);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/include/winconfig.h
----------------------------------------------------------------------
diff --git a/src/c/include/winconfig.h b/src/c/include/winconfig.h
deleted file mode 100644
index c273a93..0000000
--- a/src/c/include/winconfig.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef WINCONFIG_H_
-#define WINCONFIG_H_
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-#define inline __inline
-#endif
-
-#define __attribute__(x)
-#define __func__ __FUNCTION__
-
-#define ACL ZKACL /* Conflict with windows API */
-
-#endif


[12/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/TestOperations.cc
----------------------------------------------------------------------
diff --git a/src/c/tests/TestOperations.cc b/src/c/tests/TestOperations.cc
deleted file mode 100644
index 27d9270..0000000
--- a/src/c/tests/TestOperations.cc
+++ /dev/null
@@ -1,710 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <cppunit/extensions/HelperMacros.h>
-#include "CppAssertHelper.h"
-
-#include "ZKMocks.h"
-#include <proto.h>
-
-using namespace std;
-
-class Zookeeper_operations : public CPPUNIT_NS::TestFixture
-{
-    CPPUNIT_TEST_SUITE(Zookeeper_operations);
-#ifndef THREADED
-    CPPUNIT_TEST(testPing);
-    CPPUNIT_TEST(testUnsolicitedPing);
-    CPPUNIT_TEST(testTimeoutCausedByWatches1);
-    CPPUNIT_TEST(testTimeoutCausedByWatches2);
-#else    
-    CPPUNIT_TEST(testAsyncWatcher1);
-    CPPUNIT_TEST(testAsyncGetOperation);
-#endif
-    CPPUNIT_TEST(testOperationsAndDisconnectConcurrently1);
-    CPPUNIT_TEST(testOperationsAndDisconnectConcurrently2);
-    CPPUNIT_TEST(testConcurrentOperations1);
-    CPPUNIT_TEST_SUITE_END();
-    zhandle_t *zh;
-    FILE *logfile;
-
-    static void watcher(zhandle_t *, int, int, const char *,void*){}
-public: 
-    Zookeeper_operations() {
-      logfile = openlogfile("Zookeeper_operations");
-    }
-
-    ~Zookeeper_operations() {
-      if (logfile) {
-        fflush(logfile);
-        fclose(logfile);
-        logfile = 0;
-      }
-    }
-
-    void setUp()
-    {
-        zoo_set_log_stream(logfile);
-
-        zoo_deterministic_conn_order(0);
-        zh=0;
-    }
-    
-    void tearDown()
-    {
-        zookeeper_close(zh);
-    }
-
-    class AsyncGetOperationCompletion: public AsyncCompletion{
-    public:
-        AsyncGetOperationCompletion():called_(false),rc_(ZAPIERROR){}
-        virtual void dataCompl(int rc, const char *value, int len, const Stat *stat){
-            synchronized(mx_);
-            called_=true;
-            rc_=rc;
-            value_.erase();
-            if(rc!=ZOK) return;
-            value_.assign(value,len);
-            if(stat)
-                stat_=*stat;
-        }
-        bool operator()()const{
-            synchronized(mx_);
-            return called_;
-        }
-        mutable Mutex mx_;
-        bool called_;
-        int rc_;
-        string value_;
-        NodeStat stat_;
-    };
-#ifndef THREADED
-    // send two get data requests; verify that the corresponding completions called
-    void testConcurrentOperations1()
-    {
-        Mock_gettimeofday timeMock;
-        ZookeeperServer zkServer;
-        // must call zookeeper_close() while all the mocks are in scope
-        CloseFinally guard(&zh);
-        
-        zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // simulate connected state
-        forceConnected(zh);
-        
-        int fd=0;
-        int interest=0;
-        timeval tv;
-        // first operation
-        AsyncGetOperationCompletion res1;
-        zkServer.addOperationResponse(new ZooGetResponse("1",1));
-        int rc=zoo_aget(zh,"/x/y/1",0,asyncCompletion,&res1);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // second operation
-        AsyncGetOperationCompletion res2;
-        zkServer.addOperationResponse(new ZooGetResponse("2",1));
-        rc=zoo_aget(zh,"/x/y/2",0,asyncCompletion,&res2);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // process the send queue
-        rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        while((rc=zookeeper_process(zh,interest))==ZOK) {
-          millisleep(100);
-          //printf("%d\n", rc);
-        }
-        //printf("RC = %d", rc);
-        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
-
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,res1.rc_);
-        CPPUNIT_ASSERT_EQUAL(string("1"),res1.value_);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,res2.rc_);
-        CPPUNIT_ASSERT_EQUAL(string("2"),res2.value_);
-    }
-    // send two getData requests and disconnect while the second request is
-    // outstanding;
-    // verify the completions are called
-    void testOperationsAndDisconnectConcurrently1()
-    {
-        Mock_gettimeofday timeMock;
-        ZookeeperServer zkServer;
-        // must call zookeeper_close() while all the mocks are in scope
-        CloseFinally guard(&zh);
-        
-        zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // simulate connected state
-        forceConnected(zh);
-        
-        int fd=0;
-        int interest=0;
-        timeval tv;
-        // first operation
-        AsyncGetOperationCompletion res1;
-        zkServer.addOperationResponse(new ZooGetResponse("1",1));
-        int rc=zoo_aget(zh,"/x/y/1",0,asyncCompletion,&res1);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // second operation
-        AsyncGetOperationCompletion res2;
-        zkServer.addOperationResponse(new ZooGetResponse("2",1));
-        rc=zoo_aget(zh,"/x/y/2",0,asyncCompletion,&res2);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // process the send queue
-        rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        rc=zookeeper_process(zh,interest);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // simulate a disconnect
-        zkServer.setConnectionLost();
-        rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        rc=zookeeper_process(zh,interest);
-        CPPUNIT_ASSERT_EQUAL((int)ZCONNECTIONLOSS,rc);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,res1.rc_);
-        CPPUNIT_ASSERT_EQUAL(string("1"),res1.value_);
-        CPPUNIT_ASSERT_EQUAL((int)ZCONNECTIONLOSS,res2.rc_);
-        CPPUNIT_ASSERT_EQUAL(string(""),res2.value_);
-    }
-    // send two getData requests and simulate timeout while the both request
-    // are pending;
-    // verify the completions are called
-    void testOperationsAndDisconnectConcurrently2()
-    {
-        Mock_gettimeofday timeMock;
-        ZookeeperServer zkServer;
-        // must call zookeeper_close() while all the mocks are in scope
-        CloseFinally guard(&zh);
-        
-        zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // simulate connected state
-        forceConnected(zh);
-        
-        int fd=0;
-        int interest=0;
-        timeval tv;
-        // first operation
-        AsyncGetOperationCompletion res1;
-        zkServer.addOperationResponse(new ZooGetResponse("1",1));
-        int rc=zoo_aget(zh,"/x/y/1",0,asyncCompletion,&res1);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // second operation
-        AsyncGetOperationCompletion res2;
-        zkServer.addOperationResponse(new ZooGetResponse("2",1));
-        rc=zoo_aget(zh,"/x/y/2",0,asyncCompletion,&res2);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // simulate timeout
-        timeMock.tick(+10); // advance system time by 10 secs
-        // the next call to zookeeper_interest should return ZOPERATIONTIMEOUT
-        rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        CPPUNIT_ASSERT_EQUAL((int)ZOPERATIONTIMEOUT,rc);
-        // make sure the completions have been called
-        CPPUNIT_ASSERT_EQUAL((int)ZOPERATIONTIMEOUT,res1.rc_);
-        CPPUNIT_ASSERT_EQUAL((int)ZOPERATIONTIMEOUT,res2.rc_);
-    }
-
-    class PingCountingServer: public ZookeeperServer{
-    public:
-        PingCountingServer():pingCount_(0){}
-        // called when a client request is received
-        virtual void onMessageReceived(const RequestHeader& rh, iarchive* ia){
-           if(rh.type==ZOO_PING_OP){
-               pingCount_++;
-           }
-        }
-        int pingCount_;
-    };
-
-    // establish a connection; idle for a while
-    // verify ping was sent at least once
-    void testPing()
-    {
-        const int TIMEOUT=9; // timeout in secs
-        Mock_gettimeofday timeMock;
-        PingCountingServer zkServer;
-        // must call zookeeper_close() while all the mocks are in scope
-        CloseFinally guard(&zh);
-        
-        // receive timeout is in milliseconds
-        zh=zookeeper_init("localhost:1234",watcher,TIMEOUT*1000,TEST_CLIENT_ID,0,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // simulate connected state
-        forceConnected(zh);
-        
-        int fd=0;
-        int interest=0;
-        timeval tv;
-        // Round 1.
-        int rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // simulate waiting for the select() call to timeout; 
-        // advance the system clock accordingly
-        timeMock.tick(tv);  
-        rc=zookeeper_process(zh,interest);
-        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
-        // verify no ping sent
-        CPPUNIT_ASSERT(zkServer.pingCount_==0);
-        
-        // Round 2.
-        // the client should have the idle threshold exceeded, by now
-        rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // assume the socket is writable, so no idling here; move on to 
-        // zookeeper_process immediately
-        rc=zookeeper_process(zh,interest);
-        // ZNOTHING means the client hasn't received a ping response yet
-        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
-        // verify a ping is sent
-        CPPUNIT_ASSERT_EQUAL(1,zkServer.pingCount_);
-        
-        // Round 3.
-        // we're going to receive a server PING response and make sure
-        // that the client has updated its last_recv timestamp 
-        zkServer.addRecvResponse(new PingResponse);
-        rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // pseudo-sleep for a short while (10 ms)
-        timeMock.millitick(10);
-        rc=zookeeper_process(zh,interest);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // only one ping so far?
-        CPPUNIT_ASSERT_EQUAL(1,zkServer.pingCount_);
-        CPPUNIT_ASSERT(timeMock==zh->last_recv);
-
-        // Round 4
-        // make sure that a ping is not sent if something is outstanding
-        AsyncGetOperationCompletion res1;
-        rc=zoo_aget(zh,"/x/y/1",0,asyncCompletion,&res1);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        timeMock.tick(tv);  
-        rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        rc=zookeeper_process(zh,interest);
-        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
-        rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // pseudo-sleep for a short while (10 ms)
-        timeMock.millitick(10);
-        rc=zookeeper_process(zh,interest);
-        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
-        // only one ping so far?
-        CPPUNIT_ASSERT_EQUAL(1,zkServer.pingCount_);
-    }
-
-    // ZOOKEEPER-2253: Permit unsolicited pings
-    void testUnsolicitedPing()
-    {
-        const int TIMEOUT=9; // timeout in secs
-        Mock_gettimeofday timeMock;
-        PingCountingServer zkServer;
-        // must call zookeeper_close() while all the mocks are in scope
-        CloseFinally guard(&zh);
-
-        // receive timeout is in milliseconds
-        zh=zookeeper_init("localhost:1234",watcher,TIMEOUT*1000,TEST_CLIENT_ID,0,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // simulate connected state
-        forceConnected(zh);
-
-        int fd=0;
-        int interest=0;
-        timeval tv;
-
-        int rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-
-        // verify no ping sent
-        CPPUNIT_ASSERT(zkServer.pingCount_==0);
-
-        // we're going to receive a unsolicited PING response; ensure
-        // that the client has updated its last_recv timestamp
-        timeMock.tick(tv);
-        zkServer.addRecvResponse(new PingResponse);
-        rc=zookeeper_process(zh,interest);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        CPPUNIT_ASSERT(timeMock==zh->last_recv);
-    }
-
-    // simulate a watch arriving right before a ping is due
-    // assert the ping is sent nevertheless
-    void testTimeoutCausedByWatches1()
-    {
-        const int TIMEOUT=9; // timeout in secs
-        Mock_gettimeofday timeMock;
-        PingCountingServer zkServer;
-        // must call zookeeper_close() while all the mocks are in scope
-        CloseFinally guard(&zh);
-        
-        // receive timeout is in milliseconds
-        zh=zookeeper_init("localhost:1234",watcher,TIMEOUT*1000,TEST_CLIENT_ID,0,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // simulate connected state
-        forceConnected(zh);
-        
-        int fd=0;
-        int interest=0;
-        timeval tv;
-        // Round 1.
-        int rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // simulate waiting for the select() call to timeout; 
-        // advance the system clock accordingly
-        timeMock.tick(tv);
-        timeMock.tick(-1); // set the clock to a millisecond before a ping is due
-        // trigger a watch now
-        zkServer.addRecvResponse(new ZNodeEvent(ZOO_CHANGED_EVENT,"/x/y/z"));
-        rc=zookeeper_process(zh,interest);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // arrival of a watch sets the last_recv to the current time
-        CPPUNIT_ASSERT(timeMock==zh->last_recv);
-        // spend 1 millisecond by processing the watch
-        timeMock.tick(1);
-        
-        // Round 2.
-        // a ping is due; zookeeper_interest() must send it now
-        rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // no delay here -- as if the socket is immediately writable
-        rc=zookeeper_process(zh,interest);
-        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
-        // verify a ping is sent
-        CPPUNIT_ASSERT_EQUAL(1,zkServer.pingCount_);        
-    }
-
-    // similar to testTimeoutCausedByWatches1, but this time the watch is 
-    // triggered while the client has an outstanding request
-    // assert the ping is sent on time
-    void testTimeoutCausedByWatches2()
-    {
-        const int TIMEOUT=9; // timeout in secs
-        Mock_gettimeofday now;
-        PingCountingServer zkServer;
-        // must call zookeeper_close() while all the mocks are in scope
-        CloseFinally guard(&zh);
-        
-        // receive timeout is in milliseconds
-        zh=zookeeper_init("localhost:1234",watcher,TIMEOUT*1000,TEST_CLIENT_ID,0,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // simulate connected state
-        forceConnected(zh);
-        
-        // queue up a request; keep it pending (as if the server is busy or has died)
-        AsyncGetOperationCompletion res1;
-        zkServer.addOperationResponse(new ZooGetResponse("2",1));
-        int rc=zoo_aget(zh,"/x/y/1",0,asyncCompletion,&res1);
-
-        int fd=0;
-        int interest=0;
-        timeval tv;
-        // Round 1.
-        // send the queued up zoo_aget() request
-        Mock_gettimeofday beginningOfTimes(now); // remember when we started
-        rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // no delay -- the socket is writable
-        rc=zookeeper_process(zh,interest);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc); 
-        
-        // Round 2.
-        // what's next?
-        rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // no response from the server yet -- waiting in the select() call
-        now.tick(tv);
-        // a watch has arrived, thus preventing the connection from timing out 
-        zkServer.addRecvResponse(new ZNodeEvent(ZOO_CHANGED_EVENT,"/x/y/z"));        
-        rc=zookeeper_process(zh,interest);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc); // read the watch message
-        CPPUNIT_ASSERT_EQUAL(0,zkServer.pingCount_); // not yet!
-        
-        //Round 3.
-        // now is the time to send a ping; make sure it's actually sent
-        rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        rc=zookeeper_process(zh,interest);
-        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
-        // verify a ping is sent
-        CPPUNIT_ASSERT_EQUAL(1,zkServer.pingCount_);
-        // make sure only 1/3 of the timeout has passed
-        CPPUNIT_ASSERT_EQUAL((int32_t)TIMEOUT/3*1000,toMilliseconds(now-beginningOfTimes));
-    }
-
-#else   
-    class TestGetDataJob: public TestJob{
-    public:
-        TestGetDataJob(ZookeeperServer* svr,zhandle_t* zh, int reps=500)
-            :svr_(svr),zh_(zh),rc_(ZAPIERROR),reps_(reps){}
-        virtual void run(){
-            int i;
-            for(i=0;i<reps_;i++){
-                char buf;
-                int size=sizeof(buf);
-
-                if (i % 10 == 0) {
-                    // We need to pause every once in a while so we don't
-                    // get too far ahead and finish before the disconnect
-	            millisleep(1);
-                }
-                svr_->addOperationResponse(new ZooGetResponse("1",1));
-                rc_=zoo_get(zh_,"/x/y/z",0,&buf,&size,0);
-                if(rc_!=ZOK){
-                    break;
-                }
-            }
-        }
-        ZookeeperServer* svr_;
-        zhandle_t* zh_;
-        int rc_;
-        int reps_;
-    };
-    class TestConcurrentOpJob: public TestGetDataJob{
-    public:
-        static const int REPS=500;
-        TestConcurrentOpJob(ZookeeperServer* svr,zhandle_t* zh):
-            TestGetDataJob(svr,zh,REPS){}
-        virtual TestJob* clone() const {
-            return new TestConcurrentOpJob(svr_,zh_);
-        }
-        virtual void validate(const char* file, int line) const{
-            CPPUNIT_ASSERT_EQUAL_MESSAGE_LOC("ZOK != rc",(int)ZOK,rc_,file,line);
-        }
-    };
-    void testConcurrentOperations1()
-    {
-        for(int counter=0; counter<50; counter++){
-            // frozen time -- no timeouts and no pings
-            Mock_gettimeofday timeMock;
-            
-            ZookeeperServer zkServer;
-            Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
-            // must call zookeeper_close() while all the mocks are in the scope!
-            CloseFinally guard(&zh);
-            
-            zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0);
-            CPPUNIT_ASSERT(zh!=0);
-            // make sure the client has connected
-            CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
-            
-            TestJobManager jmgr(TestConcurrentOpJob(&zkServer,zh),10);
-            jmgr.startAllJobs();
-            jmgr.wait();
-            // validate test results
-            VALIDATE_JOBS(jmgr);
-        }
-    }
-    class ZKGetJob: public TestJob{
-    public:
-        static const int REPS=1000;
-        ZKGetJob(zhandle_t* zh)
-            :zh_(zh),rc_(ZAPIERROR){}
-        virtual TestJob* clone() const {
-            return new ZKGetJob(zh_);
-        }
-        virtual void run(){
-            int i;
-            for(i=0;i<REPS;i++){
-                char buf;
-                int size=sizeof(buf);                
-                rc_=zoo_get(zh_,"/xyz",0,&buf,&size,0);
-                if(rc_!=ZOK){
-                    break;
-                }
-            }
-            //TEST_TRACE(("Finished %d iterations",i));
-        }
-        virtual void validate(const char* file, int line) const{
-            CPPUNIT_ASSERT_EQUAL_MESSAGE_LOC("ZOK != rc",(int)ZOK,rc_,file,line);
-        }
-        zhandle_t* zh_;
-        int rc_;
-    };
-
-    // this test connects to a real ZK server and creates the /xyz node and sends
-    // lots of zoo_get requests.
-    // to run this test use the following command:
-    // zktest-mt Zookeeper_operations::testOperationsAndDisconnectConcurrently2 localhost:3181
-    // where the second parameter is the server host and port
-    void testOperationsAndDisconnectConcurrently2()
-    {
-        if(globalTestConfig.getTestName().find(__func__)==string::npos || 
-                globalTestConfig.getExtraOptCount()==0)
-        {
-            // only run this test when specifically asked so
-            return;
-        }
-        string host(*(globalTestConfig.getExtraOptBegin()));
-        zhandle_t* lzh=zookeeper_init(host.c_str(),watcher,10000,0,0,0);
-        CPPUNIT_ASSERT(lzh!=0);
-        // make sure the client has connected
-        CPPUNIT_ASSERT_MESSAGE("Unable to connect to the host",
-                ensureCondition(ClientConnected(zh),5000)<5000);
-        
-        char realpath[1024];
-        int rc=zoo_create(lzh,"/xyz","1",1,&ZOO_OPEN_ACL_UNSAFE,0,realpath,sizeof(realpath)-1);
-        CPPUNIT_ASSERT(rc==ZOK || rc==ZNODEEXISTS);
-        zookeeper_close(lzh); 
-  
-        for(int counter=0; counter<200; counter++){
-            TEST_TRACE(("Loop count %d",counter));
-            
-            CloseFinally guard(&zh);
-
-            zh=zookeeper_init(host.c_str(),watcher,10000,0,0,0);
-            CPPUNIT_ASSERT(zh!=0);
-            // make sure the client has connected
-            CPPUNIT_ASSERT_MESSAGE("Unable to connect to the host",
-                    ensureCondition(ClientConnected(zh),5000)<5000);
-            
-            TestJobManager jmgr(ZKGetJob(zh),10);
-            jmgr.startJobsImmediately();
-            jmgr.wait();
-            VALIDATE_JOBS(jmgr);
-            TEST_TRACE(("run %d finished",counter));
-        }
-
-    }
-
-    class TestConcurrentOpWithDisconnectJob: public TestGetDataJob{
-    public:
-        static const int REPS=1000;
-        TestConcurrentOpWithDisconnectJob(ZookeeperServer* svr,zhandle_t* zh):
-            TestGetDataJob(svr,zh,REPS){}
-        virtual TestJob* clone() const {
-            return new TestConcurrentOpWithDisconnectJob(svr_,zh_);
-        }
-        virtual void validate(const char* file, int line) const{
-            CPPUNIT_ASSERT_EQUAL_MESSAGE_LOC("ZCONNECTIONLOSS != rc",(int)ZCONNECTIONLOSS,rc_,file,line);
-        }
-    };
-
-    // this test is not 100% accurate in a sense it may not detect all error cases.
-    // TODO: I can't think of a test that is 100% accurate and doesn't interfere
-    //       with the code being tested (in terms of introducing additional 
-    //       implicit synchronization points)
-    void testOperationsAndDisconnectConcurrently1()
-    {
-        for(int counter=0; counter<50; counter++){
-            //TEST_TRACE(("Loop count %d",counter));
-            // frozen time -- no timeouts and no pings
-            Mock_gettimeofday timeMock;
-            
-            ZookeeperServer zkServer;
-            Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
-            // must call zookeeper_close() while all the mocks are in the scope!
-            CloseFinally guard(&zh);
-            
-            zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0);
-            CPPUNIT_ASSERT(zh!=0);
-            // make sure the client has connected
-            CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
-            
-            TestJobManager jmgr(TestConcurrentOpWithDisconnectJob(&zkServer,zh),10);
-            jmgr.startJobsImmediately();
-            // let everything startup before we shutdown the server
-            millisleep(4);
-            // reconnect attempts will start failing immediately 
-            zkServer.setServerDown(0);
-            // next recv call will return 0
-            zkServer.setConnectionLost();
-            jmgr.wait();
-            VALIDATE_JOBS(jmgr);
-        }
-        
-    }
-    // call zoo_aget() in the multithreaded mode
-    void testAsyncGetOperation()
-    {
-        Mock_gettimeofday timeMock;
-        
-        ZookeeperServer zkServer;
-        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
-        // must call zookeeper_close() while all the mocks are in the scope!
-        CloseFinally guard(&zh);
-        
-        zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // make sure the client has connected
-        CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
-
-        AsyncGetOperationCompletion res1;
-        zkServer.addOperationResponse(new ZooGetResponse("1",1));
-        int rc=zoo_aget(zh,"/x/y/1",0,asyncCompletion,&res1);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        
-        CPPUNIT_ASSERT(ensureCondition(res1,1000)<1000);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,res1.rc_);
-        CPPUNIT_ASSERT_EQUAL(string("1"),res1.value_);        
-    }
-    class ChangeNodeWatcher: public WatcherAction{
-    public:
-        ChangeNodeWatcher():changed_(false){}
-        virtual void onNodeValueChanged(zhandle_t*,const char* path){
-            synchronized(mx_);
-            changed_=true;
-            if(path!=0) path_=path;
-        }
-        // this predicate checks if CHANGE_EVENT event type was triggered, unlike
-        // the isWatcherTriggered() that returns true whenever a watcher is triggered
-        // regardless of the event type
-        SyncedBoolCondition isNodeChangedTriggered() const{
-            return SyncedBoolCondition(changed_,mx_);
-        }
-        bool changed_;
-        string path_;
-    };
-    
-    class AsyncWatcherCompletion: public AsyncCompletion{
-    public:
-        AsyncWatcherCompletion(ZookeeperServer& zkServer):zkServer_(zkServer){}
-        virtual void statCompl(int rc, const Stat *stat){
-            // we received a server response, now enqueue a watcher event
-            // to trigger the watcher
-            zkServer_.addRecvResponse(new ZNodeEvent(ZOO_CHANGED_EVENT,"/x/y/z"));
-        }
-        ZookeeperServer& zkServer_;
-    };
-    // verify that async watcher is called for znode events (CREATED, DELETED etc.)
-    void testAsyncWatcher1(){
-        Mock_gettimeofday timeMock;
-        
-        ZookeeperServer zkServer;
-        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
-        // must call zookeeper_close() while all the mocks are in the scope!
-        CloseFinally guard(&zh);
-        
-        ChangeNodeWatcher action;        
-        zh=zookeeper_init("localhost:2121",activeWatcher,10000,
-                TEST_CLIENT_ID,&action,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // make sure the client has connected
-        CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
-        
-        // set the watcher
-        AsyncWatcherCompletion completion(zkServer);
-        // prepare a response for the zoo_aexists() request
-        zkServer.addOperationResponse(new ZooStatResponse);
-        int rc=zoo_aexists(zh,"/x/y/z",1,asyncCompletion,&completion);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        
-        CPPUNIT_ASSERT(ensureCondition(action.isNodeChangedTriggered(),1000)<1000);
-        CPPUNIT_ASSERT_EQUAL(string("/x/y/z"),action.path_);                
-    }
-#endif
-};
-
-CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_operations);

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/TestWatchers.cc
----------------------------------------------------------------------
diff --git a/src/c/tests/TestWatchers.cc b/src/c/tests/TestWatchers.cc
deleted file mode 100644
index 0a26934..0000000
--- a/src/c/tests/TestWatchers.cc
+++ /dev/null
@@ -1,773 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <cppunit/extensions/HelperMacros.h>
-#include "CppAssertHelper.h"
-
-#include "ZKMocks.h"
-#include "CollectionUtil.h"
-#include "Util.h"
-
-class Zookeeper_watchers : public CPPUNIT_NS::TestFixture
-{
-    CPPUNIT_TEST_SUITE(Zookeeper_watchers);
-    CPPUNIT_TEST(testDefaultSessionWatcher1);
-    CPPUNIT_TEST(testDefaultSessionWatcher2);
-    CPPUNIT_TEST(testObjectSessionWatcher1);
-    CPPUNIT_TEST(testObjectSessionWatcher2);
-    CPPUNIT_TEST(testNodeWatcher1);
-    CPPUNIT_TEST(testChildWatcher1);
-    CPPUNIT_TEST(testChildWatcher2);
-    CPPUNIT_TEST_SUITE_END();
-
-    static void watcher(zhandle_t *, int, int, const char *,void*){}
-    zhandle_t *zh;
-    FILE *logfile;
-    
-public:
-
-    Zookeeper_watchers() {
-      logfile = openlogfile("Zookeeper_watchers");
-    }
-
-    ~Zookeeper_watchers() {
-      if (logfile) {
-        fflush(logfile);
-        fclose(logfile);
-        logfile = 0;
-      }
-    }
-
-    void setUp()
-    {
-        zoo_set_log_stream(logfile);
-
-        zoo_deterministic_conn_order(0);
-        zh=0;
-    }
-    
-    void tearDown()
-    {
-        zookeeper_close(zh);
-    }
-    
-    class ConnectionWatcher: public WatcherAction{
-    public:
-        ConnectionWatcher():connected_(false),counter_(0){}
-        virtual void onConnectionEstablished(zhandle_t*){
-            synchronized(mx_);
-            counter_++;
-            connected_=true;
-        }
-        SyncedBoolCondition isConnectionEstablished() const{
-            return SyncedBoolCondition(connected_,mx_);
-        }
-        bool connected_;
-        int counter_;
-    };
-
-    class DisconnectWatcher: public WatcherAction{
-    public:
-        DisconnectWatcher():disconnected_(false),counter_(0){}
-        virtual void onConnectionLost(zhandle_t*){
-            synchronized(mx_);
-            counter_++;
-            disconnected_=true;
-        }
-        SyncedBoolCondition isDisconnected() const{
-            return SyncedBoolCondition(disconnected_,mx_);
-        }
-        bool disconnected_;
-        int counter_;
-    };
-
-    class CountingDataWatcher: public WatcherAction{
-    public:
-        CountingDataWatcher():disconnected_(false),counter_(0){}
-        virtual void onNodeValueChanged(zhandle_t*,const char* path){
-            synchronized(mx_);
-            counter_++;
-        }
-        virtual void onConnectionLost(zhandle_t*){
-            synchronized(mx_);
-            counter_++;
-            disconnected_=true;
-        }
-        bool disconnected_;
-        int counter_;
-    };
-
-    class DeletionCountingDataWatcher: public WatcherAction{
-    public:
-        DeletionCountingDataWatcher():counter_(0){}
-        virtual void onNodeDeleted(zhandle_t*,const char* path){
-            synchronized(mx_);
-            counter_++;
-        }
-        int counter_;
-    };
-
-    class ChildEventCountingWatcher: public WatcherAction{
-    public:
-        ChildEventCountingWatcher():counter_(0){}
-        virtual void onChildChanged(zhandle_t*,const char* path){
-            synchronized(mx_);
-            counter_++;
-        }
-        int counter_;
-    };
-
-#ifndef THREADED
-    
-    // verify: the default watcher is called once for a session event
-    void testDefaultSessionWatcher1(){
-        Mock_gettimeofday timeMock;
-        ZookeeperServer zkServer;
-        // must call zookeeper_close() while all the mocks are in scope
-        CloseFinally guard(&zh);
-
-        ConnectionWatcher watcher;
-        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
-                &watcher,0);
-        CPPUNIT_ASSERT(zh!=0);
-        
-        int fd=0;
-        int interest=0;
-        timeval tv;
-        // open the socket
-        int rc=zookeeper_interest(zh,&fd,&interest,&tv);        
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);        
-        CPPUNIT_ASSERT_EQUAL(ZOO_CONNECTING_STATE,zoo_state(zh));
-        // send the handshake packet to the server
-        rc=zookeeper_process(zh,interest);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);        
-        CPPUNIT_ASSERT_EQUAL(ZOO_ASSOCIATING_STATE,zoo_state(zh));
-        // receive the server handshake response
-        rc=zookeeper_process(zh,interest);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // verify connected
-        CPPUNIT_ASSERT_EQUAL(ZOO_CONNECTED_STATE,zoo_state(zh));
-        CPPUNIT_ASSERT(watcher.connected_);
-        CPPUNIT_ASSERT_EQUAL(1,watcher.counter_);
-    }
-    
-    // test case: connect to server, set a default watcher, disconnect from the server
-    // verify: the default watcher is called once
-    void testDefaultSessionWatcher2(){
-        Mock_gettimeofday timeMock;
-        ZookeeperServer zkServer;
-        // must call zookeeper_close() while all the mocks are in scope
-        CloseFinally guard(&zh);
-
-        DisconnectWatcher watcher;
-        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
-                &watcher,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // simulate connected state
-        forceConnected(zh);
-        
-        // first operation
-        AsyncCompletion ignored;
-        zkServer.addOperationResponse(new ZooGetResponse("1",1));
-        int rc=zoo_aget(zh,"/x/y/1",0,asyncCompletion,&ignored);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // this will process the response and activate the watcher
-        rc=zookeeper_process(zh,ZOOKEEPER_READ);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-
-        // now, disconnect
-        zkServer.setConnectionLost();
-        rc=zookeeper_process(zh,ZOOKEEPER_READ);
-        CPPUNIT_ASSERT_EQUAL((int)ZCONNECTIONLOSS,rc);
-        // verify disconnected
-        CPPUNIT_ASSERT(watcher.disconnected_);
-        CPPUNIT_ASSERT_EQUAL(1,watcher.counter_);
-    }
-    
-    // testcase: connect to the server, set a watcher object on a node, 
-    //           disconnect from the server
-    // verify: the watcher object as well as the default watcher are called
-    void testObjectSessionWatcher1(){
-        Mock_gettimeofday timeMock;
-        ZookeeperServer zkServer;
-        // must call zookeeper_close() while all the mocks are in scope
-        CloseFinally guard(&zh);
-
-        DisconnectWatcher defWatcher;
-        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
-                &defWatcher,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // simulate connected state
-        forceConnected(zh);
-        
-        AsyncCompletion ignored;
-        CountingDataWatcher wobject;
-        zkServer.addOperationResponse(new ZooStatResponse);
-        int rc=zoo_awexists(zh,"/x/y/1",activeWatcher,&wobject,
-                asyncCompletion,&ignored);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // this will process the response and activate the watcher
-        rc=zookeeper_process(zh,ZOOKEEPER_READ);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-
-        // now, disconnect
-        zkServer.setConnectionLost();
-        rc=zookeeper_process(zh,ZOOKEEPER_READ);
-        CPPUNIT_ASSERT_EQUAL((int)ZCONNECTIONLOSS,rc);
-
-        // verify the default watcher has been triggered
-        CPPUNIT_ASSERT(defWatcher.disconnected_);
-        // and triggered only once
-        CPPUNIT_ASSERT_EQUAL(1,defWatcher.counter_);
-        
-        // the path-specific watcher has been triggered as well
-        CPPUNIT_ASSERT(wobject.disconnected_);
-        // only once!
-        CPPUNIT_ASSERT_EQUAL(1,wobject.counter_);
-    }
-
-    // testcase: connect to the server, set a watcher object on a node, 
-    //           set a def watcher on another node,disconnect from the server
-    // verify: the watcher object as well as the default watcher are called
-    void testObjectSessionWatcher2(){
-        Mock_gettimeofday timeMock;
-        ZookeeperServer zkServer;
-        // must call zookeeper_close() while all the mocks are in scope
-        CloseFinally guard(&zh);
-
-        DisconnectWatcher defWatcher;
-        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
-                &defWatcher,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // simulate connected state
-        forceConnected(zh);
-        
-        // set the default watcher
-        AsyncCompletion ignored;
-        zkServer.addOperationResponse(new ZooStatResponse);
-        int rc=zoo_aexists(zh,"/a/b/c",1,asyncCompletion,&ignored);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-
-        CountingDataWatcher wobject;
-        zkServer.addOperationResponse(new ZooStatResponse);
-        rc=zoo_awexists(zh,"/x/y/z",activeWatcher,&wobject,
-                asyncCompletion,&ignored);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        
-        // this will process the response and activate the watcher
-        while((rc=zookeeper_process(zh,ZOOKEEPER_READ))==ZOK) {
-          millisleep(100);
-        }
-        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
-
-        // disconnect now
-        zkServer.setConnectionLost();
-        rc=zookeeper_process(zh,ZOOKEEPER_READ);
-        CPPUNIT_ASSERT_EQUAL((int)ZCONNECTIONLOSS,rc);
-
-        // verify the default watcher has been triggered
-        CPPUNIT_ASSERT(defWatcher.disconnected_);
-        // and triggered only once
-        CPPUNIT_ASSERT_EQUAL(1,defWatcher.counter_);
-        
-        // the path-specific watcher has been triggered as well
-        CPPUNIT_ASSERT(wobject.disconnected_);
-        // only once!
-        CPPUNIT_ASSERT_EQUAL(1,wobject.counter_);
-    }
-
-    // testcase: register 2 node watches for different paths, trigger the watches
-    // verify: the data watchers are processed, the default watcher is not called
-    void testNodeWatcher1(){
-        Mock_gettimeofday timeMock;
-        ZookeeperServer zkServer;
-        // must call zookeeper_close() while all the mocks are in scope
-        CloseFinally guard(&zh);
-
-        DisconnectWatcher defWatcher;
-        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
-                &defWatcher,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // simulate connected state
-        forceConnected(zh);
-        
-        AsyncCompletion ignored;
-        CountingDataWatcher wobject1;
-        zkServer.addOperationResponse(new ZooStatResponse);
-        int rc=zoo_awexists(zh,"/a/b/c",activeWatcher,&wobject1,
-                asyncCompletion,&ignored);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-
-        CountingDataWatcher wobject2;
-        zkServer.addOperationResponse(new ZooStatResponse);
-        rc=zoo_awexists(zh,"/x/y/z",activeWatcher,&wobject2,
-                asyncCompletion,&ignored);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        
-        // this will process the response and activate the watcher
-        while((rc=zookeeper_process(zh,ZOOKEEPER_READ))==ZOK) {
-          millisleep(100);
-        }
-        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
-
-        // we are all set now; let's trigger the watches
-        zkServer.addRecvResponse(new ZNodeEvent(ZOO_CHANGED_EVENT,"/a/b/c"));
-        zkServer.addRecvResponse(new ZNodeEvent(ZOO_CHANGED_EVENT,"/x/y/z"));
-        // make sure all watchers have been processed
-        while((rc=zookeeper_process(zh,ZOOKEEPER_READ))==ZOK) {
-          millisleep(100);
-        }
-        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
-        
-        CPPUNIT_ASSERT_EQUAL(1,wobject1.counter_);
-        CPPUNIT_ASSERT_EQUAL(1,wobject2.counter_);        
-        CPPUNIT_ASSERT_EQUAL(0,defWatcher.counter_);
-    }
-
-    // testcase: set up both a children and a data watchers on the node /a, then
-    //           delete the node by sending a DELETE_EVENT event
-    // verify: both watchers are triggered
-    void testChildWatcher1(){
-        Mock_gettimeofday timeMock;
-        ZookeeperServer zkServer;
-        // must call zookeeper_close() while all the mocks are in scope
-        CloseFinally guard(&zh);
-
-        DeletionCountingDataWatcher defWatcher;
-        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
-                &defWatcher,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // simulate connected state
-        forceConnected(zh);
-        
-        AsyncCompletion ignored;
-        DeletionCountingDataWatcher wobject1;
-        zkServer.addOperationResponse(new ZooStatResponse);
-        int rc=zoo_awexists(zh,"/a",activeWatcher,&wobject1,
-                asyncCompletion,&ignored);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-
-        typedef ZooGetChildrenResponse::StringVector ZooVector;
-        zkServer.addOperationResponse(new ZooGetChildrenResponse(
-                Util::CollectionBuilder<ZooVector>()("/a/1")("/a/2")
-                ));
-        DeletionCountingDataWatcher wobject2;
-        rc=zoo_awget_children(zh,"/a",activeWatcher,
-                &wobject2,asyncCompletion,&ignored);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        
-        // this will process the response and activate the watcher
-        while((rc=zookeeper_process(zh,ZOOKEEPER_READ))==ZOK) {
-          millisleep(100);
-        }
-        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
-
-        // we are all set now; let's trigger the watches
-        zkServer.addRecvResponse(new ZNodeEvent(ZOO_DELETED_EVENT,"/a"));
-        // make sure the watchers have been processed
-        while((rc=zookeeper_process(zh,ZOOKEEPER_READ))==ZOK) {
-          millisleep(100);
-        }
-        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
-
-        CPPUNIT_ASSERT_EQUAL(1,wobject1.counter_);
-        CPPUNIT_ASSERT_EQUAL(1,wobject2.counter_);        
-        CPPUNIT_ASSERT_EQUAL(0,defWatcher.counter_);
-    }
-
-    // testcase: create both a child and data watch on the node /a, send a ZOO_CHILD_EVENT
-    // verify: only the child watch triggered
-    void testChildWatcher2(){
-        Mock_gettimeofday timeMock;
-        ZookeeperServer zkServer;
-        // must call zookeeper_close() while all the mocks are in scope
-        CloseFinally guard(&zh);
-
-        ChildEventCountingWatcher defWatcher;
-        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
-                &defWatcher,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // simulate connected state
-        forceConnected(zh);
-        
-        AsyncCompletion ignored;
-        ChildEventCountingWatcher wobject1;
-        zkServer.addOperationResponse(new ZooStatResponse);
-        int rc=zoo_awexists(zh,"/a",activeWatcher,&wobject1,
-                asyncCompletion,&ignored);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-
-        typedef ZooGetChildrenResponse::StringVector ZooVector;
-        zkServer.addOperationResponse(new ZooGetChildrenResponse(
-                Util::CollectionBuilder<ZooVector>()("/a/1")("/a/2")
-                ));
-        ChildEventCountingWatcher wobject2;
-        rc=zoo_awget_children(zh,"/a",activeWatcher,
-                &wobject2,asyncCompletion,&ignored);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        
-        // this will process the response and activate the watcher
-        while((rc=zookeeper_process(zh,ZOOKEEPER_READ))==ZOK) {
-          millisleep(100);
-        }
-        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
-
-        // we are all set now; let's trigger the watches
-        zkServer.addRecvResponse(new ZNodeEvent(ZOO_CHILD_EVENT,"/a"));
-        // make sure the watchers have been processed
-        while((rc=zookeeper_process(zh,ZOOKEEPER_READ))==ZOK) {
-          millisleep(100);
-        }
-        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
-
-        CPPUNIT_ASSERT_EQUAL(0,wobject1.counter_);
-        CPPUNIT_ASSERT_EQUAL(1,wobject2.counter_);        
-        CPPUNIT_ASSERT_EQUAL(0,defWatcher.counter_);
-    }
-
-#else
-    // verify: the default watcher is called once for a session event
-    void testDefaultSessionWatcher1(){
-        Mock_gettimeofday timeMock;
-        // zookeeper simulator
-        ZookeeperServer zkServer;
-        // detects when all watchers have been delivered
-        WatcherDeliveryTracker deliveryTracker(ZOO_SESSION_EVENT,ZOO_CONNECTED_STATE);
-        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
-        // must call zookeeper_close() while all the mocks are in the scope!
-        CloseFinally guard(&zh);
-        
-        ConnectionWatcher watcher;
-        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
-                &watcher,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // wait till watcher proccessing has completed (the connection 
-        // established event)
-        CPPUNIT_ASSERT(ensureCondition(
-                deliveryTracker.isWatcherProcessingCompleted(),1000)<1000);
-        
-        // verify the watcher has been triggered
-        CPPUNIT_ASSERT(ensureCondition(watcher.isConnectionEstablished(),1000)<1000);
-        // triggered only once
-        CPPUNIT_ASSERT_EQUAL(1,watcher.counter_);
-    }
-
-    // test case: connect to server, set a default watcher, disconnect from the server
-    // verify: the default watcher is called once
-    void testDefaultSessionWatcher2(){
-        Mock_gettimeofday timeMock;
-        // zookeeper simulator
-        ZookeeperServer zkServer;
-        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
-        // must call zookeeper_close() while all the mocks are in the scope!
-        CloseFinally guard(&zh);
-        
-        // detects when all watchers have been delivered
-        WatcherDeliveryTracker deliveryTracker(ZOO_SESSION_EVENT,ZOO_CONNECTING_STATE);
-        DisconnectWatcher watcher;
-        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
-                &watcher,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // make sure the client has connected
-        CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
-        // set a default watch
-        AsyncCompletion ignored;
-        // a successful server response will activate the watcher 
-        zkServer.addOperationResponse(new ZooStatResponse);
-        int rc=zoo_aexists(zh,"/x/y/z",1,asyncCompletion,&ignored);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-
-        // now, initiate a disconnect
-        zkServer.setConnectionLost();
-        CPPUNIT_ASSERT(ensureCondition(
-                deliveryTracker.isWatcherProcessingCompleted(),1000)<1000);
-        
-        // verify the watcher has been triggered
-        CPPUNIT_ASSERT(watcher.disconnected_);
-        // triggered only once
-        CPPUNIT_ASSERT_EQUAL(1,watcher.counter_);
-    }
-
-    // testcase: connect to the server, set a watcher object on a node, 
-    //           disconnect from the server
-    // verify: the watcher object as well as the default watcher are called
-    void testObjectSessionWatcher1(){
-        Mock_gettimeofday timeMock;
-        // zookeeper simulator
-        ZookeeperServer zkServer;
-        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
-        // must call zookeeper_close() while all the mocks are in the scope!
-        CloseFinally guard(&zh);
-        
-        // detects when all watchers have been delivered
-        WatcherDeliveryTracker deliveryTracker(ZOO_SESSION_EVENT,ZOO_CONNECTING_STATE);
-        DisconnectWatcher defWatcher;
-        // use the tracker to find out when the watcher has been activated
-        WatcherActivationTracker activationTracker;
-        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
-                &defWatcher,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // make sure the client has connected
-        CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
-
-        AsyncCompletion ignored;
-        // this successful server response will activate the watcher 
-        zkServer.addOperationResponse(new ZooStatResponse);
-        CountingDataWatcher wobject;
-        activationTracker.track(&wobject);
-        // set a path-specific watcher
-        int rc=zoo_awexists(zh,"/x/y/z",activeWatcher,&wobject,
-                asyncCompletion,&ignored);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // make sure the watcher gets activated before we continue
-        CPPUNIT_ASSERT(ensureCondition(activationTracker.isWatcherActivated(),1000)<1000);
-        
-        // now, initiate a disconnect
-        zkServer.setConnectionLost();
-        // make sure all watchers have been processed
-        CPPUNIT_ASSERT(ensureCondition(
-                deliveryTracker.isWatcherProcessingCompleted(),1000)<1000);
-        
-        // verify the default watcher has been triggered
-        CPPUNIT_ASSERT(defWatcher.disconnected_);
-        // and triggered only once
-        CPPUNIT_ASSERT_EQUAL(1,defWatcher.counter_);
-        
-        // the path-specific watcher has been triggered as well
-        CPPUNIT_ASSERT(wobject.disconnected_);
-        // only once!
-        CPPUNIT_ASSERT_EQUAL(1,wobject.counter_);
-    }
-
-    // testcase: connect to the server, set a watcher object on a node, 
-    //           set a def watcher on another node,disconnect from the server
-    // verify: the watcher object as well as the default watcher are called
-    void testObjectSessionWatcher2(){
-        Mock_gettimeofday timeMock;
-        // zookeeper simulator
-        ZookeeperServer zkServer;
-        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
-        // must call zookeeper_close() while all the mocks are in the scope!
-        CloseFinally guard(&zh);
-        
-        // detects when all watchers have been delivered
-        WatcherDeliveryTracker deliveryTracker(ZOO_SESSION_EVENT,ZOO_CONNECTING_STATE);
-        DisconnectWatcher defWatcher;
-        // use the tracker to find out when the watcher has been activated
-        WatcherActivationTracker activationTracker;
-        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
-                &defWatcher,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // make sure the client has connected
-        CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
-
-        // set a default watch
-        AsyncCompletion ignored;
-        // a successful server response will activate the watcher 
-        zkServer.addOperationResponse(new ZooStatResponse);
-        activationTracker.track(&defWatcher);
-        int rc=zoo_aexists(zh,"/a/b/c",1,asyncCompletion,&ignored);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // make sure the watcher gets activated before we continue
-        CPPUNIT_ASSERT(ensureCondition(activationTracker.isWatcherActivated(),1000)<1000);
-
-        // this successful server response will activate the watcher 
-        zkServer.addOperationResponse(new ZooStatResponse);
-        CountingDataWatcher wobject;
-        activationTracker.track(&wobject);
-        // set a path-specific watcher
-        rc=zoo_awexists(zh,"/x/y/z",activeWatcher,&wobject,
-                asyncCompletion,&ignored);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // make sure the watcher gets activated before we continue
-        CPPUNIT_ASSERT(ensureCondition(activationTracker.isWatcherActivated(),1000)<1000);
-        
-        // now, initiate a disconnect
-        zkServer.setConnectionLost();
-        // make sure all watchers have been processed
-        CPPUNIT_ASSERT(ensureCondition(
-                deliveryTracker.isWatcherProcessingCompleted(),1000)<1000);
-        
-        // verify the default watcher has been triggered
-        CPPUNIT_ASSERT(defWatcher.disconnected_);
-        // and triggered only once
-        CPPUNIT_ASSERT_EQUAL(1,defWatcher.counter_);
-        
-        // the path-specific watcher has been triggered as well
-        CPPUNIT_ASSERT(wobject.disconnected_);
-        // only once!
-        CPPUNIT_ASSERT_EQUAL(1,wobject.counter_);
-    }
-
-    // testcase: register 2 node watches for different paths, trigger the watches
-    // verify: the data watchers are processed, the default watcher is not called
-    void testNodeWatcher1(){
-        Mock_gettimeofday timeMock;
-        // zookeeper simulator
-        ZookeeperServer zkServer;
-        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
-        // must call zookeeper_close() while all the mocks are in the scope!
-        CloseFinally guard(&zh);
-        
-        // detects when all watchers have been delivered
-        WatcherDeliveryTracker deliveryTracker(ZOO_CHANGED_EVENT,0,false);
-        CountingDataWatcher defWatcher;
-        // use the tracker to find out when the watcher has been activated
-        WatcherActivationTracker activationTracker;
-        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
-                &defWatcher,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // make sure the client has connected
-        CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
-
-        // don't care about completions
-        AsyncCompletion ignored;
-        // set a one-shot watch
-        // a successful server response will activate the watcher 
-        zkServer.addOperationResponse(new ZooStatResponse);
-        CountingDataWatcher wobject1;
-        activationTracker.track(&wobject1);
-        int rc=zoo_awexists(zh,"/a/b/c",activeWatcher,&wobject1,
-                asyncCompletion,&ignored);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // make sure the watcher gets activated before we continue
-        CPPUNIT_ASSERT(ensureCondition(activationTracker.isWatcherActivated(),1000)<1000);
-
-        // this successful server response will activate the watcher 
-        zkServer.addOperationResponse(new ZooStatResponse);
-        CountingDataWatcher wobject2;
-        activationTracker.track(&wobject2);
-        // set a path-specific watcher
-        rc=zoo_awexists(zh,"/x/y/z",activeWatcher,&wobject2,
-                asyncCompletion,&ignored);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // make sure the watcher gets activated before we continue
-        CPPUNIT_ASSERT(ensureCondition(activationTracker.isWatcherActivated(),1000)<1000);
-
-        // we are all set now; let's trigger the watches
-        zkServer.addRecvResponse(new ZNodeEvent(ZOO_CHANGED_EVENT,"/a/b/c"));
-        zkServer.addRecvResponse(new ZNodeEvent(ZOO_CHANGED_EVENT,"/x/y/z"));
-        // make sure all watchers have been processed
-        CPPUNIT_ASSERT(ensureCondition(
-                deliveryTracker.deliveryCounterEquals(2),1000)<1000);
-        
-        CPPUNIT_ASSERT_EQUAL(1,wobject1.counter_);
-        CPPUNIT_ASSERT_EQUAL(1,wobject2.counter_);        
-        CPPUNIT_ASSERT_EQUAL(0,defWatcher.counter_);
-    }
-
-    // testcase: set up both a children and a data watchers on the node /a, then
-    //           delete the node (that is, send a DELETE_EVENT)
-    // verify: both watchers are triggered
-    void testChildWatcher1(){
-        Mock_gettimeofday timeMock;
-        // zookeeper simulator
-        ZookeeperServer zkServer;
-        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
-        // must call zookeeper_close() while all the mocks are in the scope!
-        CloseFinally guard(&zh);
-        
-        // detects when all watchers have been delivered
-        WatcherDeliveryTracker deliveryTracker(ZOO_DELETED_EVENT,0);
-        DeletionCountingDataWatcher defWatcher;
-        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
-                &defWatcher,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // make sure the client has connected
-        CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
-        
-        // a successful server response will activate the watcher 
-        zkServer.addOperationResponse(new ZooStatResponse);
-        DeletionCountingDataWatcher wobject1;
-        Stat stat;
-        // add a node watch
-        int rc=zoo_wexists(zh,"/a",activeWatcher,&wobject1,&stat);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        
-        typedef ZooGetChildrenResponse::StringVector ZooVector;
-        zkServer.addOperationResponse(new ZooGetChildrenResponse(
-                Util::CollectionBuilder<ZooVector>()("/a/1")("/a/2")
-                ));
-        DeletionCountingDataWatcher wobject2;
-        String_vector children;
-        rc=zoo_wget_children(zh,"/a",activeWatcher,&wobject2,&children);
-        deallocate_String_vector(&children);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        
-        // we are all set now; let's trigger the watches
-        zkServer.addRecvResponse(new ZNodeEvent(ZOO_DELETED_EVENT,"/a"));
-        // make sure the watchers have been processed
-        CPPUNIT_ASSERT(ensureCondition(
-                deliveryTracker.isWatcherProcessingCompleted(),1000)<1000);
-
-        CPPUNIT_ASSERT_EQUAL(1,wobject1.counter_);
-        CPPUNIT_ASSERT_EQUAL(1,wobject2.counter_);        
-        CPPUNIT_ASSERT_EQUAL(0,defWatcher.counter_);
-    }
-    
-    // testcase: create both a child and data watch on the node /a, send a ZOO_CHILD_EVENT
-    // verify: only the child watch triggered
-    void testChildWatcher2(){
-        Mock_gettimeofday timeMock;
-        // zookeeper simulator
-        ZookeeperServer zkServer;
-        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
-        // must call zookeeper_close() while all the mocks are in the scope!
-        CloseFinally guard(&zh);
-        
-        // detects when all watchers have been delivered
-        WatcherDeliveryTracker deliveryTracker(ZOO_CHILD_EVENT,0);
-        ChildEventCountingWatcher defWatcher;
-        zh=zookeeper_init("localhost:2121",activeWatcher,10000,TEST_CLIENT_ID,
-                &defWatcher,0);
-        CPPUNIT_ASSERT(zh!=0);
-        // make sure the client has connected
-        CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
-        // a successful server response will activate the watcher 
-        zkServer.addOperationResponse(new ZooStatResponse);
-        ChildEventCountingWatcher wobject1;
-        Stat stat;
-        // add a node watch
-        int rc=zoo_wexists(zh,"/a",activeWatcher,&wobject1,&stat);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        
-        typedef ZooGetChildrenResponse::StringVector ZooVector;
-        zkServer.addOperationResponse(new ZooGetChildrenResponse(
-                Util::CollectionBuilder<ZooVector>()("/a/1")("/a/2")
-                ));
-        ChildEventCountingWatcher wobject2;
-        String_vector children;
-        rc=zoo_wget_children(zh,"/a",activeWatcher,&wobject2,&children);
-        deallocate_String_vector(&children);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-
-        // we are all set now; let's trigger the watches
-        zkServer.addRecvResponse(new ZNodeEvent(ZOO_CHILD_EVENT,"/a"));
-        // make sure the watchers have been processed
-        CPPUNIT_ASSERT(ensureCondition(
-                deliveryTracker.isWatcherProcessingCompleted(),1000)<1000);
-
-        CPPUNIT_ASSERT_EQUAL(0,wobject1.counter_);
-        CPPUNIT_ASSERT_EQUAL(1,wobject2.counter_);        
-        CPPUNIT_ASSERT_EQUAL(0,defWatcher.counter_);
-    }
-
-#endif //THREADED
-};
-
-CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_watchers);

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/src/c/tests/TestZookeeperClose.cc
----------------------------------------------------------------------
diff --git a/src/c/tests/TestZookeeperClose.cc b/src/c/tests/TestZookeeperClose.cc
deleted file mode 100644
index edefa66..0000000
--- a/src/c/tests/TestZookeeperClose.cc
+++ /dev/null
@@ -1,472 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <cppunit/extensions/HelperMacros.h>
-
-#include "ZKMocks.h"
-
-#ifdef THREADED
-#include "PthreadMocks.h"
-#endif
-
-using namespace std;
-
-class Zookeeper_close : public CPPUNIT_NS::TestFixture
-{
-    CPPUNIT_TEST_SUITE(Zookeeper_close);
-#ifdef THREADED
-    CPPUNIT_TEST(testIOThreadStoppedOnExpire);
-#endif
-    CPPUNIT_TEST(testCloseUnconnected);
-    CPPUNIT_TEST(testCloseUnconnected1);
-    CPPUNIT_TEST(testCloseConnected1);
-    CPPUNIT_TEST(testCloseFromWatcher1);
-    CPPUNIT_TEST_SUITE_END();
-    zhandle_t *zh;
-    static void watcher(zhandle_t *, int, int, const char *,void*){}
-    FILE *logfile;
-public: 
-
-    Zookeeper_close() {
-      logfile = openlogfile("Zookeeper_close");
-    }
-
-    ~Zookeeper_close() {
-      if (logfile) {
-        fflush(logfile);
-        fclose(logfile);
-        logfile = 0;
-      }
-    }
-
-    void setUp()
-    {
-        zoo_set_log_stream(logfile);
-
-        zoo_deterministic_conn_order(0);
-        zh=0;
-    }
-    
-    void tearDown()
-    {
-        zookeeper_close(zh);
-    }
-
-    class CloseOnSessionExpired: public WatcherAction{
-    public:
-        CloseOnSessionExpired(bool callClose=true):
-            callClose_(callClose),rc(ZOK){}
-        virtual void onSessionExpired(zhandle_t* zh){
-            memcpy(&lzh,zh,sizeof(lzh));
-            if(callClose_)
-                rc=zookeeper_close(zh);
-        }
-        zhandle_t lzh;
-        bool callClose_;
-        int rc;
-    };
-    
-#ifndef THREADED
-    void testCloseUnconnected()
-    {       
-        zh=zookeeper_init("localhost:2121",watcher,10000,0,0,0);       
-        CPPUNIT_ASSERT(zh!=0);
-        
-        // do not actually free the memory while in zookeeper_close()
-        Mock_free_noop freeMock;
-        // make a copy of zhandle before close() overwrites some of 
-        // it members with NULLs
-        zhandle_t lzh;
-        memcpy(&lzh,zh,sizeof(lzh));
-        int rc=zookeeper_close(zh);
-        zhandle_t* savezh=zh; zh=0;
-        freeMock.disable(); // disable mock's fake free()- use libc's free() instead
-        
-        // verify that zookeeper_close has done its job
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // memory
-        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
-        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.hostname));
-        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.addrs));
-        // This cannot be maintained properly CPPUNIT_ASSERT_EQUAL(9,freeMock.callCounter);
-    }
-    void testCloseUnconnected1()
-    {
-        zh=zookeeper_init("localhost:2121",watcher,10000,0,0,0);       
-        CPPUNIT_ASSERT(zh!=0);
-        // simulate connected state 
-        zh->fd=ZookeeperServer::FD;
-        zh->state=ZOO_CONNECTED_STATE;
-        Mock_flush_send_queue zkMock;
-        // do not actually free the memory while in zookeeper_close()
-        Mock_free_noop freeMock;
-        // make a copy of zhandle before close() overwrites some of 
-        // it members with NULLs
-        zhandle_t lzh;
-        memcpy(&lzh,zh,sizeof(lzh));
-        int rc=zookeeper_close(zh);
-        zhandle_t* savezh=zh; zh=0;
-        freeMock.disable(); // disable mock's fake free()- use libc's free() instead
-
-        // verify that zookeeper_close has done its job
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // memory
-        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
-        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.hostname));
-        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.addrs));
-        // the close request sent?
-        CPPUNIT_ASSERT_EQUAL(1,zkMock.counter);
-    }
-    void testCloseConnected1()
-    {
-        ZookeeperServer zkServer;
-        // poll() will called from zookeeper_close()
-        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
-
-        zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0);
-        CPPUNIT_ASSERT(zh!=0);
-
-        Mock_gettimeofday timeMock;
-        
-        int fd=0;
-        int interest=0;
-        timeval tv;
-        int rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);        
-        CPPUNIT_ASSERT_EQUAL(ZOO_CONNECTING_STATE,zoo_state(zh));
-        CPPUNIT_ASSERT_EQUAL(ZOOKEEPER_READ|ZOOKEEPER_WRITE,interest);
-        
-        rc=zookeeper_process(zh,interest);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);        
-        CPPUNIT_ASSERT_EQUAL(ZOO_ASSOCIATING_STATE,zoo_state(zh));
-        
-        rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        rc=zookeeper_process(zh,interest);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);        
-        CPPUNIT_ASSERT_EQUAL(ZOO_CONNECTED_STATE,zoo_state(zh));
-        // do not actually free the memory while in zookeeper_close()
-        Mock_free_noop freeMock;
-        // make a copy of zhandle before close() overwrites some of 
-        // it members with NULLs
-        zhandle_t lzh;
-        memcpy(&lzh,zh,sizeof(lzh));
-        zookeeper_close(zh);
-        zhandle_t* savezh=zh; zh=0;
-        freeMock.disable(); // disable mock's fake free()- use libc's free() instead
-        // memory
-        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
-        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.hostname));
-        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.addrs));
-        // the close request sent?
-        CPPUNIT_ASSERT_EQUAL(1,(int)zkServer.closeSent);
-    }
-    void testCloseFromWatcher1()
-    {
-        Mock_gettimeofday timeMock;
-
-        ZookeeperServer zkServer;
-        // make the server return a non-matching session id
-        zkServer.returnSessionExpired();
-        // poll() will called from zookeeper_close()
-        Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
-
-        CloseOnSessionExpired closeAction;
-        zh=zookeeper_init("localhost:2121",activeWatcher,10000,
-                TEST_CLIENT_ID,&closeAction,0);
-        CPPUNIT_ASSERT(zh!=0);
-        
-        int fd=0;
-        int interest=0;
-        timeval tv;
-        // initiate connection
-        int rc=zookeeper_interest(zh,&fd,&interest,&tv);        
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);        
-        CPPUNIT_ASSERT_EQUAL(ZOO_CONNECTING_STATE,zoo_state(zh));
-        CPPUNIT_ASSERT_EQUAL(ZOOKEEPER_READ|ZOOKEEPER_WRITE,interest);
-        rc=zookeeper_process(zh,interest);
-        // make sure the handshake in progress 
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);        
-        CPPUNIT_ASSERT_EQUAL(ZOO_ASSOCIATING_STATE,zoo_state(zh));
-        rc=zookeeper_interest(zh,&fd,&interest,&tv);
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        
-        // do not actually free the memory while in zookeeper_close()
-        Mock_free_noop freeMock;
-        // should call the watcher with ZOO_EXPIRED_SESSION_STATE state
-        rc=zookeeper_process(zh,interest);
-        zhandle_t* savezh=zh; zh=0;
-        freeMock.disable(); // disable mock's fake free()- use libc's free() instead
-        
-        CPPUNIT_ASSERT_EQUAL(ZOO_EXPIRED_SESSION_STATE,zoo_state(savezh));
-        // memory
-        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
-        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.hostname));
-        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.addrs));
-        // make sure the close request NOT sent
-        CPPUNIT_ASSERT_EQUAL(0,(int)zkServer.closeSent);
-    }
-#else
-    void testCloseUnconnected()
-    {
-        // disable threading
-        MockPthreadZKNull pthreadMock;
-        zh=zookeeper_init("localhost:2121",watcher,10000,0,0,0); 
-        
-        CPPUNIT_ASSERT(zh!=0);
-        adaptor_threads* adaptor=(adaptor_threads*)zh->adaptor_priv;
-        CPPUNIT_ASSERT(adaptor!=0);
-
-        // do not actually free the memory while in zookeeper_close()
-        Mock_free_noop freeMock;
-        // make a copy of zhandle before close() overwrites some of 
-        // it members with NULLs
-        zhandle_t lzh;
-        memcpy(&lzh,zh,sizeof(lzh));
-        int rc=zookeeper_close(zh);
-        zhandle_t* savezh=zh; zh=0;
-        // we're done, disable mock's fake free(), use libc's free() instead
-        freeMock.disable();
-        
-        // verify that zookeeper_close has done its job
-        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        // memory
-        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
-        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.hostname));
-        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.addrs));
-        CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(adaptor));
-        // Cannot be maintained accurately: CPPUNIT_ASSERT_EQUAL(10,freeMock.callCounter);
-        // threads
-        CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(adaptor->io));
-        CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(adaptor->completion));
-        // mutexes
-        CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->to_process.lock));
-        CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->to_process.lock));
-        CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->to_send.lock));
-        CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->to_send.lock));
-        CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->sent_requests.lock));
-        CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->sent_requests.lock));
-        CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->completions_to_process.lock));
-        CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->completions_to_process.lock));
-        // conditionals
-        CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->sent_requests.cond));
-        CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->sent_requests.cond));
-        CPPUNIT_ASSERT_EQUAL(1,MockPthreadsNull::getDestroyCounter(&savezh->completions_to_process.cond));
-        CPPUNIT_ASSERT_EQUAL(0,MockPthreadsNull::getInvalidAccessCounter(&savezh->completions_to_process.cond));
-    }
-    void testCloseUnconnected1()
-    {
-        for(int i=0; i<100;i++){
-            zh=zookeeper_init("localhost:2121",watcher,10000,0,0,0); 
-            CPPUNIT_ASSERT(zh!=0);
-            adaptor_threads* adaptor=(adaptor_threads*)zh->adaptor_priv;
-            CPPUNIT_ASSERT(adaptor!=0);
-            int rc=zookeeper_close(zh);
-            zh=0;
-            CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
-        }
-    }
-    void testCloseConnected1()
-    {
-        // frozen time -- no timeouts and no pings
-        Mock_gettimeofday timeMock;
-
-        for(int i=0;i<100;i++){
-            ZookeeperServer zkServer;
-            Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
-            // use a checked version of pthread calls
-            CheckedPthread threadMock;
-            // do not actually free the memory while in zookeeper_close()
-            Mock_free_noop freeMock;
-            
-            zh=zookeeper_init("localhost:2121",watcher,10000,TEST_CLIENT_ID,0,0); 
-            CPPUNIT_ASSERT(zh!=0);
-            // make sure the client has connected
-            CPPUNIT_ASSERT(ensureCondition(ClientConnected(zh),1000)<1000);
-            // make a copy of zhandle before close() overwrites some of 
-            // its members with NULLs
-            zhandle_t lzh;
-            memcpy(&lzh,zh,sizeof(lzh));
-            int rc=zookeeper_close(zh);
-            zhandle_t* savezh=zh; zh=0;
-            // we're done, disable mock's fake free(), use libc's free() instead
-            freeMock.disable();
-            
-            CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);            
-            adaptor_threads* adaptor=(adaptor_threads*)lzh.adaptor_priv;
-            // memory
-            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(savezh));
-            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.hostname));
-            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh.addrs));
-            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(adaptor));
-            // threads
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->io));
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->completion));
-            // mutexes
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->to_process.lock));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->to_process.lock));
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->to_send.lock));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->to_send.lock));
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->sent_requests.lock));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->sent_requests.lock));
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->completions_to_process.lock));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->completions_to_process.lock));
-            // conditionals
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->sent_requests.cond));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->sent_requests.cond));
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&savezh->completions_to_process.cond));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&savezh->completions_to_process.cond));
-        }
-    }
-    
-    struct PointerFreed{
-        PointerFreed(Mock_free_noop& freeMock,void* ptr):
-            freeMock_(freeMock),ptr_(ptr){}
-        bool operator()() const{return freeMock_.isFreed(ptr_); }
-        Mock_free_noop& freeMock_;
-        void* ptr_;
-    };
-    // test if zookeeper_close may be called from a watcher callback on
-    // SESSION_EXPIRED event
-    void testCloseFromWatcher1()
-    {
-        // frozen time -- no timeouts and no pings
-        Mock_gettimeofday timeMock;
-        
-        for(int i=0;i<100;i++){
-            ZookeeperServer zkServer;
-            // make the server return a non-matching session id
-            zkServer.returnSessionExpired();
-            
-            Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
-            // use a checked version of pthread calls
-            CheckedPthread threadMock;
-            // do not actually free the memory while in zookeeper_close()
-            Mock_free_noop freeMock;
-
-            CloseOnSessionExpired closeAction;
-            zh=zookeeper_init("localhost:2121",activeWatcher,10000,
-                    TEST_CLIENT_ID,&closeAction,0);
-            
-            CPPUNIT_ASSERT(zh!=0);
-            // we rely on the fact that zh is freed the last right before
-            // zookeeper_close() returns...
-            CPPUNIT_ASSERT(ensureCondition(PointerFreed(freeMock,zh),1000)<1000);
-            zhandle_t* lzh=zh;
-            zh=0;
-            // we're done, disable mock's fake free(), use libc's free() instead
-            freeMock.disable();
-            
-            CPPUNIT_ASSERT_EQUAL((int)ZOK,closeAction.rc);          
-            adaptor_threads* adaptor=(adaptor_threads*)closeAction.lzh.adaptor_priv;
-            // memory
-            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh));
-            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.hostname));
-            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.addrs));
-            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(adaptor));
-            // threads
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->io));
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->completion));
-            // mutexes
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->to_process.lock));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->to_process.lock));
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->to_send.lock));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->to_send.lock));
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->sent_requests.lock));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->sent_requests.lock));
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->completions_to_process.lock));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->completions_to_process.lock));
-            // conditionals
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->sent_requests.cond));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->sent_requests.cond));
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->completions_to_process.cond));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->completions_to_process.cond));
-        }
-    }
-
-    void testIOThreadStoppedOnExpire()
-    {
-        // frozen time -- no timeouts and no pings
-        Mock_gettimeofday timeMock;
-        
-        for(int i=0;i<100;i++){
-            ZookeeperServer zkServer;
-            // make the server return a non-matching session id
-            zkServer.returnSessionExpired();
-            
-            Mock_poll pollMock(&zkServer,ZookeeperServer::FD);
-            // use a checked version of pthread calls
-            CheckedPthread threadMock;
-            // do not call zookeeper_close() from the watcher
-            CloseOnSessionExpired closeAction(false);
-            zh=zookeeper_init("localhost:2121",activeWatcher,10000,
-                    &testClientId,&closeAction,0);
-            
-            // this is to ensure that if any assert fires, zookeeper_close() 
-            // will still be called while all the mocks are in the scope!
-            CloseFinally guard(&zh);
-
-            CPPUNIT_ASSERT(zh!=0);
-            CPPUNIT_ASSERT(ensureCondition(SessionExpired(zh),1000)<1000);
-            CPPUNIT_ASSERT(ensureCondition(IOThreadStopped(zh),1000)<1000);
-            // make sure the watcher has been processed
-            CPPUNIT_ASSERT(ensureCondition(closeAction.isWatcherTriggered(),1000)<1000);
-            // make sure the threads have not been destroyed yet
-            adaptor_threads* adaptor=(adaptor_threads*)zh->adaptor_priv;
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getDestroyCounter(adaptor->io));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getDestroyCounter(adaptor->completion));
-            // about to call zookeeper_close() -- no longer need the guard
-            guard.disarm();
-            
-            // do not actually free the memory while in zookeeper_close()
-            Mock_free_noop freeMock;
-            zookeeper_close(zh);
-            zhandle_t* lzh=zh; zh=0;
-            // we're done, disable mock's fake free(), use libc's free() instead
-            freeMock.disable();
-            
-            // memory
-            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(lzh));
-            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.hostname));
-            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(closeAction.lzh.addrs));
-            CPPUNIT_ASSERT_EQUAL(1,freeMock.getFreeCount(adaptor));
-            // threads
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->io));
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(adaptor->completion));
-            // mutexes
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->to_process.lock));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->to_process.lock));
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->to_send.lock));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->to_send.lock));
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->sent_requests.lock));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->sent_requests.lock));
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->completions_to_process.lock));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->completions_to_process.lock));
-            // conditionals
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->sent_requests.cond));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->sent_requests.cond));
-            CPPUNIT_ASSERT_EQUAL(1,CheckedPthread::getDestroyCounter(&lzh->completions_to_process.cond));
-            CPPUNIT_ASSERT_EQUAL(0,CheckedPthread::getInvalidAccessCounter(&lzh->completions_to_process.cond));
-        }
-    }
-
-#endif
-};
-
-CPPUNIT_TEST_SUITE_REGISTRATION(Zookeeper_close);


[05/20] zookeeper git commit: ZOOKEEPER-3031: 3.4: MAVEN MIGRATION - move client dir

Posted by an...@apache.org.
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/5694559d/zookeeper-client/zookeeper-client-c/src/zookeeper.c
----------------------------------------------------------------------
diff --git a/zookeeper-client/zookeeper-client-c/src/zookeeper.c b/zookeeper-client/zookeeper-client-c/src/zookeeper.c
new file mode 100644
index 0000000..c087864
--- /dev/null
+++ b/zookeeper-client/zookeeper-client-c/src/zookeeper.c
@@ -0,0 +1,3767 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if !defined(DLL_EXPORT) && !defined(USE_STATIC_LIB)
+#  define USE_STATIC_LIB
+#endif
+
+#if defined(__CYGWIN__)
+#define USE_IPV6
+#endif
+
+#include "config.h"
+#include <zookeeper.h>
+#include <zookeeper.jute.h>
+#include <proto.h>
+#include "zk_adaptor.h"
+#include "zookeeper_log.h"
+#include "zk_hashtable.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <limits.h>
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifdef HAVE_POLL
+#include <poll.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> // needed for _POSIX_MONOTONIC_CLOCK
+#endif
+
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+
+#ifdef HAVE_GETPWUID_R
+#include <pwd.h>
+#endif
+
+#ifdef WIN32
+#define random rand /* replace POSIX random with Windows rand */
+#include <process.h> /* for getpid */
+#include <direct.h> /* for getcwd */
+#define EAI_ADDRFAMILY WSAEINVAL /* is this still needed? */
+#define EHOSTDOWN EPIPE
+#define ESTALE ENODEV
+#endif
+
+#define IF_DEBUG(x) if(logLevel==ZOO_LOG_LEVEL_DEBUG) {x;}
+
+const int ZOOKEEPER_WRITE = 1 << 0;
+const int ZOOKEEPER_READ = 1 << 1;
+
+const int ZOO_EPHEMERAL = 1 << 0;
+const int ZOO_SEQUENCE = 1 << 1;
+
+const int ZOO_EXPIRED_SESSION_STATE = EXPIRED_SESSION_STATE_DEF;
+const int ZOO_AUTH_FAILED_STATE = AUTH_FAILED_STATE_DEF;
+const int ZOO_CONNECTING_STATE = CONNECTING_STATE_DEF;
+const int ZOO_ASSOCIATING_STATE = ASSOCIATING_STATE_DEF;
+const int ZOO_CONNECTED_STATE = CONNECTED_STATE_DEF;
+static __attribute__ ((unused)) const char* state2String(int state){
+    switch(state){
+    case 0:
+        return "ZOO_CLOSED_STATE";
+    case CONNECTING_STATE_DEF:
+        return "ZOO_CONNECTING_STATE";
+    case ASSOCIATING_STATE_DEF:
+        return "ZOO_ASSOCIATING_STATE";
+    case CONNECTED_STATE_DEF:
+        return "ZOO_CONNECTED_STATE";
+    case EXPIRED_SESSION_STATE_DEF:
+        return "ZOO_EXPIRED_SESSION_STATE";
+    case AUTH_FAILED_STATE_DEF:
+        return "ZOO_AUTH_FAILED_STATE";
+    }
+    return "INVALID_STATE";
+}
+
+const int ZOO_CREATED_EVENT = CREATED_EVENT_DEF;
+const int ZOO_DELETED_EVENT = DELETED_EVENT_DEF;
+const int ZOO_CHANGED_EVENT = CHANGED_EVENT_DEF;
+const int ZOO_CHILD_EVENT = CHILD_EVENT_DEF;
+const int ZOO_SESSION_EVENT = SESSION_EVENT_DEF;
+const int ZOO_NOTWATCHING_EVENT = NOTWATCHING_EVENT_DEF;
+static __attribute__ ((unused)) const char* watcherEvent2String(int ev){
+    switch(ev){
+    case 0:
+        return "ZOO_ERROR_EVENT";
+    case CREATED_EVENT_DEF:
+        return "ZOO_CREATED_EVENT";
+    case DELETED_EVENT_DEF:
+        return "ZOO_DELETED_EVENT";
+    case CHANGED_EVENT_DEF:
+        return "ZOO_CHANGED_EVENT";
+    case CHILD_EVENT_DEF:
+        return "ZOO_CHILD_EVENT";
+    case SESSION_EVENT_DEF:
+        return "ZOO_SESSION_EVENT";
+    case NOTWATCHING_EVENT_DEF:
+        return "ZOO_NOTWATCHING_EVENT";
+    }
+    return "INVALID_EVENT";
+}
+
+const int ZOO_PERM_READ = 1 << 0;
+const int ZOO_PERM_WRITE = 1 << 1;
+const int ZOO_PERM_CREATE = 1 << 2;
+const int ZOO_PERM_DELETE = 1 << 3;
+const int ZOO_PERM_ADMIN = 1 << 4;
+const int ZOO_PERM_ALL = 0x1f;
+struct Id ZOO_ANYONE_ID_UNSAFE = {"world", "anyone"};
+struct Id ZOO_AUTH_IDS = {"auth", ""};
+static struct ACL _OPEN_ACL_UNSAFE_ACL[] = {{0x1f, {"world", "anyone"}}};
+static struct ACL _READ_ACL_UNSAFE_ACL[] = {{0x01, {"world", "anyone"}}};
+static struct ACL _CREATOR_ALL_ACL_ACL[] = {{0x1f, {"auth", ""}}};
+struct ACL_vector ZOO_OPEN_ACL_UNSAFE = { 1, _OPEN_ACL_UNSAFE_ACL};
+struct ACL_vector ZOO_READ_ACL_UNSAFE = { 1, _READ_ACL_UNSAFE_ACL};
+struct ACL_vector ZOO_CREATOR_ALL_ACL = { 1, _CREATOR_ALL_ACL_ACL};
+
+#define COMPLETION_WATCH -1
+#define COMPLETION_VOID 0
+#define COMPLETION_STAT 1
+#define COMPLETION_DATA 2
+#define COMPLETION_STRINGLIST 3
+#define COMPLETION_STRINGLIST_STAT 4
+#define COMPLETION_ACLLIST 5
+#define COMPLETION_STRING 6
+#define COMPLETION_MULTI 7
+
+typedef struct _auth_completion_list {
+    void_completion_t completion;
+    const char *auth_data;
+    struct _auth_completion_list *next;
+} auth_completion_list_t;
+
+typedef struct completion {
+    int type; /* one of COMPLETION_* values above */
+    union {
+        void_completion_t void_result;
+        stat_completion_t stat_result;
+        data_completion_t data_result;
+        strings_completion_t strings_result;
+        strings_stat_completion_t strings_stat_result;
+        acl_completion_t acl_result;
+        string_completion_t string_result;
+        struct watcher_object_list *watcher_result;
+    };
+    completion_head_t clist; /* For multi-op */
+} completion_t;
+
+typedef struct _completion_list {
+    int xid;
+    completion_t c;
+    const void *data;
+    buffer_list_t *buffer;
+    struct _completion_list *next;
+    watcher_registration_t* watcher;
+} completion_list_t;
+
+const char*err2string(int err);
+static int queue_session_event(zhandle_t *zh, int state);
+static const char* format_endpoint_info(const struct sockaddr_storage* ep);
+static const char* format_current_endpoint_info(zhandle_t* zh);
+
+/* deserialize forward declarations */
+static void deserialize_response(int type, int xid, int failed, int rc, completion_list_t *cptr, struct iarchive *ia);
+static int deserialize_multi(int xid, completion_list_t *cptr, struct iarchive *ia);
+
+/* completion routine forward declarations */
+static int add_completion(zhandle_t *zh, int xid, int completion_type,
+        const void *dc, const void *data, int add_to_front, 
+        watcher_registration_t* wo, completion_head_t *clist);
+static completion_list_t* create_completion_entry(int xid, int completion_type,
+        const void *dc, const void *data, watcher_registration_t* wo, 
+        completion_head_t *clist);
+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);
+
+static int disable_conn_permute=0; // permute enabled by default
+
+static __attribute__((unused)) void print_completion_queue(zhandle_t *zh);
+
+static void *SYNCHRONOUS_MARKER = (void*)&SYNCHRONOUS_MARKER;
+static int isValidPath(const char* path, const int flags);
+
+#ifdef _WINDOWS
+static int zookeeper_send(SOCKET s, const char* buf, int len)
+#else
+static ssize_t zookeeper_send(int s, const void* buf, size_t len)
+#endif
+{
+#ifdef __linux__
+  return send(s, buf, len, MSG_NOSIGNAL);
+#else
+  return send(s, buf, len, 0);
+#endif
+}
+
+const void *zoo_get_context(zhandle_t *zh)
+{
+    return zh->context;
+}
+
+void zoo_set_context(zhandle_t *zh, void *context)
+{
+    if (zh != NULL) {
+        zh->context = context;
+    }
+}
+
+int zoo_recv_timeout(zhandle_t *zh)
+{
+    return zh->recv_timeout;
+}
+
+/** these functions are thread unsafe, so make sure that
+    zoo_lock_auth is called before you access them **/
+static auth_info* get_last_auth(auth_list_head_t *auth_list) {
+    auth_info *element;
+    element = auth_list->auth;
+    if (element == NULL) {
+        return NULL;
+    }
+    while (element->next != NULL) {
+        element = element->next;
+    }
+    return element;
+}
+
+static void free_auth_completion(auth_completion_list_t *a_list) {
+    auth_completion_list_t *tmp, *ftmp;
+    if (a_list == NULL) {
+        return;
+    }
+    tmp = a_list->next;
+    while (tmp != NULL) {
+        ftmp = tmp;
+        tmp = tmp->next;
+        ftmp->completion = NULL;
+        ftmp->auth_data = NULL;
+        free(ftmp);
+    }
+    a_list->completion = NULL;
+    a_list->auth_data = NULL;
+    a_list->next = NULL;
+    return;
+}
+
+static void add_auth_completion(auth_completion_list_t* a_list, void_completion_t* completion,
+                                const char *data) {
+    auth_completion_list_t *element;
+    auth_completion_list_t *n_element;
+    element = a_list;
+    if (a_list->completion == NULL) {
+        //this is the first element
+        a_list->completion = *completion;
+        a_list->next = NULL;
+        a_list->auth_data = data;
+        return;
+    }
+    while (element->next != NULL) {
+        element = element->next;
+    }
+    n_element = (auth_completion_list_t*) malloc(sizeof(auth_completion_list_t));
+    n_element->next = NULL;
+    n_element->completion = *completion;
+    n_element->auth_data = data;
+    element->next = n_element;
+    return;
+}
+
+static void get_auth_completions(auth_list_head_t *auth_list, auth_completion_list_t *a_list) {
+    auth_info *element;
+    element = auth_list->auth;
+    if (element == NULL) {
+        return;
+    }
+    while (element) {
+        if (element->completion) {
+            add_auth_completion(a_list, &element->completion, element->data);
+        }
+        element->completion = NULL;
+        element = element->next;
+    }
+    return;
+}
+
+static void add_last_auth(auth_list_head_t *auth_list, auth_info *add_el) {
+    auth_info  *element;
+    element = auth_list->auth;
+    if (element == NULL) {
+        //first element in the list
+        auth_list->auth = add_el;
+        return;
+    }
+    while (element->next != NULL) {
+        element = element->next;
+    }
+    element->next = add_el;
+    return;
+}
+
+static void init_auth_info(auth_list_head_t *auth_list)
+{
+    auth_list->auth = NULL;
+}
+
+static void mark_active_auth(zhandle_t *zh) {
+    auth_list_head_t auth_h = zh->auth_h;
+    auth_info *element;
+    if (auth_h.auth == NULL) {
+        return;
+    }
+    element = auth_h.auth;
+    while (element != NULL) {
+        element->state = 1;
+        element = element->next;
+    }
+}
+
+static void free_auth_info(auth_list_head_t *auth_list)
+{
+    auth_info *auth = auth_list->auth;
+    while (auth != NULL) {
+        auth_info* old_auth = NULL;
+        if(auth->scheme!=NULL)
+            free(auth->scheme);
+        deallocate_Buffer(&auth->auth);
+        old_auth = auth;
+        auth = auth->next;
+        free(old_auth);
+    }
+    init_auth_info(auth_list);
+}
+
+int is_unrecoverable(zhandle_t *zh)
+{
+    return (zh->state<0)? ZINVALIDSTATE: ZOK;
+}
+
+zk_hashtable *exists_result_checker(zhandle_t *zh, int rc)
+{
+    if (rc == ZOK) {
+        return zh->active_node_watchers;
+    } else if (rc == ZNONODE) {
+        return zh->active_exist_watchers;
+    }
+    return 0;
+}
+
+zk_hashtable *data_result_checker(zhandle_t *zh, int rc)
+{
+    return rc==ZOK ? zh->active_node_watchers : 0;
+}
+
+zk_hashtable *child_result_checker(zhandle_t *zh, int rc)
+{
+    return rc==ZOK ? zh->active_child_watchers : 0;
+}
+
+/**
+ * Frees and closes everything associated with a handle,
+ * including the handle itself.
+ */
+static void destroy(zhandle_t *zh)
+{
+    if (zh == NULL) {
+        return;
+    }
+    /* call any outstanding completions with a special error code */
+    cleanup_bufs(zh,1,ZCLOSING);
+    if (zh->hostname != 0) {
+        free(zh->hostname);
+        zh->hostname = NULL;
+    }
+    if (zh->fd != -1) {
+        close(zh->fd);
+        zh->fd = -1;
+        zh->state = 0;
+    }
+    if (zh->addrs != 0) {
+        free(zh->addrs);
+        zh->addrs = NULL;
+    }
+
+    if (zh->chroot != 0) {
+        free(zh->chroot);
+        zh->chroot = NULL;
+    }
+
+    free_auth_info(&zh->auth_h);
+    destroy_zk_hashtable(zh->active_node_watchers);
+    destroy_zk_hashtable(zh->active_exist_watchers);
+    destroy_zk_hashtable(zh->active_child_watchers);
+}
+
+static void setup_random()
+{
+#ifndef WIN32          // TODO: better seed
+    int seed;
+    int fd = open("/dev/urandom", O_RDONLY);
+    if (fd == -1) {
+        seed = getpid();
+    } else {
+        int seed_len = 0;
+
+        /* Enter a loop to fill in seed with random data from /dev/urandom.
+         * This is done in a loop so that we can safely handle short reads
+         * which can happen due to signal interruptions.
+         */
+        while (seed_len < sizeof(seed)) {
+            /* Assert we either read something or we were interrupted due to a
+             * signal (errno == EINTR) in which case we need to retry.
+             */
+            int rc = read(fd, &seed + seed_len, sizeof(seed) - seed_len);
+            assert(rc > 0 || errno == EINTR);
+            if (rc > 0) {
+                seed_len += rc;
+            }
+        }
+        close(fd);
+    }
+    srandom(seed);
+#endif
+}
+
+#ifndef __CYGWIN__
+/**
+ * get the errno from the return code 
+ * of get addrinfo. Errno is not set
+ * with the call to getaddrinfo, so thats
+ * why we have to do this.
+ */
+static int getaddrinfo_errno(int rc) { 
+    switch(rc) {
+    case EAI_NONAME:
+// ZOOKEEPER-1323 EAI_NODATA and EAI_ADDRFAMILY are deprecated in FreeBSD.
+#if defined EAI_NODATA && EAI_NODATA != EAI_NONAME
+    case EAI_NODATA:
+#endif
+        return ENOENT;
+    case EAI_MEMORY:
+        return ENOMEM;
+    default:
+        return EINVAL;
+    }
+}
+#endif
+
+/**
+ * fill in the addrs array of the zookeeper servers in the zhandle. after filling
+ * them in, we will permute them for load balancing.
+ */
+int getaddrs(zhandle_t *zh)
+{
+    char *hosts = strdup(zh->hostname);
+    char *host;
+    char *strtok_last;
+    struct sockaddr_storage *addr;
+    int i;
+    int rc;
+    int alen = 0; /* the allocated length of the addrs array */
+
+    zh->addrs_count = 0;
+    if (zh->addrs) {
+        free(zh->addrs);
+        zh->addrs = 0;
+    }
+    if (!hosts) {
+         LOG_ERROR(("out of memory"));
+        errno=ENOMEM;
+        return ZSYSTEMERROR;
+    }
+    zh->addrs = 0;
+    host=strtok_r(hosts, ",", &strtok_last);
+    while(host) {
+        char *port_spec = strrchr(host, ':');
+        char *end_port_spec;
+        int port;
+        if (!port_spec) {
+            LOG_ERROR(("no port in %s", host));
+            errno=EINVAL;
+            rc=ZBADARGUMENTS;
+            goto fail;
+        }
+        *port_spec = '\0';
+        port_spec++;
+        port = strtol(port_spec, &end_port_spec, 0);
+        if (!*port_spec || *end_port_spec || port == 0) {
+            LOG_ERROR(("invalid port in %s", host));
+            errno=EINVAL;
+            rc=ZBADARGUMENTS;
+            goto fail;
+        }
+#if defined(__CYGWIN__)
+        // sadly CYGWIN doesn't have getaddrinfo
+        // but happily gethostbyname is threadsafe in windows
+        {
+        struct hostent *he;
+        char **ptr;
+        struct sockaddr_in *addr4;
+
+        he = gethostbyname(host);
+        if (!he) {
+            LOG_ERROR(("could not resolve %s", host));
+            errno=ENOENT;
+            rc=ZBADARGUMENTS;
+            goto fail;
+        }
+
+        /* Setup the address array */
+        for(ptr = he->h_addr_list;*ptr != 0; ptr++) {
+            if (zh->addrs_count == alen) {
+                alen += 16;
+                zh->addrs = realloc(zh->addrs, sizeof(*zh->addrs)*alen);
+                if (zh->addrs == 0) {
+                    LOG_ERROR(("out of memory"));
+                    errno=ENOMEM;
+                    rc=ZSYSTEMERROR;
+                    goto fail;
+                }
+            }
+            addr = &zh->addrs[zh->addrs_count];
+            addr4 = (struct sockaddr_in*)addr;
+            addr->ss_family = he->h_addrtype;
+            if (addr->ss_family == AF_INET) {
+                addr4->sin_port = htons(port);
+                memset(&addr4->sin_zero, 0, sizeof(addr4->sin_zero));
+                memcpy(&addr4->sin_addr, *ptr, he->h_length);
+                zh->addrs_count++;
+            }
+#if defined(AF_INET6)
+            else if (addr->ss_family == AF_INET6) {
+                struct sockaddr_in6 *addr6;
+
+                addr6 = (struct sockaddr_in6*)addr;
+                addr6->sin6_port = htons(port);
+                addr6->sin6_scope_id = 0;
+                addr6->sin6_flowinfo = 0;
+                memcpy(&addr6->sin6_addr, *ptr, he->h_length);
+                zh->addrs_count++;
+            }
+#endif
+            else {
+                LOG_WARN(("skipping unknown address family %x for %s",
+                         addr->ss_family, zh->hostname));
+            }
+        }
+        host = strtok_r(0, ",", &strtok_last);
+        }
+#else
+        {
+        struct addrinfo hints, *res, *res0;
+
+        memset(&hints, 0, sizeof(hints));
+#ifdef AI_ADDRCONFIG
+        hints.ai_flags = AI_ADDRCONFIG;
+#else
+        hints.ai_flags = 0;
+#endif
+        hints.ai_family = AF_UNSPEC;
+        hints.ai_socktype = SOCK_STREAM;
+        hints.ai_protocol = IPPROTO_TCP;
+
+        while(isspace(*host) && host != strtok_last)
+            host++;
+
+        if ((rc = getaddrinfo(host, port_spec, &hints, &res0)) != 0) {
+            //bug in getaddrinfo implementation when it returns
+            //EAI_BADFLAGS or EAI_ADDRFAMILY with AF_UNSPEC and 
+            // ai_flags as AI_ADDRCONFIG
+#ifdef AI_ADDRCONFIG
+            if ((hints.ai_flags == AI_ADDRCONFIG) && 
+// ZOOKEEPER-1323 EAI_NODATA and EAI_ADDRFAMILY are deprecated in FreeBSD.
+#ifdef EAI_ADDRFAMILY
+                ((rc ==EAI_BADFLAGS) || (rc == EAI_ADDRFAMILY))) {
+#else
+                (rc == EAI_BADFLAGS)) {
+#endif
+                //reset ai_flags to null
+                hints.ai_flags = 0;
+                //retry getaddrinfo
+                rc = getaddrinfo(host, port_spec, &hints, &res0);
+            }
+#endif
+            if (rc != 0) {
+                errno = getaddrinfo_errno(rc);
+#ifdef WIN32
+                LOG_ERROR(("Win32 message: %s\n", gai_strerror(rc)));
+#else
+                LOG_ERROR(("getaddrinfo: %s\n", strerror(errno)));
+#endif
+                rc=ZSYSTEMERROR;
+                goto fail;
+            }
+        }
+
+        for (res = res0; res; res = res->ai_next) {
+            // Expand address list if needed
+            if (zh->addrs_count == alen) {
+                void *tmpaddr;
+                alen += 16;
+                tmpaddr = realloc(zh->addrs, sizeof(*zh->addrs)*alen);
+                if (tmpaddr == 0) {
+                    LOG_ERROR(("out of memory"));
+                    errno=ENOMEM;
+                    rc=ZSYSTEMERROR;
+                    goto fail;
+                }
+                zh->addrs=tmpaddr;
+            }
+
+            // Copy addrinfo into address list
+            addr = &zh->addrs[zh->addrs_count];
+            switch (res->ai_family) {
+            case AF_INET:
+#if defined(AF_INET6)
+            case AF_INET6:
+#endif
+                memcpy(addr, res->ai_addr, res->ai_addrlen);
+                ++zh->addrs_count;
+                break;
+            default:
+                LOG_WARN(("skipping unknown address family %x for %s",
+                res->ai_family, zh->hostname));
+                break;
+            }
+        }
+
+        freeaddrinfo(res0);
+
+        host = strtok_r(0, ",", &strtok_last);
+        }
+#endif
+    }
+    free(hosts);
+
+    if(!disable_conn_permute){
+        setup_random();
+        /* Permute */
+        for (i = zh->addrs_count - 1; i > 0; --i) {
+            long int j = random()%(i+1);
+            if (i != j) {
+                struct sockaddr_storage t = zh->addrs[i];
+                zh->addrs[i] = zh->addrs[j];
+                zh->addrs[j] = t;
+            }
+        }
+    }
+    return ZOK;
+fail:
+    if (zh->addrs) {
+        free(zh->addrs);
+        zh->addrs=0;
+    }
+    if (hosts) {
+        free(hosts);
+    }
+    return rc;
+}
+
+const clientid_t *zoo_client_id(zhandle_t *zh)
+{
+    return &zh->client_id;
+}
+
+static void null_watcher_fn(zhandle_t* p1, int p2, int p3,const char* p4,void*p5){}
+
+watcher_fn zoo_set_watcher(zhandle_t *zh,watcher_fn newFn)
+{
+    watcher_fn oldWatcher=zh->watcher;
+    if (newFn) {
+       zh->watcher = newFn;
+    } else {
+       zh->watcher = null_watcher_fn;
+    }
+    return oldWatcher;
+}
+
+struct sockaddr* zookeeper_get_connected_host(zhandle_t *zh,
+                 struct sockaddr *addr, socklen_t *addr_len)
+{
+    if (zh->state!=ZOO_CONNECTED_STATE) {
+        return NULL;
+    }
+    if (getpeername(zh->fd, addr, addr_len)==-1) {
+        return NULL;
+    }
+    return addr;
+}
+
+static void log_env() {
+  char buf[2048];
+#ifdef HAVE_SYS_UTSNAME_H
+  struct utsname utsname;
+#endif
+
+#if defined(HAVE_GETUID) && defined(HAVE_GETPWUID_R)
+  struct passwd pw;
+  struct passwd *pwp = NULL;
+  uid_t uid = 0;
+#endif
+
+  LOG_INFO(("Client environment:zookeeper.version=%s", PACKAGE_STRING));
+
+#ifdef HAVE_GETHOSTNAME
+  gethostname(buf, sizeof(buf));
+  LOG_INFO(("Client environment:host.name=%s", buf));
+#else
+  LOG_INFO(("Client environment:host.name=<not implemented>"));
+#endif
+
+#ifdef HAVE_SYS_UTSNAME_H
+  uname(&utsname);
+  LOG_INFO(("Client environment:os.name=%s", utsname.sysname));
+  LOG_INFO(("Client environment:os.arch=%s", utsname.release));
+  LOG_INFO(("Client environment:os.version=%s", utsname.version));
+#else
+  LOG_INFO(("Client environment:os.name=<not implemented>"));
+  LOG_INFO(("Client environment:os.arch=<not implemented>"));
+  LOG_INFO(("Client environment:os.version=<not implemented>"));
+#endif
+
+#ifdef HAVE_GETLOGIN
+  LOG_INFO(("Client environment:user.name=%s", getlogin()));
+#else
+  LOG_INFO(("Client environment:user.name=<not implemented>"));
+#endif
+
+#if defined(HAVE_GETUID) && defined(HAVE_GETPWUID_R)
+  uid = getuid();
+  if (!getpwuid_r(uid, &pw, buf, sizeof(buf), &pwp)) {
+    LOG_INFO(("Client environment:user.home=%s", pw.pw_dir));
+  } else {
+    LOG_INFO(("Client environment:user.home=<NA>"));
+  }
+#else
+  LOG_INFO(("Client environment:user.home=<not implemented>"));
+#endif
+
+#ifdef HAVE_GETCWD
+  if (!getcwd(buf, sizeof(buf))) {
+    LOG_INFO(("Client environment:user.dir=<toolong>"));
+  } else {
+    LOG_INFO(("Client environment:user.dir=%s", buf));
+  }
+#else
+  LOG_INFO(("Client environment:user.dir=<not implemented>"));
+#endif
+}
+
+/**
+ * Create a zookeeper handle associated with the given host and port.
+ */
+zhandle_t *zookeeper_init(const char *host, watcher_fn watcher,
+  int recv_timeout, const clientid_t *clientid, void *context, int flags)
+{
+    int errnosave = 0;
+    zhandle_t *zh = NULL;
+    char *index_chroot = NULL;
+
+    log_env();
+#ifdef WIN32
+       if (Win32WSAStartup()){
+               LOG_ERROR(("Error initializing ws2_32.dll"));
+               return 0;
+       }
+#endif
+    LOG_INFO(("Initiating client connection, host=%s sessionTimeout=%d watcher=%p"
+          " sessionId=%#llx sessionPasswd=%s context=%p flags=%d",
+              host,
+              recv_timeout,
+              watcher,
+              (clientid == 0 ? 0 : clientid->client_id),
+              ((clientid == 0) || (clientid->passwd[0] == 0) ?
+               "<null>" : "<hidden>"),
+              context,
+              flags));
+
+    zh = calloc(1, sizeof(*zh));
+    if (!zh) {
+        return 0;
+    }
+    zh->fd = -1;
+    zh->state = NOTCONNECTED_STATE_DEF;
+    zh->context = context;
+    zh->recv_timeout = recv_timeout;
+    init_auth_info(&zh->auth_h);
+    if (watcher) {
+       zh->watcher = watcher;
+    } else {
+       zh->watcher = null_watcher_fn;
+    }
+    if (host == 0 || *host == 0) { // what we shouldn't dup
+        errno=EINVAL;
+        goto abort;
+    }
+    //parse the host to get the chroot if
+    //available
+    index_chroot = strchr(host, '/');
+    if (index_chroot) {
+        zh->chroot = strdup(index_chroot);
+        if (zh->chroot == NULL) {
+            goto abort;
+        }
+        // if chroot is just / set it to null
+        if (strlen(zh->chroot) == 1) {
+            free(zh->chroot);
+            zh->chroot = NULL;
+        }
+        // cannot use strndup so allocate and strcpy
+        zh->hostname = (char *) malloc(index_chroot - host + 1);
+        zh->hostname = strncpy(zh->hostname, host, (index_chroot - host));
+        //strncpy does not null terminate
+        *(zh->hostname + (index_chroot - host)) = '\0';
+
+    } else {
+        zh->chroot = NULL;
+        zh->hostname = strdup(host);
+    }
+    if (zh->chroot && !isValidPath(zh->chroot, 0)) {
+        errno = EINVAL;
+        goto abort;
+    }
+    if (zh->hostname == 0) {
+        goto abort;
+    }
+    if(getaddrs(zh)!=0) {
+        goto abort;
+    }
+    zh->connect_index = 0;
+    if (clientid) {
+        memcpy(&zh->client_id, clientid, sizeof(zh->client_id));
+    } else {
+        memset(&zh->client_id, 0, sizeof(zh->client_id));
+    }
+    zh->primer_buffer.buffer = zh->primer_storage_buffer;
+    zh->primer_buffer.curr_offset = 0;
+    zh->primer_buffer.len = sizeof(zh->primer_storage_buffer);
+    zh->primer_buffer.next = 0;
+    zh->last_zxid = 0;
+    zh->next_deadline.tv_sec=zh->next_deadline.tv_usec=0;
+    zh->socket_readable.tv_sec=zh->socket_readable.tv_usec=0;
+    zh->active_node_watchers=create_zk_hashtable();
+    zh->active_exist_watchers=create_zk_hashtable();
+    zh->active_child_watchers=create_zk_hashtable();
+
+    if (adaptor_init(zh) == -1) {
+        goto abort;
+    }
+
+    return zh;
+abort:
+    errnosave=errno;
+    destroy(zh);
+    free(zh);
+    errno=errnosave;
+    return 0;
+}
+
+/**
+ * deallocated the free_path only its beeen allocated
+ * and not equal to path
+ */
+void free_duplicate_path(const char *free_path, const char* path) {
+    if (free_path != path) {
+        free((void*)free_path);
+    }
+}
+
+/**
+  prepend the chroot path if available else return the path
+*/
+static char* prepend_string(zhandle_t *zh, const char* client_path) {
+    char *ret_str;
+    if (zh == NULL || zh->chroot == NULL)
+        return (char *) client_path;
+    // handle the chroot itself, client_path = "/"
+    if (strlen(client_path) == 1) {
+        return strdup(zh->chroot);
+    }
+    ret_str = (char *) malloc(strlen(zh->chroot) + strlen(client_path) + 1);
+    strcpy(ret_str, zh->chroot);
+    return strcat(ret_str, client_path);
+}
+
+/**
+   strip off the chroot string from the server path
+   if there is one else return the exact path
+ */
+char* sub_string(zhandle_t *zh, const char* server_path) {
+    char *ret_str;
+    if (zh->chroot == NULL)
+        return (char *) server_path;
+    //ZOOKEEPER-1027
+    if (strncmp(server_path, zh->chroot, strlen(zh->chroot)) != 0) {
+        LOG_ERROR(("server path %s does not include chroot path %s",
+                   server_path, zh->chroot));
+        return (char *) server_path;
+    }
+    if (strlen(server_path) == strlen(zh->chroot)) {
+        //return "/"
+        ret_str = strdup("/");
+        return ret_str;
+    }
+    ret_str = strdup(server_path + strlen(zh->chroot));
+    return ret_str;
+}
+
+static buffer_list_t *allocate_buffer(char *buff, int len)
+{
+    buffer_list_t *buffer = calloc(1, sizeof(*buffer));
+    if (buffer == 0)
+        return 0;
+
+    buffer->len = len==0?sizeof(*buffer):len;
+    buffer->curr_offset = 0;
+    buffer->buffer = buff;
+    buffer->next = 0;
+    return buffer;
+}
+
+static void free_buffer(buffer_list_t *b)
+{
+    if (!b) {
+        return;
+    }
+    if (b->buffer) {
+        free(b->buffer);
+    }
+    free(b);
+}
+
+static buffer_list_t *dequeue_buffer(buffer_head_t *list)
+{
+    buffer_list_t *b;
+    lock_buffer_list(list);
+    b = list->head;
+    if (b) {
+        list->head = b->next;
+        if (!list->head) {
+            assert(b == list->last);
+            list->last = 0;
+        }
+    }
+    unlock_buffer_list(list);
+    return b;
+}
+
+static int remove_buffer(buffer_head_t *list)
+{
+    buffer_list_t *b = dequeue_buffer(list);
+    if (!b) {
+        return 0;
+    }
+    free_buffer(b);
+    return 1;
+}
+
+static void queue_buffer(buffer_head_t *list, buffer_list_t *b, int add_to_front)
+{
+    b->next = 0;
+    lock_buffer_list(list);
+    if (list->head) {
+        assert(list->last);
+        // The list is not empty
+        if (add_to_front) {
+            b->next = list->head;
+            list->head = b;
+        } else {
+            list->last->next = b;
+            list->last = b;
+        }
+    }else{
+        // The list is empty
+        assert(!list->head);
+        list->head = b;
+        list->last = b;
+    }
+    unlock_buffer_list(list);
+}
+
+static int queue_buffer_bytes(buffer_head_t *list, char *buff, int len)
+{
+    buffer_list_t *b  = allocate_buffer(buff,len);
+    if (!b)
+        return ZSYSTEMERROR;
+    queue_buffer(list, b, 0);
+    return ZOK;
+}
+
+static int queue_front_buffer_bytes(buffer_head_t *list, char *buff, int len)
+{
+    buffer_list_t *b  = allocate_buffer(buff,len);
+    if (!b)
+        return ZSYSTEMERROR;
+    queue_buffer(list, b, 1);
+    return ZOK;
+}
+
+static __attribute__ ((unused)) int get_queue_len(buffer_head_t *list)
+{
+    int i;
+    buffer_list_t *ptr;
+    lock_buffer_list(list);
+    ptr = list->head;
+    for (i=0; ptr!=0; ptr=ptr->next, i++)
+        ;
+    unlock_buffer_list(list);
+    return i;
+}
+/* returns:
+ * -1 if send failed,
+ * 0 if send would block while sending the buffer (or a send was incomplete),
+ * 1 if success
+ */
+#ifdef WIN32
+static int send_buffer(SOCKET fd, buffer_list_t *buff)
+#else
+static int send_buffer(int fd, buffer_list_t *buff)
+#endif
+{
+    int len = buff->len;
+    int off = buff->curr_offset;
+    int rc = -1;
+
+    if (off < 4) {
+        /* we need to send the length at the beginning */
+        int nlen = htonl(len);
+        char *b = (char*)&nlen;
+        rc = zookeeper_send(fd, b + off, sizeof(nlen) - off);
+        if (rc == -1) {
+#ifndef _WINDOWS
+            if (errno != EAGAIN) {
+#else            
+            if (WSAGetLastError() != WSAEWOULDBLOCK) {
+#endif            
+                return -1;
+            } else {
+                return 0;
+            }
+        } else {
+            buff->curr_offset  += rc;
+        }
+        off = buff->curr_offset;
+    }
+    if (off >= 4) {
+        /* want off to now represent the offset into the buffer */
+        off -= sizeof(buff->len);
+        rc = zookeeper_send(fd, buff->buffer + off, len - off);
+        if (rc == -1) {
+#ifndef _WINDOWS
+            if (errno != EAGAIN) {
+#else            
+            if (WSAGetLastError() != WSAEWOULDBLOCK) {
+#endif            
+                return -1;
+            }
+        } else {
+            buff->curr_offset += rc;
+        }
+    }
+    return buff->curr_offset == len + sizeof(buff->len);
+}
+
+/* returns:
+ * -1 if recv call failed,
+ * 0 if recv would block,
+ * 1 if success
+ */
+#ifdef WIN32
+static int recv_buffer(SOCKET fd, buffer_list_t *buff)
+#else
+static int recv_buffer(int fd, buffer_list_t *buff)
+#endif
+{
+    int off = buff->curr_offset;
+    int rc = 0;
+    //fprintf(LOGSTREAM, "rc = %d, off = %d, line %d\n", rc, off, __LINE__);
+
+    /* if buffer is less than 4, we are reading in the length */
+    if (off < 4) {
+        char *buffer = (char*)&(buff->len);
+        rc = recv(fd, buffer+off, sizeof(int)-off, 0);
+        //fprintf(LOGSTREAM, "rc = %d, off = %d, line %d\n", rc, off, __LINE__);
+        switch(rc) {
+        case 0:
+            errno = EHOSTDOWN;
+        case -1:
+#ifndef _WINDOWS
+            if (errno == EAGAIN) {
+#else
+            if (WSAGetLastError() == WSAEWOULDBLOCK) {
+#endif
+                return 0;
+            }
+            return -1;
+        default:
+            buff->curr_offset += rc;
+        }
+        off = buff->curr_offset;
+        if (buff->curr_offset == sizeof(buff->len)) {
+            buff->len = ntohl(buff->len);
+            buff->buffer = calloc(1, buff->len);
+        }
+    }
+    if (buff->buffer) {
+        /* want off to now represent the offset into the buffer */
+        off -= sizeof(buff->len);
+
+        rc = recv(fd, buff->buffer+off, buff->len-off, 0);
+        switch(rc) {
+        case 0:
+            errno = EHOSTDOWN;
+        case -1:
+#ifndef _WINDOWS
+            if (errno == EAGAIN) {
+#else
+            if (WSAGetLastError() == WSAEWOULDBLOCK) {
+#endif
+                break;
+            }
+            return -1;
+        default:
+            buff->curr_offset += rc;
+        }
+    }
+    return buff->curr_offset == buff->len + sizeof(buff->len);
+}
+
+void free_buffers(buffer_head_t *list)
+{
+    while (remove_buffer(list))
+        ;
+}
+
+void free_completions(zhandle_t *zh,int callCompletion,int reason)
+{
+    completion_head_t tmp_list;
+    struct oarchive *oa;
+    struct ReplyHeader h;
+    void_completion_t auth_completion = NULL;
+    auth_completion_list_t a_list, *a_tmp;
+
+    if (lock_completion_list(&zh->sent_requests) == 0) {
+        tmp_list = zh->sent_requests;
+        zh->sent_requests.head = 0;
+        zh->sent_requests.last = 0;
+        unlock_completion_list(&zh->sent_requests);
+    
+        while (tmp_list.head) {
+            completion_list_t *cptr = tmp_list.head;
+
+            tmp_list.head = cptr->next;
+            if (cptr->c.data_result == SYNCHRONOUS_MARKER) {
+                struct sync_completion
+                            *sc = (struct sync_completion*)cptr->data;
+                sc->rc = reason;
+                notify_sync_completion(sc);
+                zh->outstanding_sync--;
+                destroy_completion_entry(cptr);
+            } else if (callCompletion) {
+                // Fake the response
+                buffer_list_t *bptr;
+                h.xid = cptr->xid;
+                h.zxid = -1;
+                h.err = reason;
+                oa = create_buffer_oarchive();
+                serialize_ReplyHeader(oa, "header", &h);
+                bptr = calloc(sizeof(*bptr), 1);
+                assert(bptr);
+                bptr->len = get_buffer_len(oa);
+                bptr->buffer = get_buffer(oa);
+                close_buffer_oarchive(&oa, 0);
+                cptr->buffer = bptr;
+                queue_completion(&zh->completions_to_process, cptr, 0);
+            }
+        }
+    }
+    if (zoo_lock_auth(zh) == 0) {
+        a_list.completion = NULL;
+        a_list.next = NULL;
+    
+        get_auth_completions(&zh->auth_h, &a_list);
+        zoo_unlock_auth(zh);
+    
+        a_tmp = &a_list;
+        // chain call user's completion function
+        while (a_tmp->completion != NULL) {
+            auth_completion = a_tmp->completion;
+            auth_completion(reason, a_tmp->auth_data);
+            a_tmp = a_tmp->next;
+            if (a_tmp == NULL)
+                break;
+        }
+    }
+    free_auth_completion(&a_list);
+}
+
+static void cleanup_bufs(zhandle_t *zh,int callCompletion,int rc)
+{
+    enter_critical(zh);
+    free_buffers(&zh->to_send);
+    free_buffers(&zh->to_process);
+    free_completions(zh,callCompletion,rc);
+    leave_critical(zh);
+    if (zh->input_buffer && zh->input_buffer != &zh->primer_buffer) {
+        free_buffer(zh->input_buffer);
+        zh->input_buffer = 0;
+    }
+}
+
+static void handle_error(zhandle_t *zh,int rc)
+{
+    close(zh->fd);
+    if (is_unrecoverable(zh)) {
+        LOG_DEBUG(("Calling a watcher for a ZOO_SESSION_EVENT and the state=%s",
+                state2String(zh->state)));
+        PROCESS_SESSION_EVENT(zh, zh->state);
+    } else if (zh->state == ZOO_CONNECTED_STATE) {
+        LOG_DEBUG(("Calling a watcher for a ZOO_SESSION_EVENT and the state=CONNECTING_STATE"));
+        PROCESS_SESSION_EVENT(zh, ZOO_CONNECTING_STATE);
+    }
+    cleanup_bufs(zh,1,rc);
+    zh->fd = -1;
+    zh->connect_index++;
+    if (!is_unrecoverable(zh)) {
+        zh->state = 0;
+    }
+    if (process_async(zh->outstanding_sync)) {
+        process_completions(zh);
+    }
+}
+
+static int handle_socket_error_msg(zhandle_t *zh, int line, int rc,
+        const char* format, ...)
+{
+    if(logLevel>=ZOO_LOG_LEVEL_ERROR){
+        va_list va;
+        char buf[1024];
+        va_start(va,format);
+        vsnprintf(buf, sizeof(buf)-1,format,va);
+        log_message(ZOO_LOG_LEVEL_ERROR,line,__func__,
+            format_log_message("Socket [%s] zk retcode=%d, errno=%d(%s): %s",
+            format_current_endpoint_info(zh),rc,errno,strerror(errno),buf));
+        va_end(va);
+    }
+    handle_error(zh,rc);
+    return rc;
+}
+
+static void auth_completion_func(int rc, zhandle_t* zh)
+{
+    void_completion_t auth_completion = NULL;
+    auth_completion_list_t a_list;
+    auth_completion_list_t *a_tmp;
+
+    if(zh==NULL)
+        return;
+
+    zoo_lock_auth(zh);
+
+    if(rc!=0){
+        zh->state=ZOO_AUTH_FAILED_STATE;
+    }else{
+        //change state for all auths
+        mark_active_auth(zh);
+    }
+    a_list.completion = NULL;
+    a_list.next = NULL;
+    get_auth_completions(&zh->auth_h, &a_list);
+    zoo_unlock_auth(zh);
+    if (rc) {
+        LOG_ERROR(("Authentication scheme %s failed. Connection closed.",
+                   zh->auth_h.auth->scheme));
+    }
+    else {
+        LOG_INFO(("Authentication scheme %s succeeded", zh->auth_h.auth->scheme));
+    }
+    a_tmp = &a_list;
+    // chain call user's completion function
+    while (a_tmp->completion != NULL) {
+        auth_completion = a_tmp->completion;
+        auth_completion(rc, a_tmp->auth_data);
+        a_tmp = a_tmp->next;
+        if (a_tmp == NULL)
+            break;
+    }
+    free_auth_completion(&a_list);
+}
+
+static int send_info_packet(zhandle_t *zh, auth_info* auth) {
+    struct oarchive *oa;
+    struct RequestHeader h = { STRUCT_INITIALIZER(xid , AUTH_XID), STRUCT_INITIALIZER(type , ZOO_SETAUTH_OP)};
+    struct AuthPacket req;
+    int rc;
+    oa = create_buffer_oarchive();
+    rc = serialize_RequestHeader(oa, "header", &h);
+    req.type=0;   // ignored by the server
+    req.scheme = auth->scheme;
+    req.auth = auth->auth;
+    rc = rc < 0 ? rc : serialize_AuthPacket(oa, "req", &req);
+    /* add this buffer to the head of the send queue */
+    rc = rc < 0 ? rc : queue_front_buffer_bytes(&zh->to_send, get_buffer(oa),
+            get_buffer_len(oa));
+    /* We queued the buffer, so don't free it */
+    close_buffer_oarchive(&oa, 0);
+
+    return rc;
+}
+
+/** send all auths, not just the last one **/
+static int send_auth_info(zhandle_t *zh) {
+    int rc = 0;
+    auth_info *auth = NULL;
+
+    zoo_lock_auth(zh);
+    auth = zh->auth_h.auth;
+    if (auth == NULL) {
+        zoo_unlock_auth(zh);
+        return ZOK;
+    }
+    while (auth != NULL) {
+        rc = send_info_packet(zh, auth);
+        auth = auth->next;
+    }
+    zoo_unlock_auth(zh);
+    LOG_DEBUG(("Sending all auth info request to %s", format_current_endpoint_info(zh)));
+    return (rc <0) ? ZMARSHALLINGERROR:ZOK;
+}
+
+static int send_last_auth_info(zhandle_t *zh)
+{    
+    int rc = 0;
+    auth_info *auth = NULL;
+
+    zoo_lock_auth(zh);
+    auth = get_last_auth(&zh->auth_h);
+    if(auth==NULL) {
+      zoo_unlock_auth(zh);
+      return ZOK; // there is nothing to send
+    }
+    rc = send_info_packet(zh, auth);
+    zoo_unlock_auth(zh);
+    LOG_DEBUG(("Sending auth info request to %s",format_current_endpoint_info(zh)));
+    return (rc < 0)?ZMARSHALLINGERROR:ZOK;
+}
+
+static void free_key_list(char **list, int count)
+{
+    int i;
+
+    for(i = 0; i < count; i++) {
+        free(list[i]);
+    }
+    free(list);
+}
+
+static int send_set_watches(zhandle_t *zh)
+{
+    struct oarchive *oa;
+    struct RequestHeader h = { STRUCT_INITIALIZER(xid , SET_WATCHES_XID), STRUCT_INITIALIZER(type , ZOO_SETWATCHES_OP)};
+    struct SetWatches req;
+    int rc;
+
+    req.relativeZxid = zh->last_zxid;
+    req.dataWatches.data = collect_keys(zh->active_node_watchers, (int*)&req.dataWatches.count);
+    req.existWatches.data = collect_keys(zh->active_exist_watchers, (int*)&req.existWatches.count);
+    req.childWatches.data = collect_keys(zh->active_child_watchers, (int*)&req.childWatches.count);
+
+    // return if there are no pending watches
+    if (!req.dataWatches.count && !req.existWatches.count &&
+        !req.childWatches.count) {
+        free_key_list(req.dataWatches.data, req.dataWatches.count);
+        free_key_list(req.existWatches.data, req.existWatches.count);
+        free_key_list(req.childWatches.data, req.childWatches.count);
+        return ZOK;
+    }
+
+
+    oa = create_buffer_oarchive();
+    rc = serialize_RequestHeader(oa, "header", &h);
+    rc = rc < 0 ? rc : serialize_SetWatches(oa, "req", &req);
+    /* add this buffer to the head of the send queue */
+    rc = rc < 0 ? rc : queue_front_buffer_bytes(&zh->to_send, get_buffer(oa),
+            get_buffer_len(oa));
+    /* We queued the buffer, so don't free it */   
+    close_buffer_oarchive(&oa, 0);
+    free_key_list(req.dataWatches.data, req.dataWatches.count);
+    free_key_list(req.existWatches.data, req.existWatches.count);
+    free_key_list(req.childWatches.data, req.childWatches.count);
+    LOG_DEBUG(("Sending set watches request to %s",format_current_endpoint_info(zh)));
+    return (rc < 0)?ZMARSHALLINGERROR:ZOK;
+}
+
+static int serialize_prime_connect(struct connect_req *req, char* buffer){
+    //this should be the order of serialization
+    int offset = 0;
+    req->protocolVersion = htonl(req->protocolVersion);
+    memcpy(buffer + offset, &req->protocolVersion, sizeof(req->protocolVersion));
+    offset = offset +  sizeof(req->protocolVersion);
+
+    req->lastZxidSeen = zoo_htonll(req->lastZxidSeen);
+    memcpy(buffer + offset, &req->lastZxidSeen, sizeof(req->lastZxidSeen));
+    offset = offset +  sizeof(req->lastZxidSeen);
+
+    req->timeOut = htonl(req->timeOut);
+    memcpy(buffer + offset, &req->timeOut, sizeof(req->timeOut));
+    offset = offset +  sizeof(req->timeOut);
+
+    req->sessionId = zoo_htonll(req->sessionId);
+    memcpy(buffer + offset, &req->sessionId, sizeof(req->sessionId));
+    offset = offset +  sizeof(req->sessionId);
+
+    req->passwd_len = htonl(req->passwd_len);
+    memcpy(buffer + offset, &req->passwd_len, sizeof(req->passwd_len));
+    offset = offset +  sizeof(req->passwd_len);
+
+    memcpy(buffer + offset, req->passwd, sizeof(req->passwd));
+
+    return 0;
+}
+
+ static int deserialize_prime_response(struct prime_struct *req, char* buffer){
+     //this should be the order of deserialization
+     int offset = 0;
+     memcpy(&req->len, buffer + offset, sizeof(req->len));
+     offset = offset +  sizeof(req->len);
+
+     req->len = ntohl(req->len);
+     memcpy(&req->protocolVersion, buffer + offset, sizeof(req->protocolVersion));
+     offset = offset +  sizeof(req->protocolVersion);
+
+     req->protocolVersion = ntohl(req->protocolVersion);
+     memcpy(&req->timeOut, buffer + offset, sizeof(req->timeOut));
+     offset = offset +  sizeof(req->timeOut);
+
+     req->timeOut = ntohl(req->timeOut);
+     memcpy(&req->sessionId, buffer + offset, sizeof(req->sessionId));
+     offset = offset +  sizeof(req->sessionId);
+
+     req->sessionId = zoo_htonll(req->sessionId);
+     memcpy(&req->passwd_len, buffer + offset, sizeof(req->passwd_len));
+     offset = offset +  sizeof(req->passwd_len);
+
+     req->passwd_len = ntohl(req->passwd_len);
+     memcpy(req->passwd, buffer + offset, sizeof(req->passwd));
+     return 0;
+ }
+
+static int prime_connection(zhandle_t *zh)
+{
+    int rc;
+    /*this is the size of buffer to serialize req into*/
+    char buffer_req[HANDSHAKE_REQ_SIZE];
+    int len = sizeof(buffer_req);
+    int hlen = 0;
+    struct connect_req req;
+    req.protocolVersion = 0;
+    req.sessionId = zh->client_id.client_id;
+    req.passwd_len = sizeof(req.passwd);
+    memcpy(req.passwd, zh->client_id.passwd, sizeof(zh->client_id.passwd));
+    req.timeOut = zh->recv_timeout;
+    req.lastZxidSeen = zh->last_zxid;
+    hlen = htonl(len);
+    /* We are running fast and loose here, but this string should fit in the initial buffer! */
+    rc=zookeeper_send(zh->fd, &hlen, sizeof(len));
+    serialize_prime_connect(&req, buffer_req);
+    rc=rc<0 ? rc : zookeeper_send(zh->fd, buffer_req, len);
+    if (rc<0) {
+        return handle_socket_error_msg(zh, __LINE__, ZCONNECTIONLOSS,
+                "failed to send a handshake packet: %s", strerror(errno));
+    }
+    zh->state = ZOO_ASSOCIATING_STATE;
+
+    zh->input_buffer = &zh->primer_buffer;
+    /* This seems a bit weird to to set the offset to 4, but we already have a
+     * length, so we skip reading the length (and allocating the buffer) by
+     * saying that we are already at offset 4 */
+    zh->input_buffer->curr_offset = 4;
+
+    return ZOK;
+}
+
+static inline int calculate_interval(const struct timeval *start,
+        const struct timeval *end)
+{
+    int interval;
+    struct timeval i = *end;
+    i.tv_sec -= start->tv_sec;
+    i.tv_usec -= start->tv_usec;
+    interval = i.tv_sec * 1000 + (i.tv_usec/1000);
+    return interval;
+}
+
+static struct timeval get_timeval(int interval)
+{
+    struct timeval tv;
+    if (interval < 0) {
+        interval = 0;
+    }
+    tv.tv_sec = interval/1000;
+    tv.tv_usec = (interval%1000)*1000;
+    return tv;
+}
+
+ static int add_void_completion(zhandle_t *zh, int xid, void_completion_t dc,
+     const void *data);
+ static int add_string_completion(zhandle_t *zh, int xid,
+     string_completion_t dc, const void *data);
+
+ int send_ping(zhandle_t* zh)
+ {
+    int rc;
+    struct oarchive *oa = create_buffer_oarchive();
+    struct RequestHeader h = { STRUCT_INITIALIZER(xid ,PING_XID), STRUCT_INITIALIZER (type , ZOO_PING_OP) };
+
+    rc = serialize_RequestHeader(oa, "header", &h);
+    enter_critical(zh);
+    gettimeofday(&zh->last_ping, 0);
+    rc = rc < 0 ? rc : queue_buffer_bytes(&zh->to_send, get_buffer(oa),
+            get_buffer_len(oa));
+    leave_critical(zh);
+    close_buffer_oarchive(&oa, 0);
+    return rc<0 ? rc : adaptor_send_queue(zh, 0);
+}
+
+#ifdef WIN32
+int zookeeper_interest(zhandle_t *zh, SOCKET *fd, int *interest,
+     struct timeval *tv)
+{
+
+    ULONG nonblocking_flag = 1;
+#else
+int zookeeper_interest(zhandle_t *zh, int *fd, int *interest,
+     struct timeval *tv)
+{
+#endif
+    struct timeval now;
+    if(zh==0 || fd==0 ||interest==0 || tv==0)
+        return ZBADARGUMENTS;
+    if (is_unrecoverable(zh))
+        return ZINVALIDSTATE;
+    gettimeofday(&now, 0);
+    if(zh->next_deadline.tv_sec!=0 || zh->next_deadline.tv_usec!=0){
+        int time_left = calculate_interval(&zh->next_deadline, &now);
+        if (time_left > 10)
+            LOG_WARN(("Exceeded deadline by %dms", time_left));
+    }
+    api_prolog(zh);
+    *fd = zh->fd;
+    *interest = 0;
+    tv->tv_sec = 0;
+    tv->tv_usec = 0;
+    if (*fd == -1) {
+        if (zh->connect_index == zh->addrs_count) {
+            /* Wait a bit before trying again so that we don't spin */
+            zh->connect_index = 0;
+        }else {
+            int rc;
+#ifdef WIN32
+            char enable_tcp_nodelay = 1;
+#else
+            int enable_tcp_nodelay = 1;
+#endif
+            int ssoresult;
+
+            zh->fd = socket(zh->addrs[zh->connect_index].ss_family, SOCK_STREAM, 0);
+            if (zh->fd < 0) {
+                return api_epilog(zh,handle_socket_error_msg(zh,__LINE__,
+                                                             ZSYSTEMERROR, "socket() call failed"));
+            }
+            ssoresult = setsockopt(zh->fd, IPPROTO_TCP, TCP_NODELAY, &enable_tcp_nodelay, sizeof(enable_tcp_nodelay));
+            if (ssoresult != 0) {
+                LOG_WARN(("Unable to set TCP_NODELAY, operation latency may be effected"));
+            }
+#ifdef WIN32
+            ioctlsocket(zh->fd, FIONBIO, &nonblocking_flag);                    
+#else
+            fcntl(zh->fd, F_SETFL, O_NONBLOCK|fcntl(zh->fd, F_GETFL, 0));
+#endif
+#if defined(AF_INET6)
+            if (zh->addrs[zh->connect_index].ss_family == AF_INET6) {
+                rc = connect(zh->fd, (struct sockaddr*) &zh->addrs[zh->connect_index], sizeof(struct sockaddr_in6));
+            } else {
+#else
+               LOG_DEBUG(("[zk] connect()\n"));
+            {
+#endif
+                rc = connect(zh->fd, (struct sockaddr*) &zh->addrs[zh->connect_index], sizeof(struct sockaddr_in));
+#ifdef WIN32
+                errno = GetLastError();
+
+#ifndef EWOULDBLOCK
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#endif
+
+#ifndef EINPROGRESS
+#define EINPROGRESS WSAEINPROGRESS
+#endif
+
+#if _MSC_VER >= 1600
+                switch (errno) {
+                case WSAEWOULDBLOCK:
+                    errno = EWOULDBLOCK;
+                    break;
+                case WSAEINPROGRESS:
+                    errno = EINPROGRESS;
+                    break;
+                }
+#endif
+#endif
+            }
+            if (rc == -1) {
+                /* we are handling the non-blocking connect according to
+                 * the description in section 16.3 "Non-blocking connect"
+                 * in UNIX Network Programming vol 1, 3rd edition */
+                if (errno == EWOULDBLOCK || errno == EINPROGRESS)
+                    zh->state = ZOO_CONNECTING_STATE;
+                else
+                    return api_epilog(zh,handle_socket_error_msg(zh,__LINE__,
+                            ZCONNECTIONLOSS,"connect() call failed"));
+            } else {
+                if((rc=prime_connection(zh))!=0)
+                    return api_epilog(zh,rc);
+
+                LOG_INFO(("Initiated connection to server [%s]",
+                        format_endpoint_info(&zh->addrs[zh->connect_index])));
+            }
+        }
+        *fd = zh->fd;
+        *tv = get_timeval(zh->recv_timeout/3);
+        zh->last_recv = now;
+        zh->last_send = now;
+        zh->last_ping = now;
+    }
+    if (zh->fd != -1) {
+        int idle_recv = calculate_interval(&zh->last_recv, &now);
+        int idle_send = calculate_interval(&zh->last_send, &now);
+        int recv_to = zh->recv_timeout*2/3 - idle_recv;
+        int send_to = zh->recv_timeout/3;
+        // have we exceeded the receive timeout threshold?
+        if (recv_to <= 0) {
+            // We gotta cut our losses and connect to someone else
+#ifdef WIN32
+            errno = WSAETIMEDOUT;
+#else
+            errno = ETIMEDOUT;
+#endif
+            *interest=0;
+            *tv = get_timeval(0);
+            return api_epilog(zh,handle_socket_error_msg(zh,
+                    __LINE__,ZOPERATIONTIMEOUT,
+                    "connection to %s timed out (exceeded timeout by %dms)",
+                    format_endpoint_info(&zh->addrs[zh->connect_index]),
+                    -recv_to));
+
+        }
+        // We only allow 1/3 of our timeout time to expire before sending
+        // a PING
+        if (zh->state==ZOO_CONNECTED_STATE) {
+            send_to = zh->recv_timeout/3 - idle_send;
+            if (send_to <= 0) {
+                if (zh->sent_requests.head==0) {
+//                    LOG_DEBUG(("Sending PING to %s (exceeded idle by %dms)",
+//                                    format_current_endpoint_info(zh),-send_to));
+                    int rc=send_ping(zh);
+                    if (rc < 0){
+                        LOG_ERROR(("failed to send PING request (zk retcode=%d)",rc));
+                        return api_epilog(zh,rc);
+                    }
+                }
+                send_to = zh->recv_timeout/3;
+            }
+        }
+        // choose the lesser value as the timeout
+        *tv = get_timeval(recv_to < send_to? recv_to:send_to);
+        zh->next_deadline.tv_sec = now.tv_sec + tv->tv_sec;
+        zh->next_deadline.tv_usec = now.tv_usec + tv->tv_usec;
+        if (zh->next_deadline.tv_usec > 1000000) {
+            zh->next_deadline.tv_sec += zh->next_deadline.tv_usec / 1000000;
+            zh->next_deadline.tv_usec = zh->next_deadline.tv_usec % 1000000;
+        }
+        *interest = ZOOKEEPER_READ;
+        /* we are interested in a write if we are connected and have something
+         * to send, or we are waiting for a connect to finish. */
+        if ((zh->to_send.head && (zh->state == ZOO_CONNECTED_STATE))
+        || zh->state == ZOO_CONNECTING_STATE) {
+            *interest |= ZOOKEEPER_WRITE;
+        }
+    }
+    return api_epilog(zh,ZOK);
+}
+
+static int check_events(zhandle_t *zh, int events)
+{
+    if (zh->fd == -1)
+        return ZINVALIDSTATE;
+    if ((events&ZOOKEEPER_WRITE)&&(zh->state == ZOO_CONNECTING_STATE)) {
+        int rc, error;
+        socklen_t len = sizeof(error);
+        rc = getsockopt(zh->fd, SOL_SOCKET, SO_ERROR, &error, &len);
+        /* the description in section 16.4 "Non-blocking connect"
+         * in UNIX Network Programming vol 1, 3rd edition, points out
+         * that sometimes the error is in errno and sometimes in error */
+        if (rc < 0 || error) {
+            if (rc == 0)
+                errno = error;
+            return handle_socket_error_msg(zh, __LINE__,ZCONNECTIONLOSS,
+                "server refused to accept the client");
+        }
+        if((rc=prime_connection(zh))!=0)
+            return rc;
+        LOG_INFO(("initiated connection to server [%s]",
+                format_endpoint_info(&zh->addrs[zh->connect_index])));
+        return ZOK;
+    }
+    if (zh->to_send.head && (events&ZOOKEEPER_WRITE)) {
+        /* make the flush call non-blocking by specifying a 0 timeout */
+        int rc=flush_send_queue(zh,0);
+        if (rc < 0)
+            return handle_socket_error_msg(zh,__LINE__,ZCONNECTIONLOSS,
+                "failed while flushing send queue");
+    }
+    if (events&ZOOKEEPER_READ) {
+        int rc;
+        if (zh->input_buffer == 0) {
+            zh->input_buffer = allocate_buffer(0,0);
+        }
+
+        rc = recv_buffer(zh->fd, zh->input_buffer);
+        if (rc < 0) {
+            return handle_socket_error_msg(zh, __LINE__,ZCONNECTIONLOSS,
+                "failed while receiving a server response");
+        }
+        if (rc > 0) {
+            gettimeofday(&zh->last_recv, 0);
+            if (zh->input_buffer != &zh->primer_buffer) {
+                queue_buffer(&zh->to_process, zh->input_buffer, 0);
+            } else  {
+                int64_t oldid,newid;
+                //deserialize
+                deserialize_prime_response(&zh->primer_storage, zh->primer_buffer.buffer);
+                /* We are processing the primer_buffer, so we need to finish
+                 * the connection handshake */
+                oldid = zh->client_id.client_id;
+                newid = zh->primer_storage.sessionId;
+                if (oldid != 0 && oldid != newid) {
+                    zh->state = ZOO_EXPIRED_SESSION_STATE;
+                    errno = ESTALE;
+                    return handle_socket_error_msg(zh,__LINE__,ZSESSIONEXPIRED,
+                            "sessionId=%#llx has expired.",oldid);
+                } else {
+                    zh->recv_timeout = zh->primer_storage.timeOut;
+                    zh->client_id.client_id = newid;
+                 
+                    memcpy(zh->client_id.passwd, &zh->primer_storage.passwd,
+                           sizeof(zh->client_id.passwd));
+                    zh->state = ZOO_CONNECTED_STATE;
+                    LOG_INFO(("session establishment complete on server [%s], sessionId=%#llx, negotiated timeout=%d",
+                              format_endpoint_info(&zh->addrs[zh->connect_index]),
+                              newid, zh->recv_timeout));
+                    /* we want the auth to be sent for, but since both call push to front
+                       we need to call send_watch_set first */
+                    send_set_watches(zh);
+                    /* send the authentication packet now */
+                    send_auth_info(zh);
+                    LOG_DEBUG(("Calling a watcher for a ZOO_SESSION_EVENT and the state=ZOO_CONNECTED_STATE"));
+                    zh->input_buffer = 0; // just in case the watcher calls zookeeper_process() again
+                    PROCESS_SESSION_EVENT(zh, ZOO_CONNECTED_STATE);
+                }
+            }
+            zh->input_buffer = 0;
+        } else {
+            // zookeeper_process was called but there was nothing to read
+            // from the socket
+            return ZNOTHING;
+        }
+    }
+    return ZOK;
+}
+
+void api_prolog(zhandle_t* zh)
+{
+    inc_ref_counter(zh,1);
+}
+
+int api_epilog(zhandle_t *zh,int rc)
+{
+    if(inc_ref_counter(zh,-1)==0 && zh->close_requested!=0)
+        zookeeper_close(zh);
+    return rc;
+}
+
+static __attribute__((unused)) void print_completion_queue(zhandle_t *zh)
+{
+    completion_list_t* cptr;
+
+    if(logLevel<ZOO_LOG_LEVEL_DEBUG) return;
+
+    fprintf(LOGSTREAM,"Completion queue: ");
+    if (zh->sent_requests.head==0) {
+        fprintf(LOGSTREAM,"empty\n");
+        return;
+    }
+
+    cptr=zh->sent_requests.head;
+    while(cptr){
+        fprintf(LOGSTREAM,"%d,",cptr->xid);
+        cptr=cptr->next;
+    }
+    fprintf(LOGSTREAM,"end\n");
+}
+
+//#ifdef THREADED
+// IO thread queues session events to be processed by the completion thread
+static int queue_session_event(zhandle_t *zh, int state)
+{
+    int rc;
+    struct WatcherEvent evt = { ZOO_SESSION_EVENT, state, "" };
+    struct ReplyHeader hdr = { WATCHER_EVENT_XID, 0, 0 };
+    struct oarchive *oa;
+    completion_list_t *cptr;
+
+    if ((oa=create_buffer_oarchive())==NULL) {
+        LOG_ERROR(("out of memory"));
+        goto error;
+    }
+    rc = serialize_ReplyHeader(oa, "hdr", &hdr);
+    rc = rc<0?rc: serialize_WatcherEvent(oa, "event", &evt);
+    if(rc<0){
+        close_buffer_oarchive(&oa, 1);
+        goto error;
+    }
+    cptr = create_completion_entry(WATCHER_EVENT_XID,-1,0,0,0,0);
+    cptr->buffer = allocate_buffer(get_buffer(oa), get_buffer_len(oa));
+    cptr->buffer->curr_offset = get_buffer_len(oa);
+    if (!cptr->buffer) {
+        free(cptr);
+        close_buffer_oarchive(&oa, 1);
+        goto error;
+    }
+    /* We queued the buffer, so don't free it */
+    close_buffer_oarchive(&oa, 0);
+    cptr->c.watcher_result = collectWatchers(zh, ZOO_SESSION_EVENT, "");
+    queue_completion(&zh->completions_to_process, cptr, 0);
+    if (process_async(zh->outstanding_sync)) {
+        process_completions(zh);
+    }
+    return ZOK;
+error:
+    errno=ENOMEM;
+    return ZSYSTEMERROR;
+}
+//#endif
+
+completion_list_t *dequeue_completion(completion_head_t *list)
+{
+    completion_list_t *cptr;
+    lock_completion_list(list);
+    cptr = list->head;
+    if (cptr) {
+        list->head = cptr->next;
+        if (!list->head) {
+            assert(list->last == cptr);
+            list->last = 0;
+        }
+    }
+    unlock_completion_list(list);
+    return cptr;
+}
+
+static void process_sync_completion(
+        completion_list_t *cptr,
+        struct sync_completion *sc,
+        struct iarchive *ia,
+	zhandle_t *zh)
+{
+    LOG_DEBUG(("Processing sync_completion with type=%d xid=%#x rc=%d",
+            cptr->c.type, cptr->xid, sc->rc));
+
+    switch(cptr->c.type) {
+    case COMPLETION_DATA: 
+        if (sc->rc==0) {
+            struct GetDataResponse res;
+            int len;
+            deserialize_GetDataResponse(ia, "reply", &res);
+            if (res.data.len <= sc->u.data.buff_len) {
+                len = res.data.len;
+            } else {
+                len = sc->u.data.buff_len;
+            }
+            sc->u.data.buff_len = len;
+            // check if len is negative
+            // just of NULL which is -1 int
+            if (len == -1) {
+                sc->u.data.buffer = NULL;
+            } else {
+                memcpy(sc->u.data.buffer, res.data.buff, len);
+            }
+            sc->u.data.stat = res.stat;
+            deallocate_GetDataResponse(&res);
+        }
+        break;
+    case COMPLETION_STAT:
+        if (sc->rc==0) {
+            struct SetDataResponse res;
+            deserialize_SetDataResponse(ia, "reply", &res);
+            sc->u.stat = res.stat;
+            deallocate_SetDataResponse(&res);
+        }
+        break;
+    case COMPLETION_STRINGLIST:
+        if (sc->rc==0) {
+            struct GetChildrenResponse res;
+            deserialize_GetChildrenResponse(ia, "reply", &res);
+            sc->u.strs2 = res.children;
+            /* We don't deallocate since we are passing it back */
+            // deallocate_GetChildrenResponse(&res);
+        }
+        break;
+    case COMPLETION_STRINGLIST_STAT:
+        if (sc->rc==0) {
+            struct GetChildren2Response res;
+            deserialize_GetChildren2Response(ia, "reply", &res);
+            sc->u.strs_stat.strs2 = res.children;
+            sc->u.strs_stat.stat2 = res.stat;
+            /* We don't deallocate since we are passing it back */
+            // deallocate_GetChildren2Response(&res);
+        }
+        break;
+    case COMPLETION_STRING:
+        if (sc->rc==0) {
+            struct CreateResponse res;
+            int len;
+            const char * client_path;
+            deserialize_CreateResponse(ia, "reply", &res);
+            //ZOOKEEPER-1027
+            client_path = sub_string(zh, res.path); 
+            len = strlen(client_path) + 1;if (len > sc->u.str.str_len) {
+                len = sc->u.str.str_len;
+            }
+            if (len > 0) {
+                memcpy(sc->u.str.str, client_path, len - 1);
+                sc->u.str.str[len - 1] = '\0';
+            }
+            free_duplicate_path(client_path, res.path);
+            deallocate_CreateResponse(&res);
+        }
+        break;
+    case COMPLETION_ACLLIST:
+        if (sc->rc==0) {
+            struct GetACLResponse res;
+            deserialize_GetACLResponse(ia, "reply", &res);
+            sc->u.acl.acl = res.acl;
+            sc->u.acl.stat = res.stat;
+            /* We don't deallocate since we are passing it back */
+            //deallocate_GetACLResponse(&res);
+        }
+        break;
+    case COMPLETION_VOID:
+        break;
+    case COMPLETION_MULTI:
+        sc->rc = deserialize_multi(cptr->xid, cptr, ia);
+        break;
+    default:
+        LOG_DEBUG(("Unsupported completion type=%d", cptr->c.type));
+        break;
+    }
+}
+
+static int deserialize_multi(int xid, completion_list_t *cptr, struct iarchive *ia)
+{
+    int rc = 0;
+    completion_head_t *clist = &cptr->c.clist;
+    struct MultiHeader mhdr = { STRUCT_INITIALIZER(type , 0), STRUCT_INITIALIZER(done , 0), STRUCT_INITIALIZER(err , 0) };
+    assert(clist);
+    deserialize_MultiHeader(ia, "multiheader", &mhdr);
+    while (!mhdr.done) {
+        completion_list_t *entry = dequeue_completion(clist);
+        assert(entry);
+
+        if (mhdr.type == -1) {
+            struct ErrorResponse er;
+            deserialize_ErrorResponse(ia, "error", &er);
+            mhdr.err = er.err ;
+            if (rc == 0 && er.err != 0 && er.err != ZRUNTIMEINCONSISTENCY) {
+                rc = er.err;
+            }
+        }
+
+        deserialize_response(entry->c.type, xid, mhdr.type == -1, mhdr.err, entry, ia);
+        deserialize_MultiHeader(ia, "multiheader", &mhdr);
+        //While deserializing the response we must destroy completion entry for each operation in 
+        //the zoo_multi transaction. Otherwise this results in memory leak when client invokes zoo_multi
+        //operation.
+        destroy_completion_entry(entry);
+    }
+
+    return rc;
+}
+
+static void deserialize_response(int type, int xid, int failed, int rc, completion_list_t *cptr, struct iarchive *ia)
+{
+    switch (type) {
+    case COMPLETION_DATA:
+        LOG_DEBUG(("Calling COMPLETION_DATA for xid=%#x failed=%d rc=%d",
+                    cptr->xid, failed, rc));
+        if (failed) {
+            cptr->c.data_result(rc, 0, 0, 0, cptr->data);
+        } else {
+            struct GetDataResponse res;
+            deserialize_GetDataResponse(ia, "reply", &res);
+            cptr->c.data_result(rc, res.data.buff, res.data.len,
+                    &res.stat, cptr->data);
+            deallocate_GetDataResponse(&res);
+        }
+        break;
+    case COMPLETION_STAT:
+        LOG_DEBUG(("Calling COMPLETION_STAT for xid=%#x failed=%d rc=%d",
+                    cptr->xid, failed, rc));
+        if (failed) {
+            cptr->c.stat_result(rc, 0, cptr->data);
+        } else {
+            struct SetDataResponse res;
+            deserialize_SetDataResponse(ia, "reply", &res);
+            cptr->c.stat_result(rc, &res.stat, cptr->data);
+            deallocate_SetDataResponse(&res);
+        }
+        break;
+    case COMPLETION_STRINGLIST:
+        LOG_DEBUG(("Calling COMPLETION_STRINGLIST for xid=%#x failed=%d rc=%d",
+                    cptr->xid, failed, rc));
+        if (failed) {
+            cptr->c.strings_result(rc, 0, cptr->data);
+        } else {
+            struct GetChildrenResponse res;
+            deserialize_GetChildrenResponse(ia, "reply", &res);
+            cptr->c.strings_result(rc, &res.children, cptr->data);
+            deallocate_GetChildrenResponse(&res);
+        }
+        break;
+    case COMPLETION_STRINGLIST_STAT:
+        LOG_DEBUG(("Calling COMPLETION_STRINGLIST_STAT for xid=%#x failed=%d rc=%d",
+                    cptr->xid, failed, rc));
+        if (failed) {
+            cptr->c.strings_stat_result(rc, 0, 0, cptr->data);
+        } else {
+            struct GetChildren2Response res;
+            deserialize_GetChildren2Response(ia, "reply", &res);
+            cptr->c.strings_stat_result(rc, &res.children, &res.stat, cptr->data);
+            deallocate_GetChildren2Response(&res);
+        }
+        break;
+    case COMPLETION_STRING:
+        LOG_DEBUG(("Calling COMPLETION_STRING for xid=%#x failed=%d, rc=%d",
+                    cptr->xid, failed, rc));
+        if (failed) {
+            cptr->c.string_result(rc, 0, cptr->data);
+        } else {
+            struct CreateResponse res;
+            memset(&res, 0, sizeof(res));
+            deserialize_CreateResponse(ia, "reply", &res);
+            cptr->c.string_result(rc, res.path, cptr->data);
+            deallocate_CreateResponse(&res);
+        }
+        break;
+    case COMPLETION_ACLLIST:
+        LOG_DEBUG(("Calling COMPLETION_ACLLIST for xid=%#x failed=%d rc=%d",
+                    cptr->xid, failed, rc));
+        if (failed) {
+            cptr->c.acl_result(rc, 0, 0, cptr->data);
+        } else {
+            struct GetACLResponse res;
+            deserialize_GetACLResponse(ia, "reply", &res);
+            cptr->c.acl_result(rc, &res.acl, &res.stat, cptr->data);
+            deallocate_GetACLResponse(&res);
+        }
+        break;
+    case COMPLETION_VOID:
+        LOG_DEBUG(("Calling COMPLETION_VOID for xid=%#x failed=%d rc=%d",
+                    cptr->xid, failed, rc));
+        assert(cptr->c.void_result);
+        cptr->c.void_result(rc, cptr->data);
+        break;
+    case COMPLETION_MULTI:
+        LOG_DEBUG(("Calling COMPLETION_MULTI for xid=%#x failed=%d rc=%d",
+                    cptr->xid, failed, rc));
+        rc = deserialize_multi(xid, cptr, ia);
+        assert(cptr->c.void_result);
+        cptr->c.void_result(rc, cptr->data);
+        break;
+    default:
+        LOG_DEBUG(("Unsupported completion type=%d", cptr->c.type));
+    }
+}
+
+
+/* handles async completion (both single- and multithreaded) */
+void process_completions(zhandle_t *zh)
+{
+    completion_list_t *cptr;
+    while ((cptr = dequeue_completion(&zh->completions_to_process)) != 0) {
+        struct ReplyHeader hdr;
+        buffer_list_t *bptr = cptr->buffer;
+        struct iarchive *ia = create_buffer_iarchive(bptr->buffer,
+                bptr->len);
+        deserialize_ReplyHeader(ia, "hdr", &hdr);
+
+        if (hdr.xid == WATCHER_EVENT_XID) {
+            int type, state;
+            struct WatcherEvent evt;
+            deserialize_WatcherEvent(ia, "event", &evt);
+            /* We are doing a notification, so there is no pending request */
+            type = evt.type;
+            state = evt.state;
+            /* This is a notification so there aren't any pending requests */
+            LOG_DEBUG(("Calling a watcher for node [%s], type = %d event=%s",
+                       (evt.path==NULL?"NULL":evt.path), cptr->c.type,
+                       watcherEvent2String(type)));
+            deliverWatchers(zh,type,state,evt.path, &cptr->c.watcher_result);
+            deallocate_WatcherEvent(&evt);
+        } else {
+            deserialize_response(cptr->c.type, hdr.xid, hdr.err != 0, hdr.err, cptr, ia);
+        }
+        destroy_completion_entry(cptr);
+        close_buffer_iarchive(&ia);
+    }
+}
+
+static void isSocketReadable(zhandle_t* zh)
+{
+#ifndef WIN32
+    struct pollfd fds;
+    fds.fd = zh->fd;
+    fds.events = POLLIN;
+    if (poll(&fds,1,0)<=0) {
+        // socket not readable -- no more responses to process
+        zh->socket_readable.tv_sec=zh->socket_readable.tv_usec=0;
+    }
+#else
+    fd_set rfds;
+    struct timeval waittime = {0, 0};
+    FD_ZERO(&rfds);
+    FD_SET( zh->fd , &rfds);
+    if (select(0, &rfds, NULL, NULL, &waittime) <= 0){
+        // socket not readable -- no more responses to process
+        zh->socket_readable.tv_sec=zh->socket_readable.tv_usec=0;
+    }
+#endif
+    else{
+        gettimeofday(&zh->socket_readable,0);
+    }
+}
+
+static void checkResponseLatency(zhandle_t* zh)
+{
+    int delay;
+    struct timeval now;
+
+    if(zh->socket_readable.tv_sec==0)
+        return;
+
+    gettimeofday(&now,0);
+    delay=calculate_interval(&zh->socket_readable, &now);
+    if(delay>20)
+        LOG_DEBUG(("The following server response has spent at least %dms sitting in the client socket recv buffer",delay));
+
+    zh->socket_readable.tv_sec=zh->socket_readable.tv_usec=0;
+}
+
+int zookeeper_process(zhandle_t *zh, int events)
+{
+    buffer_list_t *bptr;
+    int rc;
+
+    if (zh==NULL)
+        return ZBADARGUMENTS;
+    if (is_unrecoverable(zh))
+        return ZINVALIDSTATE;
+    api_prolog(zh);
+    IF_DEBUG(checkResponseLatency(zh));
+    rc = check_events(zh, events);
+    if (rc!=ZOK)
+        return api_epilog(zh, rc);
+
+    IF_DEBUG(isSocketReadable(zh));
+
+    while (rc >= 0 && (bptr=dequeue_buffer(&zh->to_process))) {
+        struct ReplyHeader hdr;
+        struct iarchive *ia = create_buffer_iarchive(
+                                    bptr->buffer, bptr->curr_offset);
+        deserialize_ReplyHeader(ia, "hdr", &hdr);
+        if (hdr.zxid > 0) {
+            zh->last_zxid = hdr.zxid;
+        } else {
+            // fprintf(stderr, "Got %#x for %#x\n", hdr.zxid, hdr.xid);
+        }
+
+        if (hdr.xid == PING_XID) {
+            // Ping replies can arrive out-of-order
+            int elapsed = 0;
+            struct timeval now;
+            gettimeofday(&now, 0);
+            elapsed = calculate_interval(&zh->last_ping, &now);
+            LOG_DEBUG(("Got ping response in %d ms", elapsed));
+            free_buffer(bptr);
+        } else if (hdr.xid == WATCHER_EVENT_XID) {
+            struct WatcherEvent evt;
+            int type = 0;
+            char *path = NULL;
+            completion_list_t *c = NULL;
+
+            LOG_DEBUG(("Processing WATCHER_EVENT"));
+
+            deserialize_WatcherEvent(ia, "event", &evt);
+            type = evt.type;
+            path = evt.path;
+            /* We are doing a notification, so there is no pending request */
+            c = create_completion_entry(WATCHER_EVENT_XID,-1,0,0,0,0);
+            c->buffer = bptr;
+            c->c.watcher_result = collectWatchers(zh, type, path);
+
+            // We cannot free until now, otherwise path will become invalid
+            deallocate_WatcherEvent(&evt);
+            queue_completion(&zh->completions_to_process, c, 0);
+        } else if (hdr.xid == SET_WATCHES_XID) {
+            LOG_DEBUG(("Processing SET_WATCHES"));
+            free_buffer(bptr);
+        } else if (hdr.xid == AUTH_XID){
+            LOG_DEBUG(("Processing AUTH_XID"));
+
+            /* special handling for the AUTH response as it may come back
+             * out-of-band */
+            auth_completion_func(hdr.err,zh);
+            free_buffer(bptr);
+            /* authentication completion may change the connection state to
+             * unrecoverable */
+            if(is_unrecoverable(zh)){
+                handle_error(zh, ZAUTHFAILED);
+                close_buffer_iarchive(&ia);
+                return api_epilog(zh, ZAUTHFAILED);
+            }
+        } else {
+            int rc = hdr.err;
+            /* Find the request corresponding to the response */
+            completion_list_t *cptr = dequeue_completion(&zh->sent_requests);
+
+            /* [ZOOKEEPER-804] Don't assert if zookeeper_close has been called. */
+            if (zh->close_requested == 1 && cptr == NULL) {
+                LOG_DEBUG(("Completion queue has been cleared by zookeeper_close()"));
+                close_buffer_iarchive(&ia);
+                free_buffer(bptr);
+                return api_epilog(zh,ZINVALIDSTATE);
+            }
+            assert(cptr);
+            /* The requests are going to come back in order */
+            if (cptr->xid != hdr.xid) {
+                LOG_DEBUG(("Processing unexpected or out-of-order response!"));
+
+                // received unexpected (or out-of-order) response
+                close_buffer_iarchive(&ia);
+                free_buffer(bptr);
+                // put the completion back on the queue (so it gets properly
+                // signaled and deallocated) and disconnect from the server
+                queue_completion(&zh->sent_requests,cptr,1);
+                return api_epilog(zh,
+                                  handle_socket_error_msg(zh, __LINE__,ZRUNTIMEINCONSISTENCY,
+                                  "unexpected server response: expected %#x, but received %#x",
+                                  hdr.xid,cptr->xid));
+            }
+
+            activateWatcher(zh, cptr->watcher, rc);
+
+            if (cptr->c.void_result != SYNCHRONOUS_MARKER) {
+                LOG_DEBUG(("Queueing asynchronous response"));
+                cptr->buffer = bptr;
+                queue_completion(&zh->completions_to_process, cptr, 0);
+            } else {
+                struct sync_completion
+                        *sc = (struct sync_completion*)cptr->data;
+                sc->rc = rc;
+                
+                process_sync_completion(cptr, sc, ia, zh); 
+                
+                notify_sync_completion(sc);
+                free_buffer(bptr);
+                zh->outstanding_sync--;
+                destroy_completion_entry(cptr);
+            }
+        }
+
+        close_buffer_iarchive(&ia);
+
+    }
+    if (process_async(zh->outstanding_sync)) {
+        process_completions(zh);
+    }
+    return api_epilog(zh,ZOK);}
+
+int zoo_state(zhandle_t *zh)
+{
+    if(zh!=0)
+        return zh->state;
+    return 0;
+}
+
+static watcher_registration_t* create_watcher_registration(const char* path,
+        result_checker_fn checker,watcher_fn watcher,void* ctx){
+    watcher_registration_t* wo;
+    if(watcher==0)
+        return 0;
+    wo=calloc(1,sizeof(watcher_registration_t));
+    wo->path=strdup(path);
+    wo->watcher=watcher;
+    wo->context=ctx;
+    wo->checker=checker;
+    return wo;
+}
+
+static void destroy_watcher_registration(watcher_registration_t* wo){
+    if(wo!=0){
+        free((void*)wo->path);
+        free(wo);
+    }
+}
+
+static completion_list_t* create_completion_entry(int xid, int completion_type,
+        const void *dc, const void *data,watcher_registration_t* wo, completion_head_t *clist)
+{
+    completion_list_t *c = calloc(1,sizeof(completion_list_t));
+    if (!c) {
+        LOG_ERROR(("out of memory"));
+        return 0;
+    }
+    c->c.type = completion_type;
+    c->data = data;
+    switch(c->c.type) {
+    case COMPLETION_VOID:
+        c->c.void_result = (void_completion_t)dc;
+        break;
+    case COMPLETION_STRING:
+        c->c.string_result = (string_completion_t)dc;
+        break;
+    case COMPLETION_DATA:
+        c->c.data_result = (data_completion_t)dc;
+        break;
+    case COMPLETION_STAT:
+        c->c.stat_result = (stat_completion_t)dc;
+        break;
+    case COMPLETION_STRINGLIST:
+        c->c.strings_result = (strings_completion_t)dc;
+        break;
+    case COMPLETION_STRINGLIST_STAT:
+        c->c.strings_stat_result = (strings_stat_completion_t)dc;
+        break;
+    case COMPLETION_ACLLIST:
+        c->c.acl_result = (acl_completion_t)dc;
+        break;
+    case COMPLETION_MULTI:
+        assert(clist);
+        c->c.void_result = (void_completion_t)dc;
+        c->c.clist = *clist;
+        break;
+    }
+    c->xid = xid;
+    c->watcher = wo;
+    
+    return c;
+}
+
+static void destroy_completion_entry(completion_list_t* c){
+    if(c!=0){
+        destroy_watcher_registration(c->watcher);
+        if(c->buffer!=0)
+            free_buffer(c->buffer);
+        free(c);
+    }
+}
+
+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 */
+    if (list->last) {
+        assert(list->head);
+        // List is not empty
+        if (!add_to_front) {
+            list->last->next = c;
+            list->last = c;
+        } else {
+            c->next = list->head;
+            list->head = c;
+        }
+    } else {
+        // List is empty
+        assert(!list->head);
+        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);
+}
+
+static int add_completion(zhandle_t *zh, int xid, int completion_type,
+        const void *dc, const void *data, int add_to_front,
+        watcher_registration_t* wo, completion_head_t *clist)
+{
+    completion_list_t *c =create_completion_entry(xid, completion_type, dc,
+            data, wo, clist);
+    int rc = 0;
+    if (!c)
+        return ZSYSTEMERROR;
+    lock_completion_list(&zh->sent_requests);
+    if (zh->close_requested != 1) {
+        queue_completion_nolock(&zh->sent_requests, c, add_to_front);
+        if (dc == SYNCHRONOUS_MARKER) {
+            zh->outstanding_sync++;
+        }
+        rc = ZOK;
+    } else {
+        free(c);
+        rc = ZINVALIDSTATE;
+    }
+    unlock_completion_list(&zh->sent_requests);
+    return rc;
+}
+
+static int add_data_completion(zhandle_t *zh, int xid, data_completion_t dc,
+        const void *data,watcher_registration_t* wo)
+{
+    return add_completion(zh, xid, COMPLETION_DATA, dc, data, 0, wo, 0);
+}
+
+static int add_stat_completion(zhandle_t *zh, int xid, stat_completion_t dc,
+        const void *data,watcher_registration_t* wo)
+{
+    return add_completion(zh, xid, COMPLETION_STAT, dc, data, 0, wo, 0);
+}
+
+static int add_strings_completion(zhandle_t *zh, int xid,
+        strings_completion_t dc, const void *data,watcher_registration_t* wo)
+{
+    return add_completion(zh, xid, COMPLETION_STRINGLIST, dc, data, 0, wo, 0);
+}
+
+static int add_strings_stat_completion(zhandle_t *zh, int xid,
+        strings_stat_completion_t dc, const void *data,watcher_registration_t* wo)
+{
+    return add_completion(zh, xid, COMPLETION_STRINGLIST_STAT, dc, data, 0, wo, 0);
+}
+
+static int add_acl_completion(zhandle_t *zh, int xid, acl_completion_t dc,
+        const void *data)
+{
+    return add_completion(zh, xid, COMPLETION_ACLLIST, dc, data, 0, 0, 0);
+}
+
+static int add_void_completion(zhandle_t *zh, int xid, void_completion_t dc,
+        const void *data)
+{
+    return add_completion(zh, xid, COMPLETION_VOID, dc, data, 0, 0, 0);
+}
+
+static int add_string_completion(zhandle_t *zh, int xid,
+        string_completion_t dc, const void *data)
+{
+    return add_completion(zh, xid, COMPLETION_STRING, dc, data, 0, 0, 0);
+}
+
+static int add_multi_completion(zhandle_t *zh, int xid, void_completion_t dc,
+        const void *data, completion_head_t *clist)
+{
+    return add_completion(zh, xid, COMPLETION_MULTI, dc, data, 0,0, clist);
+}
+
+int zookeeper_close(zhandle_t *zh)
+{
+    int rc=ZOK;
+    if (zh==0)
+        return ZBADARGUMENTS;
+
+    zh->close_requested=1;
+    if (inc_ref_counter(zh,1)>1) {
+        /* We have incremented the ref counter to prevent the
+         * completions from calling zookeeper_close before we have
+         * completed the adaptor_finish call below. */
+
+	/* Signal any syncronous completions before joining the threads */
+        enter_critical(zh);
+        free_completions(zh,1,ZCLOSING);
+        leave_critical(zh);
+
+        adaptor_finish(zh);
+        /* Now we can allow the handle to be cleaned up, if the completion
+         * threads finished during the adaptor_finish call. */
+        api_epilog(zh, 0);
+        return ZOK;
+    }
+    /* No need to decrement the counter since we're just going to
+     * destroy the handle later. */
+    if(zh->state==ZOO_CONNECTED_STATE){
+        struct oarchive *oa;
+        struct RequestHeader h = { STRUCT_INITIALIZER (xid , get_xid()), STRUCT_INITIALIZER (type , ZOO_CLOSE_OP)};
+        LOG_INFO(("Closing zookeeper sessionId=%#llx to [%s]\n",
+                zh->client_id.client_id,format_current_endpoint_info(zh)));
+        oa = create_buffer_oarchive();
+        rc = serialize_RequestHeader(oa, "header", &h);
+        rc = rc < 0 ? rc : queue_buffer_bytes(&zh->to_send, get_buffer(oa),
+                get_buffer_len(oa));
+        /* We queued the buffer, so don't free it */
+        close_buffer_oarchive(&oa, 0);
+        if (rc < 0) {
+            rc = ZMARSHALLINGERROR;
+            goto finish;
+        }
+
+        /* make sure the close request is sent; we set timeout to an arbitrary
+         * (but reasonable) number of milliseconds since we want the call to block*/
+        rc=adaptor_send_queue(zh, 3000);
+    }else{
+        LOG_INFO(("Freeing zookeeper resources for sessionId=%#llx\n",
+                zh->client_id.client_id));
+        rc = ZOK;
+    }
+
+finish:
+    destroy(zh);
+    adaptor_destroy(zh);
+    free(zh);
+#ifdef WIN32
+    Win32WSACleanup();
+#endif
+    return rc;
+}
+
+static int isValidPath(const char* path, const int flags) {
+    int len = 0;
+    char lastc = '/';
+    char c;
+    int i = 0;
+
+  if (path == 0)
+    return 0;
+  len = strlen(path);
+  if (len == 0)
+    return 0;
+  if (path[0] != '/')
+    return 0;
+  if (len == 1) // done checking - it's the root
+    return 1;
+  if (path[len - 1] == '/' && !(flags & ZOO_SEQUENCE))
+    return 0;
+
+  i = 1;
+  for (; i < len; lastc = path[i], i++) {
+    c = path[i];
+
+    if (c == 0) {
+      return 0;
+    } else if (c == '/' && lastc == '/') {
+      return 0;
+    } else if (c == '.' && lastc == '.') {
+      if (path[i-2] == '/' && (((i + 1 == len) && !(flags & ZOO_SEQUENCE))
+                               || path[i+1] == '/')) {
+        return 0;
+      }
+    } else if (c == '.') {
+      if ((path[i-1] == '/') && (((i + 1 == len) && !(flags & ZOO_SEQUENCE))
+                                 || path[i+1] == '/')) {
+        return 0;
+      }
+    } else if (c > 0x00 && c < 0x1f) {
+      return 0;
+    }
+  }
+
+  return 1;
+}
+
+/*---------------------------------------------------------------------------*
+ * REQUEST INIT HELPERS
+ *---------------------------------------------------------------------------*/
+/* Common Request init helper functions to reduce code duplication */
+static int Request_path_init(zhandle_t *zh, int flags, 
+        char **path_out, const char *path)
+{
+    assert(path_out);
+    
+    *path_out = prepend_string(zh, path);
+    if (zh == NULL || !isValidPath(*path_out, flags)) {
+        free_duplicate_path(*path_out, path);
+        return ZBADARGUMENTS;
+    }
+    if (is_unrecoverable(zh)) {
+        free_duplicate_path(*path_out, path);
+        return ZINVALIDSTATE;
+    }
+
+    return ZOK;
+}
+
+static int Request_path_watch_init(zhandle_t *zh, int flags,
+        char **path_out, const char *path,
+        int32_t *watch_out, uint32_t watch)
+{
+    int rc = Request_path_init(zh, flags, path_out, path);
+    if (rc != ZOK) {
+        return rc;
+    }
+    *watch_out = watch;
+    return ZOK;
+}
+
+/*---------------------------------------------------------------------------*
+ * ASYNC API
+ *---------------------------------------------------------------------------*/
+int zoo_aget(zhandle_t *zh, const char *path, int watch, data_completion_t dc,
+        const void *data)
+{
+    return zoo_awget(zh,path,watch?zh->watcher:0,zh->context,dc,data);
+}
+
+int zoo_awget(zhandle_t *zh, const char *path,
+        watcher_fn watcher, void* watcherCtx,
+        data_completion_t dc, const void *data)
+{
+    struct oarchive *oa;
+    char *server_path = prepend_string(zh, path);
+    struct RequestHeader h = { STRUCT_INITIALIZER (xid , get_xid()), STRUCT_INITIALIZER (type ,ZOO_GETDATA_OP)};
+    struct GetDataRequest req =  { (char*)server_path, watcher!=0 };
+    int rc;
+
+    if (zh==0 || !isValidPath(server_path, 0)) {
+        free_duplicate_path(server_path, path);
+        return ZBADARGUMENTS;
+    }
+    if (is_unrecoverable(zh)) {
+        free_duplicate_path(server_path, path);
+        return ZINVALIDSTATE;
+    }
+    oa=create_buffer_oarchive();
+    rc = serialize_RequestHeader(oa, "header", &h);
+    rc = rc < 0 ? rc : serialize_GetDataRequest(oa, "req", &req);
+    enter_critical(zh);
+    rc = rc < 0 ? rc : add_data_completion(zh, h.xid, dc, data,
+        create_watcher_registration(server_path,data_result_checker,watcher,watcherCtx));
+    rc = rc < 0 ? rc : queue_buffer_bytes(&zh->to_send, get_buffer(oa),
+            get_buffer_len(oa));
+    leave_critical(zh);
+    free_duplicate_path(server_path, path);
+    /* We queued the buffer, so don't free it */
+    close_buffer_oarchive(&oa, 0);
+
+    LOG_DEBUG(("Sending request xid=%#x for path [%s] to %s",h.xid,path,
+            format_current_endpoint_info(zh)));
+    /* make a best (non-blocking) effort to send the requests asap */
+    adaptor_send_queue(zh, 0);
+    return (rc < 0)?ZMARSHALLINGERROR:ZOK;
+}
+
+static int SetDataRequest_init(zhandle_t *zh, struct SetDataRequest *req,
+        const char *path, const char *buffer, int buflen, int version)
+{
+    int rc;
+    assert(req);
+    rc = Request_path_init(zh, 0, &req->path, path);
+    if (rc != ZOK) {
+        return rc;
+    }
+    req->data.buff = (char*)buffer;
+    req->data.len = buflen;
+    req->version = version;
+
+    return ZOK;
+}
+
+int zoo_aset(zhandle_t *zh, const char *path, const char *buffer, int buflen,
+        int version, stat_completion_t dc, const void *data)
+{
+    struct oarchive *oa;
+    struct RequestHeader h = { STRUCT_INITIALIZER(xid , get_xid()), STRUCT_INITIALIZER (type , ZOO_SETDATA_OP)};
+    struct SetDataRequest req;
+    int rc = SetDataRequest_init(zh, &req, path, buffer, buflen, version);
+    if (rc != ZOK) {
+        return rc;
+    }
+    oa = create_buffer_oarchive();
+    rc = serialize_RequestHeader(oa, "header", &h);
+    rc = rc < 0 ? rc : serialize_SetDataRequest(oa, "req", &req);
+    enter_critical(zh);
+    rc = rc < 0 ? rc : add_stat_completion(zh, h.xid, dc, data,0);
+    rc

<TRUNCATED>