Skip to content

Instantly share code, notes, and snippets.

@ochinchina
Created July 7, 2014 10:05
Show Gist options
  • Save ochinchina/54f013aaff449cb6ecde to your computer and use it in GitHub Desktop.
Save ochinchina/54f013aaff449cb6ecde to your computer and use it in GitHub Desktop.
implement barrier with the zookeeper C API, require C++11 compiler
CPP = g++
INCS = -I$(ZK_DIR)/src/c/include -I$(ZK_DIR)/src/c/generated
LIBS = -L$(ZK_DIR)/src/c/.libs -lzookeeper_mt -lpthread
CXX_FLAGS = -std=c++11
all: barrier
barrier: ZkBarrierTest.o
$(CPP) -o barrier ZkBarrierTest.o $(LIBS)
.cpp.o:
$(CPP) -c $(CXX_FLAGS) $(INCS) $<
#include <zookeeper.h>
#include <iostream>
#include <string>
#include <unistd.h>
#include <mutex>
#include <condition_variable>
class ZkBarrier {
public:
ZkBarrier( const std::string& host,
const std::string& root,
const std::string& name,
int size )
:host_( host ),
root_( root ),
name_( name ),
size_( size ),
connected_( false )
{
handle_ = zookeeper_init( host_.c_str(), watch, 5*1000, 0, this, 0 );
{
std::unique_lock<std::mutex> lock(mutex_);
while( !connected_) {
cond_.wait( lock );
}
}
std::cout << "2, zookeeper connected" << std::endl;
Stat stat;
if( zoo_exists( handle_, root_.c_str(), false, &stat ) == ZOK ) {
std::cout << root_ << " already exists" << std::endl;
} else {
std::cout << root_ << " does not exist" << std::endl;
if( zoo_create( handle_, root_.c_str(), "simple test", 11, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0 ) == ZOK ) {
std::cout << "create " << root_ << " successfully" << std::endl;
}
}
}
~ZkBarrier() {
zookeeper_close( handle_ );
}
void enter() {
std::string path = root_ + "/" + name_;
if( zoo_create( handle_, path.c_str(), "simple test", 11, &ZOO_OPEN_ACL_UNSAFE, 0, 0, 0 ) == ZOK ) {
std::cout << "create " << path << " successfully" << std::endl;
}
for( ; ; ) {
std::unique_lock<std::mutex> lock(mutex_);
String_vector children;
if( zoo_get_children( handle_, root_.c_str(), true, &children ) == ZOK ) {
if( children.count >= size_ ) {
deallocate_String_vector( &children );
break;
} else {
deallocate_String_vector( &children );
}
cond_.wait( lock );
}
}
}
void leave() {
std::string path = root_ + "/" + name_;
if( zoo_delete( handle_, path.c_str(), -1 ) == ZOK ) {
std::cout << "delete " << path << " successfully" << std::endl;
}
}
private:
static void watch(zhandle_t *zh, int type, int state, const char *path,void *watcherCtx ) {
ZkBarrier* barrier = (ZkBarrier*)watcherCtx;
if( state == ZOO_CONNECTED_STATE || type == ZOO_CHILD_EVENT ) {
std::cout << "1, zookeeper connected" << std::endl;
{
std::unique_lock<std::mutex> lock(barrier->mutex_);
barrier->connected_ = true;
}
barrier->cond_.notify_one();
}
}
private:
std::string host_;
std::string root_;
std::string name_;
int size_;
zhandle_t* handle_;
bool connected_;
std::mutex mutex_;
std::condition_variable cond_;
};
int main( int argc, char** argv ) {
ZkBarrier barrier("127.0.0.1:2181", "/root", argv[1], atoi( argv[2]) );
barrier.enter();
//TODO: do something you like
barrier.leave();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment